diff --git a/plugins/gs/gsdx9/GS.cpp b/plugins/gs/gsdx9/GS.cpp deleted file mode 100644 index 78070540b4..0000000000 --- a/plugins/gs/gsdx9/GS.cpp +++ /dev/null @@ -1,441 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" -#include "GSdx9.h" -#include "GS.h" -#include "GSRendererHW.h" -#include "GSRendererSoft.h" -#include "GSRendererNull.h" -#include "GSWnd.h" -#include "GSSettingsDlg.h" - -#define PS2E_LT_GS 0x01 -#define PS2E_GS_VERSION 0x0006 -#define PS2E_DLL_VERSION 0x09 -#define PS2E_X86 0x01 // 32 bit -#define PS2E_X86_64 0x02 // 64 bit - -EXPORT_C_(UINT32) PS2EgetLibType() -{ - return PS2E_LT_GS; -} - -EXPORT_C_(char*) PS2EgetLibName() -{ - CString str = _T("GSdx9"); - -#if _M_AMD64 - str += _T(" 64-bit"); -#endif - - CList sl; - -#ifdef __INTEL_COMPILER - CString s; - s.Format(_T("Intel C++ %d.%02d"), __INTEL_COMPILER/100, __INTEL_COMPILER%100); - sl.AddTail(s); -#elif _MSC_VER - CString s; - s.Format(_T("MSVC %d.%02d"), _MSC_VER/100, _MSC_VER%100); - sl.AddTail(s); -#endif - -#if _M_IX86_FP >= 2 - sl.AddTail(_T("SSE2")); -#elif _M_IX86_FP >= 1 - sl.AddTail(_T("SSE")); -#endif - -#ifdef _OPENMP - sl.AddTail(_T("OpenMP")); -#endif - - POSITION pos = sl.GetHeadPosition(); - while(pos) - { - if(pos == sl.GetHeadPosition()) str += _T(" ("); - str += sl.GetNext(pos); - str += pos ? _T(", ") : _T(")"); - } - - static char buff[256]; - strncpy(buff, CStringA(str), min(countof(buff)-1, str.GetLength())); - return buff; -} - -EXPORT_C_(UINT32) PS2EgetLibVersion2(UINT32 type) -{ - return (PS2E_GS_VERSION<<16)|(0x00<<8)|PS2E_DLL_VERSION; -} - -EXPORT_C_(UINT32) PS2EgetCpuPlatform() -{ -#if _M_AMD64 - return PS2E_X86_64; -#else - return PS2E_X86; -#endif -} - -////////////////// - -#define REPLAY_TITLE "Replay" - -static HRESULT s_hrCoInit = E_FAIL; -static CGSWnd s_hWnd; -static CAutoPtr s_gs; -static void (*s_fpGSirq)() = NULL; - -BYTE* g_pBasePS2Mem = NULL; - -EXPORT_C GSsetBaseMem(BYTE* pBasePS2Mem) -{ - g_pBasePS2Mem = pBasePS2Mem - 0x12000000; -} - -EXPORT_C_(INT32) GSinit() -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - return 0; -} - -EXPORT_C GSshutdown() -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); -} - -EXPORT_C_(INT32) GSopen(void* pDsp, char* Title, int multithread) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - // - - s_hrCoInit = ::CoInitialize(0); - - ASSERT(!s_gs); - s_gs.Free(); - - if(!s_hWnd.Create(_T("PCSX2"))) - return -1; - - HRESULT hr; - - switch(AfxGetApp()->GetProfileInt(_T("Settings"), _T("Renderer"), RENDERER_D3D_HW)) - { - case RENDERER_D3D_HW: s_gs.Attach(new GSRendererHW(s_hWnd, hr)); break; - // case RENDERER_D3D_SW_FX: s_gs.Attach(new GSRendererSoftFX(s_hWnd, hr)); break; - case RENDERER_D3D_SW_FP: s_gs.Attach(new GSRendererSoftFP(s_hWnd, hr)); break; - case RENDERER_D3D_NULL: s_gs.Attach(new GSRendererNull(s_hWnd, hr)); break; - } - - if(!s_gs || FAILED(hr)) - { - s_gs.Free(); - s_hWnd.DestroyWindow(); - return -1; - } - - // - - if(!IsWindow(s_hWnd)) - return -1; - - *(HWND*)pDsp = s_hWnd; - - s_gs->ResetDevice(); - - s_gs->GSirq(s_fpGSirq); - - s_gs->m_fMultiThreaded = !!multithread; - - if((!Title || strcmp(Title, REPLAY_TITLE) != 0) - && AfxGetApp()->GetProfileInt(_T("Settings"), _T("RecordState"), FALSE)) - { - CPath spath = AfxGetApp()->GetProfileString(_T("Settings"), _T("RecordStatePath"), _T("")); - CString fn; - fn.Format(_T("gsdx9_%s.gs"), CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S"))); - spath.Append(fn); - s_gs->CaptureState(spath); - } - - s_hWnd.SetWindowText(CString(Title)); - - s_hWnd.Show(); - - return 0; -} - -EXPORT_C GSclose() -{ - s_hWnd.Show(false); - - ASSERT(s_gs); - s_gs.Free(); - - s_hWnd.DestroyWindow(); - - if(SUCCEEDED(s_hrCoInit)) ::CoUninitialize(); -} - -EXPORT_C GSreset() -{ - s_gs->Reset(); -} - -EXPORT_C GSwriteCSR(UINT32 csr) -{ - s_gs->WriteCSR(csr); -} - -EXPORT_C GSreadFIFO(BYTE* pMem) -{ - s_gs->ReadFIFO(pMem); -} - -EXPORT_C GSgifTransfer1(BYTE* pMem, UINT32 addr) -{ - s_gs->Transfer1(pMem, addr); -} - -EXPORT_C GSgifTransfer2(BYTE* pMem, UINT32 size) -{ - s_gs->Transfer2(pMem, size); -} - -EXPORT_C GSgifTransfer3(BYTE* pMem, UINT32 size) -{ - s_gs->Transfer3(pMem, size); -} - -extern int Path3hack; - -EXPORT_C GSgetLastTag(UINT64* ptag) -{ - *(UINT32*)ptag = Path3hack; - Path3hack = 0; -} - -EXPORT_C GSvsync(int field) -{ - MSG msg; - ZeroMemory(&msg, sizeof(msg)); - while(msg.message != WM_QUIT) - { - if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else - { - // TODO - // Sleep(40); - s_gs->VSync(field); - break; - } - } -} - -//////// - -EXPORT_C_(UINT32) GSmakeSnapshot(char* path) -{ - return s_gs->MakeSnapshot(path); -} - - - -EXPORT_C GSkeyEvent(keyEvent* ev) -{ - if(ev->event != KEYPRESS) return; - - switch(ev->key) - { - case VK_INSERT: - s_gs->Capture(); - break; - - case VK_DELETE: - s_gs->ToggleOSD(); - break; - - default: - break; - } -} - -EXPORT_C_(INT32) GSfreeze(int mode, freezeData* data) -{ - if(mode == FREEZE_SAVE) - { - return s_gs->Freeze(data, false); - } - else if(mode == FREEZE_SIZE) - { - return s_gs->Freeze(data, true); - } - else if(mode == FREEZE_LOAD) - { - return s_gs->Defrost(data); - } - - return 0; -} - -EXPORT_C GSconfigure() -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - if(IDOK == CGSSettingsDlg().DoModal()) - { - GSshutdown(); - GSinit(); - } -} - -EXPORT_C_(INT32) GStest() -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - int ret = 0; - - D3DCAPS9 caps; - ZeroMemory(&caps, sizeof(caps)); - caps.PixelShaderVersion = D3DPS_VERSION(0, 0); - - if(CComPtr pD3D = Direct3DCreate9(D3D_SDK_VERSION)) - { - pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, &caps); - - LPCTSTR yep = _T("^_^"), nope = _T(":'("); - - CString str, tmp; - - if(caps.PixelShaderVersion < D3DPS_VERSION(1, 4)) - ret = -1; - - tmp.Format(_T("%s Pixel Shader version %d.%d\n"), - caps.PixelShaderVersion >= D3DPS_VERSION(1, 4) ? yep : nope, - D3DSHADER_VERSION_MAJOR(caps.PixelShaderVersion), - D3DSHADER_VERSION_MINOR(caps.PixelShaderVersion)); - str += tmp; - - if(!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND)) - ret = -1; - - tmp.Format(_T("%s Separate Alpha Blend\n"), - !!(caps.PrimitiveMiscCaps & D3DPMISCCAPS_SEPARATEALPHABLEND) ? yep : nope); - str += tmp; - - if(!(caps.SrcBlendCaps & D3DPBLENDCAPS_BLENDFACTOR) - || !(caps.DestBlendCaps & D3DPBLENDCAPS_BLENDFACTOR)) - ret = -1; - - tmp.Format(_T("%s Source Blend Factor\n"), - !!(caps.SrcBlendCaps & D3DPBLENDCAPS_BLENDFACTOR) ? yep : nope); - str += tmp; - - tmp.Format(_T("%s Destination Blend Factor\n"), - !!(caps.DestBlendCaps & D3DPBLENDCAPS_BLENDFACTOR) ? yep : nope); - str += tmp; - - AfxMessageBox(str); - } - else - { - ret = -1; - } - - return ret; -} - -EXPORT_C GSabout() -{ -} - -EXPORT_C GSirqCallback(void (*fpGSirq)()) -{ - s_fpGSirq = fpGSirq; - // if(s_gs) s_gs->GSirq(fpGSirq); -} - -///////////////// -/* -EXPORT_C GSReplay(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) -{ - if(!GSinit()) - { - HWND hWnd = NULL; - if(!GSopen((void*)&hWnd, REPLAY_TITLE)) - { - if(FILE* sfp = _tfopen(lpszCmdLine, _T("rb"))) - { - BYTE* buff = (BYTE*)_aligned_malloc(4*1024*1024, 16); - - while(!feof(sfp)) - { - switch(fgetc(sfp)) - { - case ST_WRITE: - { - GS_REG mem; - UINT64 value, mask; - fread(&mem, 4, 1, sfp); - fread(&value, 8, 1, sfp); - fread(&mask, 8, 1, sfp); - switch(mask) - { - case 0xff: GSwrite8(mem, (UINT8)value); break; - case 0xffff: GSwrite16(mem, (UINT16)value); break; - case 0xffffffff: GSwrite32(mem, (UINT32)value); break; - case 0xffffffffffffffff: GSwrite64(mem, value); break; - } - break; - } - case ST_TRANSFER: - { - UINT32 size = 0; - fread(&size, 4, 1, sfp); - UINT32 len = 0; - fread(&len, 4, 1, sfp); - if(len > 4*1024*1024) {ASSERT(0); break;} - fread(buff, len, 1, sfp); - GSgifTransfer3(buff, size); - break; - } - case ST_VSYNC: - GSvsync(); - break; - } - } - - _aligned_free(buff); - } - - GSclose(); - } - - GSshutdown(); - } -} -*/ \ No newline at end of file diff --git a/plugins/gs/gsdx9/GS.h b/plugins/gs/gsdx9/GS.h deleted file mode 100644 index 89c20272a5..0000000000 --- a/plugins/gs/gsdx9/GS.h +++ /dev/null @@ -1,945 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - * Special Notes: - * - * Register definitions and most of the enums originate from sps2dev-0.4.0 - * Copyright (C) 2002 Terratron Technologies Inc. All Rights Reserved. - * - */ - -#pragma once - -// - -#pragma pack(push, 1) - -// -// sps2registers.h -// - -enum GS_REG -{ - GS_PMODE = 0x12000000, - GS_SMODE1 = 0x12000010, - GS_SMODE2 = 0x12000020, - GS_SRFSH = 0x12000030, - GS_SYNCH1 = 0x12000040, - GS_SYNCH2 = 0x12000050, - GS_SYNCV = 0x12000060, - GS_DISPFB1 = 0x12000070, - GS_DISPLAY1 = 0x12000080, - GS_DISPFB2 = 0x12000090, - GS_DISPLAY2 = 0x120000a0, - GS_EXTBUF = 0x120000b0, - GS_EXTDATA = 0x120000c0, - GS_EXTWRITE = 0x120000d0, - GS_BGCOLOR = 0x120000e0, - GS_UNKNOWN = 0x12000400, - GS_CSR = 0x12001000, - GS_IMR = 0x12001010, - GS_BUSDIR = 0x12001040, - GS_SIGLBLID = 0x12001080 -}; - -enum GS_PRIM -{ - GS_POINTLIST = 0, - GS_LINELIST = 1, - GS_LINESTRIP = 2, - GS_TRIANGLELIST = 3, - GS_TRIANGLESTRIP = 4, - GS_TRIANGLEFAN = 5, - GS_SPRITE = 6, - GS_INVALID = 7, -}; - -enum GIF_REG -{ - GIF_REG_PRIM = 0x00, - GIF_REG_RGBA = 0x01, - GIF_REG_STQ = 0x02, - GIF_REG_UV = 0x03, - GIF_REG_XYZF2 = 0x04, - GIF_REG_XYZ2 = 0x05, - GIF_REG_TEX0_1 = 0x06, - GIF_REG_TEX0_2 = 0x07, - GIF_REG_CLAMP_1 = 0x08, - GIF_REG_CLAMP_2 = 0x09, - GIF_REG_FOG = 0x0a, - GIF_REG_XYZF3 = 0x0c, - GIF_REG_XYZ3 = 0x0d, - GIF_REG_A_D = 0x0e, - GIF_REG_NOP = 0x0f, -}; - -enum GIF_A_D_REG -{ - GIF_A_D_REG_PRIM = 0x00, - GIF_A_D_REG_RGBAQ = 0x01, - GIF_A_D_REG_ST = 0x02, - GIF_A_D_REG_UV = 0x03, - GIF_A_D_REG_XYZF2 = 0x04, - GIF_A_D_REG_XYZ2 = 0x05, - GIF_A_D_REG_TEX0_1 = 0x06, - GIF_A_D_REG_TEX0_2 = 0x07, - GIF_A_D_REG_CLAMP_1 = 0x08, - GIF_A_D_REG_CLAMP_2 = 0x09, - GIF_A_D_REG_FOG = 0x0a, - GIF_A_D_REG_XYZF3 = 0x0c, - GIF_A_D_REG_XYZ3 = 0x0d, - GIF_A_D_REG_NOP = 0x0f, - GIF_A_D_REG_TEX1_1 = 0x14, - GIF_A_D_REG_TEX1_2 = 0x15, - GIF_A_D_REG_TEX2_1 = 0x16, - GIF_A_D_REG_TEX2_2 = 0x17, - GIF_A_D_REG_XYOFFSET_1 = 0x18, - GIF_A_D_REG_XYOFFSET_2 = 0x19, - GIF_A_D_REG_PRMODECONT = 0x1a, - GIF_A_D_REG_PRMODE = 0x1b, - GIF_A_D_REG_TEXCLUT = 0x1c, - GIF_A_D_REG_SCANMSK = 0x22, - GIF_A_D_REG_MIPTBP1_1 = 0x34, - GIF_A_D_REG_MIPTBP1_2 = 0x35, - GIF_A_D_REG_MIPTBP2_1 = 0x36, - GIF_A_D_REG_MIPTBP2_2 = 0x37, - GIF_A_D_REG_TEXA = 0x3b, - GIF_A_D_REG_FOGCOL = 0x3d, - GIF_A_D_REG_TEXFLUSH = 0x3f, - GIF_A_D_REG_SCISSOR_1 = 0x40, - GIF_A_D_REG_SCISSOR_2 = 0x41, - GIF_A_D_REG_ALPHA_1 = 0x42, - GIF_A_D_REG_ALPHA_2 = 0x43, - GIF_A_D_REG_DIMX = 0x44, - GIF_A_D_REG_DTHE = 0x45, - GIF_A_D_REG_COLCLAMP = 0x46, - GIF_A_D_REG_TEST_1 = 0x47, - GIF_A_D_REG_TEST_2 = 0x48, - GIF_A_D_REG_PABE = 0x49, - GIF_A_D_REG_FBA_1 = 0x4a, - GIF_A_D_REG_FBA_2 = 0x4b, - GIF_A_D_REG_FRAME_1 = 0x4c, - GIF_A_D_REG_FRAME_2 = 0x4d, - GIF_A_D_REG_ZBUF_1 = 0x4e, - GIF_A_D_REG_ZBUF_2 = 0x4f, - GIF_A_D_REG_BITBLTBUF = 0x50, - GIF_A_D_REG_TRXPOS = 0x51, - GIF_A_D_REG_TRXREG = 0x52, - GIF_A_D_REG_TRXDIR = 0x53, - GIF_A_D_REG_HWREG = 0x54, - GIF_A_D_REG_SIGNAL = 0x60, - GIF_A_D_REG_FINISH = 0x61, - GIF_A_D_REG_LABEL = 0x62, -}; - -enum GIF_FLG -{ - GIF_FLG_PACKED = 0, - GIF_FLG_REGLIST = 1, - GIF_FLG_IMAGE = 2, - GIF_FLG_IMAGE2 = 3 -}; - -enum PSM -{ - PSM_PSMCT32 = 0, - PSM_PSMCT24 = 1, - PSM_PSMCT16 = 2, - PSM_PSMCT16S = 10, - PSM_PSMT8 = 19, - PSM_PSMT4 = 20, - PSM_PSMT8H = 27, - PSM_PSMT4HL = 36, - PSM_PSMT4HH = 44, - PSM_PSMZ32 = 48, - PSM_PSMZ24 = 49, - PSM_PSMZ16 = 50, - PSM_PSMZ16S = 58, -}; - -// -// sps2regstructs.h -// - -#define REG64(name) \ -union name \ -{ \ - UINT64 i64; \ - UINT32 ai32[2]; \ - struct { \ - -#define REG128(name)\ -union name \ -{ \ - UINT64 ai64[2]; \ - UINT32 ai32[4]; \ - struct { \ - -#define REG64_(prefix, name) REG64(prefix##name) -#define REG128_(prefix, name) REG128(prefix##name) - -#define REG_END }; }; -#define REG_END2 }; - -#define REG64_SET(name) \ -union name \ -{ \ - UINT64 i64; \ - UINT32 ai32[2]; \ - -#define REG128_SET(name)\ -union name \ -{ \ - UINT64 ai64[2]; \ - UINT32 ai32[4]; \ - -#define REG_SET_END }; - -REG64_(GSReg, BGCOLOR) - UINT32 R:8; - UINT32 G:8; - UINT32 B:8; - UINT32 _PAD1:8; - UINT32 _PAD2:32; -REG_END - -REG64_(GSReg, BUSDIR) - UINT32 DIR:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; -REG_END - -REG64_(GSReg, CSR) - UINT32 rSIGNAL:1; - UINT32 rFINISH:1; - UINT32 rHSINT:1; - UINT32 rVSINT:1; - UINT32 rEDWINT:1; - UINT32 rZERO1:1; - UINT32 rZERO2:1; - UINT32 r_PAD1:1; - UINT32 rFLUSH:1; - UINT32 rRESET:1; - UINT32 r_PAD2:2; - UINT32 rNFIELD:1; - UINT32 rFIELD:1; - UINT32 rFIFO:2; - UINT32 rREV:8; - UINT32 rID:8; - UINT32 wSIGNAL:1; - UINT32 wFINISH:1; - UINT32 wHSINT:1; - UINT32 wVSINT:1; - UINT32 wEDWINT:1; - UINT32 wZERO1:1; - UINT32 wZERO2:1; - UINT32 w_PAD1:1; - UINT32 wFLUSH:1; - UINT32 wRESET:1; - UINT32 w_PAD2:2; - UINT32 wNFIELD:1; - UINT32 wFIELD:1; - UINT32 wFIFO:2; - UINT32 wREV:8; - UINT32 wID:8; -REG_END - -REG64_(GSReg, DISPFB) // (-1/2) - UINT32 FBP:9; - UINT32 FBW:6; - UINT32 PSM:5; - UINT32 _PAD:12; - UINT32 DBX:11; - UINT32 DBY:11; - UINT32 _PAD2:10; -REG_END - -REG64_(GSReg, DISPLAY) // (-1/2) - UINT32 DX:12; - UINT32 DY:11; - UINT32 MAGH:4; - UINT32 MAGV:2; - UINT32 _PAD:3; - UINT32 DW:12; - UINT32 DH:11; - UINT32 _PAD2:9; -REG_END - -REG64_(GSReg, EXTBUF) - UINT32 EXBP:14; - UINT32 EXBW:6; - UINT32 FBIN:2; - UINT32 WFFMD:1; - UINT32 EMODA:2; - UINT32 EMODC:2; - UINT32 _PAD1:5; - UINT32 WDX:11; - UINT32 WDY:11; - UINT32 _PAD2:10; -REG_END - -REG64_(GSReg, EXTDATA) - UINT32 SX:12; - UINT32 SY:11; - UINT32 SMPH:4; - UINT32 SMPV:2; - UINT32 _PAD1:3; - UINT32 WW:12; - UINT32 WH:11; - UINT32 _PAD2:9; -REG_END - -REG64_(GSReg, EXTWRITE) - UINT32 WRITE:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; -REG_END - -REG64_(GSReg, IMR) - UINT32 _PAD1:8; - UINT32 SIGMSK:1; - UINT32 FINISHMSK:1; - UINT32 HSMSK:1; - UINT32 VSMSK:1; - UINT32 EDWMSK:1; - UINT32 _PAD2:19; - UINT32 _PAD3:32; -REG_END - -REG64_(GSReg, PMODE) - UINT32 EN1:1; - UINT32 EN2:1; - UINT32 CRTMD:3; - UINT32 MMOD:1; - UINT32 AMOD:1; - UINT32 SLBG:1; - UINT32 ALP:8; - UINT32 _PAD:16; - UINT32 _PAD1:32; -REG_END - -REG64_(GSReg, SIGLBLID) - UINT32 SIGID:32; - UINT32 LBLID:32; -REG_END - -REG64_(GSReg, SMODE1) - UINT32 RC:3; - UINT32 LC:7; - UINT32 T1248:2; - UINT32 SLCK:1; - UINT32 CMOD:2; - UINT32 EX:1; - UINT32 PRST:1; - UINT32 SINT:1; - UINT32 XPCK:1; - UINT32 PCK2:2; - UINT32 SPML:4; - UINT32 GCONT:1; - UINT32 PHS:1; - UINT32 PVS:1; - UINT32 PEHS:1; - UINT32 PEVS:1; - UINT32 CLKSEL:2; - UINT32 NVCK:1; - UINT32 SLCK2:1; - UINT32 VCKSEL:2; - UINT32 VHP:1; - UINT32 _PAD1:27; -REG_END - -REG64_(GSReg, SMODE2) - UINT32 INT:1; - UINT32 FFMD:1; - UINT32 DPMS:2; - UINT32 _PAD2:28; - UINT32 _PAD3:32; -REG_END - -REG64_SET(GSReg) - GSRegBGCOLOR BGCOLOR; - GSRegBUSDIR BUSDIR; - GSRegCSR CSR; - GSRegDISPFB DISPFB; - GSRegDISPLAY DISPLAY; - GSRegEXTBUF EXTBUF; - GSRegEXTDATA EXTDATA; - GSRegEXTWRITE EXTWRITE; - GSRegIMR IMR; - GSRegPMODE PMODE; - GSRegSIGLBLID SIGLBLID; - GSRegSMODE1 SMODE1; - GSRegSMODE2 SMODE2; -REG_SET_END - -// -// sps2tags.h -// - -#define SET_GIF_REG(gifTag, iRegNo, uiValue) \ - {((GIFTag*)&gifTag)->ai64[1] |= (((uiValue) & 0xf) << ((iRegNo) << 2));} - -#ifdef _M_AMD64 -#define GET_GIF_REG(tag, reg) \ - (((tag).ai64[1] >> ((reg) << 2)) & 0xf) -#else -#define GET_GIF_REG(tag, reg) \ - (((tag).ai32[2 + ((reg) >> 3)] >> (((reg) & 7) << 2)) & 0xf) -#endif - -// -// GIFTag - -REG128(GIFTag) - UINT32 NLOOP:15; - UINT32 EOP:1; - UINT32 _PAD1:16; - UINT32 _PAD2:14; - UINT32 PRE:1; - UINT32 PRIM:11; - UINT32 FLG:2; // enum GIF_FLG - UINT32 NREG:4; - UINT64 REGS:64; -REG_END - -// GIFReg - -REG64_(GIFReg, ALPHA) - UINT32 A:2; - UINT32 B:2; - UINT32 C:2; - UINT32 D:2; - UINT32 _PAD1:24; - UINT32 FIX:8; - UINT32 _PAD2:24; -REG_END - -REG64_(GIFReg, BITBLTBUF) - UINT32 SBP:14; - UINT32 _PAD1:2; - UINT32 SBW:6; - UINT32 _PAD2:2; - UINT32 SPSM:6; - UINT32 _PAD3:2; - UINT32 DBP:14; - UINT32 _PAD4:2; - UINT32 DBW:6; - UINT32 _PAD5:2; - UINT32 DPSM:6; - UINT32 _PAD6:2; -REG_END - -REG64_(GIFReg, CLAMP) - UINT64 WMS:2; - UINT64 WMT:2; - UINT64 MINU:10; - UINT64 MAXU:10; - UINT64 MINV:10; - UINT64 MAXV:10; - UINT64 _PAD:20; -REG_END - -REG64_(GIFReg, COLCLAMP) - UINT32 CLAMP:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, DIMX) - UINT32 DM00:3; - UINT32 _PAD00:1; - UINT32 DM01:3; - UINT32 _PAD01:1; - UINT32 DM02:3; - UINT32 _PAD02:1; - UINT32 DM03:3; - UINT32 _PAD03:1; - - UINT32 DM10:3; - UINT32 _PAD10:1; - UINT32 DM11:3; - UINT32 _PAD11:1; - UINT32 DM12:3; - UINT32 _PAD12:1; - UINT32 DM13:3; - UINT32 _PAD13:1; - - UINT32 DM20:3; - UINT32 _PAD20:1; - UINT32 DM21:3; - UINT32 _PAD21:1; - UINT32 DM22:3; - UINT32 _PAD22:1; - UINT32 DM23:3; - UINT32 _PAD23:1; - - UINT32 DM30:3; - UINT32 _PAD30:1; - UINT32 DM31:3; - UINT32 _PAD31:1; - UINT32 DM32:3; - UINT32 _PAD32:1; - UINT32 DM33:3; - UINT32 _PAD33:1; -REG_END - -REG64_(GIFReg, DTHE) - UINT32 DTHE:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, FBA) - UINT32 FBA:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, FINISH) - UINT32 _PAD1:32; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, FOG) - UINT32 _PAD1:32; - UINT32 _PAD2:24; - UINT32 F:8; -REG_END - -REG64_(GIFReg, FOGCOL) - UINT32 FCR:8; - UINT32 FCG:8; - UINT32 FCB:8; - UINT32 _PAD1:8; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, FRAME) - UINT32 FBP:9; - UINT32 _PAD1:7; - UINT32 FBW:6; - UINT32 _PAD2:2; - UINT32 PSM:6; - UINT32 _PAD3:2; - UINT32 FBMSK:32; -REG_END2 - UINT32 Block() {return FBP<<5;} -REG_END2 - -REG64_(GIFReg, HWREG) - UINT32 DATA_LOWER:32; - UINT32 DATA_UPPER:32; -REG_END - -REG64_(GIFReg, LABEL) - UINT32 ID:32; - UINT32 IDMSK:32; -REG_END - -REG64_(GIFReg, MIPTBP1) - UINT64 TBP1:14; - UINT64 TBW1:6; - UINT64 TBP2:14; - UINT64 TBW2:6; - UINT64 TBP3:14; - UINT64 TBW3:6; - UINT64 _PAD:4; -REG_END - -REG64_(GIFReg, MIPTBP2) - UINT64 TBP4:14; - UINT64 TBW4:6; - UINT64 TBP5:14; - UINT64 TBW5:6; - UINT64 TBP6:14; - UINT64 TBW6:6; - UINT64 _PAD:4; -REG_END - -REG64_(GIFReg, NOP) - UINT32 _PAD1:32; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, PABE) - UINT32 PABE:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, PRIM) - UINT32 PRIM:3; - UINT32 IIP:1; - UINT32 TME:1; - UINT32 FGE:1; - UINT32 ABE:1; - UINT32 AA1:1; - UINT32 FST:1; - UINT32 CTXT:1; - UINT32 FIX:1; - UINT32 _PAD1:21; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, PRMODE) - UINT32 _PRIM:3; - UINT32 IIP:1; - UINT32 TME:1; - UINT32 FGE:1; - UINT32 ABE:1; - UINT32 AA1:1; - UINT32 FST:1; - UINT32 CTXT:1; - UINT32 FIX:1; - UINT32 _PAD2:21; - UINT32 _PAD3:32; -REG_END - -REG64_(GIFReg, PRMODECONT) - UINT32 AC:1; - UINT32 _PAD1:31; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, RGBAQ) - UINT32 R:8; - UINT32 G:8; - UINT32 B:8; - UINT32 A:8; - float Q; -REG_END - -REG64_(GIFReg, SCANMSK) - UINT32 MSK:2; - UINT32 _PAD1:30; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, SCISSOR) - UINT32 SCAX0:11; - UINT32 _PAD1:5; - UINT32 SCAX1:11; - UINT32 _PAD2:5; - UINT32 SCAY0:11; - UINT32 _PAD3:5; - UINT32 SCAY1:11; - UINT32 _PAD4:5; -REG_END - -REG64_(GIFReg, SIGNAL) - UINT32 ID:32; - UINT32 IDMSK:32; -REG_END - -REG64_(GIFReg, ST) - float S; - float T; -REG_END - -REG64_(GIFReg, TEST) - UINT32 ATE:1; - UINT32 ATST:3; - UINT32 AREF:8; - UINT32 AFAIL:2; - UINT32 DATE:1; - UINT32 DATM:1; - UINT32 ZTE:1; - UINT32 ZTST:2; - UINT32 _PAD1:13; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, TEX0) - UINT64 TBP0:14; - UINT64 TBW:6; - UINT64 PSM:6; - UINT64 TW:4; - UINT64 TH:4; - UINT64 TCC:1; - UINT64 TFX:2; - UINT64 CBP:14; - UINT64 CPSM:4; - UINT64 CSM:1; - UINT64 CSA:5; - UINT64 CLD:3; -REG_END - -REG64_(GIFReg, TEX1) - UINT32 LCM:1; - UINT32 _PAD1:1; - UINT32 MXL:3; - UINT32 MMAG:1; - UINT32 MMIN:3; - UINT32 MTBA:1; - UINT32 _PAD2:9; - UINT32 L:2; - UINT32 _PAD3:11; - UINT32 K:12; - UINT32 _PAD4:20; -REG_END - -REG64_(GIFReg, TEX2) - UINT32 _PAD1:20; - UINT32 PSM:6; - UINT32 _PAD2:6; - UINT32 _PAD3:5; - UINT32 CBP:14; - UINT32 CPSM:4; - UINT32 CSM:1; - UINT32 CSA:5; - UINT32 CLD:3; -REG_END - -REG64_(GIFReg, TEXA) - UINT32 TA0:8; - UINT32 _PAD1:7; - UINT32 AEM:1; - UINT32 _PAD2:16; - UINT32 TA1:8; - UINT32 _PAD3:24; -REG_END - -REG64_(GIFReg, TEXCLUT) - UINT32 CBW:6; - UINT32 COU:6; - UINT32 COV:10; - UINT32 _PAD1:10; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, TEXFLUSH) - UINT32 _PAD1:32; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, TRXDIR) - UINT32 XDIR:2; - UINT32 _PAD1:30; - UINT32 _PAD2:32; -REG_END - -REG64_(GIFReg, TRXPOS) - UINT32 SSAX:11; - UINT32 _PAD1:5; - UINT32 SSAY:11; - UINT32 _PAD2:5; - UINT32 DSAX:11; - UINT32 _PAD3:5; - UINT32 DSAY:11; - UINT32 DIR:2; - UINT32 _PAD4:3; -REG_END - -REG64_(GIFReg, TRXREG) - UINT32 RRW:12; - UINT32 _PAD1:20; - UINT32 RRH:12; - UINT32 _PAD2:20; -REG_END - -REG64_(GIFReg, UV) - UINT32 U:14; - UINT32 _PAD1:2; - UINT32 V:14; - UINT32 _PAD2:2; - UINT32 _PAD3:32; -REG_END - -REG64_(GIFReg, XYOFFSET) - UINT32 OFX:16; - UINT32 _PAD1:16; - UINT32 OFY:16; - UINT32 _PAD2:16; -REG_END - -REG64_(GIFReg, XYZ) - UINT32 X:16; - UINT32 Y:16; - UINT32 Z:32; -REG_END - -REG64_(GIFReg, XYZF) - UINT32 X:16; - UINT32 Y:16; - UINT32 Z:24; - UINT32 F:8; -REG_END - -REG64_(GIFReg, ZBUF) - UINT32 ZBP:9; - UINT32 _PAD1:15; - // UINT32 PSM:4; - // UINT32 _PAD2:4; - UINT32 PSM:6; - UINT32 _PAD2:2; - UINT32 ZMSK:1; - UINT32 _PAD3:31; -REG_END - -REG64_SET(GIFReg) - GIFRegALPHA ALPHA; - GIFRegBITBLTBUF BITBLTBUF; - GIFRegCLAMP CLAMP; - GIFRegCOLCLAMP COLCLAMP; - GIFRegDIMX DIMX; - GIFRegDTHE DTHE; - GIFRegFBA FBA; - GIFRegFINISH FINISH; - GIFRegFOG FOG; - GIFRegFOGCOL FOGCOL; - GIFRegFRAME FRAME; - GIFRegHWREG HWREG; - GIFRegLABEL LABEL; - GIFRegMIPTBP1 MIPTBP1; - GIFRegMIPTBP2 MIPTBP2; - GIFRegNOP NOP; - GIFRegPABE PABE; - GIFRegPRIM PRIM; - GIFRegPRMODE PRMODE; - GIFRegPRMODECONT PRMODECONT; - GIFRegRGBAQ RGBAQ; - GIFRegSCANMSK SCANMSK; - GIFRegSCISSOR SCISSOR; - GIFRegSIGNAL SIGNAL; - GIFRegST ST; - GIFRegTEST TEST; - GIFRegTEX0 TEX0; - GIFRegTEX1 TEX1; - GIFRegTEX2 TEX2; - GIFRegTEXA TEXA; - GIFRegTEXCLUT TEXCLUT; - GIFRegTEXFLUSH TEXFLUSH; - GIFRegTRXDIR TRXDIR; - GIFRegTRXPOS TRXPOS; - GIFRegTRXREG TRXREG; - GIFRegUV UV; - GIFRegXYOFFSET XYOFFSET; - GIFRegXYZ XYZ; - GIFRegXYZF XYZF; - GIFRegZBUF ZBUF; -REG_SET_END - -// GIFPacked - -REG128_(GIFPacked, PRIM) - UINT32 PRIM:11; - UINT32 _PAD1:21; - UINT32 _PAD2:32; - UINT32 _PAD3:32; - UINT32 _PAD4:32; -REG_END - -REG128_(GIFPacked, RGBA) - UINT32 R:8; - UINT32 _PAD1:24; - UINT32 G:8; - UINT32 _PAD2:24; - UINT32 B:8; - UINT32 _PAD3:24; - UINT32 A:8; - UINT32 _PAD4:24; -REG_END - -REG128_(GIFPacked, STQ) - float S; - float T; - float Q; - UINT32 _PAD1:32; -REG_END - -REG128_(GIFPacked, UV) - UINT32 U:14; - UINT32 _PAD1:18; - UINT32 V:14; - UINT32 _PAD2:18; - UINT32 _PAD3:32; - UINT32 _PAD4:32; -REG_END - -REG128_(GIFPacked, XYZF2) - UINT32 X:16; - UINT32 _PAD1:16; - UINT32 Y:16; - UINT32 _PAD2:16; - UINT32 _PAD3:4; - UINT32 Z:24; - UINT32 _PAD4:4; - UINT32 _PAD5:4; - UINT32 F:8; - UINT32 _PAD6:3; - UINT32 ADC:1; - UINT32 _PAD7:16; -REG_END - -REG128_(GIFPacked, XYZ2) - UINT32 X:16; - UINT32 _PAD1:16; - UINT32 Y:16; - UINT32 _PAD2:16; - UINT32 Z:32; - UINT32 _PAD3:15; - UINT32 ADC:1; - UINT32 _PAD4:16; -REG_END - -REG128_(GIFPacked, FOG) - UINT32 _PAD1:32; - UINT32 _PAD2:32; - UINT32 _PAD3:32; - UINT32 _PAD4:4; - UINT32 F:8; - UINT32 _PAD5:20; -REG_END - -REG128_(GIFPacked, A_D) - UINT64 DATA:64; - UINT32 ADDR:8; // enum GIF_A_D_REG - UINT32 _PAD1:24; - UINT32 _PAD2:32; -REG_END - -REG128_(GIFPacked, NOP) - UINT32 _PAD1:32; - UINT32 _PAD2:32; - UINT32 _PAD3:32; - UINT32 _PAD4:32; -REG_END - -REG128_SET(GIFPackedReg) - GIFReg r; - GIFPackedPRIM PRIM; - GIFPackedRGBA RGBA; - GIFPackedSTQ STQ; - GIFPackedUV UV; - GIFPackedXYZF2 XYZF2; - GIFPackedXYZ2 XYZ2; - GIFPackedFOG FOG; - GIFPackedA_D A_D; - GIFPackedNOP NOP; -REG_SET_END - -#pragma pack(pop) - -enum {KEYPRESS=1, KEYRELEASE=2}; -struct keyEvent {UINT32 key, event;}; - -enum {FREEZE_LOAD=0, FREEZE_SAVE=1, FREEZE_SIZE=2}; -struct freezeData {int size; BYTE* data;}; - -enum stateType {ST_WRITE, ST_TRANSFER, ST_VSYNC}; diff --git a/plugins/gs/gsdx9/GSCapture.cpp b/plugins/gs/gsdx9/GSCapture.cpp deleted file mode 100644 index 99ca45a49b..0000000000 --- a/plugins/gs/gsdx9/GSCapture.cpp +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSCapture.h" -#include "GSCaptureDlg.h" -#include -#include -// -// GSSource -// - -#ifdef __INTEL_COMPILER -interface __declspec(uuid("59C193BB-C520-41F3-BC1D-E245B80A86FA")) -#else -[uuid("59C193BB-C520-41F3-BC1D-E245B80A86FA")] interface -#endif -IGSSource : public IUnknown -{ - STDMETHOD(DeliverNewSegment)() PURE; - STDMETHOD(DeliverFrame)(D3DLOCKED_RECT& r) PURE; - STDMETHOD(DeliverEOS)() PURE; -}; - -#ifdef __INTEL_COMPILER -class __declspec(uuid("F8BB6F4F-0965-4ED4-BA74-C6A01E6E6C77")) -#else -[uuid("F8BB6F4F-0965-4ED4-BA74-C6A01E6E6C77")] class -#endif -GSSource : public CBaseFilter, public IGSSource -{ - CCritSec m_csLock; - CAutoPtr m_pOutput; - CSize m_size; - REFERENCE_TIME m_rtAvgTimePerFrame, m_rtNow; - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void** ppv) - { - return - QI(IGSSource) - __super::NonDelegatingQueryInterface(riid, ppv); - } - - class GSSourceOutputPin : public CBaseOutputPin - { - CMediaType m_mt; - - public: - GSSourceOutputPin(CMediaType& mt, CBaseFilter* pFilter, CCritSec* pLock, HRESULT& hr) - : CBaseOutputPin("GSSourceOutputPin", pFilter, pLock, &hr, L"Output") - , m_mt(mt) - { - } - - HRESULT GSSourceOutputPin::DecideBufferSize(IMemAllocator* pAlloc, ALLOCATOR_PROPERTIES* pProperties) - { - ASSERT(pAlloc && pProperties); - - HRESULT hr; - - pProperties->cBuffers = 1; - pProperties->cbBuffer = m_mt.lSampleSize; - - ALLOCATOR_PROPERTIES Actual; - if(FAILED(hr = pAlloc->SetProperties(pProperties, &Actual))) return hr; - - if(Actual.cbBuffer < pProperties->cbBuffer) return E_FAIL; - ASSERT(Actual.cBuffers == pProperties->cBuffers); - - return S_OK; - } - - HRESULT CheckMediaType(const CMediaType* pmt) - { - return pmt->majortype == MEDIATYPE_Video && pmt->subtype == MEDIASUBTYPE_RGB32 ? S_OK : E_FAIL; - } - - HRESULT GetMediaType(int iPosition, CMediaType* pmt) - { - CheckPointer(pmt, E_POINTER); - if(iPosition < 0) return E_INVALIDARG; - if(iPosition > 0) return VFW_S_NO_MORE_ITEMS; - *pmt = m_mt; - return S_OK; - } - - STDMETHODIMP Notify(IBaseFilter* pSender, Quality q) - { - return E_NOTIMPL; - } - }; - -public: - GSSource(int w, int h, int fps, IUnknown* pUnk, HRESULT& hr) - : CBaseFilter(NAME("GSSource"), pUnk, &m_csLock, __uuidof(this), &hr) - , m_pOutput(NULL) - , m_size(w, h) - , m_rtAvgTimePerFrame(10000000i64/fps) - , m_rtNow(0) - { - CMediaType mt; - - mt.majortype = MEDIATYPE_Video; - mt.subtype = MEDIASUBTYPE_RGB32; - mt.formattype = FORMAT_VideoInfo; - mt.lSampleSize = w*h*4; - - VIDEOINFOHEADER vih; - memset(&vih, 0, sizeof(vih)); - vih.AvgTimePerFrame = m_rtAvgTimePerFrame; - vih.bmiHeader.biSize = sizeof(vih.bmiHeader); - vih.bmiHeader.biCompression = BI_RGB; - vih.bmiHeader.biPlanes = 1; - vih.bmiHeader.biWidth = w; - vih.bmiHeader.biHeight = -h; - vih.bmiHeader.biBitCount = 32; - vih.bmiHeader.biSizeImage = w*h*4; - mt.SetFormat((BYTE*)&vih, sizeof(vih)); - - m_pOutput.Attach(new GSSourceOutputPin(mt, this, &m_csLock, hr)); - } - - DECLARE_IUNKNOWN; - - int GetPinCount() {return 1;} - CBasePin* GetPin(int n) {return n == 0 ? m_pOutput.m_p : NULL;} - - // IGSSource - - STDMETHODIMP DeliverNewSegment() - { - return m_pOutput->DeliverNewSegment(m_rtNow = 0, _I64_MAX, 1.0); - } - - STDMETHODIMP DeliverFrame(D3DLOCKED_RECT& r) - { - HRESULT hr; - - if(!m_pOutput || !m_pOutput->IsConnected()) return E_UNEXPECTED; - - CComPtr pSample; - if(FAILED(hr = m_pOutput->GetDeliveryBuffer(&pSample, NULL, NULL, 0))) - return hr; - - REFERENCE_TIME rtStart = m_rtNow, rtStop = m_rtNow + m_rtAvgTimePerFrame; - - pSample->SetTime(&rtStart, &rtStop); - pSample->SetSyncPoint(TRUE); - - BYTE* pSrc = (BYTE*)r.pBits; - int srcpitch = r.Pitch; - - BYTE* pDst = NULL; - pSample->GetPointer(&pDst); - CMediaType mt; - m_pOutput->GetMediaType(0, &mt); - int dstpitch = ((VIDEOINFOHEADER*)mt.Format())->bmiHeader.biWidth*4; - - int minpitch = min(srcpitch, dstpitch); - - for(int y = 0; y < m_size.cy; y++, pDst += dstpitch, pSrc += srcpitch) - memcpy(pDst, pSrc, minpitch); - - if(FAILED(hr = m_pOutput->Deliver(pSample))) - return hr; - - m_rtNow = rtStop; - - return S_OK; - } - - STDMETHODIMP DeliverEOS() - { - return m_pOutput->DeliverEndOfStream(); - } -}; - -// -// GSCapture -// - -GSCapture::GSCapture() -{ -} - -bool GSCapture::BeginCapture(IDirect3DDevice9* pD3Dev, int fps) -{ - ASSERT(pD3Dev != NULL && fps != 0); - - EndCapture(); - - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - GSCaptureDlg dlg; - dlg.DoModal(); - //if(IDOK != dlg.DoModal()) - // return false; - - HRESULT hr; - - int w, h; - w = 640, h = 480; // TODO - - CComPtr pRTSurf; - if(FAILED(hr = pD3Dev->CreateRenderTarget(w, h, D3DFMT_A8R8G8B8, D3DMULTISAMPLE_NONE, 0, TRUE, &pRTSurf, NULL))) - return false; - - if(FAILED(hr = pD3Dev->CreateOffscreenPlainSurface(w, h, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &m_pSysMemSurf, NULL))) - return false; - - // - - m_pGB.CoCreateInstance(CLSID_FilterGraph); - if(!m_pGB) return false; - - CComPtr pCGB; - pCGB.CoCreateInstance(CLSID_CaptureGraphBuilder2); - if(!pCGB) return false; - - pCGB->SetFiltergraph(m_pGB); - - CComPtr pMux; - if(FAILED(hr = pCGB->SetOutputFileName(&MEDIASUBTYPE_Avi, CStringW(dlg.m_filename), &pMux, NULL))) - return false; - - m_pSrc = new GSSource(w, h, fps, NULL, hr); - if(FAILED(hr = m_pGB->AddFilter(m_pSrc, L"Source"))) - return false; - - if(FAILED(hr = m_pGB->AddFilter(dlg.m_pVidEnc, L"Encoder"))) - return false; - - if(FAILED(hr = pCGB->RenderStream(NULL, NULL, m_pSrc, dlg.m_pVidEnc, pMux))) - return false; - - hr = CComQIPtr(m_pGB)->Run(); - - hr = CComQIPtr(m_pSrc)->DeliverNewSegment(); - - m_pRTSurf = pRTSurf; - - return true; -} - -bool GSCapture::BeginFrame(int& w, int& h, IDirect3DSurface9** pRTSurf) -{ - if(!m_pRTSurf || !pRTSurf) return false; - - // FIXME: remember w, h from BeginCapture - D3DSURFACE_DESC desc; - if(FAILED(m_pRTSurf->GetDesc(&desc))) return false; - w = desc.Width; - h = desc.Height; - - (*pRTSurf = m_pRTSurf)->AddRef(); - - return true; -} - -bool GSCapture::EndFrame() -{ - if(m_pRTSurf == NULL || m_pSysMemSurf == NULL) {ASSERT(0); return false;} - - CComPtr pD3DDev; - D3DLOCKED_RECT r; - - if(FAILED(m_pRTSurf->GetDevice(&pD3DDev)) - || FAILED(pD3DDev->GetRenderTargetData(m_pRTSurf, m_pSysMemSurf)) - || FAILED(m_pSysMemSurf->LockRect(&r, NULL, D3DLOCK_READONLY))) - return false; - - CComQIPtr(m_pSrc)->DeliverFrame(r); - - m_pSysMemSurf->UnlockRect(); - - return true; -} - -bool GSCapture::EndCapture() -{ - m_pRTSurf = NULL; - m_pSysMemSurf = NULL; - - if(m_pSrc) CComQIPtr(m_pSrc)->DeliverEOS(); - if(m_pGB) CComQIPtr(m_pGB)->Stop(); - - m_pSrc = NULL; - m_pGB = NULL; - - return true; -} diff --git a/plugins/gs/gsdx9/GSCapture.h b/plugins/gs/gsdx9/GSCapture.h deleted file mode 100644 index 8d6e05ee54..0000000000 --- a/plugins/gs/gsdx9/GSCapture.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -class GSCapture -{ - CComPtr m_pRTSurf, m_pSysMemSurf; - - CComPtr m_pGB; - CComPtr m_pSrc; - -public: - GSCapture(); - - bool BeginCapture(IDirect3DDevice9* pD3Dev, int fps); - bool BeginFrame(int& w, int& h, IDirect3DSurface9** pRTSurf); - bool EndFrame(); - bool EndCapture(); - - bool IsCapturing() {return !!m_pRTSurf;} -}; diff --git a/plugins/gs/gsdx9/GSCaptureDlg.cpp b/plugins/gs/gsdx9/GSCaptureDlg.cpp deleted file mode 100644 index ccad461f0c..0000000000 --- a/plugins/gs/gsdx9/GSCaptureDlg.cpp +++ /dev/null @@ -1,230 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -// GSCaptureDlg.cpp : implementation file -// - -#include "stdafx.h" -#include -#include "GSCaptureDlg.h" - -// GSCaptureDlg dialog - -IMPLEMENT_DYNAMIC(GSCaptureDlg, CDialog) -GSCaptureDlg::GSCaptureDlg(CWnd* pParent /*=NULL*/) - : CDialog(GSCaptureDlg::IDD, pParent) -{ - m_filename = AfxGetApp()->GetProfileString(_T("Capture"), _T("FileName")); -} - -GSCaptureDlg::~GSCaptureDlg() -{ -} - -int GSCaptureDlg::GetSelCodec(Codec& c) -{ - int iSel = m_codeclist.GetCurSel(); - if(iSel < 0) return 0; - - POSITION pos = (POSITION)m_codeclist.GetItemDataPtr(iSel); - if(pos == NULL) return 2; - - c = m_codecs.GetAt(pos); - - if(!c.pBF) - { - c.pMoniker->BindToObject(NULL, NULL, __uuidof(IBaseFilter), (void**)&c.pBF); - if(!c.pBF) return 0; - } - - return 1; -} - -LRESULT GSCaptureDlg::DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam) -{ - LRESULT ret = __super::DefWindowProc(message, wParam, lParam); - if(message == WM_INITDIALOG) SendMessage(WM_KICKIDLE); - return(ret); -} - -void GSCaptureDlg::DoDataExchange(CDataExchange* pDX) -{ - __super::DoDataExchange(pDX); - DDX_Text(pDX, IDC_EDIT1, m_filename); - DDX_Control(pDX, IDC_COMBO1, m_codeclist); -} - -BOOL GSCaptureDlg::OnInitDialog() -{ - __super::OnInitDialog(); - - m_codecs.RemoveAll(); - - m_codeclist.ResetContent(); - m_codeclist.SetItemDataPtr(m_codeclist.AddString(_T("Uncompressed")), NULL); - - BeginEnumSysDev(CLSID_VideoCompressorCategory, pMoniker) - { - Codec c; - c.pMoniker = pMoniker; - - LPOLESTR strName = NULL; - if(FAILED(pMoniker->GetDisplayName(NULL, NULL, &strName))) - continue; - - c.DisplayName = strName; - CoTaskMemFree(strName); - - CComPtr pPB; - pMoniker->BindToStorage(0, 0, IID_IPropertyBag, (void**)&pPB); - - CComVariant var; - if(FAILED(pPB->Read(CComBSTR(_T("FriendlyName")), &var, NULL))) - continue; - - c.FriendlyName = var.bstrVal; - - CStringW str = CStringW(c.DisplayName).MakeLower(); - if(str.Find(L"@device:dmo:") == 0) - c.FriendlyName = _T("(DMO) ") + c.FriendlyName; - else if(str.Find(L"@device:sw:") == 0) - c.FriendlyName = _T("(DS) ") + c.FriendlyName; - else if(str.Find(L"@device:cm:") == 0) - c.FriendlyName = _T("(VfW) ") + c.FriendlyName; - - m_codeclist.SetItemDataPtr(m_codeclist.AddString(c.FriendlyName), m_codecs.AddTail(c)); - } - EndEnumSysDev - - // - - CString DisplayNameToFind = AfxGetApp()->GetProfileString(_T("Capture"), _T("VideoCodecDisplayName")); - - for(int i = 0; i < m_codeclist.GetCount(); i++) - { - CString DisplayName; - - POSITION pos = (POSITION)m_codeclist.GetItemDataPtr(i); - if(pos) DisplayName = m_codecs.GetAt(pos).DisplayName; - - if(DisplayName == DisplayNameToFind) - { - m_codeclist.SetCurSel(i); - break; - } - } - - // - - UpdateData(FALSE); - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE -} - -BEGIN_MESSAGE_MAP(GSCaptureDlg, CDialog) - ON_MESSAGE_VOID(WM_KICKIDLE, OnKickIdle) - ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) - ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2) - ON_UPDATE_COMMAND_UI(IDC_BUTTON2, OnUpdateButton2) - ON_BN_CLICKED(IDOK, OnBnClickedOk) - ON_UPDATE_COMMAND_UI(IDOK, OnUpdateOK) -END_MESSAGE_MAP() - -// GSCaptureDlg message handlers - -void GSCaptureDlg::OnKickIdle() -{ - UpdateDialogControls(this, false); -} - -void GSCaptureDlg::OnBnClickedButton1() -{ - UpdateData(); - - CFileDialog fd(FALSE, _T("avi"), m_filename, - OFN_EXPLORER|OFN_ENABLESIZING|OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST, - _T("Avi files (*.avi)|*.avi||"), this, 0); - - if(fd.DoModal() == IDOK) - { - m_filename = fd.GetPathName(); - UpdateData(FALSE); - } -} - -void GSCaptureDlg::OnBnClickedButton2() -{ - Codec c; - if(GetSelCodec(c) != 1) return; - - if(CComQIPtr pSPP = c.pBF) - { - CAUUID caGUID; - caGUID.pElems = NULL; - if(SUCCEEDED(pSPP->GetPages(&caGUID))) - { - IUnknown* lpUnk = NULL; - pSPP.QueryInterface(&lpUnk); - OleCreatePropertyFrame( - m_hWnd, 0, 0, CStringW(c.FriendlyName), - 1, (IUnknown**)&lpUnk, - caGUID.cElems, caGUID.pElems, - 0, 0, NULL); - lpUnk->Release(); - - if(caGUID.pElems) CoTaskMemFree(caGUID.pElems); - } - } - else if(CComQIPtr pAMVfWCD = c.pBF) - { - if(pAMVfWCD->ShowDialog(VfwCompressDialog_QueryConfig, NULL) == S_OK) - pAMVfWCD->ShowDialog(VfwCompressDialog_Config, m_hWnd); - } -} - -void GSCaptureDlg::OnUpdateButton2(CCmdUI* pCmdUI) -{ - pCmdUI->Enable(m_codeclist.GetCurSel() >= 0 && m_codeclist.GetItemDataPtr(m_codeclist.GetCurSel()) != NULL); -} - -void GSCaptureDlg::OnBnClickedOk() -{ - UpdateData(); - - Codec c; - if(GetSelCodec(c) == 0) return; - - m_pVidEnc = c.pBF; - - AfxGetApp()->WriteProfileString(_T("Capture"), _T("FileName"), m_filename); - AfxGetApp()->WriteProfileString(_T("Capture"), _T("VideoCodecDisplayName"), CString(c.DisplayName)); - - OnOK(); -} - -void GSCaptureDlg::OnUpdateOK(CCmdUI* pCmdUI) -{ - CString str; - GetDlgItem(IDC_EDIT1)->GetWindowText(str); - - pCmdUI->Enable(!str.IsEmpty() && m_codeclist.GetCurSel() >= 0); -} diff --git a/plugins/gs/gsdx9/GSCaptureDlg.h b/plugins/gs/gsdx9/GSCaptureDlg.h deleted file mode 100644 index 758493f904..0000000000 --- a/plugins/gs/gsdx9/GSCaptureDlg.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "resource.h" -#include "afxwin.h" - -// GSCaptureDlg dialog - -class GSCaptureDlg : public CDialog -{ - DECLARE_DYNAMIC(GSCaptureDlg) - -private: - struct Codec - { - CComPtr pMoniker; - CComPtr pBF; - CString FriendlyName; - CComBSTR DisplayName; - }; - - CList m_codecs; - - int GetSelCodec(Codec& c); - -public: - GSCaptureDlg(CWnd* pParent = NULL); // standard constructor - virtual ~GSCaptureDlg(); - - CComPtr m_pVidEnc; - -// Dialog Data - enum { IDD = IDD_CAPTURE }; - CString m_filename; - CComboBox m_codeclist; - -protected: - virtual LRESULT DefWindowProc(UINT message, WPARAM wParam, LPARAM lParam); - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - virtual BOOL OnInitDialog(); - - DECLARE_MESSAGE_MAP() -public: - afx_msg void OnKickIdle(); - afx_msg void OnBnClickedButton1(); - afx_msg void OnBnClickedButton2(); - afx_msg void OnUpdateButton2(CCmdUI* pCmdUI); - afx_msg void OnBnClickedOk(); - afx_msg void OnUpdateOK(CCmdUI* pCmdUI); -}; diff --git a/plugins/gs/gsdx9/GSHash.cpp b/plugins/gs/gsdx9/GSHash.cpp deleted file mode 100644 index cdc030360d..0000000000 --- a/plugins/gs/gsdx9/GSHash.cpp +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" - -static const DWORD s_crctable[256] = -{ - 0x00000000l, 0x90910101l, 0x91210201l, 0x01b00300l, - 0x92410401l, 0x02d00500l, 0x03600600l, 0x93f10701l, - 0x94810801l, 0x04100900l, 0x05a00a00l, 0x95310b01l, - 0x06c00c00l, 0x96510d01l, 0x97e10e01l, 0x07700f00l, - 0x99011001l, 0x09901100l, 0x08201200l, 0x98b11301l, - 0x0b401400l, 0x9bd11501l, 0x9a611601l, 0x0af01700l, - 0x0d801800l, 0x9d111901l, 0x9ca11a01l, 0x0c301b00l, - 0x9fc11c01l, 0x0f501d00l, 0x0ee01e00l, 0x9e711f01l, - 0x82012001l, 0x12902100l, 0x13202200l, 0x83b12301l, - 0x10402400l, 0x80d12501l, 0x81612601l, 0x11f02700l, - 0x16802800l, 0x86112901l, 0x87a12a01l, 0x17302b00l, - 0x84c12c01l, 0x14502d00l, 0x15e02e00l, 0x85712f01l, - 0x1b003000l, 0x8b913101l, 0x8a213201l, 0x1ab03300l, - 0x89413401l, 0x19d03500l, 0x18603600l, 0x88f13701l, - 0x8f813801l, 0x1f103900l, 0x1ea03a00l, 0x8e313b01l, - 0x1dc03c00l, 0x8d513d01l, 0x8ce13e01l, 0x1c703f00l, - 0xb4014001l, 0x24904100l, 0x25204200l, 0xb5b14301l, - 0x26404400l, 0xb6d14501l, 0xb7614601l, 0x27f04700l, - 0x20804800l, 0xb0114901l, 0xb1a14a01l, 0x21304b00l, - 0xb2c14c01l, 0x22504d00l, 0x23e04e00l, 0xb3714f01l, - 0x2d005000l, 0xbd915101l, 0xbc215201l, 0x2cb05300l, - 0xbf415401l, 0x2fd05500l, 0x2e605600l, 0xbef15701l, - 0xb9815801l, 0x29105900l, 0x28a05a00l, 0xb8315b01l, - 0x2bc05c00l, 0xbb515d01l, 0xbae15e01l, 0x2a705f00l, - 0x36006000l, 0xa6916101l, 0xa7216201l, 0x37b06300l, - 0xa4416401l, 0x34d06500l, 0x35606600l, 0xa5f16701l, - 0xa2816801l, 0x32106900l, 0x33a06a00l, 0xa3316b01l, - 0x30c06c00l, 0xa0516d01l, 0xa1e16e01l, 0x31706f00l, - 0xaf017001l, 0x3f907100l, 0x3e207200l, 0xaeb17301l, - 0x3d407400l, 0xadd17501l, 0xac617601l, 0x3cf07700l, - 0x3b807800l, 0xab117901l, 0xaaa17a01l, 0x3a307b00l, - 0xa9c17c01l, 0x39507d00l, 0x38e07e00l, 0xa8717f01l, - 0xd8018001l, 0x48908100l, 0x49208200l, 0xd9b18301l, - 0x4a408400l, 0xdad18501l, 0xdb618601l, 0x4bf08700l, - 0x4c808800l, 0xdc118901l, 0xdda18a01l, 0x4d308b00l, - 0xdec18c01l, 0x4e508d00l, 0x4fe08e00l, 0xdf718f01l, - 0x41009000l, 0xd1919101l, 0xd0219201l, 0x40b09300l, - 0xd3419401l, 0x43d09500l, 0x42609600l, 0xd2f19701l, - 0xd5819801l, 0x45109900l, 0x44a09a00l, 0xd4319b01l, - 0x47c09c00l, 0xd7519d01l, 0xd6e19e01l, 0x46709f00l, - 0x5a00a000l, 0xca91a101l, 0xcb21a201l, 0x5bb0a300l, - 0xc841a401l, 0x58d0a500l, 0x5960a600l, 0xc9f1a701l, - 0xce81a801l, 0x5e10a900l, 0x5fa0aa00l, 0xcf31ab01l, - 0x5cc0ac00l, 0xcc51ad01l, 0xcde1ae01l, 0x5d70af00l, - 0xc301b001l, 0x5390b100l, 0x5220b200l, 0xc2b1b301l, - 0x5140b400l, 0xc1d1b501l, 0xc061b601l, 0x50f0b700l, - 0x5780b800l, 0xc711b901l, 0xc6a1ba01l, 0x5630bb00l, - 0xc5c1bc01l, 0x5550bd00l, 0x54e0be00l, 0xc471bf01l, - 0x6c00c000l, 0xfc91c101l, 0xfd21c201l, 0x6db0c300l, - 0xfe41c401l, 0x6ed0c500l, 0x6f60c600l, 0xfff1c701l, - 0xf881c801l, 0x6810c900l, 0x69a0ca00l, 0xf931cb01l, - 0x6ac0cc00l, 0xfa51cd01l, 0xfbe1ce01l, 0x6b70cf00l, - 0xf501d001l, 0x6590d100l, 0x6420d200l, 0xf4b1d301l, - 0x6740d400l, 0xf7d1d501l, 0xf661d601l, 0x66f0d700l, - 0x6180d800l, 0xf111d901l, 0xf0a1da01l, 0x6030db00l, - 0xf3c1dc01l, 0x6350dd00l, 0x62e0de00l, 0xf271df01l, - 0xee01e001l, 0x7e90e100l, 0x7f20e200l, 0xefb1e301l, - 0x7c40e400l, 0xecd1e501l, 0xed61e601l, 0x7df0e700l, - 0x7a80e800l, 0xea11e901l, 0xeba1ea01l, 0x7b30eb00l, - 0xe8c1ec01l, 0x7850ed00l, 0x79e0ee00l, 0xe971ef01l, - 0x7700f000l, 0xe791f101l, 0xe621f201l, 0x76b0f300l, - 0xe541f401l, 0x75d0f500l, 0x7460f600l, 0xe4f1f701l, - 0xe381f801l, 0x7310f900l, 0x72a0fa00l, 0xe231fb01l, - 0x71c0fc00l, 0xe151fd01l, 0xe0e1fe01l, 0x7070ff00l -}; - -DWORD hash_crc(const CRect& r, int pitch, BYTE* p) -{ - if(r.Width() == 0) {ASSERT(0); return 0;} - - DWORD hash = 0xffffffff; - - for(int j = r.top; j < r.bottom; j++, p += pitch) - { - for(int i = r.left, x = 0; i < r.right; i++, x += 4) - { - hash = s_crctable[(hash ^ p[x+0]) & 0xff] ^ (hash >> 8); - hash = s_crctable[(hash ^ p[x+1]) & 0xff] ^ (hash >> 8); - hash = s_crctable[(hash ^ p[x+2]) & 0xff] ^ (hash >> 8); - hash = s_crctable[(hash ^ p[x+3]) & 0xff] ^ (hash >> 8); - } - } - - return hash; -} - -#define MOD_ADLER 65521 - -DWORD hash_adler(const CRect& r, int pitch, BYTE* p) -{ - if(r.Width() == 0) {ASSERT(0); return 0;} - - DWORD a = 1, b = 0; - - for(int j = r.top; j < r.bottom; j++, p += pitch) - { - for(int i = r.left, x = 0; i < r.right; i++, x += 4) - { - a += p[x+0]; b += a; - a += p[x+1]; b += a; - a += p[x+2]; b += a; - a += p[x+3]; b += a; - } - - a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); - b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); - } - - // a = (a & 0xffff) + (a >> 16) * (65536 - MOD_ADLER); - if(a >= MOD_ADLER) a -= MOD_ADLER; - b = (b & 0xffff) + (b >> 16) * (65536 - MOD_ADLER); - if(b >= MOD_ADLER) b -= MOD_ADLER; - - return b << 16 | a; -} - -DWORD hash_checksum(const CRect& r, int pitch, BYTE* p) -{ - if(r.Width() == 0) {ASSERT(0); return 0;} - - DWORD hash = 0; - -#if defined(_M_AMD64) || _M_IX86_FP >= 2 - if(r.Width() >= 4 && !((DWORD_PTR)p & 0xf) && !(pitch & 0xf)) - { - __m128i hash128 = _mm_setzero_si128(); - for(int j = r.top; j < r.bottom; j++, p += pitch) - { - hash128 = _mm_add_epi32(hash128, _mm_set1_epi32(j)); - for(int i = r.left, x = 0; i < r.right; i += 4, x++) - { - hash128 = _mm_shuffle_epi32(hash128, 0x93); - ////hash128 = _mm_shufflelo_epi16(hash128, 0x93); - //hash128 = _mm_shufflehi_epi16(hash128, 0x93); - hash128 = _mm_add_epi32(hash128, _mm_load_si128(&((__m128i*)p)[x])); - } - } - hash128 = _mm_add_epi32(hash128, _mm_srli_si128(hash128, 8)); - hash128 = _mm_add_epi32(hash128, _mm_srli_si128(hash128, 4)); - hash += _mm_cvtsi128_si32(hash128); - } - else -#endif - { - for(int j = r.top; j < r.bottom; j++, p += pitch) - { - hash += j; - for(int i = r.left, x = 0; i < r.right; i++, x++) - { - hash += ((DWORD*)p)[x]; - } - } - } - - return hash; -} \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSHash.h b/plugins/gs/gsdx9/GSHash.h deleted file mode 100644 index 48a6adc7d3..0000000000 --- a/plugins/gs/gsdx9/GSHash.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -extern DWORD hash_crc(const CRect& r, int pitch, BYTE* p); -extern DWORD hash_adler(const CRect& r, int pitch, BYTE* p); -extern DWORD hash_checksum(const CRect& r, int pitch, BYTE* p); diff --git a/plugins/gs/gsdx9/GSLocalMemory.cpp b/plugins/gs/gsdx9/GSLocalMemory.cpp deleted file mode 100644 index 8d4e2bb6d5..0000000000 --- a/plugins/gs/gsdx9/GSLocalMemory.cpp +++ /dev/null @@ -1,2859 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - * Special Notes: - * - * Based on Page.c from GSSoft - * Copyright (C) 2002-2004 GSsoft Team - * - */ - -#include "StdAfx.h" -#include "GSLocalMemory.h" -#include "x86.h" - -// - -static class cdscd -{ - CString toBin(UINT64 n, int bits) - { - CString str; - while(bits-- > 0) str += n&(1i64<= w && (r).Height() >= h && !((r).left&(w-1)) && !((r).top&(h-1)) && !((r).right&(w-1)) && !((r).bottom&(h-1))); \ - -#if defined(_M_AMD64) || _M_IX86_FP >= 2 -#define BLOCK_PREFETCH(mem) \ - _mm_prefetch(&mem[16*0], _MM_HINT_T0); \ - _mm_prefetch(&mem[16*2], _MM_HINT_T0); \ - _mm_prefetch(&mem[16*4], _MM_HINT_T0); \ - _mm_prefetch(&mem[16*6], _MM_HINT_T0); \ - _mm_prefetch(&mem[16*8], _MM_HINT_T0); \ - _mm_prefetch(&mem[16*10], _MM_HINT_T0); \ - _mm_prefetch(&mem[16*12], _MM_HINT_T0); \ - _mm_prefetch(&mem[16*14], _MM_HINT_T0); \ - -#define BLOCK_PREFETCH_32(x, y, w) {const char* next = (const char*)&m_vm32[blockAddress32(x + (w), y, TEX0.TBP0, TEX0.TBW)]; BLOCK_PREFETCH(next);} -#define BLOCK_PREFETCH_16(x, y, w) {const char* next = (const char*)&m_vm16[blockAddress16(x + (w), y, TEX0.TBP0, TEX0.TBW)]; BLOCK_PREFETCH(next);} -#define BLOCK_PREFETCH_16S(x, y, w) {const char* next = (const char*)&m_vm16[blockAddress16S(x + (w), y, TEX0.TBP0, TEX0.TBW)]; BLOCK_PREFETCH(next);} -#define BLOCK_PREFETCH_8(x, y, w) {const char* next = (const char*)&m_vm8[blockAddress8(x + (w), y, TEX0.TBP0, TEX0.TBW)]; BLOCK_PREFETCH(next);} -#define BLOCK_PREFETCH_4(x, y, w) {const char* next = (const char*)&m_vm8[blockAddress4(x + (w), y, TEX0.TBP0, TEX0.TBW)>>1]; BLOCK_PREFETCH(next);} -#else -#define BLOCK_PREFETCH_32(x, y, w) -#define BLOCK_PREFETCH_16(x, y, w) -#define BLOCK_PREFETCH_16S(x, y, w) -#define BLOCK_PREFETCH_8(x, y, w) -#define BLOCK_PREFETCH_4(x, y, w) -#endif - -#define FOREACH_BLOCK_START(r, w, h, t) \ - for(int y = (r).top; y < (r).bottom; y += (h)) \ - { ASSERT_BLOCK(r, w, h); \ - BYTE* ptr = dst + (y-(r).top)*dstpitch; \ - for(int x = (r).left; x < (r).right; x += (w)) \ - { \ - BLOCK_PREFETCH_##t##(x + (w), y, w) \ - -#define FOREACH_BLOCK_END }} - -// - -DWORD GSLocalMemory::pageOffset32[32][32][64]; -DWORD GSLocalMemory::pageOffset32Z[32][32][64]; -DWORD GSLocalMemory::pageOffset16[32][64][64]; -DWORD GSLocalMemory::pageOffset16S[32][64][64]; -DWORD GSLocalMemory::pageOffset16Z[32][64][64]; -DWORD GSLocalMemory::pageOffset16SZ[32][64][64]; -DWORD GSLocalMemory::pageOffset8[32][64][128]; -DWORD GSLocalMemory::pageOffset4[32][128][128]; - -int GSLocalMemory::rowOffset32[2048]; -int GSLocalMemory::rowOffset32Z[2048]; -int GSLocalMemory::rowOffset16[2048]; -int GSLocalMemory::rowOffset16S[2048]; -int GSLocalMemory::rowOffset16Z[2048]; -int GSLocalMemory::rowOffset16SZ[2048]; -int GSLocalMemory::rowOffset8[2][2048]; -int GSLocalMemory::rowOffset4[2][2048]; - -// - -DWORD GSLocalMemory::m_xtbl[1024]; -DWORD GSLocalMemory::m_ytbl[1024]; - -// - -GSLocalMemory::psmtbl_t GSLocalMemory::m_psmtbl[64]; - -// - -GSLocalMemory::GSLocalMemory() - : m_fCLUTMayBeDirty(true) -{ - int len = 1024*1024*4*2; // *2 for safety... - - m_vm8 = (BYTE*)_aligned_malloc(len, 16); - memset(m_vm8, 0, len); - - m_pCLUT = (WORD*)_aligned_malloc(256*2*sizeof(WORD)*2, 16); - m_pCLUT32 = (DWORD*)_aligned_malloc(256*sizeof(DWORD), 16); - m_pCLUT64 = (UINT64*)_aligned_malloc(256*sizeof(UINT64), 16); - - for(int bp = 0; bp < 32; bp++) - { - for(int y = 0; y < 32; y++) for(int x = 0; x < 64; x++) - { - pageOffset32[bp][y][x] = pixelAddressOrg32(x, y, bp, 0); - pageOffset32Z[bp][y][x] = pixelAddressOrg32Z(x, y, bp, 0); - } - - for(int y = 0; y < 64; y++) for(int x = 0; x < 64; x++) - { - pageOffset16[bp][y][x] = pixelAddressOrg16(x, y, bp, 0); - pageOffset16S[bp][y][x] = pixelAddressOrg16S(x, y, bp, 0); - pageOffset16Z[bp][y][x] = pixelAddressOrg16Z(x, y, bp, 0); - pageOffset16SZ[bp][y][x] = pixelAddressOrg16SZ(x, y, bp, 0); - } - - for(int y = 0; y < 64; y++) for(int x = 0; x < 128; x++) - { - pageOffset8[bp][y][x] = pixelAddressOrg8(x, y, bp, 0); - } - - for(int y = 0; y < 128; y++) for(int x = 0; x < 128; x++) - { - pageOffset4[bp][y][x] = pixelAddressOrg4(x, y, bp, 0); - } - } - - { - for(int x = 0; x < countof(rowOffset32); x++) - rowOffset32[x] = (int)pixelAddress32(x, 0, 0, 32) - (int)pixelAddress32(0, 0, 0, 32); - - for(int x = 0; x < countof(rowOffset32Z); x++) - rowOffset32Z[x] = (int)pixelAddress32Z(x, 0, 0, 32) - (int)pixelAddress32Z(0, 0, 0, 32); - - for(int x = 0; x < countof(rowOffset16); x++) - rowOffset16[x] = (int)pixelAddress16(x, 0, 0, 32) - (int)pixelAddress16(0, 0, 0, 32); - - for(int x = 0; x < countof(rowOffset16S); x++) - rowOffset16S[x] = (int)pixelAddress16S(x, 0, 0, 32) - (int)pixelAddress16S(0, 0, 0, 32); - - for(int x = 0; x < countof(rowOffset16Z); x++) - rowOffset16Z[x] = (int)pixelAddress16Z(x, 0, 0, 32) - (int)pixelAddress16Z(0, 0, 0, 32); - - for(int x = 0; x < countof(rowOffset16SZ); x++) - rowOffset16SZ[x] = (int)pixelAddress16SZ(x, 0, 0, 32) - (int)pixelAddress16SZ(0, 0, 0, 32); - - for(int x = 0; x < countof(rowOffset8[0]); x++) - rowOffset8[0][x] = (int)pixelAddress8(x, 0, 0, 32) - (int)pixelAddress8(0, 0, 0, 32), - rowOffset8[1][x] = (int)pixelAddress8(x, 2, 0, 32) - (int)pixelAddress8(0, 2, 0, 32); - - for(int x = 0; x < countof(rowOffset4[0]); x++) - rowOffset4[0][x] = (int)pixelAddress4(x, 0, 0, 32) - (int)pixelAddress4(0, 0, 0, 32), - rowOffset4[1][x] = (int)pixelAddress4(x, 2, 0, 32) - (int)pixelAddress4(0, 2, 0, 32); - } - - for(int i = 0; i < countof(m_psmtbl); i++) - { - m_psmtbl[i].pa = &GSLocalMemory::pixelAddress32; - m_psmtbl[i].ba = &GSLocalMemory::blockAddress32; - m_psmtbl[i].pga = &GSLocalMemory::pageAddress32; - m_psmtbl[i].rp = &GSLocalMemory::readPixel32; - m_psmtbl[i].rpa = &GSLocalMemory::readPixel32; - m_psmtbl[i].wp = &GSLocalMemory::writePixel32; - m_psmtbl[i].wpa = &GSLocalMemory::writePixel32; - m_psmtbl[i].rt = m_psmtbl[i].rtNP = m_psmtbl[i].rtP = &GSLocalMemory::readTexel32; - m_psmtbl[i].rta = &GSLocalMemory::readTexel32; - m_psmtbl[i].wfa = &GSLocalMemory::writePixel32; - m_psmtbl[i].st = &GSLocalMemory::SwizzleTexture32; - m_psmtbl[i].ust = m_psmtbl[i].ustP = m_psmtbl[i].ustNP = &GSLocalMemory::unSwizzleTexture32; - m_psmtbl[i].bpp = m_psmtbl[i].trbpp = 32; - m_psmtbl[i].pal = 0; - m_psmtbl[i].bs = CSize(8, 8); - for(int j = 0; j < 8; j++) m_psmtbl[i].rowOffset[j] = rowOffset32; - } - - m_psmtbl[PSM_PSMCT16].pa = &GSLocalMemory::pixelAddress16; - m_psmtbl[PSM_PSMCT16S].pa = &GSLocalMemory::pixelAddress16S; - m_psmtbl[PSM_PSMT8].pa = &GSLocalMemory::pixelAddress8; - m_psmtbl[PSM_PSMT4].pa = &GSLocalMemory::pixelAddress4; - m_psmtbl[PSM_PSMZ32].pa = &GSLocalMemory::pixelAddress32Z; - m_psmtbl[PSM_PSMZ24].pa = &GSLocalMemory::pixelAddress32Z; - m_psmtbl[PSM_PSMZ16].pa = &GSLocalMemory::pixelAddress16Z; - m_psmtbl[PSM_PSMZ16S].pa = &GSLocalMemory::pixelAddress16SZ; - - m_psmtbl[PSM_PSMCT16].ba = &GSLocalMemory::blockAddress16; - m_psmtbl[PSM_PSMCT16S].ba = &GSLocalMemory::blockAddress16S; - m_psmtbl[PSM_PSMT8].ba = &GSLocalMemory::blockAddress8; - m_psmtbl[PSM_PSMT4].ba = &GSLocalMemory::blockAddress4; - m_psmtbl[PSM_PSMZ32].ba = &GSLocalMemory::blockAddress32Z; - m_psmtbl[PSM_PSMZ24].ba = &GSLocalMemory::blockAddress32Z; - m_psmtbl[PSM_PSMZ16].ba = &GSLocalMemory::blockAddress16Z; - m_psmtbl[PSM_PSMZ16S].ba = &GSLocalMemory::blockAddress16SZ; - - m_psmtbl[PSM_PSMCT16].pga = &GSLocalMemory::pageAddress16; - m_psmtbl[PSM_PSMCT16S].pga = &GSLocalMemory::pageAddress16; - m_psmtbl[PSM_PSMZ16].pga = &GSLocalMemory::pageAddress16; - m_psmtbl[PSM_PSMZ16S].pga = &GSLocalMemory::pageAddress16; - m_psmtbl[PSM_PSMT8].pga = &GSLocalMemory::pageAddress8; - m_psmtbl[PSM_PSMT4].pga = &GSLocalMemory::pageAddress4; - - m_psmtbl[PSM_PSMCT24].rp = &GSLocalMemory::readPixel24; - m_psmtbl[PSM_PSMCT16].rp = &GSLocalMemory::readPixel16; - m_psmtbl[PSM_PSMCT16S].rp = &GSLocalMemory::readPixel16S; - m_psmtbl[PSM_PSMT8].rp = &GSLocalMemory::readPixel8; - m_psmtbl[PSM_PSMT4].rp = &GSLocalMemory::readPixel4; - m_psmtbl[PSM_PSMT8H].rp = &GSLocalMemory::readPixel8H; - m_psmtbl[PSM_PSMT4HL].rp = &GSLocalMemory::readPixel4HL; - m_psmtbl[PSM_PSMT4HH].rp = &GSLocalMemory::readPixel4HH; - m_psmtbl[PSM_PSMZ32].rp = &GSLocalMemory::readPixel32Z; - m_psmtbl[PSM_PSMZ24].rp = &GSLocalMemory::readPixel24Z; - m_psmtbl[PSM_PSMZ16].rp = &GSLocalMemory::readPixel16Z; - m_psmtbl[PSM_PSMZ16S].rp = &GSLocalMemory::readPixel16SZ; - - m_psmtbl[PSM_PSMCT24].rpa = &GSLocalMemory::readPixel24; - m_psmtbl[PSM_PSMCT16].rpa = &GSLocalMemory::readPixel16; - m_psmtbl[PSM_PSMCT16S].rpa = &GSLocalMemory::readPixel16S; - m_psmtbl[PSM_PSMT8].rpa = &GSLocalMemory::readPixel8; - m_psmtbl[PSM_PSMT4].rpa = &GSLocalMemory::readPixel4; - m_psmtbl[PSM_PSMT8H].rpa = &GSLocalMemory::readPixel8H; - m_psmtbl[PSM_PSMT4HL].rpa = &GSLocalMemory::readPixel4HL; - m_psmtbl[PSM_PSMT4HH].rpa = &GSLocalMemory::readPixel4HH; - m_psmtbl[PSM_PSMZ32].rpa = &GSLocalMemory::readPixel32Z; - m_psmtbl[PSM_PSMZ24].rpa = &GSLocalMemory::readPixel24Z; - m_psmtbl[PSM_PSMZ16].rpa = &GSLocalMemory::readPixel16Z; - m_psmtbl[PSM_PSMZ16S].rpa = &GSLocalMemory::readPixel16SZ; - - m_psmtbl[PSM_PSMCT32].wp = &GSLocalMemory::writePixel32; - m_psmtbl[PSM_PSMCT24].wp = &GSLocalMemory::writePixel24; - m_psmtbl[PSM_PSMCT16].wp = &GSLocalMemory::writePixel16; - m_psmtbl[PSM_PSMCT16S].wp = &GSLocalMemory::writePixel16S; - m_psmtbl[PSM_PSMT8].wp = &GSLocalMemory::writePixel8; - m_psmtbl[PSM_PSMT4].wp = &GSLocalMemory::writePixel4; - m_psmtbl[PSM_PSMT8H].wp = &GSLocalMemory::writePixel8H; - m_psmtbl[PSM_PSMT4HL].wp = &GSLocalMemory::writePixel4HL; - m_psmtbl[PSM_PSMT4HH].wp = &GSLocalMemory::writePixel4HH; - m_psmtbl[PSM_PSMZ32].wp = &GSLocalMemory::writePixel32Z; - m_psmtbl[PSM_PSMZ24].wp = &GSLocalMemory::writePixel24Z; - m_psmtbl[PSM_PSMZ16].wp = &GSLocalMemory::writePixel16Z; - m_psmtbl[PSM_PSMZ16S].wp = &GSLocalMemory::writePixel16SZ; - - m_psmtbl[PSM_PSMCT32].wpa = &GSLocalMemory::writePixel32; - m_psmtbl[PSM_PSMCT24].wpa = &GSLocalMemory::writePixel24; - m_psmtbl[PSM_PSMCT16].wpa = &GSLocalMemory::writePixel16; - m_psmtbl[PSM_PSMCT16S].wpa = &GSLocalMemory::writePixel16S; - m_psmtbl[PSM_PSMT8].wpa = &GSLocalMemory::writePixel8; - m_psmtbl[PSM_PSMT4].wpa = &GSLocalMemory::writePixel4; - m_psmtbl[PSM_PSMT8H].wpa = &GSLocalMemory::writePixel8H; - m_psmtbl[PSM_PSMT4HL].wpa = &GSLocalMemory::writePixel4HL; - m_psmtbl[PSM_PSMT4HH].wpa = &GSLocalMemory::writePixel4HH; - m_psmtbl[PSM_PSMZ32].wpa = &GSLocalMemory::writePixel32Z; - m_psmtbl[PSM_PSMZ24].wpa = &GSLocalMemory::writePixel24Z; - m_psmtbl[PSM_PSMZ16].wpa = &GSLocalMemory::writePixel16Z; - m_psmtbl[PSM_PSMZ16S].wpa = &GSLocalMemory::writePixel16SZ; - - m_psmtbl[PSM_PSMCT24].rt = &GSLocalMemory::readTexel24; - m_psmtbl[PSM_PSMCT16].rt = &GSLocalMemory::readTexel16; - m_psmtbl[PSM_PSMCT16S].rt = &GSLocalMemory::readTexel16S; - m_psmtbl[PSM_PSMT8].rt = &GSLocalMemory::readTexel8; - m_psmtbl[PSM_PSMT4].rt = &GSLocalMemory::readTexel4; - m_psmtbl[PSM_PSMT8H].rt = &GSLocalMemory::readTexel8H; - m_psmtbl[PSM_PSMT4HL].rt = &GSLocalMemory::readTexel4HL; - m_psmtbl[PSM_PSMT4HH].rt = &GSLocalMemory::readTexel4HH; - - m_psmtbl[PSM_PSMCT24].rta = &GSLocalMemory::readTexel24; - m_psmtbl[PSM_PSMCT16].rta = &GSLocalMemory::readTexel16; - m_psmtbl[PSM_PSMCT16S].rta = &GSLocalMemory::readTexel16S; - m_psmtbl[PSM_PSMT8].rta = &GSLocalMemory::readTexel8; - m_psmtbl[PSM_PSMT4].rta = &GSLocalMemory::readTexel4; - m_psmtbl[PSM_PSMT8H].rta = &GSLocalMemory::readTexel8H; - m_psmtbl[PSM_PSMT4HL].rta = &GSLocalMemory::readTexel4HL; - m_psmtbl[PSM_PSMT4HH].rta = &GSLocalMemory::readTexel4HH; - - m_psmtbl[PSM_PSMCT24].wfa = &GSLocalMemory::writePixel24; - m_psmtbl[PSM_PSMCT16].wfa = &GSLocalMemory::writeFrame16; - m_psmtbl[PSM_PSMCT16S].wfa = &GSLocalMemory::writeFrame16S; - - m_psmtbl[PSM_PSMCT16].rtP = &GSLocalMemory::readTexel16P; - m_psmtbl[PSM_PSMCT16S].rtP = &GSLocalMemory::readTexel16SP; - m_psmtbl[PSM_PSMT8].rtP = &GSLocalMemory::readTexel8P; - m_psmtbl[PSM_PSMT4].rtP = &GSLocalMemory::readTexel4P; - m_psmtbl[PSM_PSMT8H].rtP = &GSLocalMemory::readTexel8HP; - m_psmtbl[PSM_PSMT4HL].rtP = &GSLocalMemory::readTexel4HLP; - m_psmtbl[PSM_PSMT4HH].rtP = &GSLocalMemory::readTexel4HHP; - - m_psmtbl[PSM_PSMCT16].rtNP = &GSLocalMemory::readTexel16P; - m_psmtbl[PSM_PSMCT16S].rtNP = &GSLocalMemory::readTexel16SP; - m_psmtbl[PSM_PSMT8].rtNP = &GSLocalMemory::readTexel8; - m_psmtbl[PSM_PSMT4].rtNP = &GSLocalMemory::readTexel4; - m_psmtbl[PSM_PSMT8H].rtNP = &GSLocalMemory::readTexel8H; - m_psmtbl[PSM_PSMT4HL].rtNP = &GSLocalMemory::readTexel4HL; - m_psmtbl[PSM_PSMT4HH].rtNP = &GSLocalMemory::readTexel4HH; - - m_psmtbl[PSM_PSMCT24].st = &GSLocalMemory::SwizzleTexture24; - m_psmtbl[PSM_PSMCT16].st = &GSLocalMemory::SwizzleTexture16; - m_psmtbl[PSM_PSMCT16S].st = &GSLocalMemory::SwizzleTexture16S; - m_psmtbl[PSM_PSMT8].st = &GSLocalMemory::SwizzleTexture8; - m_psmtbl[PSM_PSMT4].st = &GSLocalMemory::SwizzleTexture4; - m_psmtbl[PSM_PSMT8H].st = &GSLocalMemory::SwizzleTexture8H; - m_psmtbl[PSM_PSMT4HL].st = &GSLocalMemory::SwizzleTexture4HL; - m_psmtbl[PSM_PSMT4HH].st = &GSLocalMemory::SwizzleTexture4HH; - - m_psmtbl[PSM_PSMCT24].ust = &GSLocalMemory::unSwizzleTexture24; - m_psmtbl[PSM_PSMCT16].ust = &GSLocalMemory::unSwizzleTexture16; - m_psmtbl[PSM_PSMCT16S].ust = &GSLocalMemory::unSwizzleTexture16S; - m_psmtbl[PSM_PSMT8].ust = &GSLocalMemory::unSwizzleTexture8; - m_psmtbl[PSM_PSMT4].ust = &GSLocalMemory::unSwizzleTexture4; - m_psmtbl[PSM_PSMT8H].ust = &GSLocalMemory::unSwizzleTexture8H; - m_psmtbl[PSM_PSMT4HL].ust = &GSLocalMemory::unSwizzleTexture4HL; - m_psmtbl[PSM_PSMT4HH].ust = &GSLocalMemory::unSwizzleTexture4HH; - - m_psmtbl[PSM_PSMCT16].ustP = &GSLocalMemory::unSwizzleTexture16P; - m_psmtbl[PSM_PSMCT16S].ustP = &GSLocalMemory::unSwizzleTexture16SP; - m_psmtbl[PSM_PSMT8].ustP = &GSLocalMemory::unSwizzleTexture8P; - m_psmtbl[PSM_PSMT4].ustP = &GSLocalMemory::unSwizzleTexture4P; - m_psmtbl[PSM_PSMT8H].ustP = &GSLocalMemory::unSwizzleTexture8HP; - m_psmtbl[PSM_PSMT4HL].ustP = &GSLocalMemory::unSwizzleTexture4HLP; - m_psmtbl[PSM_PSMT4HH].ustP = &GSLocalMemory::unSwizzleTexture4HHP; - - m_psmtbl[PSM_PSMCT16].ustNP = &GSLocalMemory::unSwizzleTexture16P; - m_psmtbl[PSM_PSMCT16S].ustNP = &GSLocalMemory::unSwizzleTexture16SP; - m_psmtbl[PSM_PSMT8].ustNP = &GSLocalMemory::unSwizzleTexture8NP; - m_psmtbl[PSM_PSMT4].ustNP = &GSLocalMemory::unSwizzleTexture4NP; - m_psmtbl[PSM_PSMT8H].ustNP = &GSLocalMemory::unSwizzleTexture8HNP; - m_psmtbl[PSM_PSMT4HL].ustNP = &GSLocalMemory::unSwizzleTexture4HLNP; - m_psmtbl[PSM_PSMT4HH].ustNP = &GSLocalMemory::unSwizzleTexture4HHNP; - - m_psmtbl[PSM_PSMT8].pal = m_psmtbl[PSM_PSMT8H].pal = 256; - m_psmtbl[PSM_PSMT4].pal = m_psmtbl[PSM_PSMT4HL].pal = m_psmtbl[PSM_PSMT4HH].pal = 16; - - m_psmtbl[PSM_PSMCT16].bpp = m_psmtbl[PSM_PSMCT16S].bpp = 16; - m_psmtbl[PSM_PSMT8].bpp = 8; - m_psmtbl[PSM_PSMT4].bpp = 4; - m_psmtbl[PSM_PSMZ16].bpp = m_psmtbl[PSM_PSMZ16S].bpp = 16; - - m_psmtbl[PSM_PSMCT24].trbpp = 24; - m_psmtbl[PSM_PSMCT16].trbpp = m_psmtbl[PSM_PSMCT16S].trbpp = 16; - m_psmtbl[PSM_PSMT8].trbpp = m_psmtbl[PSM_PSMT8H].trbpp = 8; - m_psmtbl[PSM_PSMT4].trbpp = m_psmtbl[PSM_PSMT4HL].trbpp = m_psmtbl[PSM_PSMT4HH].trbpp = 4; - m_psmtbl[PSM_PSMZ24].trbpp = 24; - m_psmtbl[PSM_PSMZ16].trbpp = m_psmtbl[PSM_PSMZ16S].trbpp = 16; - - m_psmtbl[PSM_PSMCT16].bs = m_psmtbl[PSM_PSMCT16S].bs = CSize(16, 8); - m_psmtbl[PSM_PSMT8].bs = CSize(16, 16); - m_psmtbl[PSM_PSMT4].bs = CSize(32, 32); - m_psmtbl[PSM_PSMZ16].bs = m_psmtbl[PSM_PSMZ16S].bs = CSize(16, 8); - - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMCT16].rowOffset[i] = rowOffset16; - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMCT16S].rowOffset[i] = rowOffset16S; - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMT8].rowOffset[i] = rowOffset8[((i+2)>>2)&1]; - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMT4].rowOffset[i] = rowOffset4[((i+2)>>2)&1]; - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMZ32].rowOffset[i] = rowOffset32Z; - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMZ24].rowOffset[i] = rowOffset32Z; - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMZ16].rowOffset[i] = rowOffset16Z; - for(int i = 0; i < 8; i++) m_psmtbl[PSM_PSMZ16S].rowOffset[i] = rowOffset16SZ; - - -#ifdef _OPENMP - // need real cpus, with HT it is only going to be slower now - omp_set_num_threads(omp_get_num_procs()); -#endif - -/* -// return; -// omp_set_num_threads(2); -// - { - int tmpsize = 1024*1024*2; - BYTE* tmp1 = new BYTE[tmpsize]; - BYTE* tmp2 = new BYTE[tmpsize]; - - for(int i = 0; i < 1024*1024; i++) - ((DWORD*)GetVM())[i] = rand()*0x12345678; - - GIFRegTEX0 TEX0; - TEX0.TBP0 = 0; - TEX0.TBW = 16; - GIFRegTEXA TEXA; - TEXA.AEM = 0; // 1 - - __declspec(align(32)) static DWORD dst[1024*1024]; - - int nthreads[] = {1,2,4,8}; - for(int j = 0; j < countof(nthreads); j++) - { - omp_set_num_threads(nthreads[j]); - - clock_t start = clock(); - - for(int i = 0; i < 1000; i++) - { - unSwizzleTexture32(CRect(0,0,1024,1024), (BYTE*)dst, 1024*4, TEX0, TEXA); - // for(int k = 0; k < tmpsize; k++) tmp2[k] = tmp1[k]; - } - - clock_t diff = clock() - start; - - CString str; - str.Format(_T("%d threads: %d ms"), nthreads[j], diff); - AfxMessageBox(str); - } - - omp_set_num_threads(2); - - delete [] tmp1; - delete [] tmp2; - } -*/ -} - -GSLocalMemory::~GSLocalMemory() -{ - _aligned_free(m_vm8); - _aligned_free(m_pCLUT); - _aligned_free(m_pCLUT32); - _aligned_free(m_pCLUT64); -} - -//////////////////// - -void GSLocalMemory::RoundDown(CSize& s, CSize bs) -{ - s.cx &= ~(bs.cx-1); - s.cy &= ~(bs.cy-1); -} - -void GSLocalMemory::RoundUp(CSize& s, CSize bs) -{ - s.cx = (s.cx + (bs.cx-1)) & ~(bs.cx-1); - s.cy = (s.cy + (bs.cy-1)) & ~(bs.cy-1); -} - -//////////////////// - -DWORD __fastcall GSLocalMemory::pageAddress32(int x, int y, DWORD bp, DWORD bw) -{ - return ((bp >> 5) + (y >> 5) * bw + (x >> 6)) << 11; -} - -DWORD __fastcall GSLocalMemory::pageAddress16(int x, int y, DWORD bp, DWORD bw) -{ - return ((bp >> 5) + (y >> 6) * bw + (x >> 6)) << 12; -} - -DWORD __fastcall GSLocalMemory::pageAddress8(int x, int y, DWORD bp, DWORD bw) -{ - return ((bp >> 5) + (y >> 6) * ((bw+1)>>1) + (x >> 7)) << 13; -} - -DWORD __fastcall GSLocalMemory::pageAddress4(int x, int y, DWORD bp, DWORD bw) -{ - return ((bp >> 5) + (y >> 7) * ((bw+1)>>1) + (x >> 7)) << 14; -} - -//////////////////// - -DWORD __fastcall GSLocalMemory::blockAddress32(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32[(y >> 3) & 3][(x >> 3) & 7]; - return (page + block) << 6; -} - -DWORD __fastcall GSLocalMemory::blockAddress16(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; -} - -DWORD __fastcall GSLocalMemory::blockAddress16S(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; -} - -DWORD __fastcall GSLocalMemory::blockAddress8(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + ((y >> 1) & ~0x1f) * ((bw+1)>>1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable8[(y >> 4) & 3][(x >> 4) & 7]; - return (page + block) << 8; -} - -DWORD __fastcall GSLocalMemory::blockAddress4(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + ((y >> 2) & ~0x1f) * ((bw+1)>>1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable4[(y >> 4) & 7][(x >> 5) & 3]; - return (page + block) << 9; -} - -DWORD __fastcall GSLocalMemory::blockAddress32Z(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; - return (page + block) << 6; -} - -DWORD __fastcall GSLocalMemory::blockAddress16Z(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; -} - -DWORD __fastcall GSLocalMemory::blockAddress16SZ(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; - return (page + block) << 7; -} - -//////////////////// - -DWORD __fastcall GSLocalMemory::pixelAddressOrg32(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 5) * bw + (x >> 6); -// DWORD block = (bp & 0x1f) + blockTable32[(y >> 3) & 3][(x >> 3) & 7]; -// DWORD word = (((page << 5) + block) << 6) + columnTable32[y & 7][x & 7]; - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32[(y >> 3) & 3][(x >> 3) & 7]; - DWORD word = ((page + block) << 6) + columnTable32[y & 7][x & 7]; - ASSERT(word < 1024*1024); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddressOrg16(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); -// DWORD block = (bp & 0x1f) + blockTable16[(y >> 3) & 7][(x >> 4) & 3]; -// DWORD word = (((page << 5) + block) << 7) + columnTable16[y & 7][x & 15]; - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + columnTable16[y & 7][x & 15]; - ASSERT(word < 1024*1024*2); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddressOrg16S(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); -// DWORD block = (bp & 0x1f) + blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; -// DWORD word = (((page << 5) + block) << 7) + columnTable16[y & 7][x & 15]; - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16S[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + columnTable16[y & 7][x & 15]; - ASSERT(word < 1024*1024*2); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddressOrg8(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 6) * ((bw+1)>>1) + (x >> 7); -// DWORD block = (bp & 0x1f) + blockTable8[(y >> 4) & 3][(x >> 4) & 7]; -// DWORD word = (((page << 5) + block) << 8) + columnTable8[y & 15][x & 15]; - DWORD page = bp + ((y >> 1) & ~0x1f) * ((bw+1)>>1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable8[(y >> 4) & 3][(x >> 4) & 7]; - DWORD word = ((page + block) << 8) + columnTable8[y & 15][x & 15]; -// ASSERT(word < 1024*1024*4); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddressOrg4(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 7) * ((bw+1)>>1) + (x >> 7); -// DWORD block = (bp & 0x1f) + blockTable4[(y >> 4) & 7][(x >> 5) & 3]; -// DWORD word = (((page << 5) + block) << 9) + columnTable4[y & 15][x & 31]; - DWORD page = bp + ((y >> 2) & ~0x1f) * ((bw+1)>>1) + ((x >> 2) & ~0x1f); - DWORD block = blockTable4[(y >> 4) & 7][(x >> 5) & 3]; - DWORD word = ((page + block) << 9) + columnTable4[y & 15][x & 31]; - ASSERT(word < 1024*1024*8); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddressOrg32Z(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 5) * bw + (x >> 6); -// DWORD block = (bp & 0x1f) + blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; -// DWORD word = (((page << 5) + block) << 6) + ((y & 7) << 3) + (x & 7); - DWORD page = bp + (y & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable32Z[(y >> 3) & 3][(x >> 3) & 7]; - DWORD word = ((page + block) << 6) + ((y & 7) << 3) + (x & 7); - ASSERT(word < 1024*1024); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddressOrg16Z(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); -// DWORD block = (bp & 0x1f) + blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; -// DWORD word = (((page << 5) + block) << 7) + ((y & 7) << 4) + (x & 15); - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16Z[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + ((y & 7) << 4) + (x & 15); - ASSERT(word < 1024*1024*2); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddressOrg16SZ(int x, int y, DWORD bp, DWORD bw) -{ -// DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); -// DWORD block = (bp & 0x1f) + blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; -// DWORD word = (((page << 5) + block) << 7) + ((y & 7) << 4) + (x & 15); - DWORD page = bp + ((y >> 1) & ~0x1f) * bw + ((x >> 1) & ~0x1f); - DWORD block = blockTable16SZ[(y >> 3) & 7][(x >> 4) & 3]; - DWORD word = ((page + block) << 7) + ((y & 7) << 4) + (x & 15); - ASSERT(word < 1024*1024*2); - return word; -} - -//////////////////// - -DWORD __fastcall GSLocalMemory::pixelAddress32(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 5) * bw + (x >> 6); - DWORD word = (page << 11) + pageOffset32[bp & 0x1f][y & 0x1f][x & 0x3f]; - ASSERT(word < 1024*1024); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddress16(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16[bp & 0x1f][y & 0x3f][x & 0x3f]; - ASSERT(word < 1024*1024*2); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddress16S(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16S[bp & 0x1f][y & 0x3f][x & 0x3f]; - ASSERT(word < 1024*1024*2); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddress8(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 6) * ((bw+1)>>1) + (x >> 7); - DWORD word = (page << 13) + pageOffset8[bp & 0x1f][y & 0x3f][x & 0x7f]; - ASSERT(word < 1024*1024*4); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddress4(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 7) * ((bw+1)>>1) + (x >> 7); - DWORD word = (page << 14) + pageOffset4[bp & 0x1f][y & 0x7f][x & 0x7f]; - ASSERT(word < 1024*1024*8); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddress32Z(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 5) * bw + (x >> 6); - DWORD word = (page << 11) + pageOffset32Z[bp & 0x1f][y & 0x1f][x & 0x3f]; - ASSERT(word < 1024*1024); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddress16Z(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16Z[bp & 0x1f][y & 0x3f][x & 0x3f]; - ASSERT(word < 1024*1024*2); - return word; -} - -DWORD __fastcall GSLocalMemory::pixelAddress16SZ(int x, int y, DWORD bp, DWORD bw) -{ - DWORD page = (bp >> 5) + (y >> 6) * bw + (x >> 6); - DWORD word = (page << 12) + pageOffset16SZ[bp & 0x1f][y & 0x3f][x & 0x3f]; - ASSERT(word < 1024*1024*2); - return word; -} - -//////////////////// - -void GSLocalMemory::writePixel32(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress32(x, y, bp, bw); - m_vm32[addr] = c; -} - -void GSLocalMemory::writePixel24(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress32(x, y, bp, bw); - m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff); -} - -void GSLocalMemory::writePixel16(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress16(x, y, bp, bw); - m_vm16[addr] = (WORD)c; -} - -void GSLocalMemory::writePixel16S(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress16S(x, y, bp, bw); - m_vm16[addr] = (WORD)c; -} - -void GSLocalMemory::writePixel8(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress8(x, y, bp, bw); - m_vm8[addr] = (BYTE)c; -} - -void GSLocalMemory::writePixel8H(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress32(x, y, bp, bw); - m_vm32[addr] = (m_vm32[addr] & 0x00ffffff) | (c << 24); -} - -void GSLocalMemory::writePixel4(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress4(x, y, bp, bw); - int shift = (addr&1) << 2; addr >>= 1; - m_vm8[addr] = (BYTE)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); -} - -void GSLocalMemory::writePixel4HL(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress32(x, y, bp, bw); - m_vm32[addr] = (m_vm32[addr] & 0xf0ffffff) | ((c & 0x0f) << 24); -} - -void GSLocalMemory::writePixel4HH(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress32(x, y, bp, bw); - m_vm32[addr] = (m_vm32[addr] & 0x0fffffff) | ((c & 0x0f) << 28); -} - -void GSLocalMemory::writePixel32Z(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress32Z(x, y, bp, bw); - m_vm32[addr] = c; -} - -void GSLocalMemory::writePixel24Z(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress32Z(x, y, bp, bw); - m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff); -} - -void GSLocalMemory::writePixel16Z(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress16Z(x, y, bp, bw); - m_vm16[addr] = (WORD)c; -} - -void GSLocalMemory::writePixel16SZ(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress16SZ(x, y, bp, bw); - m_vm16[addr] = (WORD)c; -} - -//////////////////// - -void GSLocalMemory::writeFrame16(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - c = ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f); - writePixel16(x, y, c, bp, bw); -} - -void GSLocalMemory::writeFrame16S(int x, int y, DWORD c, DWORD bp, DWORD bw) -{ - c = ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f); - writePixel16S(x, y, c, bp, bw); -} - -//////////////////// - -DWORD GSLocalMemory::readPixel32(int x, int y, DWORD bp, DWORD bw) -{ - return m_vm32[pixelAddress32(x, y, bp, bw)]; -} - -DWORD GSLocalMemory::readPixel24(int x, int y, DWORD bp, DWORD bw) -{ - return m_vm32[pixelAddress32(x, y, bp, bw)] & 0x00ffffff; -} - -DWORD GSLocalMemory::readPixel16(int x, int y, DWORD bp, DWORD bw) -{ - return (DWORD)m_vm16[pixelAddress16(x, y, bp, bw)]; -} - -DWORD GSLocalMemory::readPixel16S(int x, int y, DWORD bp, DWORD bw) -{ - return (DWORD)m_vm16[pixelAddress16S(x, y, bp, bw)]; -} - -DWORD GSLocalMemory::readPixel8(int x, int y, DWORD bp, DWORD bw) -{ - return (DWORD)m_vm8[pixelAddress8(x, y, bp, bw)]; -} - -DWORD GSLocalMemory::readPixel8H(int x, int y, DWORD bp, DWORD bw) -{ - return m_vm32[pixelAddress32(x, y, bp, bw)] >> 24; -} - -DWORD GSLocalMemory::readPixel4(int x, int y, DWORD bp, DWORD bw) -{ - DWORD addr = pixelAddress4(x, y, bp, bw); - return (m_vm8[addr>>1] >> ((addr&1) << 2)) & 0x0f; -} - -DWORD GSLocalMemory::readPixel4HL(int x, int y, DWORD bp, DWORD bw) -{ - return (m_vm32[pixelAddress32(x, y, bp, bw)] >> 24) & 0x0f; -} - -DWORD GSLocalMemory::readPixel4HH(int x, int y, DWORD bp, DWORD bw) -{ - return (m_vm32[pixelAddress32(x, y, bp, bw)] >> 28) & 0x0f; -} - -DWORD GSLocalMemory::readPixel32Z(int x, int y, DWORD bp, DWORD bw) -{ - return m_vm32[pixelAddress32Z(x, y, bp, bw)]; -} - -DWORD GSLocalMemory::readPixel24Z(int x, int y, DWORD bp, DWORD bw) -{ - return m_vm32[pixelAddress32Z(x, y, bp, bw)] & 0x00ffffff; -} - -DWORD GSLocalMemory::readPixel16Z(int x, int y, DWORD bp, DWORD bw) -{ - return (DWORD)m_vm16[pixelAddress16Z(x, y, bp, bw)]; -} - -DWORD GSLocalMemory::readPixel16SZ(int x, int y, DWORD bp, DWORD bw) -{ - return (DWORD)m_vm16[pixelAddress16SZ(x, y, bp, bw)]; -} - -//////////////////// -/* -void GSLocalMemory::writePixel32(DWORD addr, DWORD c) -{ - m_vm32[addr] = c; -} - -void GSLocalMemory::writePixel24(DWORD addr, DWORD c) -{ - m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff); -} - -void GSLocalMemory::writePixel16(DWORD addr, DWORD c) -{ - m_vm16[addr] = (WORD)c; -} - -void GSLocalMemory::writePixel16S(DWORD addr, DWORD c) -{ - m_vm16[addr] = (WORD)c; -} - -void GSLocalMemory::writePixel8(DWORD addr, DWORD c) -{ - m_vm8[addr] = (BYTE)c; -} - -void GSLocalMemory::writePixel8H(DWORD addr, DWORD c) -{ - m_vm32[addr] = (m_vm32[addr] & 0x00ffffff) | (c << 24); -} - -void GSLocalMemory::writePixel4(DWORD addr, DWORD c) -{ - int shift = (addr&1) << 2; addr >>= 1; - m_vm8[addr] = (BYTE)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift)); -} - -void GSLocalMemory::writePixel4HL(DWORD addr, DWORD c) -{ - m_vm32[addr] = (m_vm32[addr] & 0xf0ffffff) | ((c & 0x0f) << 24); -} - -void GSLocalMemory::writePixel4HH(DWORD addr, DWORD c) -{ - m_vm32[addr] = (m_vm32[addr] & 0x0fffffff) | ((c & 0x0f) << 28); -} - -void GSLocalMemory::writePixel32Z(DWORD addr, DWORD c) -{ - m_vm32[addr] = c; -} - -void GSLocalMemory::writePixel24Z(DWORD addr, DWORD c) -{ - m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff); -} - -void GSLocalMemory::writePixel16Z(DWORD addr, DWORD c) -{ - m_vm16[addr] = (WORD)c; -} - -void GSLocalMemory::writePixel16SZ(DWORD addr, DWORD c) -{ - m_vm16[addr] = (WORD)c; -} - -//////////////////// - -void GSLocalMemory::writeFrame16(DWORD addr, DWORD c) -{ - writePixel16(addr, ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f)); -} - -void GSLocalMemory::writeFrame16S(DWORD addr, DWORD c) -{ - writePixel16S(addr, ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f)); -} - -//////////////////// - -DWORD GSLocalMemory::readPixel32(DWORD addr) -{ - return m_vm32[addr]; -} - -DWORD GSLocalMemory::readPixel24(DWORD addr) -{ - return m_vm32[addr] & 0x00ffffff; -} - -DWORD GSLocalMemory::readPixel16(DWORD addr) -{ - return (DWORD)m_vm16[addr]; -} - -DWORD GSLocalMemory::readPixel16S(DWORD addr) -{ - return (DWORD)m_vm16[addr]; -} - -DWORD GSLocalMemory::readPixel8(DWORD addr) -{ - return (DWORD)m_vm8[addr]; -} - -DWORD GSLocalMemory::readPixel8H(DWORD addr) -{ - return m_vm32[addr] >> 24; -} - -DWORD GSLocalMemory::readPixel4(DWORD addr) -{ - return (m_vm8[addr>>1] >> ((addr&1) << 2)) & 0x0f; -} - -DWORD GSLocalMemory::readPixel4HL(DWORD addr) -{ - return (m_vm32[addr] >> 24) & 0x0f; -} - -DWORD GSLocalMemory::readPixel4HH(DWORD addr) -{ - return (m_vm32[addr] >> 28) & 0x0f; -} - -DWORD GSLocalMemory::readPixel32Z(DWORD addr) -{ - return m_vm32[addr]; -} - -DWORD GSLocalMemory::readPixel24Z(DWORD addr) -{ - return m_vm32[addr] & 0x00ffffff; -} - -DWORD GSLocalMemory::readPixel16Z(DWORD addr) -{ - return (DWORD)m_vm16[addr]; -} - -DWORD GSLocalMemory::readPixel16SZ(DWORD addr) -{ - return (DWORD)m_vm16[addr]; -} -*/ -//////////////////// - -bool GSLocalMemory::FillRect(const CRect& r, DWORD c, DWORD psm, DWORD fbp, DWORD fbw) -{ - const psmtbl_t& tbl = m_psmtbl[psm]; - - writePixel wp = tbl.wp; - pixelAddress ba = tbl.ba; - - int w = tbl.bs.cx; - int h = tbl.bs.cy; - int bpp = tbl.bpp; - - int shift = 0; - - switch(bpp) - { - case 32: shift = 0; break; - case 16: shift = 1; c = (c&0xffff)*0x00010001; break; - case 8: shift = 2; c = (c&0xff)*0x01010101; break; - case 4: shift = 3; c = (c&0xf)*0x11111111; break; - } - - CRect clip((r.left+(w-1))&~(w-1), (r.top+(h-1))&~(h-1), r.right&~(w-1), r.bottom&~(h-1)); - - for(int y = r.top; y < clip.top; y++) - for(int x = r.left; x < r.right; x++) - (this->*wp)(x, y, c, fbp, fbw); - - for(int y = clip.top; y < clip.bottom; y += h) - { - for(int ys = y, ye = y + h; ys < ye; ys++) - { - for(int x = r.left; x < clip.left; x++) - (this->*wp)(x, ys, c, fbp, fbw); - for(int x = clip.right; x < r.right; x++) - (this->*wp)(x, ys, c, fbp, fbw); - } - } - - if(psm == PSM_PSMCT24 || psm == PSM_PSMZ24) - { - c &= 0x00ffffff; - for(int y = clip.top; y < clip.bottom; y += h) - { - for(int x = clip.left; x < clip.right; x += w) - { - DWORD* p = &m_vm32[ba(x, y, fbp, fbw)]; - for(int i = 0; i < 64; i++) - p[i] = (p[i]&0xff000000) | c; - } - } - } - else - { - for(int y = clip.top; y < clip.bottom; y += h) - for(int x = clip.left; x < clip.right; x += w) - memsetd(&m_vm8[ba(x, y, fbp, fbw) << 2 >> shift], c, 64); - } - - for(int y = clip.bottom; y < r.bottom; y++) - for(int x = r.left; x < r.right; x++) - (this->*wp)(x, y, c, fbp, fbw); - - return(true); -} - -//////////////////// - -void GSLocalMemory::WriteCLUT(GIFRegTEX0 TEX0, GIFRegTEXCLUT TEXCLUT) -{ - switch(TEX0.CLD) - { - default: - case 0: return; - case 1: break; - case 2: m_CBP[0] = TEX0.CBP; break; - case 3: m_CBP[1] = TEX0.CBP; break; - case 4: if(m_CBP[0] == TEX0.CBP) return; break; - case 5: if(m_CBP[1] == TEX0.CBP) return; break; - } - - { - if(!m_fCLUTMayBeDirty && m_prevTEX0.i64 == TEX0.i64 && m_prevTEXCLUT.i64 == TEXCLUT.i64) - return; - - m_prevTEX0 = TEX0; - m_prevTEXCLUT = TEXCLUT; - - m_fCLUTMayBeDirty = false; - } - - DWORD bp = TEX0.CBP; - DWORD bw = TEX0.CSM == 0 ? 1 : TEXCLUT.CBW; - - WORD* pCLUT = m_pCLUT + (TEX0.CSA<<4); - - // NOTE: TEX0.CPSM == PSM_PSMCT24 is non-standard, KH uses it - - if(TEX0.CSM == 0) - { - if(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S) - { - WORD* vm = &m_vm16[TEX0.CPSM == PSM_PSMCT16 ? blockAddress16(0, 0, bp, bw) : blockAddress16S(0, 0, bp, bw)]; - - if(TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT8H) - { - WriteCLUT_T16_I8_CSM1(vm, pCLUT); - } - else if(TEX0.PSM == PSM_PSMT4HH || TEX0.PSM == PSM_PSMT4HL || TEX0.PSM == PSM_PSMT4) - { - WriteCLUT_T16_I4_CSM1(vm, pCLUT); - } - } - else if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) - { - DWORD* vm = &m_vm32[blockAddress32(0, 0, bp, bw)]; - - if(TEX0.PSM == PSM_PSMT8 || TEX0.PSM == PSM_PSMT8H) - { - WriteCLUT_T32_I8_CSM1(vm, pCLUT); - } - else if(TEX0.PSM == PSM_PSMT4HH || TEX0.PSM == PSM_PSMT4HL || TEX0.PSM == PSM_PSMT4) - { - WriteCLUT_T32_I4_CSM1(vm, pCLUT); - } - } - } - else - { - readPixel rp = m_psmtbl[TEX0.CPSM].rp; - - int nPaletteEntries = m_psmtbl[TEX0.PSM].pal; - - ASSERT(nPaletteEntries == 0 || TEX0.CPSM == PSM_PSMCT16); // this is the only allowed format for CSM2, but we implement all of them, just in case... - - if(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S) - { - for(int i = 0; i < nPaletteEntries; i++) - { - pCLUT[i] = (WORD)(this->*rp)((TEXCLUT.COU<<4) + i, TEXCLUT.COV, bp, bw); - } - } - else if(TEX0.CPSM == PSM_PSMCT32 || TEX0.CPSM == PSM_PSMCT24) - { - for(int i = 0; i < nPaletteEntries; i++) - { - DWORD dw = (this->*rp)((TEXCLUT.COU<<4) + i, TEXCLUT.COV, bp, bw); - pCLUT[i] = (WORD)(dw & 0xffff); - pCLUT[i+256] = (WORD)(dw >> 16); - } - } - } -} - -// - -void GSLocalMemory::ReadCLUT(GIFRegTEX0 TEX0, GIFRegTEXA TEXA, DWORD* pCLUT32) -{ - ASSERT(pCLUT32); - - WORD* pCLUT = m_pCLUT + (TEX0.CSA<<4); - - if(TEX0.CPSM == PSM_PSMCT32) - { - switch(TEX0.PSM) - { - case PSM_PSMT8: - case PSM_PSMT8H: - ReadCLUT32_T32_I8(pCLUT, pCLUT32); - break; - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ReadCLUT32_T32_I4(pCLUT, pCLUT32); - break; - } - } - else if(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S) - { - switch(TEX0.PSM) - { - case PSM_PSMT8: - case PSM_PSMT8H: - ReadCLUT32_T16_I8(pCLUT, pCLUT32); - break; - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ReadCLUT32_T16_I4(pCLUT, pCLUT32); - break; - } - } -} - -void GSLocalMemory::SetupCLUT(GIFRegTEX0 TEX0, GIFRegTEXA TEXA) -{ - // TODO: cache m_pCLUT* - - ReadCLUT(TEX0, TEXA, m_pCLUT32); - - switch(TEX0.PSM) - { - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - // sse2? - if(TEX0.CPSM == PSM_PSMCT32) - { - for(int j = 0, k = 0; j < 16; j++) - for(int i = 0; i < 16; i++, k++) - m_pCLUT64[k] = ((UINT64)m_pCLUT32[j] << 32) | m_pCLUT32[i]; - } - else - { - for(int j = 0, k = 0; j < 16; j++) - for(int i = 0; i < 16; i++, k++) - m_pCLUT64[k] = ((UINT64)m_pCLUT32[j] << 16) | (m_pCLUT32[i]&0xffff); - } - break; - } -} - -// - -void GSLocalMemory::ReadCLUT32(GIFRegTEX0 TEX0, GIFRegTEXA TEXA, DWORD* pCLUT32) -{ - ASSERT(pCLUT32); - - WORD* pCLUT = m_pCLUT + (TEX0.CSA<<4); - - if(TEX0.CPSM == PSM_PSMCT32) - { - switch(TEX0.PSM) - { - case PSM_PSMT8: - case PSM_PSMT8H: - ReadCLUT32_T32_I8(pCLUT, pCLUT32); - break; - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ReadCLUT32_T32_I4(pCLUT, pCLUT32); - break; - } - } - else if(TEX0.CPSM == PSM_PSMCT16 || TEX0.CPSM == PSM_PSMCT16S) - { - Expand16(pCLUT, pCLUT32, m_psmtbl[TEX0.PSM].pal, &TEXA); - } -} - -void GSLocalMemory::SetupCLUT32(GIFRegTEX0 TEX0, GIFRegTEXA TEXA) -{ - // TODO: cache m_pCLUT* - - ReadCLUT32(TEX0, TEXA, m_pCLUT32); - - switch(TEX0.PSM) - { - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - // sse2? - for(int j = 0, k = 0; j < 16; j++) - for(int i = 0; i < 16; i++, k++) - m_pCLUT64[k] = ((UINT64)m_pCLUT32[j] << 32) | m_pCLUT32[i]; - break; - } -} - -void GSLocalMemory::CopyCLUT32(DWORD* pCLUT32, int nPaletteEntries) -{ - memcpy(pCLUT32, m_pCLUT32, sizeof(DWORD)*nPaletteEntries); -} - -//////////////////// - -DWORD GSLocalMemory::readTexel32(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_vm32[pixelAddress32(x, y, TEX0.TBP0, TEX0.TBW)]; -} - -DWORD GSLocalMemory::readTexel24(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return Expand24To32(m_vm32[pixelAddress32(x, y, TEX0.TBP0, TEX0.TBW)], TEX0.ai32[1]&4, TEXA); -} - -DWORD GSLocalMemory::readTexel16(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return Expand16To32(m_vm16[pixelAddress16(x, y, TEX0.TBP0, TEX0.TBW)], TEXA); -} - -DWORD GSLocalMemory::readTexel16S(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return Expand16To32(m_vm16[pixelAddress16S(x, y, TEX0.TBP0, TEX0.TBW)], TEXA); -} - -DWORD GSLocalMemory::readTexel8(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel8(x, y, TEX0.TBP0, TEX0.TBW)]; -} - -DWORD GSLocalMemory::readTexel8H(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel8H(x, y, TEX0.TBP0, TEX0.TBW)]; -} - -DWORD GSLocalMemory::readTexel4(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel4(x, y, TEX0.TBP0, TEX0.TBW)]; -} - -DWORD GSLocalMemory::readTexel4HL(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel4HL(x, y, TEX0.TBP0, TEX0.TBW)]; -} - -DWORD GSLocalMemory::readTexel4HH(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel4HH(x, y, TEX0.TBP0, TEX0.TBW)]; -} - -//////////////////// -/* -DWORD GSLocalMemory::readTexel32(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_vm32[addr]; -} - -DWORD GSLocalMemory::readTexel24(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return Expand24To32(m_vm32[addr], TEX0.ai32[1]&4, TEXA); -} - -DWORD GSLocalMemory::readTexel16(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return Expand16To32(m_vm16[addr], TEXA); -} - -DWORD GSLocalMemory::readTexel16S(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return Expand16To32(m_vm16[addr], TEXA); -} - -DWORD GSLocalMemory::readTexel8(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel8(addr)]; -} - -DWORD GSLocalMemory::readTexel8H(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel8H(addr)]; -} - -DWORD GSLocalMemory::readTexel4(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel4(addr)]; -} - -DWORD GSLocalMemory::readTexel4HL(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel4HL(addr)]; -} - -DWORD GSLocalMemory::readTexel4HH(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return m_pCLUT32[readPixel4HH(addr)]; -} -*/ -//////////////////// - -static void SwizzleTextureStep(int& tx, int& ty, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ -// if(ty == TRXREG.RRH && tx == TRXPOS.DSAX) ASSERT(0); - - if(++tx == TRXREG.RRW) - { - tx = TRXPOS.DSAX; - ty++; - } -} - -#define IsTopLeftAligned(dsax, tx, ty, bw, bh) \ - (((dsax) & ((bw)-1)) == 0 && ((tx) & ((bw)-1)) == 0 && (dsax) == (tx) && ((ty) & ((bh)-1)) == 0) - -void GSLocalMemory::SwizzleTexture32(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX)*4; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8); - - if(!fTopLeftAligned || (tw & 7) || (th & 7) || (len % srcpitch)) - { - if(fTopLeftAligned && tw >= 8 && th >= 8) - { - int twa = tw & ~7; - int tha = th & ~7; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 8) - { - for(int x = tx; x < twa; x += 8) - SwizzleBlock32u((BYTE*)&m_vm32[blockAddress32(x, ty, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*4, srcpitch); - - for(int i = 0; i < 8; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel32(x, ty, ((DWORD*)src)[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - if(len > 0 && tw >= 8 && th >= 2 && IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 2)) - { - int twa = tw & ~7; - int tha = th & ~1; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 2) - { - for(int x = tx; x < twa; x += 8) - SwizzleColumn32(ty, (BYTE*)&m_vm32[blockAddress32(x, ty&~7, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*4, srcpitch); - - for(int i = 0; i < 2; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel32(x, ty, ((DWORD*)src)[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - th += ty; - - if((DWORD_PTR)src & 0xf) - { - for(int y = ty; y < th; y += 8, src += srcpitch*8) - for(int x = tx; x < tw; x += 8) - SwizzleBlock32u((BYTE*)&m_vm32[blockAddress32(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*4, srcpitch); - } - else - { - for(int y = ty; y < th; y += 8, src += srcpitch*8) - for(int x = tx; x < tw; x += 8) - SwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*4, srcpitch); - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture24(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX)*3; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8); - - if(!fTopLeftAligned || (tw & 7) || (th & 7) || (len % srcpitch)) - { - // TODO - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - __declspec(align(16)) DWORD block[8*8]; - - th += ty; - - for(int y = ty; y < th; y += 8, src += srcpitch*8) - { - for(int x = tx; x < tw; x += 8) - { - BYTE* s = src + (x - tx)*3; - DWORD* d = block; - - for(int j = 0, diff = srcpitch - 8*3; j < 8; j++, s += diff, d += 8) - for(int i = 0; i < 8; i++, s += 3) - d[i] = (s[2]<<16)|(s[1]<<8)|s[0]; - - SwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], (BYTE*)block, sizeof(block)/8, 0x00ffffff); - } - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture16(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX)*2; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 16, 8); - - if(!fTopLeftAligned || (tw & 15) || (th & 7) || (len % srcpitch)) - { - if(fTopLeftAligned && tw >= 16 && th >= 8) - { - int twa = tw & ~15; - int tha = th & ~7; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 8) - { - for(int x = tx; x < twa; x += 16) - SwizzleBlock16u((BYTE*)&m_vm16[blockAddress16(x, ty, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - - for(int i = 0; i < 8; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel16(x, ty, ((WORD*)src)[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - if(len > 0 && tw >= 16 && th >= 2 && IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 16, 2)) - { - int twa = tw & ~15; - int tha = th & ~1; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 2) - { - for(int x = tx; x < twa; x += 16) - SwizzleColumn16(ty, (BYTE*)&m_vm16[blockAddress16(x, ty&~7, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - - for(int i = 0; i < 2; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel16(x, ty, ((WORD*)src)[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - th += ty; - - if((DWORD_PTR)src & 0xf) - { - for(int y = ty; y < th; y += 8, src += srcpitch*8) - for(int x = tx; x < tw; x += 16) - SwizzleBlock16u((BYTE*)&m_vm16[blockAddress16(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - } - else - { - for(int y = ty; y < th; y += 8, src += srcpitch*8) - for(int x = tx; x < tw; x += 16) - SwizzleBlock16((BYTE*)&m_vm16[blockAddress16(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture16S(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX)*2; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 16, 8); - - if(!fTopLeftAligned || (tw & 15) || (th & 7) || (len % srcpitch)) - { - if(fTopLeftAligned && tw >= 16 && th >= 8) - { - int twa = tw & ~15; - int tha = th & ~7; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 8) - { - for(int x = tx; x < twa; x += 16) - SwizzleBlock16u((BYTE*)&m_vm16[blockAddress16S(x, ty, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - - for(int i = 0; i < 8; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel16S(x, ty, ((WORD*)src)[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - if(len > 0 && tw >= 16 && th >= 2 && IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 16, 2)) - { - int twa = tw & ~15; - int tha = th & ~1; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 2) - { - for(int x = tx; x < twa; x += 16) - SwizzleColumn16(ty, (BYTE*)&m_vm16[blockAddress16S(x, ty&~7, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - - for(int i = 0; i < 2; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel16S(x, ty, ((WORD*)src)[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - th += ty; - - if((DWORD_PTR)src & 0xf) - { - for(int y = ty; y < th; y += 8, src += srcpitch*8) - for(int x = tx; x < tw; x += 16) - SwizzleBlock16((BYTE*)&m_vm16[blockAddress16S(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - } - else - { - for(int y = ty; y < th; y += 8, src += srcpitch*8) - for(int x = tx; x < tw; x += 16) - SwizzleBlock16((BYTE*)&m_vm16[blockAddress16S(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx)*2, srcpitch); - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture8(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = TRXREG.RRW - TRXPOS.DSAX; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 16, 16); - - if(!fTopLeftAligned || (tw & 15) || (th & 15) || (len % srcpitch)) - { - if(fTopLeftAligned && tw >= 16 && th >= 16) - { - int twa = tw & ~15; - int tha = th & ~15; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 16) - { - for(int x = tx; x < twa; x += 16) - SwizzleBlock8u((BYTE*)&m_vm8[blockAddress8(x, ty, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx), srcpitch); - - for(int i = 0; i < 16; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel8(x, ty, src[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - if(len > 0 && tw >= 16 && th >= 4 && IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 16, 4)) - { - int twa = tw & ~15; - int tha = th & ~3; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 4) - { - for(int x = tx; x < twa; x += 16) - SwizzleColumn8(ty, (BYTE*)&m_vm8[blockAddress8(x, ty&~15, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx), srcpitch); - - for(int i = 0; i < 4; i++, ty++, src += srcpitch) - for(int x = twa; x < tw; x++) - writePixel8(x, ty, src[x - tx], BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - th += ty; - - if((DWORD_PTR)src & 0xf) - { - for(int y = ty; y < th; y += 16, src += srcpitch*16) - for(int x = tx; x < tw; x += 16) - SwizzleBlock8u((BYTE*)&m_vm8[blockAddress8(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx), srcpitch); - } - else - { - for(int y = ty; y < th; y += 16, src += srcpitch*16) - for(int x = tx; x < tw; x += 16) - SwizzleBlock8((BYTE*)&m_vm8[blockAddress8(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], src + (x - tx), srcpitch); - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = TRXREG.RRW - TRXPOS.DSAX; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8); - - if(!fTopLeftAligned || (tw & 7) || (th & 7) || (len % srcpitch)) - { - // TODO - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - __declspec(align(16)) DWORD block[8*8]; - - th += ty; - - for(int y = ty; y < th; y += 8, src += srcpitch*8) - { - for(int x = tx; x < tw; x += 8) - { - BYTE* s = src + (x - tx); - DWORD* d = block; - - for(int j = 0; j < 8; j++, s += srcpitch, d += 8) - for(int i = 0; i < 8; i++) - d[i] = s[i] << 24; - - SwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], (BYTE*)block, sizeof(block)/8, 0xff000000); - } - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture4(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX)/2; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 32, 16); - - if(!fTopLeftAligned || (tw & 31) || (th & 15) || (len % srcpitch)) - { - if(fTopLeftAligned && tw >= 32 && th >= 16) - { - int twa = tw & ~31; - int tha = th & ~15; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 16) - { - for(int x = tx; x < twa; x += 32) - SwizzleBlock4u((BYTE*)&m_vm8[blockAddress4(x, ty, BITBLTBUF.DBP, BITBLTBUF.DBW)>>1], src + (x - tx)/2, srcpitch); - - for(int i = 0; i < 16; i++, ty++, src += srcpitch) - { - BYTE* s = src + (twa - tx)/2; - - for(int x = twa; x < tw; x += 2, s++) - { - writePixel4(x, ty, *s&0xf, BITBLTBUF.DBP, BITBLTBUF.DBW), - writePixel4(x+1, ty, *s>>4, BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - } - } - - if(len > 0 && tw >= 32 && th >= 4 && IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 32, 4)) - { - int twa = tw & ~31; - int tha = th & ~3; - - len -= tha * srcpitch; - th -= tha; - - for(int j = 0; j < tha; j += 4) - { - for(int x = tx; x < twa; x += 32) - SwizzleColumn4(ty, (BYTE*)&m_vm8[blockAddress4(x, ty&~15, BITBLTBUF.DBP, BITBLTBUF.DBW)>>1], src + (x - tx)/2, srcpitch); - - for(int i = 0; i < 4; i++, ty++, src += srcpitch) - { - BYTE* s = src + (twa - tx)/2; - - for(int x = twa; x < tw; x += 2, s++) - { - writePixel4(x, ty, *s&0xf, BITBLTBUF.DBP, BITBLTBUF.DBW), - writePixel4(x+1, ty, *s>>4, BITBLTBUF.DBP, BITBLTBUF.DBW); - } - } - } - } - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - th += ty; - - if((DWORD_PTR)src & 0xf) - { - for(int y = ty; y < th; y += 16, src += srcpitch*16) - for(int x = tx; x < tw; x += 32) - SwizzleBlock4u((BYTE*)&m_vm8[blockAddress4(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)>>1], src + (x - tx)/2, srcpitch); - } - else - { - for(int y = ty; y < th; y += 16, src += srcpitch*16) - for(int x = tx; x < tw; x += 32) - SwizzleBlock4((BYTE*)&m_vm8[blockAddress4(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)>>1], src + (x - tx)/2, srcpitch); - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX)/2; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8); - - if(!fTopLeftAligned || (tw & 7) || (th & 7) || (len % srcpitch)) - { - // TODO - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - __declspec(align(16)) DWORD block[8*8]; - - th += ty; - - for(int y = ty; y < th; y += 8, src += srcpitch*8) - { - for(int x = tx; x < tw; x += 8) - { - BYTE* s = src + (x - tx)/2; - DWORD* d = block; - - for(int j = 0; j < 8; j++, s += srcpitch, d += 8) - for(int i = 0; i < 8/2; i++) - d[i*2] = (s[i]&0x0f) << 24, - d[i*2+1] = (s[i]&0xf0) << 20; - - SwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], (BYTE*)block, sizeof(block)/8, 0x0f000000); - } - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTexture4HH(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(TRXREG.RRW == 0) return; - - int tw = TRXREG.RRW, srcpitch = (TRXREG.RRW - TRXPOS.DSAX)/2; - int th = len / srcpitch; - - bool fTopLeftAligned = IsTopLeftAligned(TRXPOS.DSAX, tx, ty, 8, 8); - - if(!fTopLeftAligned || (tw & 7) || (th & 7) || (len % srcpitch)) - { - // TODO - - SwizzleTextureX(tx, ty, src, len, BITBLTBUF, TRXPOS, TRXREG); - } - else - { - __declspec(align(16)) DWORD block[8*8]; - - th += ty; - - for(int y = ty; y < th; y += 8, src += srcpitch*8) - { - for(int x = tx; x < tw; x += 8) - { - BYTE* s = src + (x - tx)/2; - DWORD* d = block; - - for(int j = 0; j < 8; j++, s += srcpitch, d += 8) - for(int i = 0; i < 8/2; i++) - d[i*2] = (s[i]&0x0f) << 28, - d[i*2+1] = (s[i]&0xf0) << 24; - - SwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, BITBLTBUF.DBP, BITBLTBUF.DBW)], (BYTE*)block, sizeof(block)/8, 0xf0000000); - } - } - - ty = th; - } -} - -void GSLocalMemory::SwizzleTextureX(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG) -{ - if(len <= 0) return; - - BYTE* pb = (BYTE*)src; - WORD* pw = (WORD*)src; - DWORD* pd = (DWORD*)src; - - // if(ty >= (int)TRXREG.RRH) {ASSERT(0); return;} - - switch(BITBLTBUF.DPSM) - { - case PSM_PSMCT32: - for(len /= 4; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pd++) - writePixel32(tx, ty, *pd, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMCT24: - for(len /= 3; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pb+=3) - writePixel24(tx, ty, *(DWORD*)pb, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMCT16: - for(len /= 2; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pw++) - writePixel16(tx, ty, *pw, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMCT16S: - for(len /= 2; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pw++) - writePixel16S(tx, ty, *pw, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMT8: - for(; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pb++) - writePixel8(tx, ty, *pb, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMT4: - for(; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pb++) - writePixel4(tx, ty, *pb&0xf, BITBLTBUF.DBP, BITBLTBUF.DBW), - writePixel4(tx+1, ty, *pb>>4, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMT8H: - for(; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pb++) - writePixel8H(tx, ty, *pb, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMT4HL: - for(; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pb++) - writePixel4HL(tx, ty, *pb&0xf, BITBLTBUF.DBP, BITBLTBUF.DBW), - writePixel4HL(tx+1, ty, *pb>>4, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMT4HH: - for(; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pb++) - writePixel4HH(tx, ty, *pb&0xf, BITBLTBUF.DBP, BITBLTBUF.DBW), - writePixel4HH(tx+1, ty, *pb>>4, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMZ32: - for(len /= 4; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pd++) - writePixel32Z(tx, ty, *pd, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMZ24: - for(len /= 3; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pb+=3) - writePixel24Z(tx, ty, *(DWORD*)pb, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMZ16: - for(len /= 2; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pw++) - writePixel16Z(tx, ty, *pw, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - case PSM_PSMZ16S: - for(len /= 2; len-- > 0; SwizzleTextureStep(tx, ty, TRXPOS, TRXREG), pw++) - writePixel16SZ(tx, ty, *pw, BITBLTBUF.DBP, BITBLTBUF.DBW); - break; - } -} - -/////////////////// - -void GSLocalMemory::unSwizzleTexture32(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], ptr + (x-r.left)*4, dstpitch); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture24(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - __declspec(align(16)) DWORD block[8*8]; - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - ExpandBlock24(block, (DWORD*)ptr + (x-r.left), dstpitch, &TEXA); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture16(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 16, 8, 16) - { - __declspec(align(16)) WORD block[16*8]; - unSwizzleBlock16((BYTE*)&m_vm16[blockAddress16(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - ExpandBlock16(block, (DWORD*)ptr + (x-r.left), dstpitch, &TEXA); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture16S(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 16, 8, 16S) - { - __declspec(align(16)) WORD block[16*8]; - unSwizzleBlock16((BYTE*)&m_vm16[blockAddress16S(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - ExpandBlock16(block, (DWORD*)ptr + (x-r.left), dstpitch, &TEXA); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture8(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 16, 16, 8) - { - __declspec(align(16)) BYTE block[16*16]; - unSwizzleBlock8((BYTE*)&m_vm8[blockAddress8(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/16); - - BYTE* s = block; - BYTE* d = ptr + (x-r.left)*4; - - for(int j = 0; j < 16; j++, s += 16, d += dstpitch) - for(int i = 0; i < 16; i++) - ((DWORD*)d)[i] = m_pCLUT32[s[i]]; - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture8H(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - __declspec(align(16)) DWORD block[8*8]; - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - - DWORD* s = block; - BYTE* d = ptr + (x-r.left)*4; - - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)d)[i] = m_pCLUT32[s[i] >> 24]; - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 32, 16, 4) - { - __declspec(align(16)) BYTE block[(32/2)*16]; - unSwizzleBlock4((BYTE*)&m_vm8[blockAddress4(x, y, TEX0.TBP0, TEX0.TBW)>>1], (BYTE*)block, sizeof(block)/16); - - BYTE* s = block; - BYTE* d = ptr + (x-r.left)*4; - - for(int j = 0; j < 16; j++, s += 32/2, d += dstpitch) - for(int i = 0; i < 32/2; i++) - ((UINT64*)d)[i] = m_pCLUT64[s[i]]; - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4HL(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - __declspec(align(16)) DWORD block[8*8]; - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - - DWORD* s = block; - BYTE* d = ptr + (x-r.left)*4; - - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)d)[i] = m_pCLUT32[(s[i] >> 24)&0x0f]; - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4HH(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - __declspec(align(16)) DWORD block[8*8]; - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - - DWORD* s = block; - BYTE* d = ptr + (x-r.left)*4; - - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)d)[i] = m_pCLUT32[s[i] >> 28]; - } - FOREACH_BLOCK_END - } -} - -/////////////////// - -void GSLocalMemory::ReadTexture(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP) -{ - unSwizzleTexture st = m_psmtbl[TEX0.PSM].ust; - readTexel rt = m_psmtbl[TEX0.PSM].rt; - CSize bs = m_psmtbl[TEX0.PSM].bs; - - if(r.Width() < bs.cx || r.Height() < bs.cy - || (r.left & (bs.cx-1)) || (r.top & (bs.cy-1)) - || (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1)) - || (CLAMP.WMS&2) || (CLAMP.WMT&2)) - { - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - } - else - { - (this->*st)(r, dst, dstpitch, TEX0, TEXA); - } -} - -//////////////////// - -DWORD GSLocalMemory::readTexel16P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return readPixel16(x, y, TEX0.TBP0, TEX0.TBW); -} - -DWORD GSLocalMemory::readTexel16SP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return readPixel16S(x, y, TEX0.TBP0, TEX0.TBW); -} - -DWORD GSLocalMemory::readTexel8P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return readPixel8(x, y, TEX0.TBP0, TEX0.TBW); -} - -DWORD GSLocalMemory::readTexel8HP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return readPixel8H(x, y, TEX0.TBP0, TEX0.TBW); -} - -DWORD GSLocalMemory::readTexel4P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return readPixel4(x, y, TEX0.TBP0, TEX0.TBW); -} - -DWORD GSLocalMemory::readTexel4HLP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return readPixel4HL(x, y, TEX0.TBP0, TEX0.TBW); -} - -DWORD GSLocalMemory::readTexel4HHP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - return readPixel4HH(x, y, TEX0.TBP0, TEX0.TBW); -} - -/////////////////// - -void GSLocalMemory::unSwizzleTexture16P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 16, 8, 16) - { - unSwizzleBlock16((BYTE*)&m_vm16[blockAddress16(x, y, TEX0.TBP0, TEX0.TBW)], ptr + (x-r.left)*2, dstpitch); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture16SP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 16, 8, 16S) - { - unSwizzleBlock16((BYTE*)&m_vm16[blockAddress16S(x, y, TEX0.TBP0, TEX0.TBW)], ptr + (x-r.left)*2, dstpitch); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture8P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 16, 16, 8) - { - unSwizzleBlock8((BYTE*)&m_vm8[blockAddress8(x, y, TEX0.TBP0, TEX0.TBW)], ptr + (x-r.left), dstpitch); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture8HP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - unSwizzleBlock8HP((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], ptr + (x-r.left), dstpitch); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 32, 16, 4) - { - unSwizzleBlock4P((BYTE*)&m_vm8[blockAddress4(x, y, TEX0.TBP0, TEX0.TBW)>>1], ptr + (x-r.left), dstpitch); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4HLP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - unSwizzleBlock4HLP((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], ptr + (x-r.left), dstpitch); - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4HHP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - unSwizzleBlock4HHP((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], ptr + (x-r.left), dstpitch); - } - FOREACH_BLOCK_END - } -} - -/////////////////// - -void GSLocalMemory::ReadTextureP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP) -{ - unSwizzleTexture st = m_psmtbl[TEX0.PSM].ustP; - readTexel rt = m_psmtbl[TEX0.PSM].rtP; - CSize bs = m_psmtbl[TEX0.PSM].bs; - - if(r.Width() < bs.cx || r.Height() < bs.cy - || (r.left & (bs.cx-1)) || (r.top & (bs.cy-1)) - || (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1)) - || (CLAMP.WMS&2) || (CLAMP.WMT&2)) - { - switch(TEX0.PSM) - { - default: - case PSM_PSMCT32: - case PSM_PSMCT24: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - break; - case PSM_PSMT8: - case PSM_PSMT8H: - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - break; - } - } - else - { - (this->*st)(r, dst, dstpitch, TEX0, TEXA); - } -} - -/////////////////// - -void GSLocalMemory::unSwizzleTexture8NP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 16, 16, 8) - { - __declspec(align(16)) BYTE block[16*16]; - unSwizzleBlock8((BYTE*)&m_vm8[blockAddress8(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/16); - - BYTE* s = block; - - if(TEX0.CPSM == PSM_PSMCT32) - { - BYTE* d = ptr + (x-r.left)*4; - for(int j = 0; j < 16; j++, s += 16, d += dstpitch) - for(int i = 0; i < 16; i++) - ((DWORD*)d)[i] = m_pCLUT32[s[i]]; - } - else - { - BYTE* d = ptr + (x-r.left)*2; - for(int j = 0; j < 16; j++, s += 16, d += dstpitch) - for(int i = 0; i < 16; i++) - ((WORD*)d)[i] = (WORD)m_pCLUT32[s[i]]; - } - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture8HNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - __declspec(align(16)) DWORD block[8*8]; - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - - DWORD* s = block; - - if(TEX0.CPSM == PSM_PSMCT32) - { - BYTE* d = ptr + (x-r.left)*4; - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)d)[i] = m_pCLUT32[s[i] >> 24]; - } - else - { - BYTE* d = ptr + (x-r.left)*2; - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((WORD*)d)[i] = (WORD)m_pCLUT32[s[i] >> 24]; - } - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4NP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 32, 16, 4) - { - __declspec(align(16)) BYTE block[(32/2)*16]; - unSwizzleBlock4((BYTE*)&m_vm8[blockAddress4(x, y, TEX0.TBP0, TEX0.TBW)>>1], (BYTE*)block, sizeof(block)/16); - - BYTE* s = block; - - if(TEX0.CPSM == PSM_PSMCT32) - { - BYTE* d = ptr + (x-r.left)*4; - for(int j = 0; j < 16; j++, s += 32/2, d += dstpitch) - for(int i = 0; i < 32/2; i++) - ((UINT64*)d)[i] = m_pCLUT64[s[i]]; - } - else - { - BYTE* d = ptr + (x-r.left)*2; - for(int j = 0; j < 16; j++, s += 32/2, d += dstpitch) - for(int i = 0; i < 32/2; i++) - ((DWORD*)d)[i] = (DWORD)m_pCLUT64[s[i]]; - } - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4HLNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - __declspec(align(16)) DWORD block[8*8]; - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - - DWORD* s = block; - - if(TEX0.CPSM == PSM_PSMCT32) - { - BYTE* d = ptr + (x-r.left)*4; - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)d)[i] = m_pCLUT32[(s[i] >> 24)&0x0f]; - } - else - { - BYTE* d = ptr + (x-r.left)*2; - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((WORD*)d)[i] = (WORD)m_pCLUT32[(s[i] >> 24)&0x0f]; - } - } - FOREACH_BLOCK_END - } -} - -void GSLocalMemory::unSwizzleTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) -{ - #pragma omp parallel - { - #pragma omp for - FOREACH_BLOCK_START(r, 8, 8, 32) - { - __declspec(align(16)) DWORD block[8*8]; - unSwizzleBlock32((BYTE*)&m_vm32[blockAddress32(x, y, TEX0.TBP0, TEX0.TBW)], (BYTE*)block, sizeof(block)/8); - - DWORD* s = block; - - if(TEX0.CPSM == PSM_PSMCT32) - { - BYTE* d = ptr + (x-r.left)*4; - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)d)[i] = m_pCLUT32[s[i] >> 28]; - } - else - { - BYTE* d = ptr + (x-r.left)*2; - for(int j = 0; j < 8; j++, s += 8, d += dstpitch) - for(int i = 0; i < 8; i++) - ((WORD*)d)[i] = (WORD)m_pCLUT32[s[i] >> 28]; - } - } - FOREACH_BLOCK_END - } -} - -/////////////////// - -void GSLocalMemory::ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP) -{ - unSwizzleTexture st = m_psmtbl[TEX0.PSM].ustNP; - readTexel rt = m_psmtbl[TEX0.PSM].rtNP; - - CSize bs = m_psmtbl[TEX0.PSM].bs; - - if(r.Width() < bs.cx || r.Height() < bs.cy - || (r.left & (bs.cx-1)) || (r.top & (bs.cy-1)) - || (r.right & (bs.cx-1)) || (r.bottom & (bs.cy-1)) - || (CLAMP.WMS&2) || (CLAMP.WMT&2)) - { - switch(TEX0.PSM) - { - default: - case PSM_PSMCT32: - case PSM_PSMCT24: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - break; - case PSM_PSMT8: - case PSM_PSMT8H: - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - switch(TEX0.CPSM) - { - default: - case PSM_PSMCT32: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - ReadTexture(r, dst, dstpitch, TEX0, TEXA, CLAMP, rt, st); - break; - } - break; - } - } - else - { - (this->*st)(r, dst, dstpitch, TEX0, TEXA); - } -} - -// - -template -void GSLocalMemory::ReadTexture(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP, readTexel rt, unSwizzleTexture st) -{ - // this function is not thread safe! - - CSize bs = m_psmtbl[TEX0.PSM].bs; - - CRect cr( - (r.left + (bs.cx-1)) & ~(bs.cx-1), - (r.top + (bs.cy-1)) & ~(bs.cy-1), - r.right & ~(bs.cx-1), - r.bottom & ~(bs.cy-1)); - - bool fAligned = ((DWORD_PTR)(dst + (cr.left-r.left)*sizeof(DstT)) & 0xf) == 0; - - if((CLAMP.WMS&2) || (CLAMP.WMT&2)) - { - DWORD wms = CLAMP.WMS, wmt = CLAMP.WMT; - DWORD minu = CLAMP.MINU, maxu = CLAMP.MAXU; - DWORD minv = CLAMP.MINV, maxv = CLAMP.MAXV; - - switch(wms) - { - default: for(int x = r.left; x < r.right; x++) m_xtbl[x] = x; break; - case 2: for(int x = r.left; x < r.right; x++) m_xtbl[x] = x < minu ? minu : x > maxu ? maxu : x; break; - case 3: for(int x = r.left; x < r.right; x++) m_xtbl[x] = (x & minu) | maxu; break; - } - - switch(wmt) - { - default: for(int y = r.top; y < r.bottom; y++) m_ytbl[y] = y; break; - case 2: for(int y = r.top; y < r.bottom; y++) m_ytbl[y] = y < minv ? minv : y > maxv ? maxv : y; break; - case 3: for(int y = r.top; y < r.bottom; y++) m_ytbl[y] = (y & minv) | maxv; break; - } - - if(fAligned && wms <= 2 && wmt <= 2) - { - // TODO: read clamped areas only once - - for(int y = r.top; y < cr.top; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(m_xtbl[x], m_ytbl[y], TEX0, TEXA); - - if(!cr.IsRectEmpty()) - (this->*st)(cr, dst + (cr.left - r.left)*sizeof(DstT), dstpitch, TEX0, TEXA); - - for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch) - { - for(int x = r.left, i = 0; x < cr.left; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(m_xtbl[x], m_ytbl[y], TEX0, TEXA); - for(int x = cr.right, i = x - r.left; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(m_xtbl[x], m_ytbl[y], TEX0, TEXA); - } - - for(int y = cr.bottom; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(m_xtbl[x], m_ytbl[y], TEX0, TEXA); - } - else - { - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(m_xtbl[x], m_ytbl[y], TEX0, TEXA); - } - } - else - { - if(fAligned) - { - for(int y = r.top; y < cr.top; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(x, y, TEX0, TEXA); - - if(!cr.IsRectEmpty()) - (this->*st)(cr, dst + (cr.left - r.left)*sizeof(DstT), dstpitch, TEX0, TEXA); - - for(int y = cr.top; y < cr.bottom; y++, dst += dstpitch) - { - for(int x = r.left, i = 0; x < cr.left; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(x, y, TEX0, TEXA); - for(int x = cr.right, i = x - r.left; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(x, y, TEX0, TEXA); - } - - for(int y = cr.bottom; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(x, y, TEX0, TEXA); - } - else - { - for(int y = r.top; y < r.bottom; y++, dst += dstpitch) - for(int x = r.left, i = 0; x < r.right; x++, i++) - ((DstT*)dst)[i] = (DstT)(this->*rt)(x, y, TEX0, TEXA); - } - } -} - -// - -HRESULT GSLocalMemory::SaveBMP(IDirect3DDevice9* pDev, LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h) -{ - CComPtr pTexture; - D3DLOCKED_RECT lr; - HRESULT hr = pDev->CreateTexture(w, h, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pTexture, NULL); - if(FAILED(hr) || FAILED(pTexture->LockRect(0, &lr, NULL, 0))) return E_FAIL; - - readTexel rt = m_psmtbl[psm].rt; - GIFRegTEX0 TEX0; - TEX0.TBP0 = bp; - TEX0.TBW = bw; - TEX0.PSM = psm; - GIFRegTEXA TEXA; - TEXA.AEM = 0; - TEXA.TA0 = 0; - TEXA.TA1 = 0x80; - - BYTE* p = (BYTE*)lr.pBits; - - for(int j = 0; j < h; j++, p += lr.Pitch) - for(int i = 0; i < w; i++) - ((DWORD*)p)[i] = (this->*rt)(i, j, TEX0, TEXA); - - pTexture->UnlockRect(0); - - return D3DXSaveTextureToFile(fn, D3DXIFF_BMP, pTexture, NULL); -} diff --git a/plugins/gs/gsdx9/GSLocalMemory.h b/plugins/gs/gsdx9/GSLocalMemory.h deleted file mode 100644 index 440a79e2dd..0000000000 --- a/plugins/gs/gsdx9/GSLocalMemory.h +++ /dev/null @@ -1,321 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#pragma warning(disable: 4244) // warning C4244: '=' : conversion from 'const UINT64' to 'int', possible loss of data - -#include "GS.h" -#include "GSTables.h" - -class GSLocalMemory -{ -public: - typedef DWORD (__fastcall *pixelAddress)(int x, int y, DWORD bp, DWORD bw); - typedef void (GSLocalMemory::*writePixel)(int x, int y, DWORD c, DWORD bp, DWORD bw); - typedef void (GSLocalMemory::*writeFrame)(int x, int y, DWORD c, DWORD bp, DWORD bw); - typedef DWORD (GSLocalMemory::*readPixel)(int x, int y, DWORD bp, DWORD bw); - typedef DWORD (GSLocalMemory::*readTexel)(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - typedef void (GSLocalMemory::*writePixelAddr)(DWORD addr, DWORD c); - typedef void (GSLocalMemory::*writeFrameAddr)(DWORD addr, DWORD c); - typedef DWORD (GSLocalMemory::*readPixelAddr)(DWORD addr); - typedef DWORD (GSLocalMemory::*readTexelAddr)(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - typedef void (GSLocalMemory::*SwizzleTexture)(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - typedef void (GSLocalMemory::*unSwizzleTexture)(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - typedef void (GSLocalMemory::*readTexture)(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP); - - typedef union - { - struct - { - pixelAddress pa, ba, pga; - readPixel rp; - readPixelAddr rpa; - writePixel wp; - writePixelAddr wpa; - readTexel rt, rtP, rtNP; - readTexelAddr rta; - writeFrameAddr wfa; - SwizzleTexture st; - unSwizzleTexture ust, ustP, ustNP; - DWORD bpp, pal, trbpp; - CSize bs; - int* rowOffset[8]; - }; - BYTE dummy[128]; - } psmtbl_t; - - static psmtbl_t m_psmtbl[64]; - -protected: - static DWORD pageOffset32[32][32][64]; - static DWORD pageOffset32Z[32][32][64]; - static DWORD pageOffset16[32][64][64]; - static DWORD pageOffset16S[32][64][64]; - static DWORD pageOffset16Z[32][64][64]; - static DWORD pageOffset16SZ[32][64][64]; - static DWORD pageOffset8[32][64][128]; - static DWORD pageOffset4[32][128][128]; - - static int rowOffset32[2048]; - static int rowOffset32Z[2048]; - static int rowOffset16[2048]; - static int rowOffset16S[2048]; - static int rowOffset16Z[2048]; - static int rowOffset16SZ[2048]; - static int rowOffset8[2][2048]; - static int rowOffset4[2][2048]; - - union {BYTE* m_vm8; WORD* m_vm16; DWORD* m_vm32;}; - - DWORD m_CBP[2]; - WORD* m_pCLUT; - DWORD* m_pCLUT32; - UINT64* m_pCLUT64; - - GIFRegTEX0 m_prevTEX0; - GIFRegTEXCLUT m_prevTEXCLUT; - bool m_fCLUTMayBeDirty; - -public: - GSLocalMemory(); - virtual ~GSLocalMemory(); - - static void RoundDown(CSize& s, CSize bs); - static void RoundUp(CSize& s, CSize bs); - - static DWORD Expand24To32(DWORD c, BYTE TCC, GIFRegTEXA& TEXA) - { - BYTE A = (!TEXA.AEM|(c&0xffffff)) ? TEXA.TA0 : 0; - return (A<<24) | (c&0xffffff); - } - - static DWORD Expand16To32(WORD c, GIFRegTEXA& TEXA) - { - BYTE A = (c&0x8000) ? TEXA.TA1 : (!TEXA.AEM|c) ? TEXA.TA0 : 0; - return (A << 24) | ((c&0x7c00) << 9) | ((c&0x03e0) << 6) | ((c&0x001f) << 3); - } - - BYTE* GetVM() {return m_vm8;} - - // address - - static DWORD __fastcall pageAddress32(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pageAddress16(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pageAddress8(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pageAddress4(int x, int y, DWORD bp, DWORD bw); - - static DWORD __fastcall blockAddress32(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall blockAddress16(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall blockAddress16S(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall blockAddress8(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall blockAddress4(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall blockAddress32Z(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall blockAddress16Z(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall blockAddress16SZ(int x, int y, DWORD bp, DWORD bw); - - static DWORD __fastcall pixelAddressOrg32(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddressOrg16(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddressOrg16S(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddressOrg8(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddressOrg4(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddressOrg32Z(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddressOrg16Z(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddressOrg16SZ(int x, int y, DWORD bp, DWORD bw); - - static DWORD __fastcall pixelAddress32(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddress16(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddress16S(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddress8(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddress4(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddress32Z(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddress16Z(int x, int y, DWORD bp, DWORD bw); - static DWORD __fastcall pixelAddress16SZ(int x, int y, DWORD bp, DWORD bw); - - // raw pixel R/W - - void writePixel32(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel24(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel16(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel16S(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel8(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel8H(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel4(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel4HL(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel4HH(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel32Z(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel24Z(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel16Z(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writePixel16SZ(int x, int y, DWORD c, DWORD bp, DWORD bw); - - void writeFrame16(int x, int y, DWORD c, DWORD bp, DWORD bw); - void writeFrame16S(int x, int y, DWORD c, DWORD bp, DWORD bw); - - DWORD readPixel32(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel24(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel16(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel16S(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel8(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel8H(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel4(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel4HL(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel4HH(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel32Z(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel24Z(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel16Z(int x, int y, DWORD bp, DWORD bw); - DWORD readPixel16SZ(int x, int y, DWORD bp, DWORD bw); - - void writePixel32(DWORD addr, DWORD c) {m_vm32[addr] = c;} - void writePixel24(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff);} - void writePixel16(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;} - void writePixel16S(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;} - void writePixel8(DWORD addr, DWORD c) {m_vm8[addr] = (BYTE)c;} - void writePixel8H(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0x00ffffff) | (c << 24);} - void writePixel4(DWORD addr, DWORD c) {int shift = (addr&1) << 2; addr >>= 1; m_vm8[addr] = (BYTE)((m_vm8[addr] & (0xf0 >> shift)) | ((c & 0x0f) << shift));} - void writePixel4HL(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0xf0ffffff) | ((c & 0x0f) << 24);} - void writePixel4HH(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0x0fffffff) | ((c & 0x0f) << 28);} - void writePixel32Z(DWORD addr, DWORD c) {m_vm32[addr] = c;} - void writePixel24Z(DWORD addr, DWORD c) {m_vm32[addr] = (m_vm32[addr] & 0xff000000) | (c & 0x00ffffff);} - void writePixel16Z(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;} - void writePixel16SZ(DWORD addr, DWORD c) {m_vm16[addr] = (WORD)c;} - - void writeFrame16(DWORD addr, DWORD c) {writePixel16(addr, ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f));} - void writeFrame16S(DWORD addr, DWORD c) {writePixel16S(addr, ((c>>16)&0x8000)|((c>>9)&0x7c00)|((c>>6)&0x03e0)|((c>>3)&0x001f));} - - DWORD readPixel32(DWORD addr) {return m_vm32[addr];} - DWORD readPixel24(DWORD addr) {return m_vm32[addr] & 0x00ffffff;} - DWORD readPixel16(DWORD addr) {return (DWORD)m_vm16[addr];} - DWORD readPixel16S(DWORD addr) {return (DWORD)m_vm16[addr];} - DWORD readPixel8(DWORD addr) {return (DWORD)m_vm8[addr];} - DWORD readPixel8H(DWORD addr) {return m_vm32[addr] >> 24;} - DWORD readPixel4(DWORD addr) {return (m_vm8[addr>>1] >> ((addr&1) << 2)) & 0x0f;} - DWORD readPixel4HL(DWORD addr) {return (m_vm32[addr] >> 24) & 0x0f;} - DWORD readPixel4HH(DWORD addr) {return (m_vm32[addr] >> 28) & 0x0f;} - DWORD readPixel32Z(DWORD addr) {return m_vm32[addr];} - DWORD readPixel24Z(DWORD addr) {return m_vm32[addr] & 0x00ffffff;} - DWORD readPixel16Z(DWORD addr) {return (DWORD)m_vm16[addr];} - DWORD readPixel16SZ(DWORD addr) {return (DWORD)m_vm16[addr];} - - // FillRect - - bool FillRect(const CRect& r, DWORD c, DWORD psm, DWORD fbp, DWORD fbw); - - // CLUT - - void InvalidateCLUT() {m_fCLUTMayBeDirty = true;} - void WriteCLUT(GIFRegTEX0 TEX0, GIFRegTEXCLUT TEXCLUT); - - void ReadCLUT(GIFRegTEX0 TEX0, GIFRegTEXA TEXA, DWORD* pCLUT32); - void SetupCLUT(GIFRegTEX0 TEX0, GIFRegTEXA TEXA); - - // expands 16->32 - void ReadCLUT32(GIFRegTEX0 TEX0, GIFRegTEXA TEXA, DWORD* pCLUT32); - void SetupCLUT32(GIFRegTEX0 TEX0, GIFRegTEXA TEXA); - void CopyCLUT32(DWORD* pCLUT32, int nPaletteEntries); - - // 32-only - - DWORD readTexel32(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel24(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel16(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel16S(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel8(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel8H(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel4(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel4HL(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel4HH(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - - DWORD readTexel32(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_vm32[addr];} - DWORD readTexel24(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return Expand24To32(m_vm32[addr], TEX0.ai32[1]&4, TEXA);} - DWORD readTexel16(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return Expand16To32(m_vm16[addr], TEXA);} - DWORD readTexel16S(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return Expand16To32(m_vm16[addr], TEXA);} - DWORD readTexel8(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel8(addr)];} - DWORD readTexel8H(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel8H(addr)];} - DWORD readTexel4(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel4(addr)];} - DWORD readTexel4HL(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel4HL(addr)];} - DWORD readTexel4HH(DWORD addr, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA) {return m_pCLUT32[readPixel4HH(addr)];} - - void SwizzleTexture32(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture24(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture16(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture16S(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture8(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture8H(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture4(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture4HL(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTexture4HH(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - void SwizzleTextureX(int& tx, int& ty, BYTE* src, int len, GIFRegBITBLTBUF& BITBLTBUF, GIFRegTRXPOS& TRXPOS, GIFRegTRXREG& TRXREG); - - void unSwizzleTexture32(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture24(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture16(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture16S(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture8(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture8H(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4HL(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4HH(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - - void ReadTexture(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP); - - // 32/16/8P - - DWORD readTexel16P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel16SP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel8P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel8HP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel4P(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel4HLP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - DWORD readTexel4HHP(int x, int y, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - - void unSwizzleTexture16P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture16SP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture8P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture8HP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4P(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4HLP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4HHP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - - void ReadTextureP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP); - - // 32/16 - - void unSwizzleTexture8NP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture8HNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4NP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4HLNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - void unSwizzleTexture4HHNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA); - - void ReadTextureNP(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP); - - // - - static DWORD m_xtbl[1024], m_ytbl[1024]; - - template - void ReadTexture(const CRect& r, BYTE* dst, int dstpitch, GIFRegTEX0& TEX0, GIFRegTEXA& TEXA, GIFRegCLAMP& CLAMP, readTexel rt, unSwizzleTexture st); - - // - - HRESULT SaveBMP(IDirect3DDevice9* pDev, LPCTSTR fn, DWORD bp, DWORD bw, DWORD psm, int w, int h); -}; - -#pragma warning(default: 4244) \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSPerfMon.cpp b/plugins/gs/gsdx9/GSPerfMon.cpp deleted file mode 100644 index f62d122960..0000000000 --- a/plugins/gs/gsdx9/GSPerfMon.cpp +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSPerfMon.h" - -#if _MSC_VER >= 1400 -extern "C" unsigned __int64 __rdtsc(); -#else -__declspec(naked) unsigned __int64 __rdtsc() {__asm rdtsc __asm ret} -#endif - -GSPerfMon::GSPerfMon() - : m_total(0), m_begin(0) - , m_frame(0), m_lastframe(0) -{ -} - -void GSPerfMon::IncCounter(counter_t c, double val) -{ - if(c == c_frame) - { - clock_t now = clock(); - if(m_lastframe != 0) - m_counters[c].AddTail(now - m_lastframe); - m_lastframe = now; - m_frame++; - } - else - { - m_counters[c].AddTail(val); - } -} - -void GSPerfMon::StartTimer() -{ - m_start = __rdtsc(); - if(m_begin == 0) m_begin = m_start; -} - -void GSPerfMon::StopTimer() -{ - if(m_start > 0) - { - m_total += __rdtsc() - m_start; - m_start = 0; - } -} - -CString GSPerfMon::ToString(double expected_fps) -{ - if(m_counters[c_frame].IsEmpty()) - return _T(""); - - double stats[c_last]; - - for(int i = 0; i < countof(m_counters); i++) - { - double sum = 0; - POSITION pos = m_counters[i].GetHeadPosition(); - while(pos) sum += m_counters[i].GetNext(pos); - stats[i] = sum / m_counters[c_frame].GetCount(); - } - - UINT64 start = m_start; - - if(start > 0) StopTimer(); - - double fps = 1000.0 / stats[c_frame]; - double cpu = 100.0 * m_total / (__rdtsc() - m_begin); - - CString str; - - str.Format(_T("frame: %I64d | cpu: %d%% | %.2f fps (%d%%) | %d ppf | %.2f kbpf | %.2f kbpf | %.2f kbpf"), - m_frame, - (int)(cpu), - (float)(fps), - (int)(100.0 * fps / expected_fps), - (int)(stats[c_prim]), - (float)(stats[c_swizzle] / 1024), - (float)(stats[c_unswizzle] / 1024), - (float)(stats[c_texture] / 1024)); - - for(int i = 0; i < countof(m_counters); i++) - m_counters[i].RemoveAll(); - m_total = m_begin = 0; - - if(start > 0) StartTimer(); - - return str; -} diff --git a/plugins/gs/gsdx9/GSPerfMon.h b/plugins/gs/gsdx9/GSPerfMon.h deleted file mode 100644 index 9acb79a766..0000000000 --- a/plugins/gs/gsdx9/GSPerfMon.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "x86.h" - -class GSPerfMon -{ -public: - enum counter_t {c_frame, c_prim, c_swizzle, c_unswizzle, c_texture, c_last}; - -protected: - CAtlList m_counters[c_last]; - UINT64 m_begin, m_total, m_start, m_frame; - clock_t m_lastframe; - -public: - GSPerfMon(); - - void IncCounter(counter_t c, double val = 0); - void StartTimer(), StopTimer(); - CString ToString(double expected_fps); - UINT64 GetFrame() {return m_frame;} -}; - -class GSPerfMonAutoTimer -{ - GSPerfMon* m_pm; - -public: - GSPerfMonAutoTimer(GSPerfMon& pm) {(m_pm = &pm)->StartTimer();} - ~GSPerfMonAutoTimer() {m_pm->StopTimer();} -}; \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSRegs.cpp b/plugins/gs/gsdx9/GSRegs.cpp deleted file mode 100644 index 8b61a40b60..0000000000 --- a/plugins/gs/gsdx9/GSRegs.cpp +++ /dev/null @@ -1,1033 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" -#include "GSState.h" - -// GIFPackedRegHandler* - -void __fastcall GSState::GIFPackedRegHandlerNull(GIFPackedReg* r) -{ - LOG(_T("GIFPackedRegHandlerNull(%016I64x%016I64x)\n"), r->ai64[0], r->ai64[1]); -} - -void __fastcall GSState::GIFPackedRegHandlerPRIM(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - GIFReg r2; - r2.PRIM.i64 = r->PRIM.PRIM; - GIFRegHandlerPRIM(&r2); -} - -void __fastcall GSState::GIFPackedRegHandlerRGBA(GIFPackedReg* r) -{ - LOG(_T("Packed RGBA(R=%x G=%x B=%x A=%x)\n"), - r->RGBA.R, - r->RGBA.G, - r->RGBA.B, - r->RGBA.A); - - m_v.RGBAQ.R = r->RGBA.R; - m_v.RGBAQ.G = r->RGBA.G; - m_v.RGBAQ.B = r->RGBA.B; - m_v.RGBAQ.A = r->RGBA.A; - m_v.RGBAQ.Q = m_q; -} - -void __fastcall GSState::GIFPackedRegHandlerSTQ(GIFPackedReg* r) -{ - LOG(_T("Packed STQ(S=%.4f T=%.4f, Q=%.4f)\n"), - r->STQ.S, - r->STQ.T, - r->STQ.Q); - - m_v.ST.S = r->STQ.S; - m_v.ST.T = r->STQ.T; - m_q = r->STQ.Q; -} - -void __fastcall GSState::GIFPackedRegHandlerUV(GIFPackedReg* r) -{ - LOG(_T("Packed UV(U=%.4f V=%.4f)\n"), - (float)r->UV.U/16, - (float)r->UV.V/16); - - m_v.UV.U = r->UV.U; - m_v.UV.V = r->UV.V; -} - -void __fastcall GSState::GIFPackedRegHandlerXYZF2(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - - LOG(_T("XYZF%d(X=%.2f Y=%.2f Z=%d F=%d)\n"), - 2 + r->XYZF2.ADC, - (float)r->XYZF2.X/16, - (float)r->XYZF2.Y/16, - r->XYZF2.Z, - r->XYZF2.F); - - m_v.XYZ.X = r->XYZF2.X; - m_v.XYZ.Y = r->XYZF2.Y; - m_v.XYZ.Z = r->XYZF2.Z; - m_v.FOG.F = r->XYZF2.F; - - VertexKick(r->XYZF2.ADC); -} - -void __fastcall GSState::GIFPackedRegHandlerXYZ2(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - - LOG(_T("XYZ%d(X=%.2f Y=%.2f Z=%d)\n"), - 2 + r->XYZ2.ADC, - (float)r->XYZ2.X/16, - (float)r->XYZ2.Y/16, - r->XYZ2.Z); - - m_v.XYZ.X = r->XYZ2.X; - m_v.XYZ.Y = r->XYZ2.Y; - m_v.XYZ.Z = r->XYZ2.Z; - - VertexKick(r->XYZ2.ADC); -} - -void __fastcall GSState::GIFPackedRegHandlerTEX0_1(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - GIFRegHandlerTEX0_1((GIFReg*)&r->ai64[0]); -} - -void __fastcall GSState::GIFPackedRegHandlerTEX0_2(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - GIFRegHandlerTEX0_2((GIFReg*)&r->ai64[0]); -} - -void __fastcall GSState::GIFPackedRegHandlerCLAMP_1(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - GIFRegHandlerCLAMP_1((GIFReg*)&r->ai64[0]); -} - -void __fastcall GSState::GIFPackedRegHandlerCLAMP_2(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - GIFRegHandlerCLAMP_2((GIFReg*)&r->ai64[0]); -} - -void __fastcall GSState::GIFPackedRegHandlerFOG(GIFPackedReg* r) -{ - LOG(_T("Packed FOG(F=%x)\n"), - r->FOG.F); - - m_v.FOG.F = r->FOG.F; -} - -void __fastcall GSState::GIFPackedRegHandlerXYZF3(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - GIFRegHandlerXYZF3((GIFReg*)&r->ai64[0]); -} - -void __fastcall GSState::GIFPackedRegHandlerXYZ3(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - GIFRegHandlerXYZ3((GIFReg*)&r->ai64[0]); -} - -void __fastcall GSState::GIFPackedRegHandlerA_D(GIFPackedReg* r) -{ - LOG(_T("Packed ")); - (this->*m_fpGIFRegHandlers[(BYTE)r->A_D.ADDR])(&r->r); -} - -void __fastcall GSState::GIFPackedRegHandlerNOP(GIFPackedReg* r) -{ - LOG(_T("Packed NOP(%016I64x%016I64x)\n"), r->ai64[0], r->ai64[1]); -} - -// GIFRegHandler* - -void __fastcall GSState::GIFRegHandlerNull(GIFReg* r) -{ - LOG(_T("*** WARNING *** GIFRegHandlerNull(%016I64x)\n"), r->i64); -} - -void __fastcall GSState::GIFRegHandlerPRIM(GIFReg* r) -{ - LOG(_T("PRIM(PRIM=%x IIP=%x TME=%x FGE=%x ABE=%x AA1=%x FST=%x CTXT=%x FIX=%x)\n"), - r->PRIM.PRIM, - r->PRIM.IIP, - r->PRIM.TME, - r->PRIM.FGE, - r->PRIM.ABE, - r->PRIM.AA1, - r->PRIM.FST, - r->PRIM.CTXT, - r->PRIM.FIX); - - if(m_de.PRIM.i64 != r->PRIM.i64) - FlushPrimInternal(); - - m_de.PRIM = r->PRIM; - m_de.PRMODE._PRIM = r->PRIM.PRIM; - - if(m_de.PRMODECONT.AC) - { - m_ctxt = &m_de.CTXT[m_de.PRIM.CTXT]; - } - - NewPrim(); -} - -void __fastcall GSState::GIFRegHandlerRGBAQ(GIFReg* r) -{ - LOG(_T("RGBAQ(R=%x G=%x B=%x A=%x Q=%.4f)\n"), - r->RGBAQ.R, - r->RGBAQ.G, - r->RGBAQ.B, - r->RGBAQ.A, - r->RGBAQ.Q); - - m_v.RGBAQ = r->RGBAQ; -} - -void __fastcall GSState::GIFRegHandlerST(GIFReg* r) -{ - LOG(_T("ST(S=%.4f T=%.4f)\n"), - r->ST.S, - r->ST.T); - - m_v.ST = r->ST; -} - -void __fastcall GSState::GIFRegHandlerUV(GIFReg* r) -{ - LOG(_T("UV(U=%.4f V=%.4f)\n"), - (float)r->UV.U/16, - (float)r->UV.V/16); - - m_v.UV = r->UV; -} - -void __fastcall GSState::GIFRegHandlerXYZF2(GIFReg* r) -{ - LOG(_T("XYZF2(X=%.2f Y=%.2f Z=%08x F=%d)\n"), - (float)r->XYZF.X/16, - (float)r->XYZF.Y/16, - r->XYZF.Z, - r->XYZF.F); -/* - m_v.XYZ.X = r->XYZF.X; - m_v.XYZ.Y = r->XYZF.Y; - m_v.XYZ.Z = r->XYZF.Z; - m_v.FOG.F = r->XYZF.F; -*/ - m_v.XYZ.ai32[0] = r->XYZF.ai32[0]; - m_v.XYZ.ai32[1] = r->XYZF.ai32[1] & 0x00ffffff; - m_v.FOG.ai32[1] = r->XYZF.ai32[1] & 0xff000000; - - VertexKick(false); -} - -void __fastcall GSState::GIFRegHandlerXYZ2(GIFReg* r) -{ - LOG(_T("XYZ2(X=%.2f Y=%.2f Z=%08x)\n"), - (float)r->XYZ.X/16, - (float)r->XYZ.Y/16, - r->XYZ.Z); - - m_v.XYZ = r->XYZ; - - VertexKick(false); -} - -void __fastcall GSState::GIFRegHandlerTEX0_1(GIFReg* r) -{ - LOG(_T("TEX0_1(TBP0=%I64x TBW=%I64d PSM=%I64x TW=%I64d TH=%I64d TCC=%I64x TFX=%I64x CBP=%I64x CPSM=%I64x CSM=%I64x CSA=%I64x CLD=%I64x)\n"), - r->TEX0.TBP0, - r->TEX0.TBW*64, - r->TEX0.PSM, - 1i64<TEX0.TW, - 1i64<TEX0.TH, - r->TEX0.TCC, - r->TEX0.TFX, - r->TEX0.CBP, - r->TEX0.CPSM, - r->TEX0.CSM, - r->TEX0.CSA, - r->TEX0.CLD); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].TEX0.i64 != r->TEX0.i64) - FlushPrimInternal(); - - m_de.CTXT[0].TEX0 = r->TEX0; - - //ASSERT(m_de.CTXT[0].TEX0.TW <= 10 && m_de.CTXT[0].TEX0.TH <= 10); - if(m_de.CTXT[0].TEX0.TW > 10) m_de.CTXT[0].TEX0.TW = 10; - if(m_de.CTXT[0].TEX0.TH > 10) m_de.CTXT[0].TEX0.TH = 10; - m_de.CTXT[0].TEX0.CPSM &= 0xa; // 1010b - - m_de.CTXT[0].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].TEX0.PSM]; - - FlushWriteTransfer(); - - m_lm.WriteCLUT(r->TEX0, m_de.TEXCLUT); -} - -void __fastcall GSState::GIFRegHandlerTEX0_2(GIFReg* r) -{ - LOG(_T("TEX0_2(TBP0=%I64x TBW=%I64d PSM=%I64x TW=%I64d TH=%I64d TCC=%I64x TFX=%I64x CBP=%I64x CPSM=%I64x CSM=%I64x CSA=%I64x CLD=%I64x)\n"), - r->TEX0.TBP0, - r->TEX0.TBW*64, - r->TEX0.PSM, - 1i64<TEX0.TW, - 1i64<TEX0.TH, - r->TEX0.TCC, - r->TEX0.TFX, - r->TEX0.CBP, - r->TEX0.CPSM, - r->TEX0.CSM, - r->TEX0.CSA, - r->TEX0.CLD); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].TEX0.i64 != r->TEX0.i64) - FlushPrimInternal(); - - m_de.CTXT[1].TEX0 = r->TEX0; - - //ASSERT(m_de.CTXT[1].TEX0.TW <= 10 && m_de.CTXT[1].TEX0.TH <= 10); - if(m_de.CTXT[1].TEX0.TW > 10) m_de.CTXT[1].TEX0.TW = 10; - if(m_de.CTXT[1].TEX0.TH > 10) m_de.CTXT[1].TEX0.TH = 10; - m_de.CTXT[1].TEX0.CPSM &= 0xa; // 1010b - - m_de.CTXT[1].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].TEX0.PSM]; - - FlushWriteTransfer(); - - m_lm.WriteCLUT(r->TEX0, m_de.TEXCLUT); -} - -void __fastcall GSState::GIFRegHandlerCLAMP_1(GIFReg* r) -{ - LOG(_T("CLAMP_1(WMS=%x WMT=%x MINU=%x MAXU=%x MINV=%x MAXV=%x)\n"), - r->CLAMP.WMS, - r->CLAMP.WMT, - r->CLAMP.MINU, - r->CLAMP.MAXU, - r->CLAMP.MINV, - r->CLAMP.MAXV); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].CLAMP.i64 != r->CLAMP.i64) - FlushPrimInternal(); - - m_de.CTXT[0].CLAMP = r->CLAMP; -} - -void __fastcall GSState::GIFRegHandlerCLAMP_2(GIFReg* r) -{ - LOG(_T("CLAMP_2(WMS=%x WMT=%x MINU=%x MAXU=%x MINV=%x MAXV=%x)\n"), - r->CLAMP.WMS, - r->CLAMP.WMT, - r->CLAMP.MINU, - r->CLAMP.MAXU, - r->CLAMP.MINV, - r->CLAMP.MAXV); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].CLAMP.i64 != r->CLAMP.i64) - FlushPrimInternal(); - - m_de.CTXT[1].CLAMP = r->CLAMP; -} - -void __fastcall GSState::GIFRegHandlerFOG(GIFReg* r) -{ - LOG(_T("FOG(F=%x)\n"), - r->FOG.F); - - m_v.FOG = r->FOG; -} - -void __fastcall GSState::GIFRegHandlerXYZF3(GIFReg* r) -{ - LOG(_T("XYZF3(X=%.2f Y=%.2f Z=%08x F=%d)\n"), - (float)r->XYZF.X/16, - (float)r->XYZF.Y/16, - r->XYZF.Z, - r->XYZF.F); -/* - m_v.XYZ.X = r->XYZF.X; - m_v.XYZ.Y = r->XYZF.Y; - m_v.XYZ.Z = r->XYZF.Z; - m_v.FOG.F = r->XYZF.F; -*/ - m_v.XYZ.ai32[0] = r->XYZF.ai32[0]; - m_v.XYZ.ai32[1] = r->XYZF.ai32[1] & 0x00ffffff; - m_v.FOG.ai32[1] = r->XYZF.ai32[1] & 0xff000000; - - VertexKick(true); -} - -void __fastcall GSState::GIFRegHandlerXYZ3(GIFReg* r) -{ - LOG(_T("XYZ3(X=%.2f Y=%.2f Z=%08x)\n"), - (float)r->XYZ.X/16, - (float)r->XYZ.Y/16, - r->XYZ.Z); - - m_v.XYZ = r->XYZ; - - VertexKick(true); -} - -void __fastcall GSState::GIFRegHandlerNOP(GIFReg* r) -{ - LOG(_T("NOP()\n")); -} - -void __fastcall GSState::GIFRegHandlerTEX1_1(GIFReg* r) -{ - LOG(_T("TEX1_1(LCM=%x MXL=%x MMAG=%x MMIN=%x MTBA=%x L=%x K=%x)\n"), - r->TEX1.LCM, - r->TEX1.MXL, - r->TEX1.MMAG, - r->TEX1.MMIN, - r->TEX1.MTBA, - r->TEX1.L, - r->TEX1.K); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].TEX1.i64 != r->TEX1.i64) - FlushPrimInternal(); - - m_de.CTXT[0].TEX1 = r->TEX1; -} - -void __fastcall GSState::GIFRegHandlerTEX1_2(GIFReg* r) -{ - LOG(_T("TEX1_2(LCM=%x MXL=%x MMAG=%x MMIN=%x MTBA=%x L=%x K=%x)\n"), - r->TEX1.LCM, - r->TEX1.MXL, - r->TEX1.MMAG, - r->TEX1.MMIN, - r->TEX1.MTBA, - r->TEX1.L, - r->TEX1.K); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].TEX1.i64 != r->TEX1.i64) - FlushPrimInternal(); - - m_de.CTXT[1].TEX1 = r->TEX1; -} - -void __fastcall GSState::GIFRegHandlerTEX2_1(GIFReg* r) -{ - LOG(_T("TEX2_1(PSM=%x CBP=%x CPSM=%x CSM=%x CSA=%x CLD=%x)\n"), - r->TEX2.PSM, - r->TEX2.CBP, - r->TEX2.CPSM, - r->TEX2.CSM, - r->TEX2.CSA, - r->TEX2.CLD); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].TEX2.i64 != r->TEX2.i64) - FlushPrimInternal(); - - m_de.CTXT[0].TEX2 = r->TEX2; - - FlushWriteTransfer(); - - m_lm.WriteCLUT(*(GIFRegTEX0*)&r->TEX2, m_de.TEXCLUT); -} - -void __fastcall GSState::GIFRegHandlerTEX2_2(GIFReg* r) -{ - LOG(_T("TEX2_2(PSM=%x CBP=%x CPSM=%x CSM=%x CSA=%x CLD=%x)\n"), - r->TEX2.PSM, - r->TEX2.CBP, - r->TEX2.CPSM, - r->TEX2.CSM, - r->TEX2.CSA, - r->TEX2.CLD); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].TEX2.i64 != r->TEX2.i64) - FlushPrimInternal(); - - m_de.CTXT[1].TEX2 = r->TEX2; - - FlushWriteTransfer(); - - m_lm.WriteCLUT(*(GIFRegTEX0*)&r->TEX2, m_de.TEXCLUT); -} - -void __fastcall GSState::GIFRegHandlerXYOFFSET_1(GIFReg* r) -{ - LOG(_T("XYOFFSET_1(OFX=%.2f OFY=%.2f)\n"), - (float)r->XYOFFSET.OFX/16, - (float)r->XYOFFSET.OFY/16); - - m_de.CTXT[0].XYOFFSET = r->XYOFFSET; -} - -void __fastcall GSState::GIFRegHandlerXYOFFSET_2(GIFReg* r) -{ - LOG(_T("XYOFFSET_2(OFX=%.2f OFY=%.2f)\n"), - (float)r->XYOFFSET.OFX/16, - (float)r->XYOFFSET.OFY/16); - - m_de.CTXT[1].XYOFFSET = r->XYOFFSET; -} - -void __fastcall GSState::GIFRegHandlerPRMODECONT(GIFReg* r) -{ - LOG(_T("PRMODECONT(AC=%x)\n"), - r->PRMODECONT.AC); - - if(m_de.PRMODECONT.i64 != r->PRMODECONT.i64) - { - FlushPrimInternal(); - } - - m_de.PRMODECONT = r->PRMODECONT; - - m_pPRIM = !m_de.PRMODECONT.AC ? (GIFRegPRIM*)&m_de.PRMODE : &m_de.PRIM; - m_ctxt = &m_de.CTXT[m_pPRIM->CTXT]; -} - -void __fastcall GSState::GIFRegHandlerPRMODE(GIFReg* r) -{ - LOG(_T("PRMODE(IIP=%x TME=%x FGE=%x ABE=%x AA1=%x FST=%x CTXT=%x FIX=%x)\n"), - r->PRMODE.IIP, - r->PRMODE.TME, - r->PRMODE.FGE, - r->PRMODE.ABE, - r->PRMODE.AA1, - r->PRMODE.FST, - r->PRMODE.CTXT, - r->PRMODE.FIX); - - if(!m_de.PRMODECONT.AC) - FlushPrimInternal(); - - UINT32 _PRIM = m_de.PRMODE._PRIM; - m_de.PRMODE = r->PRMODE; - m_de.PRMODE._PRIM = _PRIM; - - m_ctxt = &m_de.CTXT[m_pPRIM->CTXT]; -} - -void __fastcall GSState::GIFRegHandlerTEXCLUT(GIFReg* r) -{ - LOG(_T("TEXCLUT(CBW=%x COU=%x COV=%x)\n"), - r->TEXCLUT.CBW, - r->TEXCLUT.COU, - r->TEXCLUT.COV); - - if(m_de.TEXCLUT.i64 != r->TEXCLUT.i64) - FlushPrimInternal(); - - m_de.TEXCLUT = r->TEXCLUT; -} - -void __fastcall GSState::GIFRegHandlerSCANMSK(GIFReg* r) -{ - LOG(_T("SCANMSK(MSK=%x)\n"), - r->SCANMSK.MSK); - - if(m_de.SCANMSK.i64 != r->SCANMSK.i64) - FlushPrimInternal(); - - m_de.SCANMSK = r->SCANMSK; -} - -void __fastcall GSState::GIFRegHandlerMIPTBP1_1(GIFReg* r) -{ - LOG(_T("MIPTBP1_1(TBP1=%x TBW1=%x TBP2=%x TBW2=%x TBP3=%x TBW3=%x)\n"), - r->MIPTBP1.TBP1, - r->MIPTBP1.TBW1, - r->MIPTBP1.TBP2, - r->MIPTBP1.TBW2, - r->MIPTBP1.TBP3, - r->MIPTBP1.TBW3); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].MIPTBP1.i64 != r->MIPTBP1.i64) - FlushPrimInternal(); - - m_de.CTXT[0].MIPTBP1 = r->MIPTBP1; -} - -void __fastcall GSState::GIFRegHandlerMIPTBP1_2(GIFReg* r) -{ - LOG(_T("MIPTBP1_2(TBP1=%x TBW1=%x TBP2=%x TBW2=%x TBP3=%x TBW3=%x)\n"), - r->MIPTBP1.TBP1, - r->MIPTBP1.TBW1, - r->MIPTBP1.TBP2, - r->MIPTBP1.TBW2, - r->MIPTBP1.TBP3, - r->MIPTBP1.TBW3); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].MIPTBP1.i64 != r->MIPTBP1.i64) - FlushPrimInternal(); - - m_de.CTXT[1].MIPTBP1 = r->MIPTBP1; -} - -void __fastcall GSState::GIFRegHandlerMIPTBP2_1(GIFReg* r) -{ - LOG(_T("MIPTBP2_1(TBP4=%x TBW4=%x TBP5=%x TBW5=%x TBP6=%x TBW6=%x)\n"), - r->MIPTBP2.TBP4, - r->MIPTBP2.TBW4, - r->MIPTBP2.TBP5, - r->MIPTBP2.TBW5, - r->MIPTBP2.TBP6, - r->MIPTBP2.TBW6); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].MIPTBP2.i64 != r->MIPTBP2.i64) - FlushPrimInternal(); - - m_de.CTXT[0].MIPTBP2 = r->MIPTBP2; -} - -void __fastcall GSState::GIFRegHandlerMIPTBP2_2(GIFReg* r) -{ - LOG(_T("MIPTBP2_2(TBP4=%x TBW4=%x TBP5=%x TBW5=%x TBP6=%x TBW6=%x)\n"), - r->MIPTBP2.TBP4, - r->MIPTBP2.TBW4, - r->MIPTBP2.TBP5, - r->MIPTBP2.TBW5, - r->MIPTBP2.TBP6, - r->MIPTBP2.TBW6); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].MIPTBP2.i64 != r->MIPTBP2.i64) - FlushPrimInternal(); - - m_de.CTXT[1].MIPTBP2 = r->MIPTBP2; -} - -void __fastcall GSState::GIFRegHandlerTEXA(GIFReg* r) -{ - LOG(_T("TEXA(TA0=%x AEM=%x TA1=%x)\n"), - r->TEXA.TA0, - r->TEXA.AEM, - r->TEXA.TA1); - - if(m_de.TEXA.i64 != r->TEXA.i64) - FlushPrimInternal(); - - m_de.TEXA = r->TEXA; -} - -void __fastcall GSState::GIFRegHandlerFOGCOL(GIFReg* r) -{ - LOG(_T("FOGCOL(FCR=%x FCG=%x FCB=%x)\n"), - r->FOGCOL.FCR, - r->FOGCOL.FCG, - r->FOGCOL.FCB); - - if(m_de.FOGCOL.i64 != r->FOGCOL.i64) - FlushPrimInternal(); - - m_de.FOGCOL = r->FOGCOL; -} - -void __fastcall GSState::GIFRegHandlerTEXFLUSH(GIFReg* r) -{ - LOG(_T("TEXFLUSH()\n")); - - // what should we do here? -} - -void __fastcall GSState::GIFRegHandlerSCISSOR_1(GIFReg* r) -{ - LOG(_T("SCISSOR_1(SCAX0=%d SCAX1=%d SCAY0=%d SCAY1=%d)\n"), - r->SCISSOR.SCAX0, - r->SCISSOR.SCAX1, - r->SCISSOR.SCAY0, - r->SCISSOR.SCAY1); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].SCISSOR.i64 != r->SCISSOR.i64) - FlushPrimInternal(); - - m_de.CTXT[0].SCISSOR = r->SCISSOR; -} - -void __fastcall GSState::GIFRegHandlerSCISSOR_2(GIFReg* r) -{ - LOG(_T("SCISSOR_2(SCAX0=%d SCAX1=%d SCAY0=%d SCAY1=%d)\n"), - r->SCISSOR.SCAX0, - r->SCISSOR.SCAX1, - r->SCISSOR.SCAY0, - r->SCISSOR.SCAY1); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].SCISSOR.i64 != r->SCISSOR.i64) - FlushPrimInternal(); - - m_de.CTXT[1].SCISSOR = r->SCISSOR; -} - -void __fastcall GSState::GIFRegHandlerALPHA_1(GIFReg* r) -{ - LOG(_T("ALPHA_1(A=%x B=%x C=%x D=%x FIX=%x)\n"), - r->ALPHA.A, - r->ALPHA.B, - r->ALPHA.C, - r->ALPHA.D, - r->ALPHA.FIX); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].ALPHA.i64 != r->ALPHA.i64) - FlushPrimInternal(); - - m_de.CTXT[0].ALPHA = r->ALPHA; -} - -void __fastcall GSState::GIFRegHandlerALPHA_2(GIFReg* r) -{ - LOG(_T("ALPHA_2(A=%x B=%x C=%x D=%x FIX=%x)\n"), - r->ALPHA.A, - r->ALPHA.B, - r->ALPHA.C, - r->ALPHA.D, - r->ALPHA.FIX); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].ALPHA.i64 != r->ALPHA.i64) - FlushPrimInternal(); - - m_de.CTXT[1].ALPHA = r->ALPHA; -} - -void __fastcall GSState::GIFRegHandlerDIMX(GIFReg* r) -{ - LOG(_T("DIMX([%d,%d,%d,%d][%d,%d,%d,%d][%d,%d,%d,%d][%d,%d,%d,%d])\n"), - r->DIMX.DM00, - r->DIMX.DM01, - r->DIMX.DM02, - r->DIMX.DM03, - r->DIMX.DM10, - r->DIMX.DM11, - r->DIMX.DM12, - r->DIMX.DM13, - r->DIMX.DM20, - r->DIMX.DM21, - r->DIMX.DM22, - r->DIMX.DM23, - r->DIMX.DM30, - r->DIMX.DM31, - r->DIMX.DM32, - r->DIMX.DM33); - - if(m_de.DIMX.i64 != r->DIMX.i64) - FlushPrimInternal(); - - m_de.DIMX = r->DIMX; -} - -void __fastcall GSState::GIFRegHandlerDTHE(GIFReg* r) -{ - LOG(_T("DTHE(DTHE=%x)\n"), - r->DTHE.DTHE); - - if(m_de.DTHE.i64 != r->DTHE.i64) - FlushPrimInternal(); - - m_de.DTHE = r->DTHE; -} - -void __fastcall GSState::GIFRegHandlerCOLCLAMP(GIFReg* r) -{ - LOG(_T("COLCLAMP(CLAMP=%x)\n"), - r->COLCLAMP.CLAMP); - - if(m_de.COLCLAMP.i64 != r->COLCLAMP.i64) - FlushPrimInternal(); - - m_de.COLCLAMP = r->COLCLAMP; -} - -void __fastcall GSState::GIFRegHandlerTEST_1(GIFReg* r) -{ - LOG(_T("TEST_1(ATE=%x ATST=%x AREF=%x AFAIL=%x DATE=%x DATM=%x ZTE=%x ZTST=%x)\n"), - r->TEST.ATE, - r->TEST.ATST, - r->TEST.AREF, - r->TEST.AFAIL, - r->TEST.DATE, - r->TEST.DATM, - r->TEST.ZTE, - r->TEST.ZTST); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].TEST.i64 != r->TEST.i64) - FlushPrimInternal(); - - m_de.CTXT[0].TEST = r->TEST; -} - -void __fastcall GSState::GIFRegHandlerTEST_2(GIFReg* r) -{ - LOG(_T("TEST_2(ATE=%x ATST=%x AREF=%x AFAIL=%x DATE=%x DATM=%x ZTE=%x ZTST=%x)\n"), - r->TEST.ATE, - r->TEST.ATST, - r->TEST.AREF, - r->TEST.AFAIL, - r->TEST.DATE, - r->TEST.DATM, - r->TEST.ZTE, - r->TEST.ZTST); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].TEST.i64 != r->TEST.i64) - FlushPrimInternal(); - - m_de.CTXT[1].TEST = r->TEST; -} - -void __fastcall GSState::GIFRegHandlerPABE(GIFReg* r) -{ - LOG(_T("PABE(PABE=%x)\n"), - r->PABE.PABE); - - if(m_de.PABE.i64 != r->PABE.i64) - FlushPrimInternal(); - - m_de.PABE = r->PABE; -} - -void __fastcall GSState::GIFRegHandlerFBA_1(GIFReg* r) -{ - LOG(_T("FBA_1(FBA=%x)\n"), - r->FBA.FBA); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].FBA.i64 != r->FBA.i64) - FlushPrimInternal(); - - m_de.CTXT[0].FBA = r->FBA; -} - -void __fastcall GSState::GIFRegHandlerFBA_2(GIFReg* r) -{ - LOG(_T("FBA_2(FBA=%x)\n"), - r->FBA.FBA); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].FBA.i64 != r->FBA.i64) - FlushPrimInternal(); - - m_de.CTXT[1].FBA = r->FBA; -} - -void __fastcall GSState::GIFRegHandlerFRAME_1(GIFReg* r) -{ - LOG(_T("FRAME_1(FBP=%x FBW=%d PSM=%x FBMSK=%x)\n"), - r->FRAME.Block(), - r->FRAME.FBW*64, - r->FRAME.PSM, - r->FRAME.FBMSK); - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].FRAME.i64 != r->FRAME.i64) - FlushPrimInternal(); - - m_de.CTXT[0].FRAME = r->FRAME; - - m_de.CTXT[0].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].FRAME.PSM]; -} - -void __fastcall GSState::GIFRegHandlerFRAME_2(GIFReg* r) -{ - LOG(_T("FRAME_2(FBP=%x FBW=%d PSM=%x FBMSK=%x)\n"), - r->FRAME.Block(), - r->FRAME.FBW*64, - r->FRAME.PSM, - r->FRAME.FBMSK); - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].FRAME.i64 != r->FRAME.i64) - FlushPrimInternal(); - - m_de.CTXT[1].FRAME = r->FRAME; - - m_de.CTXT[1].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].FRAME.PSM]; -} - -void __fastcall GSState::GIFRegHandlerZBUF_1(GIFReg* r) -{ - LOG(_T("ZBUF_1(ZBP=%x PSM=%x ZMSK=%x)\n"), - r->ZBUF.ZBP<<5, - r->ZBUF.PSM, - r->ZBUF.ZMSK); - - r->ZBUF.PSM |= 0x30; - - if(m_pPRIM->CTXT == 0 && m_de.CTXT[0].ZBUF.i64 != r->ZBUF.i64) - FlushPrimInternal(); - - m_de.CTXT[0].ZBUF = r->ZBUF; - - if(m_de.CTXT[0].ZBUF.PSM != PSM_PSMZ32 - && m_de.CTXT[0].ZBUF.PSM != PSM_PSMZ24 - && m_de.CTXT[0].ZBUF.PSM != PSM_PSMZ16 - && m_de.CTXT[0].ZBUF.PSM != PSM_PSMZ16S) - m_de.CTXT[0].ZBUF.PSM = PSM_PSMZ32; - - m_de.CTXT[0].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].ZBUF.PSM]; -} - -void __fastcall GSState::GIFRegHandlerZBUF_2(GIFReg* r) -{ - LOG(_T("ZBUF_2(ZBP=%x PSM=%x ZMSK=%x)\n"), - r->ZBUF.ZBP<<5, - r->ZBUF.PSM, - r->ZBUF.ZMSK); - - r->ZBUF.PSM |= 0x30; - - if(m_pPRIM->CTXT == 1 && m_de.CTXT[1].ZBUF.i64 != r->ZBUF.i64) - FlushPrimInternal(); - - m_de.CTXT[1].ZBUF = r->ZBUF; - - if(m_de.CTXT[1].ZBUF.PSM != PSM_PSMZ32 - && m_de.CTXT[1].ZBUF.PSM != PSM_PSMZ24 - && m_de.CTXT[1].ZBUF.PSM != PSM_PSMZ16 - && m_de.CTXT[1].ZBUF.PSM != PSM_PSMZ16S) - m_de.CTXT[1].ZBUF.PSM = PSM_PSMZ32; - - m_de.CTXT[1].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].ZBUF.PSM]; -} - -void __fastcall GSState::GIFRegHandlerBITBLTBUF(GIFReg* r) -{ - LOG(_T("BITBLTBUF(SBP=%x SBW=%d SPSM=%x DBP=%x DBW=%d DPSM=%x)\n"), - r->BITBLTBUF.SBP, - r->BITBLTBUF.SBW*64, - r->BITBLTBUF.SPSM, - r->BITBLTBUF.DBP, - r->BITBLTBUF.DBW*64, - r->BITBLTBUF.DPSM); - - if(m_de.BITBLTBUF.i64 != r->BITBLTBUF.i64) - FlushWriteTransfer(); - - m_de.BITBLTBUF = r->BITBLTBUF; -} - -void __fastcall GSState::GIFRegHandlerTRXPOS(GIFReg* r) -{ - LOG(_T("TRXPOS(SSAX=%d SSAY=%d DSAX=%d DSAY=%d DIR=%d)\n"), - r->TRXPOS.SSAX, - r->TRXPOS.SSAY, - r->TRXPOS.DSAX, - r->TRXPOS.DSAY, - r->TRXPOS.DIR); - - if(m_de.TRXPOS.i64 != r->TRXPOS.i64) - FlushWriteTransfer(); - - m_de.TRXPOS = r->TRXPOS; -} - -void __fastcall GSState::GIFRegHandlerTRXREG(GIFReg* r) -{ - LOG(_T("TRXREG(RRW=%d RRH=%d)\n"), - r->TRXREG.RRW, - r->TRXREG.RRH); - - if(m_de.TRXREG.i64 != r->TRXREG.i64 || m_de.TRXREG2.i64 != r->TRXREG.i64) - FlushWriteTransfer(); - - m_de.TRXREG = m_de.TRXREG2 = r->TRXREG; -} - -void __fastcall GSState::GIFRegHandlerTRXDIR(GIFReg* r) -{ - LOG(_T("TRXDIR(XDIR=%d)\n"), - r->TRXDIR.XDIR); - - FlushWriteTransfer(); - - FlushPrimInternal(); - - m_de.TRXDIR = r->TRXDIR; - - switch(m_de.TRXDIR.XDIR) - { - case 0: // host -> local - m_x = m_de.TRXPOS.DSAX; - m_y = m_de.TRXPOS.DSAY; - m_de.TRXREG.RRW = m_x + m_de.TRXREG2.RRW; - m_de.TRXREG.RRH = m_y + m_de.TRXREG2.RRH; - break; - case 1: // local -> host - m_x = m_de.TRXPOS.SSAX; - m_y = m_de.TRXPOS.SSAY; - m_de.TRXREG.RRW = m_x + m_de.TRXREG2.RRW; - m_de.TRXREG.RRH = m_y + m_de.TRXREG2.RRH; - break; - case 2: // local -> local - MoveTransfer(); - break; - case 3: - ASSERT(0); - break; - } -} - -void __fastcall GSState::GIFRegHandlerHWREG(GIFReg* r) -{ - LOG(_T("HWREG(DATA_LOWER=%08x DATA_UPPER=%08x)\n"), - r->HWREG.DATA_LOWER, - r->HWREG.DATA_UPPER); - - // TODO - - ASSERT(0); -} - -void __fastcall GSState::GIFRegHandlerSIGNAL(GIFReg* r) -{ - LOG(_T("SIGNAL(ID=%08x IDMSK=%08x)\n"), - r->SIGNAL.ID, - r->SIGNAL.IDMSK); - - if(m_fMultiThreaded) return; - - m_rs.pSIGLBLID->SIGID = (m_rs.pSIGLBLID->SIGID & ~r->SIGNAL.IDMSK) | (r->SIGNAL.ID & r->SIGNAL.IDMSK); - - if(m_rs.pCSR->wSIGNAL) m_rs.pCSR->rSIGNAL = 1; - if(!m_rs.pIMR->SIGMSK && m_fpGSirq) m_fpGSirq(); -} - -void __fastcall GSState::GIFRegHandlerFINISH(GIFReg* r) -{ - LOG(_T("FINISH()\n")); - - if(m_fMultiThreaded) return; - - if(m_rs.pCSR->wFINISH) m_rs.pCSR->rFINISH = 1; - if(!m_rs.pIMR->FINISHMSK && m_fpGSirq) m_fpGSirq(); -} - -void __fastcall GSState::GIFRegHandlerLABEL(GIFReg* r) -{ - LOG(_T("LABEL(ID=%08x IDMSK=%08x)\n"), - r->LABEL.ID, - r->LABEL.IDMSK); - - if(m_fMultiThreaded) return; - - m_rs.pSIGLBLID->LBLID = (m_rs.pSIGLBLID->LBLID & ~r->LABEL.IDMSK) | (r->LABEL.ID & r->LABEL.IDMSK); -} - diff --git a/plugins/gs/gsdx9/GSRenderer.cpp b/plugins/gs/gsdx9/GSRenderer.cpp deleted file mode 100644 index 0035211283..0000000000 --- a/plugins/gs/gsdx9/GSRenderer.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSRenderer.h" diff --git a/plugins/gs/gsdx9/GSRenderer.h b/plugins/gs/gsdx9/GSRenderer.h deleted file mode 100644 index 6e27aa3bba..0000000000 --- a/plugins/gs/gsdx9/GSRenderer.h +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "GSState.h" - -template -class GSRenderer : public GSState -{ -protected: - GSVertexList m_vl; - - VERTEX* m_pVertices; - int m_nMaxVertices, m_nVertices, m_nPrims; - - void Reset() - { - m_nVertices = m_nPrims = 0; - m_vl.RemoveAll(); - __super::Reset(); - } - - void VertexKick(bool fSkip) - { - LOG(_T("VertexKick(%d)\n"), fSkip); - - static const int vmin[8] = {1, 2, 2, 3, 3, 3, 2, 1}; - - while(m_vl.GetCount() >= vmin[m_pPRIM->PRIM]) - { - if(m_nVertices+6 > m_nMaxVertices) - { - VERTEX* pVertices = (VERTEX*)_aligned_malloc(sizeof(VERTEX) * (m_nMaxVertices <<= 1), 16); - memcpy(pVertices, m_pVertices, m_nVertices*sizeof(VERTEX)); - _aligned_free(m_pVertices); - m_pVertices = pVertices; - } - - LOG(_T("DrawingKick %d\n"), m_pPRIM->PRIM); - - if(m_PRIM != m_pPRIM->PRIM && m_nVertices > 0) FlushPrimInternal(); - m_PRIM = m_pPRIM->PRIM; - - LOG2(_T("Prim (%d) %05x %05x %05x %04x\n"), - m_PRIM, - m_ctxt->FRAME.Block(), - m_pPRIM->TME ? (UINT32)m_ctxt->TEX0.TBP0 : 0xfffff, - m_pPRIM->TME ? (UINT32)m_ctxt->TEX0.CBP : 0xfffff, - (m_pPRIM->ABE || (m_PRIM == 1 || m_PRIM == 2) && m_pPRIM->AA1) - ? ((m_ctxt->ALPHA.A<<12)|(m_ctxt->ALPHA.B<<8)|(m_ctxt->ALPHA.C<<4)|m_ctxt->ALPHA.D) - : 0xffff); - - m_nVertices += DrawingKick(fSkip); - -#ifdef DEBUG_RENDERTARGETS - if(::GetAsyncKeyState(VK_SPACE)&0x80000000) {FlushPrimInternal(); Flip();} -#endif - } - } - - void NewPrim() {m_vl.RemoveAll();} - void FlushPrim() {m_PRIM = 8; m_nVertices = 0;} - -public: - GSRenderer(int w, int h, HWND hWnd, HRESULT& hr) - : GSState(w, h, hWnd, hr) - { - m_pVertices = (VERTEX*)_aligned_malloc(sizeof(VERTEX) * (m_nMaxVertices = 256), 16); - Reset(); - } - - ~GSRenderer() - { - _aligned_free(m_pVertices); - } -}; \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSRendererHW.cpp b/plugins/gs/gsdx9/GSRendererHW.cpp deleted file mode 100644 index 52dce24886..0000000000 --- a/plugins/gs/gsdx9/GSRendererHW.cpp +++ /dev/null @@ -1,1310 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSRendererHW.h" - -#define INTERNALRESX 1024 -#define INTERNALRESY 1024 - -inline BYTE SCALE_ALPHA(BYTE a) -{ - return (((a)&0x80)?0xff:((a)<<1)); -} - -static const float one_over_log_2pow32 = 1.0f / (log(2.0f)*32); - -// - -GSRendererHW::GSRendererHW(HWND hWnd, HRESULT& hr) - : GSRenderer(INTERNALRESX, INTERNALRESY, hWnd, hr) -{ - Reset(); -} - -GSRendererHW::~GSRendererHW() -{ -} - -HRESULT GSRendererHW::ResetDevice(bool fForceWindowed) -{ - m_pRTs.RemoveAll(); - m_pDSs.RemoveAll(); - m_tc.RemoveAll(); - - return __super::ResetDevice(fForceWindowed); -} - -void GSRendererHW::Reset() -{ - m_primtype = D3DPT_FORCE_DWORD; - - m_tc.RemoveAll(); - - m_pRTs.RemoveAll(); - m_pDSs.RemoveAll(); - - POSITION pos = m_pRenderWnds.GetStartPosition(); - while(pos) - { - DWORD FBP; - CGSWnd* pWnd = NULL; - m_pRenderWnds.GetNextAssoc(pos, FBP, pWnd); - pWnd->DestroyWindow(); - delete pWnd; - } - m_pRenderWnds.RemoveAll(); - - __super::Reset(); -} - -void GSRendererHW::VertexKick(bool fSkip) -{ - GSVertexHW& v = m_vl.AddTail(); - - v.x = (float)((int)m_v.XYZ.X - (int)m_ctxt->XYOFFSET.OFX) * (1.0f/16); - v.y = (float)((int)m_v.XYZ.Y - (int)m_ctxt->XYOFFSET.OFY) * (1.0f/16); - //if(m_v.XYZ.Z && m_v.XYZ.Z < 0x100) m_v.XYZ.Z = 0x100; - //v.z = 1.0f * (m_v.XYZ.Z>>8)/(UINT_MAX>>8); - v.z = log(1.0f + m_v.XYZ.Z) * one_over_log_2pow32; - //v.z = (float)m_v.XYZ.Z / UINT_MAX; - //v.rhw = v.z ? 1.0f/v.z : 1.0f; - v.rhw = m_v.RGBAQ.Q > 0 ? m_v.RGBAQ.Q : 1.0f; // TODO - //v.rhw = m_v.RGBAQ.Q; - - v.color = m_v.RGBAQ.ai32[0]; - - if(m_pPRIM->TME) - { - if(m_pPRIM->FST) - { - v.tu = (float)(int)m_v.UV.U / (16 << m_ctxt->TEX0.TW); - v.tv = (float)(int)m_v.UV.V / (16 << m_ctxt->TEX0.TH); - v.rhw = 1.0f; - } - else - { - float w = m_v.RGBAQ.Q ? 1.0f / m_v.RGBAQ.Q : 1.0f; - v.tu = m_v.ST.S * w; - v.tv = m_v.ST.T * w; - } - } - else - { - v.a = SCALE_ALPHA(v.a); - } - - v.fog = (m_pPRIM->FGE ? m_v.FOG.F : 0xff) << 24; - - __super::VertexKick(fSkip); -} - -int GSRendererHW::DrawingKick(bool fSkip) -{ - GSVertexHW* pVertices = &m_pVertices[m_nVertices]; - int nVertices = 0; - - CRect sc(m_ctxt->SCISSOR.SCAX0, m_ctxt->SCISSOR.SCAY0, m_ctxt->SCISSOR.SCAX1+1, m_ctxt->SCISSOR.SCAY1+1); - - switch(m_PRIM) - { - case 3: // triangle list - m_primtype = D3DPT_TRIANGLELIST; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - if(pVertices[nVertices-1].x < sc.left && pVertices[nVertices-2].x < sc.left && pVertices[nVertices-3].x < sc.left - || pVertices[nVertices-1].y < sc.top && pVertices[nVertices-2].y < sc.top && pVertices[nVertices-3].y < sc.top - || pVertices[nVertices-1].x >= sc.right && pVertices[nVertices-2].x >= sc.right && pVertices[nVertices-3].x >= sc.right - || pVertices[nVertices-1].y >= sc.bottom && pVertices[nVertices-2].y >= sc.bottom && pVertices[nVertices-3].y >= sc.bottom) - return 0; - LOGV((pVertices[0], _T("TriList"))); - LOGV((pVertices[1], _T("TriList"))); - LOGV((pVertices[2], _T("TriList"))); - break; - case 4: // triangle strip - m_primtype = D3DPT_TRIANGLELIST; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.GetAt(0, pVertices[nVertices++]); - m_vl.GetAt(1, pVertices[nVertices++]); - if(pVertices[nVertices-1].x < sc.left && pVertices[nVertices-2].x < sc.left && pVertices[nVertices-3].x < sc.left - || pVertices[nVertices-1].y < sc.top && pVertices[nVertices-2].y < sc.top && pVertices[nVertices-3].y < sc.top - || pVertices[nVertices-1].x >= sc.right && pVertices[nVertices-2].x >= sc.right && pVertices[nVertices-3].x >= sc.right - || pVertices[nVertices-1].y >= sc.bottom && pVertices[nVertices-2].y >= sc.bottom && pVertices[nVertices-3].y >= sc.bottom) - return 0; - LOGV((pVertices[0], _T("TriStrip"))); - LOGV((pVertices[1], _T("TriStrip"))); - LOGV((pVertices[2], _T("TriStrip"))); - break; - case 5: // triangle fan - m_primtype = D3DPT_TRIANGLELIST; - m_vl.GetAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(1, pVertices[nVertices++]); - m_vl.GetAt(1, pVertices[nVertices++]); - if(pVertices[nVertices-1].x < sc.left && pVertices[nVertices-2].x < sc.left && pVertices[nVertices-3].x < sc.left - || pVertices[nVertices-1].y < sc.top && pVertices[nVertices-2].y < sc.top && pVertices[nVertices-3].y < sc.top - || pVertices[nVertices-1].x >= sc.right && pVertices[nVertices-2].x >= sc.right && pVertices[nVertices-3].x >= sc.right - || pVertices[nVertices-1].y >= sc.bottom && pVertices[nVertices-2].y >= sc.bottom && pVertices[nVertices-3].y >= sc.bottom) - return 0; - LOGV((pVertices[0], _T("TriFan"))); - LOGV((pVertices[1], _T("TriFan"))); - LOGV((pVertices[2], _T("TriFan"))); - break; - case 6: // sprite - m_primtype = D3DPT_TRIANGLELIST; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - if(pVertices[nVertices-1].x < sc.left && pVertices[nVertices-2].x < sc.left - || pVertices[nVertices-1].y < sc.top && pVertices[nVertices-2].y < sc.top - || pVertices[nVertices-1].x >= sc.right && pVertices[nVertices-2].x >= sc.right - || pVertices[nVertices-1].y >= sc.bottom && pVertices[nVertices-2].y >= sc.bottom) - return 0; - nVertices += 2; - -/* - float lod; - if(m_ctxt->TEX1.LCM) lod = -log(pVertices[nVertices-1].rhw)/log(2.0f) * (1 << m_ctxt->TEX1.L) + m_ctxt->TEX1.K; - else lod = m_ctxt->TEX1.K; - - int filter; - if(lod < 0) filter = m_ctxt->TEX1.MMAG&1; - else filter = m_ctxt->TEX1.MMIN&1; - -// if(!filter) - { - pVertices[nVertices-2].x -= 0.5f; - pVertices[nVertices-2].y -= 0.5f; - pVertices[nVertices-1].x -= 0.5f; - pVertices[nVertices-1].y -= 0.5f; - } -*/ - // ASSERT(pVertices[0].z == pVertices[1].z); - pVertices[0].z = pVertices[1].z; - pVertices[2] = pVertices[1]; - pVertices[3] = pVertices[1]; - pVertices[1].y = pVertices[0].y; - pVertices[1].tv = pVertices[0].tv; - pVertices[2].x = pVertices[0].x; - pVertices[2].tu = pVertices[0].tu; - LOGV((pVertices[0], _T("Sprite"))); - LOGV((pVertices[1], _T("Sprite"))); - LOGV((pVertices[2], _T("Sprite"))); - LOGV((pVertices[3], _T("Sprite"))); - nVertices += 2; - pVertices[5] = pVertices[3]; - pVertices[3] = pVertices[1]; - pVertices[4] = pVertices[2]; - break; - case 1: // line - m_primtype = D3DPT_LINELIST; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - if(pVertices[nVertices-1].x < sc.left && pVertices[nVertices-2].x < sc.left - || pVertices[nVertices-1].y < sc.top && pVertices[nVertices-2].y < sc.top - || pVertices[nVertices-1].x >= sc.right && pVertices[nVertices-2].x >= sc.right - || pVertices[nVertices-1].y >= sc.bottom && pVertices[nVertices-2].y >= sc.bottom) - return 0; - LOGV((pVertices[0], _T("LineList"))); - LOGV((pVertices[1], _T("LineList"))); - break; - case 2: // line strip - m_primtype = D3DPT_LINELIST; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.GetAt(0, pVertices[nVertices++]); - if(pVertices[nVertices-1].x < sc.left && pVertices[nVertices-2].x < sc.left - || pVertices[nVertices-1].y < sc.top && pVertices[nVertices-2].y < sc.top - || pVertices[nVertices-1].x >= sc.right && pVertices[nVertices-2].x >= sc.right - || pVertices[nVertices-1].y >= sc.bottom && pVertices[nVertices-2].y >= sc.bottom) - return 0; - LOGV((pVertices[0], _T("LineStrip"))); - LOGV((pVertices[1], _T("LineStrip"))); - break; - case 0: // point - m_primtype = D3DPT_POINTLIST; - m_vl.RemoveAt(0, pVertices[nVertices++]); - if(pVertices[nVertices-1].x < sc.left - || pVertices[nVertices-1].y < sc.top - || pVertices[nVertices-1].x >= sc.right - || pVertices[nVertices-1].y >= sc.bottom) - return 0; - LOGV((pVertices[0], _T("PointList"))); - break; - default: - //ASSERT(0); - m_vl.RemoveAll(); - return 0; - } -/* - int gt = 0; - for(int i = 0; i < nVertices; i++) - if(pVertices[i].rhw > 0) gt++; - if(gt != nVertices) - return 0; -*/ - if(fSkip || !m_rs.IsEnabled(0) && !m_rs.IsEnabled(1)) - return 0; - - if(!m_pPRIM->IIP) - { - pVertices[0].color = pVertices[nVertices-1].color; - if(m_PRIM == 6) pVertices[3].color = pVertices[5].color; - /*for(int i = nVertices-1; i > 0; i--) - pVertices[i-1].color = pVertices[i].color;*/ - } - - return nVertices; -} - -void GSRendererHW::FlushPrim() -{ - if(m_nVertices > 0 && !(m_pPRIM->TME && HasSharedBits(m_ctxt->TEX0.TBP0, m_ctxt->TEX0.PSM, m_ctxt->FRAME.Block(), m_ctxt->FRAME.PSM))) - do - { - int nPrims = 0; - - switch(m_primtype) - { - case D3DPT_TRIANGLELIST: ASSERT(!(m_nVertices%3)); nPrims = m_nVertices/3; break; - case D3DPT_TRIANGLESTRIP: ASSERT(m_nVertices > 2); nPrims = m_nVertices-2; break; - case D3DPT_TRIANGLEFAN: ASSERT(m_nVertices > 2); nPrims = m_nVertices-2; break; - case D3DPT_LINELIST: ASSERT(!(m_nVertices&1)); nPrims = m_nVertices/2; break; - case D3DPT_LINESTRIP: ASSERT(m_nVertices > 1); nPrims = m_nVertices-1; break; - case D3DPT_POINTLIST: nPrims = m_nVertices; break; - default: ASSERT(0); return; - } - - LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)\n"), m_primtype, m_nVertices, nPrims); - - m_perfmon.IncCounter(GSPerfMon::c_prim, nPrims); - - ////////////////////// - - HRESULT hr; - - scale_t scale( - (float)m_bd.Width / (m_ctxt->FRAME.FBW*64), -// (float)m_bd.Width / m_rs.GetDispRect(m_rs.IsEnabled(1)?1:0).right, - (float)m_bd.Height / m_rs.GetDispRect(m_rs.IsEnabled(1)?1:0).bottom); - - ////////////////////// - - CComPtr pRT; - CComPtr pDS; - - bool fClearRT = false; - bool fClearDS = false; - - if(!m_pRTs.Lookup(m_ctxt->FRAME.Block(), pRT)) - { - hr = m_pD3DDev->CreateTexture(m_bd.Width, m_bd.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pRT, NULL); - if(S_OK != hr) {ASSERT(0); return;} - m_pRTs[m_ctxt->FRAME.Block()] = pRT; -#ifdef DEBUG_RENDERTARGETS - CGSWnd* pWnd = NULL; - if(!m_pRenderWnds.Lookup(m_ctxt->FRAME.Block(), pWnd)) - { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - pWnd = new CGSWnd(); - CString str; str.Format(_T("%05x"), m_ctxt->FRAME.Block()); - pWnd->Create(str); - m_pRenderWnds[m_ctxt->FRAME.Block()] = pWnd; - pWnd->Show(); - } -#endif - fClearRT = true; - } - - if(!m_pDSs.Lookup(m_ctxt->ZBUF.ZBP, pDS)) - { - hr = m_pD3DDev->CreateDepthStencilSurface(m_bd.Width, m_bd.Height, m_fmtDepthStencil, D3DMULTISAMPLE_NONE, 0, FALSE, &pDS, NULL); - if(S_OK != hr) {ASSERT(0); return;} - m_pDSs[m_ctxt->ZBUF.ZBP] = pDS; - fClearDS = true; - } - - if(!pRT || !pDS) {ASSERT(0); return;} - - ////////////////////// - - GSTextureBase t; - - if(m_pPRIM->TME) - { -if(m_ctxt->TEX0.TBP0 == 0x800) -{ - int i = 0; -} - - bool fFetched = - m_fEnablePalettizedTextures && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0) ? m_tc.FetchP(this, t) : - m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0) ? m_tc.FetchNP(this, t) : - m_tc.Fetch(this, t); - - if(!fFetched) break; - - if(nPrims > 100 && t.m_pPalette) // TODO: find the optimal value for nPrims > ? - { - CComPtr pRT; - hr = m_pD3DDev->CreateTexture(t.m_desc.Width, t.m_desc.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pRT, NULL); - - CComPtr pRTSurf; - hr = pRT->GetSurfaceLevel(0, &pRTSurf); - hr = m_pD3DDev->SetRenderTarget(0, pRTSurf); - hr = m_pD3DDev->SetDepthStencilSurface(NULL); - - hr = m_pD3DDev->SetTexture(0, t.m_pTexture); - hr = m_pD3DDev->SetTexture(1, t.m_pPalette); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_POINT); - hr = m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - hr = m_pD3DDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - hr = m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); - hr = m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO); - hr = m_pD3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - hr = m_pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RGBA); - - hr = m_pD3DDev->SetPixelShader(m_pHLSLTFX[37]); - - struct - { - float x, y, z, rhw; - float tu, tv; - } - pVertices[] = - { - {0, 0, 0.5f, 2.0f, 0, 0}, - {(float)t.m_desc.Width, 0, 0.5f, 2.0f, 1, 0}, - {0, (float)t.m_desc.Height, 0.5f, 2.0f, 0, 1}, - {(float)t.m_desc.Width, (float)t.m_desc.Height, 0.5f, 2.0f, 1, 1}, - }; - - hr = m_pD3DDev->BeginScene(); - hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0])); - hr = m_pD3DDev->EndScene(); - - t.m_pTexture = pRT; - t.m_pPalette = NULL; - - t.m_pTexture->GetLevelDesc(0, &t.m_desc); - } - } - - ////////////////////// - - hr = m_pD3DDev->BeginScene(); - - ////////////////////// - - CComPtr pSurf; - hr = pRT->GetSurfaceLevel(0, &pSurf); - hr = m_pD3DDev->SetRenderTarget(0, pSurf); - hr = m_pD3DDev->SetDepthStencilSurface(pDS); - if(fClearRT) hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); - if(fClearDS) hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_ZBUFFER, 0, 1.0f, 0); - - D3DSURFACE_DESC rd; - ZeroMemory(&rd, sizeof(rd)); - pRT->GetLevelDesc(0, &rd); - - ////////////////////// - - hr = m_pD3DDev->SetRenderState(D3DRS_SHADEMODE, m_pPRIM->IIP ? D3DSHADE_GOURAUD : D3DSHADE_FLAT); - - ////////////////////// - - float tsx = 1.0f, tsy = 1.0f; - - if(m_pPRIM->TME) - { - tsx = 1.0f * (1 << m_ctxt->TEX0.TW) / t.m_desc.Width * t.m_scale.x; - tsy = 1.0f * (1 << m_ctxt->TEX0.TH) / t.m_desc.Height * t.m_scale.y; - } - - ASSERT(abs(tsx - 1.0f) < 0.001 && abs(tsy - 1.0f) < 0.001); - - SetupTexture(t, tsx, tsy); - - ////////////////////// - - SetupAlphaBlend(); - - ////////////////////// - - SetupColorMask(); - - ////////////////////// - - SetupZBuffer(); - - ////////////////////// - - SetupAlphaTest(); - - ////////////////////// - - SetupScissor(scale); - - scale.Set(pRT); - - ////////////////////// - - // ASSERT(!m_de.PABE.PABE); // bios - // ASSERT(!m_ctxt->FBA.FBA); // bios - // ASSERT(!m_ctxt->TEST.DATE); // sfex3 (after the capcom logo), vf4 (first menu fading in) - - ////////////////////// - - { - // hr = m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - // hr = m_pD3DDev->SetTexture(1, pRT); - - GSVertexHW* pVertices = m_pVertices; - for(int i = m_nVertices; i-- > 0; pVertices++) - { - pVertices->x *= scale.x; - pVertices->y *= scale.y; - - // pVertices->tu2 = pVertices->x / rd.Width; - // pVertices->tv2 = pVertices->y / rd.Height; - - if(m_pPRIM->TME) - { - // FIXME - float base, fract; - fract = modf(pVertices->tu, &base); - fract *= tsx; - //ASSERT(-1 <= fract && fract <= 1.01); - pVertices->tu = base + fract; - fract = modf(pVertices->tv, &base); - fract *= tsy; - //ASSERT(-1 <= fract && fract <= 1.01); - pVertices->tv = base + fract; - } - -/* - if(m_pPRIM->TME) - { - pVertices->tu *= tsx; - pVertices->tv *= tsy; - } -*/ - if(m_pPRIM->FGE) - { - pVertices->fog = (pVertices->fog & 0xff000000) | (m_de.FOGCOL.ai32[0] & 0x00ffffff); - // D3DCOLOR_ARGB(pVertices->fog >> 24, m_de.FOGCOL.FCB, m_de.FOGCOL.FCG, m_de.FOGCOL.FCR) - } - } - } - - hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_DIFFUSE|D3DFVF_SPECULAR|D3DFVF_TEX1); - - if(1)//!m_de.PABE.PABE) - { - hr = m_pD3DDev->DrawPrimitiveUP(m_primtype, nPrims, m_pVertices, sizeof(GSVertexHW)); - } -/* else - { - ASSERT(!m_ctxt->TEST.ATE); // TODO - - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, TRUE); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAREF, 0xfe); - - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATEREQUAL); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - hr = m_pD3DDev->DrawPrimitive(m_primtype, 0, nPrims); - - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_LESS); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - hr = m_pD3DDev->DrawPrimitive(m_primtype, 0, nPrims); - } -*/ - if(m_ctxt->TEST.ATE && m_ctxt->TEST.AFAIL && m_ctxt->TEST.ATST != 1) - { - ASSERT(!m_de.PABE.PABE); - - static const DWORD iafunc[] = {D3DCMP_ALWAYS, D3DCMP_NEVER, D3DCMP_GREATEREQUAL, D3DCMP_GREATER, D3DCMP_NOTEQUAL, D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_EQUAL}; - - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAFUNC, iafunc[m_ctxt->TEST.ATST]); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAREF, (DWORD)SCALE_ALPHA(m_ctxt->TEST.AREF)); - - int mask = 0; - bool zwrite = false; - - switch(m_ctxt->TEST.AFAIL) - { - case 0: break; // keep - case 1: mask = D3DCOLORWRITEENABLE_RGBA; break; // fbuf - case 2: zwrite = true; break; // zbuf - case 3: mask = D3DCOLORWRITEENABLE_RGB; break; // fbuf w/o alpha - default: __assume(0); - } - - hr = m_pD3DDev->SetRenderState(D3DRS_ZWRITEENABLE, zwrite); - hr = m_pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, mask); - - if(mask || zwrite) - hr = m_pD3DDev->DrawPrimitiveUP(m_primtype, nPrims, m_pVertices, sizeof(GSVertexHW)); - } - - hr = m_pD3DDev->EndScene(); - - ////////////////////// - - GIFRegTEX0 TEX0; - TEX0.TBP0 = m_ctxt->FRAME.Block(); - TEX0.TBW = m_ctxt->FRAME.FBW; - TEX0.PSM = m_ctxt->FRAME.PSM; - m_tc.AddRT(TEX0, pRT, scale); - } - while(0); - - m_primtype = D3DPT_FORCE_DWORD; - - __super::FlushPrim(); -} - -void GSRendererHW::Flip() -{ - HRESULT hr; - - FlipInfo rt[2]; - - for(int i = 0; i < countof(rt); i++) - { - if(!m_rs.IsEnabled(i)) continue; - - DWORD FBP = m_rs.pDISPFB[i]->FBP<<5; - -#ifdef DEBUG_RENDERTARGETS - if(::GetAsyncKeyState(VK_SPACE)&0x80000000) FBP = m_ctxt->FRAME.Block(); -#endif - - CSurfMap::CPair* pPair = m_pRTs.PLookup(FBP); - - if(!pPair) - { - for(CSurfMap::CPair* pPair2 = m_pRTs.PGetFirstAssoc(); - pPair2; - pPair2 = m_pRTs.PGetNextAssoc(pPair2)) - { - if(pPair2->key <= FBP && (!pPair || pPair2->key >= pPair->key)) - { - pPair = pPair2; - } - } - } - - if(!pPair) - { - CComPtr pRT; - - if(S_OK == m_pD3DDev->CreateTexture(m_bd.Width, m_bd.Height, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, &pRT, NULL)) - { - m_pRTs[FBP] = pRT; - - EXECUTE_ASSERT(pPair = m_pRTs.PLookup(FBP)); - -#ifdef DEBUG_RENDERTARGETS - CGSWnd* pWnd = NULL; - if(!m_pRenderWnds.Lookup(m_ctxt->FRAME.Block(), pWnd)) - { - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - pWnd = new CGSWnd(); - CString str; str.Format(_T("%05x"), FBP); - pWnd->Create(str); - m_pRenderWnds[FBP] = pWnd; - pWnd->Show(); - } -#endif - - CRect r = m_rs.GetDispRect(m_rs.IsEnabled(1)?1:0); - - scale_t scale( - (float)m_bd.Width / (m_rs.pDISPFB[i]->FBW*64), - // (float)m_bd.Width / m_rs.GetDispRect(m_rs.IsEnabled(1)?1:0).right, - (float)m_bd.Height / r.bottom); - - scale.Set(pRT); - - GIFRegTEX0 TEX0; - TEX0.TBP0 = m_rs.pDISPFB[i]->FBP; - TEX0.TBW = m_rs.pDISPFB[i]->FBW; - TEX0.PSM = m_rs.pDISPFB[i]->PSM; - - m_tc.AddRT(TEX0, pRT, scale); - - GIFRegBITBLTBUF BITBLTBUF; - BITBLTBUF.DBP = TEX0.TBP0; - BITBLTBUF.DBW = TEX0.TBW; - BITBLTBUF.DPSM = TEX0.PSM; - - m_tc.InvalidateTexture(this, BITBLTBUF, r); - } - } - - if(pPair) - { - m_tc.ResetAge(pPair->key); - - rt[i].pRT = pPair->value; - - ZeroMemory(&rt[i].rd, sizeof(rt[i].rd)); - hr = rt[i].pRT->GetLevelDesc(0, &rt[i].rd); - - rt[i].scale.Get(rt[i].pRT); - } - } - - FinishFlip(rt); - -#ifdef DEBUG_RENDERTARGETS - CRect dst(0, 0, m_bd.Width, m_bd.Height); - - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - if(!m_pRenderWnds.IsEmpty()) - { - POSITION pos = m_pRenderWnds.GetStartPosition(); - while(pos) - { - DWORD fbp; - CGSWnd* pWnd = NULL; - m_pRenderWnds.GetNextAssoc(pos, fbp, pWnd); - - CComPtr pRT; - if(m_pRTs.Lookup(fbp, pRT)) - { - D3DSURFACE_DESC rd; - ZeroMemory(&rd, sizeof(rd)); - hr = pRT->GetLevelDesc(0, &rd); - - hr = m_pD3DDev->SetTexture(0, pRT); - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - - scale_t scale(pRT); - - CRect rect = m_rs.GetDispRect(m_rs.IsEnabled(1)?1:0); - //CSize size = m_rs.GetSize(m_rs.IsEnabled(1)?1:0); - CRect src = CRect(0, 0, scale.x*rect.right, scale.y*rect.bottom); - - struct - { - float x, y, z, rhw; - float tu, tv; - } - pVertices[] = - { - {(float)dst.left, (float)dst.top, 0.5f, 2.0f, (float)src.left / rd.Width, (float)src.top / rd.Height}, - {(float)dst.right, (float)dst.top, 0.5f, 2.0f, (float)src.right / rd.Width, (float)src.top / rd.Height}, - {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, (float)src.left / rd.Width, (float)src.bottom / rd.Height}, - {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, (float)src.right / rd.Width, (float)src.bottom / rd.Height}, - }; - - for(int i = 0; i < countof(pVertices); i++) - { - pVertices[i].x -= 0.5; - pVertices[i].y -= 0.5; - } - - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - - hr = m_pD3DDev->SetPixelShader(NULL); - - hr = m_pD3DDev->BeginScene(); - hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0])); - hr = m_pD3DDev->EndScene(); - - hr = m_pD3DDev->Present(NULL, NULL, pWnd->m_hWnd, NULL); - - hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); - - CString str; - str.Format(_T("PCSX2 - %05x - %05x"), fbp, m_ctxt->TEX0.TBP0); - if(fbp == (m_ctxt->FRAME.Block())) - { - // pWnd->SetFocus(); - str += _T(" - Drawing"); - } - pWnd->SetWindowText(str); - - MSG msg; - ZeroMemory(&msg, sizeof(msg)); - while(msg.message != WM_QUIT) - { - if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } -#ifdef DEBUG_RENDERTARGETS - else if(!(::GetAsyncKeyState(VK_RCONTROL)&0x80000000)) - { - break; - } -#endif - } - -#ifdef DEBUG_RENDERTARGETS - if(::GetAsyncKeyState(VK_LCONTROL)&0x80000000) - Sleep(500); -#endif - } - else - { - if(IsWindow(pWnd->m_hWnd)) pWnd->DestroyWindow(); - m_pRenderWnds.RemoveKey(fbp); - } - - CString str; - str.Format(_T("PCSX2 - %05x - %05x"), m_ctxt->FRAME.Block(), m_ctxt->TEX0.TBP0); - SetWindowText(m_hWnd, str); - } - } - else - { - SetWindowText(m_hWnd, _T("PCSX2")); - } -#endif -} - -void GSRendererHW::EndFrame() -{ - m_tc.IncAge(m_pRTs); -} - -void GSRendererHW::InvalidateTexture(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) -{ - m_tc.InvalidateTexture(this, BITBLTBUF, &r); -} - -void GSRendererHW::InvalidateLocalMem(DWORD TBP0, DWORD BW, DWORD PSM, CRect r) -{ - m_tc.InvalidateLocalMem(this, TBP0, BW, PSM, &r); -} - -void GSRendererHW::MinMaxUV(int w, int h, CRect& r) -{ - r.SetRect(0, 0, w, h); - - uvmm_t uv; - CSize bsm; - - if(m_ctxt->CLAMP.WMS < 3 || m_ctxt->CLAMP.WMT < 3) - { - UVMinMax(m_nVertices, (vertex_t*)m_pVertices, &uv); - CSize bs = GSLocalMemory::m_psmtbl[m_ctxt->TEX0.PSM].bs; - bsm.SetSize(bs.cx-1, bs.cy-1); - } - - // FIXME: region clamp returns the right rect but we should still update the whole texture later in TC... - - if(m_ctxt->CLAMP.WMS < 3) - { - if(m_ctxt->CLAMP.WMS == 0) - { - float fmin = floor(uv.umin); - float fmax = floor(uv.umax); - - if(fmin != fmax) {uv.umin = 0; uv.umax = 1.0f;} - else {uv.umin -= fmin; uv.umax -= fmax;} - - // FIXME - if(uv.umin == 0 && uv.umax != 1.0f) uv.umax = 1.0f; - } - else if(m_ctxt->CLAMP.WMS == 1) - { - if(uv.umin < 0) uv.umin = 0; - if(uv.umax > 1.0f) uv.umax = 1.0f; - } - else if(m_ctxt->CLAMP.WMS == 2) - { - float minu = 1.0f * m_ctxt->CLAMP.MINU / w; - float maxu = 1.0f * m_ctxt->CLAMP.MAXU / w; - if(uv.umin < minu) uv.umin = minu; - if(uv.umax > maxu) uv.umax = maxu; - } - - r.left = max((int)(uv.umin * w) & ~bsm.cx, 0); - r.right = min(((int)(uv.umax * w) + bsm.cx + 1) & ~bsm.cx, w); - } - - if(m_ctxt->CLAMP.WMT < 3) - { - if(m_ctxt->CLAMP.WMT == 0) - { - float fmin = floor(uv.vmin); - float fmax = floor(uv.vmax); - - if(fmin != fmax) {uv.vmin = 0; uv.vmax = 1.0f;} - else {uv.vmin -= fmin; uv.vmax -= fmax;} - - // FIXME - if(uv.vmin == 0 && uv.vmax != 1.0f) uv.vmax = 1.0f; - } - else if(m_ctxt->CLAMP.WMT == 1) - { - if(uv.vmin < 0) uv.vmin = 0; - if(uv.vmax > 1.0f) uv.vmax = 1.0f; - } - else if(m_ctxt->CLAMP.WMT == 2) - { - float minv = 1.0f * m_ctxt->CLAMP.MINV / h; - float maxv = 1.0f * m_ctxt->CLAMP.MAXV / h; - if(uv.vmin < minv) uv.vmin = minv; - if(uv.vmax > maxv) uv.vmax = maxv; - } - - r.top = max((int)(uv.vmin * h) & ~bsm.cy, 0); - r.bottom = min(((int)(uv.vmax * h) + bsm.cy + 1) & ~bsm.cy, h); - } - - ASSERT(r.left <= r.right); - ASSERT(r.top <= r.bottom); -} - -void GSRendererHW::SetupTexture(const GSTextureBase& t, float tsx, float tsy) -{ - HRESULT hr; - - int tw = 0, th = 0; - float rw = 0, rh = 0; - - IDirect3DPixelShader9* pPixelShader = NULL; - - if(m_pPRIM->TME && t.m_pTexture) - { - tw = t.m_desc.Width; - th = t.m_desc.Height; - rw = 1.0f / tw; - rh = 1.0f / th; - - hr = m_pD3DDev->SetTexture(0, t.m_pTexture); - hr = m_pD3DDev->SetTexture(1, t.m_pPalette); - - D3DTEXTUREADDRESS u, v; - - switch(m_ctxt->CLAMP.WMS) - { - case 0: case 3: u = D3DTADDRESS_WRAP; break; // repeat - case 1: case 2: u = D3DTADDRESS_CLAMP; break; // clamp - default: __assume(0); - } - - switch(m_ctxt->CLAMP.WMT) - { - case 0: case 3: v = D3DTADDRESS_WRAP; break; // repeat - case 1: case 2: v = D3DTADDRESS_CLAMP; break; // clamp - default: __assume(0); - } - - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, u); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, v); - - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, t.m_pPalette ? D3DTEXF_POINT : m_texfilter); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, t.m_pPalette ? D3DTEXF_POINT : m_texfilter); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MAGFILTER, t.m_pPalette ? D3DTEXF_POINT : m_texfilter); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MINFILTER, t.m_pPalette ? D3DTEXF_POINT : m_texfilter); - - if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0) && m_pHLSLTFX[m_ctxt->TEX0.TFX]) - { - int i = m_ctxt->TEX0.TFX; - - switch(t.m_desc.Format) - { - default: - ASSERT(0); - break; - case D3DFMT_A8R8G8B8: - //ASSERT(m_ctxt->TEX0.PSM != PSM_PSMCT24); // format must be D3DFMT_X8R8G8B8 for PSM_PSMCT24 - //if(m_ctxt->TEX0.PSM == PSM_PSMCT24) {i += 4; if(m_de.TEXA.AEM) i += 4;} - if(m_ctxt->TEX0.PSM == PSM_PSMT8H) i += 32; - break; - case D3DFMT_X8R8G8B8: - i += 4; if(m_de.TEXA.AEM) i += 4; - break; - case D3DFMT_A1R5G5B5: - i += 12; if(m_de.TEXA.AEM) i += 4; - break; - case D3DFMT_L8: - i += 24; - ASSERT(t.m_pPalette); - break; - } - - pPixelShader = m_pHLSLTFX[i]; - } - - if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)) - { - switch(m_ctxt->TEX0.TFX) - { - case 0: - if(!m_ctxt->TEX0.TCC) pPixelShader = m_pPixelShaders[0]; - else if(!t.m_fRT) pPixelShader = m_pPixelShaders[1]; - else pPixelShader = m_pPixelShaders[2]; - break; - case 1: - if(!t.m_fRT) pPixelShader = m_pPixelShaders[3]; - else pPixelShader = m_pPixelShaders[4]; - break; - case 2: - if(!m_ctxt->TEX0.TCC) pPixelShader = m_pPixelShaders[5]; - else if(!t.m_fRT) pPixelShader = m_pPixelShaders[6]; - else pPixelShader = m_pPixelShaders[7]; - break; - case 3: - if(!m_ctxt->TEX0.TCC) pPixelShader = m_pPixelShaders[8]; - else if(!t.m_fRT) pPixelShader = m_pPixelShaders[9]; - else pPixelShader = m_pPixelShaders[10]; - break; - default: - __assume(0); - } - } - - if(!pPixelShader) - { - int stage = 0; - - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); - hr = m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 0); - - switch(m_ctxt->TEX0.TFX) - { - case 0: - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_MODULATE2X); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - if(m_ctxt->TEX0.TCC) - { - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, t.m_fRT ? D3DTOP_MODULATE2X : D3DTOP_MODULATE4X); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - } - else - { - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_ADD); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG2, D3DTA_DIFFUSE); - } - stage++; - break; - case 1: - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, t.m_fRT ? D3DTOP_SELECTARG1 : D3DTOP_ADD); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); - stage++; - break; - case 2: - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_MODULATE2X); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - if(m_ctxt->TEX0.TCC) - { - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_ADD); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG2, D3DTA_TEXTURE); - ASSERT(!t.m_fRT); // FIXME - } - stage++; - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_ADD); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_CURRENT); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, D3DTA_ALPHAREPLICATE|D3DTA_DIFFUSE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_ADD); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG2, D3DTA_CURRENT); - stage++; - break; - case 3: - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_MODULATE2X); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, D3DTA_DIFFUSE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_DIFFUSE); - if(m_ctxt->TEX0.TCC) - { - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_TEXTURE); - ASSERT(!t.m_fRT); // FIXME - } - stage++; - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_ADD); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_CURRENT); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, D3DTA_ALPHAREPLICATE|D3DTA_DIFFUSE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_ADD); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG1, D3DTA_CURRENT); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAARG2, D3DTA_CURRENT); - stage++; - break; - default: - __assume(0); - } - - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_DISABLE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - } - else - { - hr = m_pD3DDev->SetTexture(0, NULL); - hr = m_pD3DDev->SetTexture(1, NULL); - - if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0) && m_pHLSLTFX[36]) - { - pPixelShader = m_pHLSLTFX[36]; - } - - if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1) && m_pPixelShaders[11]) - { - pPixelShader = m_pPixelShaders[11]; - } - - if(!pPixelShader) - { - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_DISABLE); - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - } - - float fConstData[][4] = - { - {(float)m_ctxt->TEX0.TCC - 0.5f, t.m_fRT ? 1.0f : 2.0f, min(2.0f * m_de.TEXA.TA0 / 255, 1), min(2.0f * m_de.TEXA.TA1 / 255, 1)}, - {(float)tw, (float)th, 0, 0}, - {rw, rh, 0, 0}, - {rw, 0, 0, 0}, - {0, rh, 0, 0}, - }; - - hr = m_pD3DDev->SetPixelShaderConstantF(0, (float*)fConstData, countof(fConstData)); - - hr = m_pD3DDev->SetPixelShader(pPixelShader); -} - -void GSRendererHW::SetupAlphaBlend() -{ - HRESULT hr; - - DWORD ABE = FALSE; - hr = m_pD3DDev->GetRenderState(D3DRS_ALPHABLENDENABLE, &ABE); - - bool fABE = m_pPRIM->ABE || (m_primtype == D3DPT_LINELIST || m_primtype == D3DPT_LINESTRIP) && m_pPRIM->AA1; // FIXME - if(fABE != !!ABE) - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, fABE); - if(fABE) - { - // (A:Cs/Cd/0 - B:Cs/Cd/0) * C:As/Ad/FIX + D:Cs/Cd/0 - - BYTE FIX = SCALE_ALPHA(m_ctxt->ALPHA.FIX); - - hr = m_pD3DDev->SetRenderState(D3DRS_BLENDFACTOR, (0x010101*FIX)|(FIX<<24)); - - D3DBLENDOP op = D3DBLENDOP_ADD; - D3DBLEND src = D3DBLEND_SRCALPHA, dst = D3DBLEND_INVSRCALPHA; - - static const struct {bool bogus; D3DBLENDOP op; D3DBLEND src, dst;} blendmap[3*3*3*3] = - { - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 0000: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 0001: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 0002: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 0010: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 0011: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 0012: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 0020: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 0021: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 0022: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {1, D3DBLENDOP_SUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, // * 0100: (Cs - Cd)*As + Cs ==> Cs*(As + 1) - Cd*As - {0, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_INVSRCALPHA}, // 0101: (Cs - Cd)*As + Cd ==> Cs*As + Cd*(1 - As) - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, // 0102: (Cs - Cd)*As + 0 ==> Cs*As - Cd*As - {1, D3DBLENDOP_SUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, // * 0110: (Cs - Cd)*Ad + Cs ==> Cs*(Ad + 1) - Cd*Ad - {0, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_INVDESTALPHA}, // 0111: (Cs - Cd)*Ad + Cd ==> Cs*Ad + Cd*(1 - Ad) - {0, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, // 0112: (Cs - Cd)*Ad + 0 ==> Cs*Ad - Cd*Ad - {1, D3DBLENDOP_SUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR}, // * 0120: (Cs - Cd)*F + Cs ==> Cs*(F + 1) - Cd*F - {0, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_INVBLENDFACTOR}, // 0121: (Cs - Cd)*F + Cd ==> Cs*F + Cd*(1 - F) - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR}, // 0122: (Cs - Cd)*F + 0 ==> Cs*F - Cd*F - {1, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, // * 0200: (Cs - 0)*As + Cs ==> Cs*(As + 1) - {0, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ONE}, // 0201: (Cs - 0)*As + Cd ==> Cs*As + Cd - {0, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, // 0202: (Cs - 0)*As + 0 ==> Cs*As - {1, D3DBLENDOP_ADD, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, // * 0210: (Cs - 0)*Ad + Cs ==> Cs*(As + 1) - {0, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ONE}, // 0211: (Cs - 0)*Ad + Cd ==> Cs*Ad + Cd - {0, D3DBLENDOP_ADD, D3DBLEND_DESTALPHA, D3DBLEND_ZERO}, // 0212: (Cs - 0)*Ad + 0 ==> Cs*Ad - {1, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, // * 0220: (Cs - 0)*F + Cs ==> Cs*(F + 1) - {0, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ONE}, // 0221: (Cs - 0)*F + Cd ==> Cs*F + Cd - {0, D3DBLENDOP_ADD, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, // 0222: (Cs - 0)*F + 0 ==> Cs*F - {0, D3DBLENDOP_ADD, D3DBLEND_INVSRCALPHA, D3DBLEND_SRCALPHA}, // 1000: (Cd - Cs)*As + Cs ==> Cd*As + Cs*(1 - As) - {1, D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, // * 1001: (Cd - Cs)*As + Cd ==> Cd*(As + 1) - Cs*As - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_SRCALPHA}, // 1002: (Cd - Cs)*As + 0 ==> Cd*As - Cs*As - {0, D3DBLENDOP_ADD, D3DBLEND_INVDESTALPHA, D3DBLEND_DESTALPHA}, // 1010: (Cd - Cs)*Ad + Cs ==> Cd*Ad + Cs*(1 - Ad) - {1, D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, // * 1011: (Cd - Cs)*Ad + Cd ==> Cd*(Ad + 1) - Cs*Ad - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_DESTALPHA}, // 1012: (Cd - Cs)*Ad + 0 ==> Cd*Ad - Cs*Ad - {0, D3DBLENDOP_ADD, D3DBLEND_INVBLENDFACTOR, D3DBLEND_BLENDFACTOR}, // 1020: (Cd - Cs)*F + Cs ==> Cd*F + Cs*(1 - F) - {1, D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR},// * 1021: (Cd - Cs)*F + Cd ==> Cd*(F + 1) - Cs*F - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_BLENDFACTOR},// 1022: (Cd - Cs)*F + 0 ==> Cd*F - Cs*F - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 1100: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 1101: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 1102: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 1110: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 1111: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 1112: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 1120: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 1121: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 1122: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_SRCALPHA}, // 1200: (Cd - 0)*As + Cs ==> Cs + Cd*As - {1, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_SRCALPHA}, // * 1201: (Cd - 0)*As + Cd ==> Cd*(1 + As) - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_SRCALPHA}, // 1202: (Cd - 0)*As + 0 ==> Cd*As - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_DESTALPHA}, // 1210: (Cd - 0)*Ad + Cs ==> Cs + Cd*Ad - {1, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_DESTALPHA}, // * 1211: (Cd - 0)*Ad + Cd ==> Cd*(1 + Ad) - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_DESTALPHA}, // 1212: (Cd - 0)*Ad + 0 ==> Cd*Ad - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_BLENDFACTOR}, // 1220: (Cd - 0)*F + Cs ==> Cs + Cd*F - {1, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_BLENDFACTOR}, // * 1221: (Cd - 0)*F + Cd ==> Cd*(1 + F) - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_BLENDFACTOR}, // 1222: (Cd - 0)*F + 0 ==> Cd*F - {0, D3DBLENDOP_ADD, D3DBLEND_INVSRCALPHA, D3DBLEND_ZERO}, // 2000: (0 - Cs)*As + Cs ==> Cs*(1 - As) - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_ONE}, // 2001: (0 - Cs)*As + Cd ==> Cd - Cs*As - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_SRCALPHA, D3DBLEND_ZERO}, // 2002: (0 - Cs)*As + 0 ==> 0 - Cs*As - {0, D3DBLENDOP_ADD, D3DBLEND_INVDESTALPHA, D3DBLEND_ZERO}, // 2010: (0 - Cs)*Ad + Cs ==> Cs*(1 - Ad) - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_ONE}, // 2011: (0 - Cs)*Ad + Cd ==> Cd - Cs*Ad - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_DESTALPHA, D3DBLEND_ZERO}, // 2012: (0 - Cs)*Ad + 0 ==> 0 - Cs*Ad - {0, D3DBLENDOP_ADD, D3DBLEND_INVBLENDFACTOR, D3DBLEND_ZERO}, // 2020: (0 - Cs)*F + Cs ==> Cs*(1 - F) - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_ONE}, // 2021: (0 - Cs)*F + Cd ==> Cd - Cs*F - {0, D3DBLENDOP_REVSUBTRACT, D3DBLEND_BLENDFACTOR, D3DBLEND_ZERO}, // 2022: (0 - Cs)*F + 0 ==> 0 - Cs*F - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_ONE, D3DBLEND_SRCALPHA}, // 2100: (0 - Cd)*As + Cs ==> Cs - Cd*As - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_INVSRCALPHA}, // 2101: (0 - Cd)*As + Cd ==> Cd*(1 - As) - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_ZERO, D3DBLEND_SRCALPHA}, // 2102: (0 - Cd)*As + 0 ==> 0 - Cd*As - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_ONE, D3DBLEND_DESTALPHA}, // 2110: (0 - Cd)*Ad + Cs ==> Cs - Cd*Ad - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_INVDESTALPHA}, // 2111: (0 - Cd)*Ad + Cd ==> Cd*(1 - Ad) - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_ONE, D3DBLEND_DESTALPHA}, // 2112: (0 - Cd)*Ad + 0 ==> 0 - Cd*Ad - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_ONE, D3DBLEND_BLENDFACTOR}, // 2120: (0 - Cd)*F + Cs ==> Cs - Cd*F - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_INVBLENDFACTOR}, // 2121: (0 - Cd)*F + Cd ==> Cd*(1 - F) - {0, D3DBLENDOP_SUBTRACT, D3DBLEND_ONE, D3DBLEND_BLENDFACTOR}, // 2122: (0 - Cd)*F + 0 ==> 0 - Cd*F - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 2200: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 2201: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 2202: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 2210: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 2211: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 2212: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - {0, D3DBLENDOP_ADD, D3DBLEND_ONE, D3DBLEND_ZERO}, // 2220: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cs ==> Cs - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ONE}, // 2221: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + Cd ==> Cd - {0, D3DBLENDOP_ADD, D3DBLEND_ZERO, D3DBLEND_ZERO}, // 2222: (Cs/Cd/0 - Cs/Cd/0)*As/Ad/F + 0 ==> 0 - }; - - // bogus: 0100, 0110, 0120, 0200, 0210, 0220, 1001, 1011, 1021, 1201, 1211, 1221 - - int i = (((m_ctxt->ALPHA.A&3)*3+(m_ctxt->ALPHA.B&3))*3+(m_ctxt->ALPHA.C&3))*3+(m_ctxt->ALPHA.D&3); - - ASSERT(m_ctxt->ALPHA.A != 3); - ASSERT(m_ctxt->ALPHA.B != 3); - ASSERT(m_ctxt->ALPHA.C != 3); - ASSERT(m_ctxt->ALPHA.D != 3); - ASSERT(!blendmap[i].bogus); - - hr = m_pD3DDev->SetRenderState(D3DRS_BLENDOP, blendmap[i].op); - hr = m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, blendmap[i].src); - hr = m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, blendmap[i].dst); - } -} - -void GSRendererHW::SetupColorMask() -{ - HRESULT hr; - - // close approx., to be tested... - int mask = D3DCOLORWRITEENABLE_RGBA; - if((m_ctxt->FRAME.FBMSK&0xff000000) == 0xff000000) mask &= ~D3DCOLORWRITEENABLE_ALPHA; - if((m_ctxt->FRAME.FBMSK&0x00ff0000) == 0x00ff0000) mask &= ~D3DCOLORWRITEENABLE_BLUE; - if((m_ctxt->FRAME.FBMSK&0x0000ff00) == 0x0000ff00) mask &= ~D3DCOLORWRITEENABLE_GREEN; - if((m_ctxt->FRAME.FBMSK&0x000000ff) == 0x000000ff) mask &= ~D3DCOLORWRITEENABLE_RED; - //if(m_ctxt->FRAME.PSM == PSM_PSMCT24) mask &= ~D3DCOLORWRITEENABLE_ALPHA; - hr = m_pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, mask); - - // ASSERT(m_ctxt->FRAME.FBMSK == 0); // wild arms (also 8H+pal on RT...) -} - -void GSRendererHW::SetupZBuffer() -{ - HRESULT hr; - - hr = m_pD3DDev->SetRenderState(D3DRS_ZENABLE, m_ctxt->TEST.ZTE); - hr = m_pD3DDev->SetRenderState(D3DRS_ZWRITEENABLE, !m_ctxt->ZBUF.ZMSK); - if(m_ctxt->TEST.ZTE) - { - static const DWORD zfunc[] = {D3DCMP_NEVER, D3DCMP_ALWAYS, D3DCMP_GREATEREQUAL, D3DCMP_GREATER}; - - hr = m_pD3DDev->SetRenderState(D3DRS_ZFUNC, zfunc[m_ctxt->TEST.ZTST]); -// hr = m_pD3DDev->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - - // FIXME - if(m_ctxt->ZBUF.ZMSK && m_ctxt->TEST.ZTST == 1) - { - for(int i = 0; i < m_nVertices; i++) - m_pVertices[i].z = 0; - } - } -} - -void GSRendererHW::SetupAlphaTest() -{ - HRESULT hr = m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, m_ctxt->TEST.ATE); - - if(m_ctxt->TEST.ATE) - { - static const DWORD afunc[] = {D3DCMP_NEVER, D3DCMP_ALWAYS, D3DCMP_LESS, D3DCMP_LESSEQUAL, D3DCMP_EQUAL, D3DCMP_GREATEREQUAL, D3DCMP_GREATER, D3DCMP_NOTEQUAL}; - - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAFUNC, afunc[m_ctxt->TEST.ATST]); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHAREF, (DWORD)SCALE_ALPHA(m_ctxt->TEST.AREF)); - } -} - -void GSRendererHW::SetupScissor(scale_t& s) -{ - HRESULT hr = m_pD3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, TRUE); - - CRect r( - (int)(s.x * m_ctxt->SCISSOR.SCAX0), - (int)(s.y * m_ctxt->SCISSOR.SCAY0), - (int)(s.x * (m_ctxt->SCISSOR.SCAX1+1)), - (int)(s.y * (m_ctxt->SCISSOR.SCAY1+1))); - - if(/*r.Width() == m_bd.Width &&*/ r.bottom > m_bd.Height && r.bottom <= m_bd.Height*2 - /*r.bottom == m_bd.Height*2*/ - ) - { - // TODO: isn't there a better way? what about s.x? -// s.y = s.y * m_bd.Height / r.bottom; - } - - r &= CRect(0, 0, m_bd.Width, m_bd.Height); - - hr = m_pD3DDev->SetScissorRect(r); -} diff --git a/plugins/gs/gsdx9/GSRendererHW.h b/plugins/gs/gsdx9/GSRendererHW.h deleted file mode 100644 index 4c1d99789c..0000000000 --- a/plugins/gs/gsdx9/GSRendererHW.h +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "GSRenderer.h" - -#pragma pack(push, 1) -__declspec(align(16)) union GSVertexHW -{ - struct - { - float x, y, z, rhw; - union {struct {BYTE r, g, b, a;}; D3DCOLOR color;}; - D3DCOLOR fog; - float tu, tv; - }; - - struct {__m128i xmm[2];}; - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - GSVertexHW& operator = (GSVertexHW& v) {xmm[0] = v.xmm[0]; xmm[1] = v.xmm[1]; return *this;} -#endif -}; -#pragma pack(pop) - -class GSRendererHW : public GSRenderer -{ -protected: - CSurfMap m_pRTs; - CSurfMap m_pDSs; - CAtlMap m_pRenderWnds; - - GSTextureCache m_tc; - - void SetupTexture(const GSTextureBase& t, float tsx, float tsy); - void SetupAlphaBlend(); - void SetupColorMask(); - void SetupZBuffer(); - void SetupAlphaTest(); - void SetupScissor(scale_t& s); - - void Reset(); - void VertexKick(bool fSkip); - int DrawingKick(bool fSkip); - void FlushPrim(); - void Flip(); - void EndFrame(); - void InvalidateTexture(const GIFRegBITBLTBUF& BITBLTBUF, CRect r); - void InvalidateLocalMem(DWORD BP, DWORD TBP0, DWORD PSM, CRect r); - void MinMaxUV(int w, int h, CRect& r); - - D3DPRIMITIVETYPE m_primtype; - -public: - GSRendererHW(HWND hWnd, HRESULT& hr); - ~GSRendererHW(); - - HRESULT ResetDevice(bool fForceWindowed = false); - - void LOGVERTEX(GSVertexHW& v, LPCTSTR type) - { - int tw = 1, th = 1; - if(m_pPRIM->TME) {tw = 1<TEX0.TW; th = 1<TEX0.TH;} - LOG2(_T("\t %s (%.2f, %.2f, %.2f, %.2f) (%08x) (%f, %f) (%f, %f)\n"), - type, - v.x, v.y, v.z, v.rhw, - v.color, v.tu, v.tv, - v.tu*tw, v.tv*th); - } -}; \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSRendererNull.cpp b/plugins/gs/gsdx9/GSRendererNull.cpp deleted file mode 100644 index e6b32a2748..0000000000 --- a/plugins/gs/gsdx9/GSRendererNull.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSRendererNull.h" - -GSRendererNull::GSRendererNull(HWND hWnd, HRESULT& hr) - : GSRenderer(256, 256, hWnd, hr) -{ -} - -GSRendererNull::~GSRendererNull() -{ -} - -void GSRendererNull::VertexKick(bool fSkip) -{ - NULLVERTEX v; - - m_vl.AddTail(v); - - __super::VertexKick(fSkip); -} - -int GSRendererNull::DrawingKick(bool fSkip) -{ - NULLVERTEX v; - - switch(m_PRIM) - { - case 3: // triangle list - m_vl.RemoveAt(0, v); - m_vl.RemoveAt(0, v); - m_vl.RemoveAt(0, v); - break; - case 4: // triangle strip - m_vl.RemoveAt(0, v); - m_vl.GetAt(0, v); - m_vl.GetAt(1, v); - break; - case 5: // triangle fan - m_vl.GetAt(0, v); - m_vl.RemoveAt(1, v); - m_vl.GetAt(1, v); - break; - case 6: // sprite - m_vl.RemoveAt(0, v); - m_vl.RemoveAt(0, v); - break; - case 1: // line - m_vl.RemoveAt(0, v); - m_vl.RemoveAt(0, v); - break; - case 2: // line strip - m_vl.RemoveAt(0, v); - m_vl.GetAt(0, v); - break; - case 0: // point - m_vl.RemoveAt(0, v); - break; - default: - ASSERT(0); - m_vl.RemoveAll(); - return 0; - } - - if(!fSkip) - { - m_perfmon.IncCounter(GSPerfMon::c_prim, 1); - } - - return 0; -} - -void GSRendererNull::Flip() -{ - FlipInfo rt[2]; - FinishFlip(rt); -} - -void GSRendererNull::EndFrame() -{ -} diff --git a/plugins/gs/gsdx9/GSRendererNull.h b/plugins/gs/gsdx9/GSRendererNull.h deleted file mode 100644 index 574a5364a3..0000000000 --- a/plugins/gs/gsdx9/GSRendererNull.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "GSRenderer.h" - -#pragma pack(push, 1) -struct NULLVERTEX {/*DWORD dummy;*/}; -#pragma pack(pop) - -class GSRendererNull : public GSRenderer -{ -protected: - void VertexKick(bool fSkip); - int DrawingKick(bool fSkip); - void Flip(); - void EndFrame(); - -public: - GSRendererNull(HWND hWnd, HRESULT& hr); - ~GSRendererNull(); -}; \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSRendererSoft.cpp b/plugins/gs/gsdx9/GSRendererSoft.cpp deleted file mode 100644 index 7018c52a17..0000000000 --- a/plugins/gs/gsdx9/GSRendererSoft.cpp +++ /dev/null @@ -1,1113 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSRendererSoft.h" -#include "x86.h" - -template -GSRendererSoft::GSRendererSoft(HWND hWnd, HRESULT& hr) - : GSRenderer(640, 512, hWnd, hr) -{ - Reset(); - - int i = SHRT_MIN; - BYTE j = 0; - for(; i < 0; i++, j++) m_clip[j] = 0, m_mask[j] = j; - for(; i < 256; i++, j++) m_clip[j] = (BYTE)i, m_mask[j] = j; - for(; i < SHRT_MAX; i++, j++) m_clip[j] = 255, m_mask[j] = j; - - m_uv = (uv_wrap_t*)_aligned_malloc(sizeof(uv_wrap_t), 16); - - // w00t :P - - #define InitATST(iZTST, iATST) \ - m_dv[iZTST][iATST] = &GSRendererSoft::DrawVertex; \ - - #define InitZTST(iZTST) \ - InitATST(iZTST, 0) \ - InitATST(iZTST, 1) \ - InitATST(iZTST, 2) \ - InitATST(iZTST, 3) \ - InitATST(iZTST, 4) \ - InitATST(iZTST, 5) \ - InitATST(iZTST, 6) \ - InitATST(iZTST, 7) \ - - #define InitDV() \ - InitZTST(0) \ - InitZTST(1) \ - InitZTST(2) \ - InitZTST(3) \ - - InitDV(); - - #define InitTFX(iLOD, bLCM, bTCC, iTFX) \ - m_dvtfx[iLOD][bLCM][bTCC][iTFX] = &GSRendererSoft::DrawVertexTFX; \ - - #define InitTCC(iLOD, bLCM, bTCC) \ - InitTFX(iLOD, bLCM, bTCC, 0) \ - InitTFX(iLOD, bLCM, bTCC, 1) \ - InitTFX(iLOD, bLCM, bTCC, 2) \ - InitTFX(iLOD, bLCM, bTCC, 3) \ - - #define InitLCM(iLOD, bLCM) \ - InitTCC(iLOD, bLCM, false) \ - InitTCC(iLOD, bLCM, true) \ - - #define InitLOD(iLOD) \ - InitLCM(iLOD, false) \ - InitLCM(iLOD, true) \ - - #define InitDVTFX() \ - InitLOD(0) \ - InitLOD(1) \ - InitLOD(2) \ - InitLOD(3) \ - - InitDVTFX(); -} - -template -GSRendererSoft::~GSRendererSoft() -{ - _aligned_free(m_uv); -} - -template -HRESULT GSRendererSoft::ResetDevice(bool fForceWindowed) -{ - m_pRT[0] = NULL; - m_pRT[1] = NULL; - - return __super::ResetDevice(fForceWindowed); -} - -template -void GSRendererSoft::Reset() -{ - m_primtype = PRIM_NONE; - m_pTexture = NULL; - - __super::Reset(); -} - -template -int GSRendererSoft::DrawingKick(bool fSkip) -{ - Vertex* pVertices = &m_pVertices[m_nVertices]; - int nVertices = 0; - - switch(m_PRIM) - { - case 3: // triangle list - m_primtype = PRIM_TRIANGLE; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - LOGV((pVertices[0], _T("TriList"))); - LOGV((pVertices[1], _T("TriList"))); - LOGV((pVertices[2], _T("TriList"))); - break; - case 4: // triangle strip - m_primtype = PRIM_TRIANGLE; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.GetAt(0, pVertices[nVertices++]); - m_vl.GetAt(1, pVertices[nVertices++]); - LOGV((pVertices[0], _T("TriStrip"))); - LOGV((pVertices[1], _T("TriStrip"))); - LOGV((pVertices[2], _T("TriStrip"))); - break; - case 5: // triangle fan - m_primtype = PRIM_TRIANGLE; - m_vl.GetAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(1, pVertices[nVertices++]); - m_vl.GetAt(1, pVertices[nVertices++]); - LOGV((pVertices[0], _T("TriFan"))); - LOGV((pVertices[1], _T("TriFan"))); - LOGV((pVertices[2], _T("TriFan"))); - break; - case 6: // sprite - m_primtype = PRIM_SPRITE; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - nVertices += 2; - pVertices[0].p.z = pVertices[1].p.z; - pVertices[0].p.q = pVertices[1].p.q; - pVertices[2] = pVertices[1]; - pVertices[3] = pVertices[1]; - pVertices[1].p.y = pVertices[0].p.y; - pVertices[1].t.y = pVertices[0].t.y; - pVertices[2].p.x = pVertices[0].p.x; - pVertices[2].t.x = pVertices[0].t.x; - LOGV((pVertices[0], _T("Sprite"))); - LOGV((pVertices[1], _T("Sprite"))); - LOGV((pVertices[2], _T("Sprite"))); - LOGV((pVertices[3], _T("Sprite"))); - /* - m_primtype = PRIM_TRIANGLE; - nVertices += 2; - pVertices[5] = pVertices[3]; - pVertices[3] = pVertices[1]; - pVertices[4] = pVertices[2]; - */ - break; - case 1: // line - m_primtype = PRIM_LINE; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.RemoveAt(0, pVertices[nVertices++]); - LOGV((pVertices[0], _T("LineList"))); - LOGV((pVertices[1], _T("LineList"))); - break; - case 2: // line strip - m_primtype = PRIM_LINE; - m_vl.RemoveAt(0, pVertices[nVertices++]); - m_vl.GetAt(0, pVertices[nVertices++]); - LOGV((pVertices[0], _T("LineStrip"))); - LOGV((pVertices[1], _T("LineStrip"))); - break; - case 0: // point - m_primtype = PRIM_POINT; - m_vl.RemoveAt(0, pVertices[nVertices++]); - LOGV((pVertices[0], _T("PointList"))); - break; - default: - ASSERT(0); - return 0; - } - - if(fSkip || !m_rs.IsEnabled(0) && !m_rs.IsEnabled(1)) - return 0; - - if(!m_pPRIM->IIP) - { - Vertex::Vector c = pVertices[nVertices-1].c; - for(int i = 0; i < nVertices-1; i++) - pVertices[i].c = c; - } - - return nVertices; -} - -template -void GSRendererSoft::FlushPrim() -{ - if(m_nVertices > 0) - { -CString fn; -static int s_savenum = 0; -s_savenum++; - -if(0) -//if(m_ctxt->FRAME.Block() == 0x008c0 && (DWORD)m_ctxt->TEX0.TBP0 == 0x03a98) -//if(m_ctxt->TEX0.PSM == 0x1b) -if(m_perfmon.GetFrame() >= 200) -{ -fn.Format(_T("g:/tmp/%04I64d_%06d_1f_%05x_%x.bmp"), m_perfmon.GetFrame(), s_savenum, m_ctxt->FRAME.Block(), m_ctxt->FRAME.PSM); -m_lm.SaveBMP(m_pD3DDev, fn, m_ctxt->FRAME.Block(), m_ctxt->FRAME.FBW, m_ctxt->FRAME.PSM, m_ctxt->FRAME.FBW*64, 224); - -if(m_pPRIM->TME) -{ -fn.Format(_T("g:/tmp/%04I64d_%06d_2t_%05x_%x.bmp"), m_perfmon.GetFrame(), s_savenum, (DWORD)m_ctxt->TEX0.TBP0, (DWORD)m_ctxt->TEX0.PSM); -m_lm.SaveBMP(m_pD3DDev, fn, m_ctxt->TEX0.TBP0, m_ctxt->TEX0.TBW, m_ctxt->TEX0.PSM, 1 << m_ctxt->TEX0.TW, 1 << m_ctxt->TEX0.TH); -} -} - - int iZTST = !m_ctxt->TEST.ZTE ? 1 : m_ctxt->TEST.ZTST; - int iATST = !m_ctxt->TEST.ATE ? 1 : m_ctxt->TEST.ATST; - - m_pDrawVertex = m_dv[iZTST][iATST]; - - if(m_pPRIM->TME) - { - int iLOD = (m_ctxt->TEX1.MMAG & 1) + (m_ctxt->TEX1.MMIN & 1); - int bLCM = m_ctxt->TEX1.LCM ? 1 : 0; - int bTCC = m_ctxt->TEX0.TCC ? 1 : 0; - int iTFX = m_ctxt->TEX0.TFX; - - if(m_pPRIM->FST) - { - iLOD = 3; - bLCM = m_ctxt->TEX1.K <= 0 && (m_ctxt->TEX1.MMAG & 1) || m_ctxt->TEX1.K > 0 && (m_ctxt->TEX1.MMIN & 1); - } - - m_pDrawVertexTFX = m_dvtfx[iLOD][bLCM][bTCC][iTFX]; - } - - SetupTexture(); - - m_scissor.SetRect( - max(m_ctxt->SCISSOR.SCAX0, 0), - max(m_ctxt->SCISSOR.SCAY0, 0), - min(m_ctxt->SCISSOR.SCAX1+1, m_ctxt->FRAME.FBW * 64), - min(m_ctxt->SCISSOR.SCAY1+1, 4096)); - - m_clamp = (m_de.COLCLAMP.CLAMP ? m_clip : m_mask) + 32768; - - int nPrims = 0; - Vertex* pVertices = m_pVertices; - - switch(m_primtype) - { - case PRIM_SPRITE: - ASSERT(!(m_nVertices&3)); - nPrims = m_nVertices / 4; - LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)\n"), m_primtype, m_nVertices, nPrims); - for(int i = 0; i < nPrims; i++, pVertices += 4) DrawSprite(pVertices); - break; - case PRIM_TRIANGLE: - ASSERT(!(m_nVertices%3)); - nPrims = m_nVertices / 3; - LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)\n"), m_primtype, m_nVertices, nPrims); - for(int i = 0; i < nPrims; i++, pVertices += 3) DrawTriangle(pVertices); - break; - case PRIM_LINE: - ASSERT(!(m_nVertices&1)); - nPrims = m_nVertices / 2; - LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)\n"), m_primtype, m_nVertices, nPrims); - for(int i = 0; i < nPrims; i++, pVertices += 2) DrawLine(pVertices); - break; - case PRIM_POINT: - nPrims = m_nVertices; - LOG(_T("FlushPrim(pt=%d, nVertices=%d, nPrims=%d)\n"), m_primtype, m_nVertices, nPrims); - for(int i = 0; i < nPrims; i++, pVertices++) DrawPoint(pVertices); - break; - default: - ASSERT(m_nVertices == 0); - return; - } - - m_perfmon.IncCounter(GSPerfMon::c_prim, nPrims); - -if(0) -//if(m_ctxt->FRAME.Block() == 0x008c0 && (DWORD)m_ctxt->TEX0.TBP0 == 0x03a98) -//if(m_ctxt->TEX0.PSM == 0x1b) -if(m_perfmon.GetFrame() >= 200) -{ -fn.Format(_T("g:/tmp/%04I64d_%06d_3f_%05x_%x.bmp"), m_perfmon.GetFrame(), s_savenum, m_ctxt->FRAME.Block(), m_ctxt->FRAME.PSM); -m_lm.SaveBMP(m_pD3DDev, fn, m_ctxt->FRAME.Block(), m_ctxt->FRAME.FBW, m_ctxt->FRAME.PSM, m_ctxt->FRAME.FBW*64, 224); -} - } - - m_primtype = PRIM_NONE; - - __super::FlushPrim(); -} - -template -void GSRendererSoft::Flip() -{ - HRESULT hr; - - FlipInfo rt[2]; - - for(int i = 0; i < countof(rt); i++) - { - if(m_rs.IsEnabled(i)) - { - CRect rect = CRect(CPoint(0, 0), m_rs.GetDispRect(i).BottomRight()); - - //GSLocalMemory::RoundUp(, GSLocalMemory::GetBlockSize(m_rs.DISPFB[i].PSM)); - - ZeroMemory(&rt[i].rd, sizeof(rt[i].rd)); - if(m_pRT[i]) m_pRT[i]->GetLevelDesc(0, &rt[i].rd); - - if(rt[i].rd.Width != (UINT)rect.right || rt[i].rd.Height != (UINT)rect.bottom) - m_pRT[i] = NULL; - - if(!m_pRT[i]) - { - CComPtr pRT; - D3DLOCKED_RECT lr; - int nTries = 0, nMaxTries = 10; - do - { - pRT = NULL; - hr = m_pD3DDev->CreateTexture(rect.right, rect.bottom, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pRT, NULL); - if(FAILED(hr)) break; - if(SUCCEEDED(pRT->LockRect(0, &lr, NULL, 0))) - pRT->UnlockRect(0); - m_pRT[i] = pRT; - } - while((((DWORD_PTR)lr.pBits & 0xf) || (lr.Pitch & 0xf)) && ++nTries < nMaxTries); - - if(nTries == nMaxTries) continue; - - ZeroMemory(&rt[i].rd, sizeof(rt[i].rd)); - hr = m_pRT[i]->GetLevelDesc(0, &rt[i].rd); - } - - rt[i].pRT = m_pRT[i]; - - rt[i].scale = scale_t(1, 1); - - D3DLOCKED_RECT lr; - if(FAILED(hr = rt[i].pRT->LockRect(0, &lr, NULL, 0))) - continue; - - GIFRegTEX0 TEX0; - TEX0.TBP0 = m_rs.pDISPFB[i]->FBP<<5; - TEX0.TBW = m_rs.pDISPFB[i]->FBW; - TEX0.PSM = m_rs.pDISPFB[i]->PSM; - - GIFRegCLAMP CLAMP; - CLAMP.WMS = CLAMP.WMT = 1; - -#ifdef DEBUG_RENDERTARGETS - if(::GetAsyncKeyState(VK_SPACE)&0x80000000) - { - TEX0.TBP0 = m_ctxt->FRAME.Block(); - TEX0.TBW = m_ctxt->FRAME.FBW; - TEX0.PSM = m_ctxt->FRAME.PSM; - } - - MSG msg; - ZeroMemory(&msg, sizeof(msg)); - while(msg.message != WM_QUIT) - { - if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) - { - TranslateMessage(&msg); - DispatchMessage(&msg); - } - else if(!(::GetAsyncKeyState(VK_RCONTROL)&0x80000000)) - { - break; - } - } - - if(::GetAsyncKeyState(VK_LCONTROL)&0x80000000) - Sleep(500); - -#endif - - m_lm.ReadTexture(rect, (BYTE*)lr.pBits, lr.Pitch, TEX0, m_de.TEXA, CLAMP); - - rt[i].pRT->UnlockRect(0); - } - } - - FinishFlip(rt); -} - -template -void GSRendererSoft::EndFrame() -{ -} - -template -void GSRendererSoft::RowInit(int x, int y) -{ - m_faddr_x0 = (m_ctxt->ftbl->pa)(0, y, m_ctxt->FRAME.FBP<<5, m_ctxt->FRAME.FBW); - m_zaddr_x0 = (m_ctxt->ztbl->pa)(0, y, m_ctxt->ZBUF.ZBP<<5, m_ctxt->FRAME.FBW); - - m_faddr_ro = &m_ctxt->ftbl->rowOffset[y&7][x]; - m_zaddr_ro = &m_ctxt->ztbl->rowOffset[y&7][x]; - - m_fx = x-1; // -1 because RowStep() will do +1, yea lame... - m_fy = y; - - RowStep(); -} - -template -void GSRendererSoft::RowStep() -{ - m_fx++; - - m_faddr = m_faddr_x0 + *m_faddr_ro++; - m_zaddr = m_zaddr_x0 + *m_zaddr_ro++; -} - -template -void GSRendererSoft::DrawPoint(Vertex* v) -{ - CPoint p = *v; - if(!m_scissor.PtInRect(p)) - { - RowInit(p.x, p.y); - (this->*m_pDrawVertex)(*v); - } -} - -template -void GSRendererSoft::DrawLine(Vertex* v) -{ - Vertex dv = v[1] - v[0]; - - Vertex::Vector dp = dv.p; - dp.x.abs(); - dp.y.abs(); - - int dx = (int)dp.x; - int dy = (int)dp.y; - - if(dx == 0 && dy == 0) return; - - int i = dx > dy ? 0 : 1; - - Vertex edge = v[0]; - Vertex dedge = dv / dp.v[i]; - - // TODO: clip with the scissor - - int steps = (int)dp.v[i]; - - while(steps-- > 0) - { - CPoint p = edge; - - if(m_scissor.PtInRect(p)) - { - RowInit(p.x, p.y); - (this->*m_pDrawVertex)(edge); - } - - edge += dedge; - } -} - -template -void GSRendererSoft::DrawTriangle(Vertex* v) -{ - if(v[1].p.y < v[0].p.y) {Exchange(&v[0], &v[1]);} - if(v[2].p.y < v[0].p.y) {Exchange(&v[0], &v[2]);} - if(v[2].p.y < v[1].p.y) {Exchange(&v[1], &v[2]);} - - if(!(v[0].p.y < v[2].p.y)) return; - - Vertex v01 = v[1] - v[0]; - Vertex v02 = v[2] - v[0]; - - Vertex::Scalar temp = v01.p.y / v02.p.y; - Vertex::Scalar longest = temp * v02.p.x - v01.p.x; - - int ledge, redge; - if(Vertex::Scalar(0) < longest) {ledge = 0; redge = 1; if(longest < Vertex::Scalar(1)) longest = Vertex::Scalar(1);} - else if(longest < Vertex::Scalar(0)) {ledge = 1; redge = 0; if(Vertex::Scalar(-1) < longest) longest = Vertex::Scalar(-1);} - else return; - - Vertex edge[2] = {v[0], v[0]}; - - Vertex dedge[2]; - dedge[0].p.y = dedge[1].p.y = Vertex::Scalar(1); - if(Vertex::Scalar(0) < v01.p.y) dedge[ledge] = v01 / v01.p.y; - if(Vertex::Scalar(0) < v02.p.y) dedge[redge] = v02 / v02.p.y; - - Vertex scan; - - Vertex dscan = (v02 * temp - v01) / longest; - dscan.p.y = 0; - - for(int i = 0; i < 2; i++, v++) - { - int top = edge[0].p.y.ceil_i(), bottom = v[1].p.y.ceil_i(); - if(top < m_scissor.top) top = min(m_scissor.top, bottom); - if(bottom > m_scissor.bottom) bottom = m_scissor.bottom; - if(edge[0].p.y < Vertex::Scalar(top)) // for(int j = 0; j < 2; j++) edge[j] += dedge[j] * ((float)top - edge[0].p.y); - { - Vertex::Scalar dy = Vertex::Scalar(top) - edge[0].p.y; - edge[0] += dedge[0] * dy; - edge[1].p.x += dedge[1].p.x * dy; - edge[0].p.y = edge[1].p.y = Vertex::Scalar(top); - } - - ASSERT(top >= bottom || (int)((edge[1].p.y - edge[0].p.y) * 10) == 0); -/* -static struct eb_t {Vertex scan; int top; int left; int steps;} eb[1024]; -int _top = top; -int _bottom = bottom; -*/ - for(; top < bottom; top++) - { - scan = edge[0]; - - int left = edge[0].p.x.ceil_i(), right = edge[1].p.x.ceil_i(); - if(left < m_scissor.left) left = m_scissor.left; - if(right > m_scissor.right) right = m_scissor.right; - if(edge[0].p.x < Vertex::Scalar(left)) - { - scan += dscan * (Vertex::Scalar(left) - edge[0].p.x); - scan.p.x = Vertex::Scalar(left); - } -/* -eb[top].scan = scan; -eb[top].top = top; -eb[top].left = left; -eb[top].steps = right - left; -*/ -///* - RowInit(left, top); - - for(int steps = right - left; steps > 0; steps--) - { - (this->*m_pDrawVertex)(scan); - scan += dscan; - RowStep(); - } -//*/ - // for(int j = 0; j < 2; j++) edge[j] += dedge[j]; - edge[0] += dedge[0]; - edge[1].p += dedge[1].p; - } -/* -top = _top; -bottom = _bottom; -for(; top < bottom; top++) -{ - eb_t& sl = eb[top]; - - RowInit(sl.left, top); - - for(; sl.steps > 0; sl.steps--) - { - (this->*m_pDrawVertex)(sl.scan); - sl.scan += dscan; - RowStep(); - } -} -*/ - if(v[1].p.y < v[2].p.y) - { - edge[ledge] = v[1]; - dedge[ledge] = (v[2] - v[1]) / (v[2].p.y - v[1].p.y); - edge[ledge] += dedge[ledge] * (edge[ledge].p.y.ceil_s() - edge[ledge].p.y); - } - } -} - -template -void GSRendererSoft::DrawSprite(Vertex* v) -{ - if(v[2].p.y < v[0].p.y) {Exchange(&v[0], &v[2]); Exchange(&v[1], &v[3]);} - if(v[1].p.x < v[0].p.x) {Exchange(&v[0], &v[1]); Exchange(&v[2], &v[3]);} - - if(v[0].p.x == v[1].p.x || v[0].p.y == v[2].p.y) return; - - Vertex v01 = v[1] - v[0]; - Vertex v02 = v[2] - v[0]; - - Vertex edge = v[0]; - Vertex dedge = v02 / v02.p.y; - Vertex scan; - Vertex dscan = v01 / v01.p.x; - - int top = v[0].p.y.ceil_i(), bottom = v[2].p.y.ceil_i(); - if(top < m_scissor.top) top = min(m_scissor.top, bottom); - if(bottom > m_scissor.bottom) bottom = m_scissor.bottom; - if(v[0].p.y < Vertex::Scalar(top)) edge += dedge * (Vertex::Scalar(top) - v[0].p.y); - - int left = v[0].p.x.ceil_i(), right = v[1].p.x.ceil_i(); - if(left < m_scissor.left) left = m_scissor.left; - if(right > m_scissor.right) right = m_scissor.right; - if(v[0].p.x < Vertex::Scalar(left)) edge += dscan * (Vertex::Scalar(left) - v[0].p.x); - - if(DrawFilledRect(left, top, right, bottom, edge)) - return; - - for(; top < bottom; top++) - { - scan = edge; - - RowInit(left, top); - - for(int steps = right - left; steps > 0; steps--) - { - (this->*m_pDrawVertex)(scan); - scan += dscan; - RowStep(); - } - - edge += dedge; - } -} - -template -bool GSRendererSoft::DrawFilledRect(int left, int top, int right, int bottom, const Vertex& v) -{ - if(left >= right || top >= bottom) - return false; - - ASSERT(top >= 0); - ASSERT(bottom >= 0); - - if(m_pPRIM->IIP - || m_ctxt->TEST.ZTE && m_ctxt->TEST.ZTST != 1 - || m_ctxt->TEST.ATE && m_ctxt->TEST.ATST != 1 - || m_ctxt->TEST.DATE - || m_pPRIM->TME - || m_pPRIM->ABE - || m_pPRIM->FGE - || m_de.DTHE.DTHE - || m_ctxt->FRAME.FBMSK) - return false; - - DWORD FBP = m_ctxt->FRAME.FBP<<5, FBW = m_ctxt->FRAME.FBW; - DWORD ZBP = m_ctxt->ZBUF.ZBP<<5; - - if(!m_ctxt->ZBUF.ZMSK) - { - m_lm.FillRect(CRect(left, top, right, bottom), v.GetZ(), m_ctxt->ZBUF.PSM, ZBP, FBW); - } - - __declspec(align(16)) union {struct {short Rf, Gf, Bf, Af;}; UINT64 Cui64;}; - Cui64 = v.c; - - Rf = m_clamp[Rf]; - Gf = m_clamp[Gf]; - Bf = m_clamp[Bf]; - Af |= m_ctxt->FBA.FBA << 7; - - DWORD Cdw; - - if(m_ctxt->FRAME.PSM == PSM_PSMCT16 || m_ctxt->FRAME.PSM == PSM_PSMCT16S) - { - Cdw = ((DWORD)(Rf&0xf8) >> 3) - | ((DWORD)(Gf&0xf8) << 2) - | ((DWORD)(Bf&0xf8) << 7) - | ((DWORD)(Af&0x80) << 8); - } - else - { -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - __m128i r0 = _mm_load_si128((__m128i*)&Cui64); - Cdw = (DWORD)_mm_cvtsi128_si32(_mm_packus_epi16(r0, r0)); -#else - Cdw = ((DWORD)(Rf&0xff) << 0) - | ((DWORD)(Gf&0xff) << 8) - | ((DWORD)(Bf&0xff) << 16) - | ((DWORD)(Af&0xff) << 24); -#endif - } - - m_lm.FillRect(CRect(left, top, right, bottom), Cdw, m_ctxt->FRAME.PSM, FBP, FBW); - - return true; -} - -template -template -void GSRendererSoft::DrawVertex(const Vertex& v) -{ - DWORD vz; - - switch(iZTST) - { - case 0: return; - case 1: break; - case 2: vz = v.GetZ(); if(vz < (m_lm.*m_ctxt->ztbl->rpa)(m_zaddr)) return; break; - case 3: vz = v.GetZ(); if(vz <= (m_lm.*m_ctxt->ztbl->rpa)(m_zaddr)) return; break; - default: __assume(0); - } - - union - { - struct {Vertex::Vector Cf, Cd, Ca;}; - struct {Vertex::Vector Cfda[3];}; - }; - - Cf = v.c; - - if(m_pPRIM->TME) - { - (this->*m_pDrawVertexTFX)(Cf, v); - } - - if(m_pPRIM->FGE) - { - Vertex::Scalar a = Cf.a; - Vertex::Vector Cfog((DWORD)m_de.FOGCOL.ai32[0]); - Cf = Cfog + (Cf - Cfog) * v.t.z; - Cf.a = a; - } - - BOOL ZMSK = m_ctxt->ZBUF.ZMSK; - DWORD FBMSK = m_ctxt->FRAME.FBMSK; - - bool fAlphaPass = true; - - BYTE Af = (BYTE)(int)Cf.a; - - switch(iATST) - { - case 0: fAlphaPass = false; break; - case 1: fAlphaPass = true; break; - case 2: fAlphaPass = Af < m_ctxt->TEST.AREF; break; - case 3: fAlphaPass = Af <= m_ctxt->TEST.AREF; break; - case 4: fAlphaPass = Af == m_ctxt->TEST.AREF; break; - case 5: fAlphaPass = Af >= m_ctxt->TEST.AREF; break; - case 6: fAlphaPass = Af > m_ctxt->TEST.AREF; break; - case 7: fAlphaPass = Af != m_ctxt->TEST.AREF; break; - default: __assume(0); - } - - if(!fAlphaPass) - { - switch(m_ctxt->TEST.AFAIL) - { - case 0: return; - case 1: ZMSK = 1; break; // RGBA - case 2: FBMSK = 0xffffffff; break; // Z - case 3: FBMSK = 0xff000000; ZMSK = 1; break; // RGB - default: __assume(0); - } - } - - if(!ZMSK) - { - if(iZTST != 2 && iZTST != 3) vz = v.GetZ(); - (m_lm.*m_ctxt->ztbl->wpa)(m_zaddr, vz); - } - - if(FBMSK != ~0) - { - if(m_ctxt->TEST.DATE && m_ctxt->FRAME.PSM <= PSM_PSMCT16S && m_ctxt->FRAME.PSM != PSM_PSMCT24) - { - BYTE A = (BYTE)((m_lm.*m_ctxt->ftbl->rpa)(m_faddr) >> (m_ctxt->FRAME.PSM == PSM_PSMCT32 ? 31 : 15)); - if(A ^ m_ctxt->TEST.DATM) return; - } - - // FIXME: for AA1 the value of Af should be calculated from the pixel coverage... - - bool fABE = (m_pPRIM->ABE || m_pPRIM->AA1 && (m_pPRIM->PRIM == 1 || m_pPRIM->PRIM == 2)) && (!m_de.PABE.PABE || (int)Cf.a >= 0x80); - - if(FBMSK || fABE) - { - GIFRegTEXA TEXA; - /* - TEXA.AEM = 0; - TEXA.TA0 = 0; - TEXA.TA1 = 0x80; - */ - TEXA.ai32[0] = 0; - TEXA.ai32[1] = 0x80; - Cd = (m_lm.*m_ctxt->ftbl->rta)(m_faddr, m_ctxt->TEX0, TEXA); - } - - if(fABE) - { - Ca = Vertex::Vector(Vertex::Scalar(0)); - Ca.a = Vertex::Scalar((int)m_ctxt->ALPHA.FIX); - - Vertex::Scalar a = Cf.a; - Cf = ((Cfda[m_ctxt->ALPHA.A] - Cfda[m_ctxt->ALPHA.B]) * Cfda[m_ctxt->ALPHA.C].a >> 7) + Cfda[m_ctxt->ALPHA.D]; - Cf.a = a; - } - - DWORD Cdw; - - if(m_de.COLCLAMP.CLAMP && !m_de.DTHE.DTHE) - { - Cdw = Cf; - } - else - { - __declspec(align(16)) union {struct {short Rf, Gf, Bf, Af;}; UINT64 Cui64;}; - Cui64 = Cf; - - if(m_de.DTHE.DTHE) - { - short DMxy = (signed char)((*((WORD*)&m_de.DIMX.i64 + (m_fy&3)) >> ((m_fx&3)<<2)) << 5) >> 5; - Rf = (short)(Rf + DMxy); - Gf = (short)(Gf + DMxy); - Bf = (short)(Bf + DMxy); - } - - Rf = m_clamp[Rf]; - Gf = m_clamp[Gf]; - Bf = m_clamp[Bf]; - Af |= m_ctxt->FBA.FBA << 7; - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - __m128i r0 = _mm_load_si128((__m128i*)&Cui64); - Cdw = (DWORD)_mm_cvtsi128_si32(_mm_packus_epi16(r0, r0)); -#else - Cdw = ((DWORD)(Rf&0xff) << 0) - | ((DWORD)(Gf&0xff) << 8) - | ((DWORD)(Bf&0xff) << 16) - | ((DWORD)(Af&0xff) << 24); -#endif - } - - if(FBMSK != 0) - { - Cdw = (Cdw & ~FBMSK) | ((DWORD)Cd & FBMSK); - } - - (m_lm.*m_ctxt->ftbl->wfa)(m_faddr, Cdw); - } -} - -static const float one_over_log2 = 1.0f / log(2.0f); - -template -template -void GSRendererSoft::DrawVertexTFX(typename Vertex::Vector& Cf, const Vertex& v) -{ - ASSERT(m_pPRIM->TME); - - Vertex::Vector t = v.t; - - bool fBiLinear = iLOD == 2; - - if(iLOD == 3) - { - fBiLinear = bLCM; - } - else - { - t.q.rcp(); - t *= t.q; - - if(iLOD == 1) - { - float lod = (float)(int)m_ctxt->TEX1.K; - if(!bLCM) lod += log(fabs((float)t.q)) * one_over_log2 * (1 << m_ctxt->TEX1.L); - fBiLinear = lod <= 0 && (m_ctxt->TEX1.MMAG & 1) || lod > 0 && (m_ctxt->TEX1.MMIN & 1); - } - } - - if(fBiLinear) t -= Vertex::Scalar(0.5f); - - __declspec(align(16)) short ituv[8] = - { - (short)(int)t.x, - (short)(int)t.x+1, - (short)(int)t.y, - (short)(int)t.y+1 - }; - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - - __m128i uv = _mm_load_si128((__m128i*)ituv); - __m128i mask = _mm_load_si128((__m128i*)m_uv->mask); - __m128i region = _mm_or_si128(_mm_and_si128(uv, *(__m128i*)m_uv->and), *(__m128i*)m_uv->or); - __m128i clamp = _mm_min_epi16(_mm_max_epi16(uv, *(__m128i*)m_uv->min), *(__m128i*)m_uv->max); - _mm_store_si128((__m128i*)ituv, _mm_or_si128(_mm_and_si128(region, mask), _mm_andnot_si128(mask, clamp))); - -#else - - for(int i = 0; i < 4; i++) - { - short region = (ituv[i] & m_uv->and[i]) | m_uv->or[i]; - short clamp = ituv[i] < m_uv->min[i] ? m_uv->min[i] : ituv[i] > m_uv->max[i] ? m_uv->max[i] : ituv[i]; - ituv[i] = (region & m_uv->mask[i]) | (clamp & ~m_uv->mask[i]); - } - -#endif - - Vertex::Vector Ct[4]; - - if(fBiLinear) - { - if(0 && m_pTexture) - { - Ct[0] = m_pTexture[(ituv[2] << m_ctxt->TEX0.TW) + ituv[0]]; - Ct[1] = m_pTexture[(ituv[2] << m_ctxt->TEX0.TW) + ituv[1]]; - Ct[2] = m_pTexture[(ituv[3] << m_ctxt->TEX0.TW) + ituv[0]]; - Ct[3] = m_pTexture[(ituv[3] << m_ctxt->TEX0.TW) + ituv[1]]; - } - else - { - Ct[0] = (m_lm.*m_ctxt->ttbl->rt)(ituv[0], ituv[2], m_ctxt->TEX0, m_de.TEXA); - Ct[1] = (m_lm.*m_ctxt->ttbl->rt)(ituv[1], ituv[2], m_ctxt->TEX0, m_de.TEXA); - Ct[2] = (m_lm.*m_ctxt->ttbl->rt)(ituv[0], ituv[3], m_ctxt->TEX0, m_de.TEXA); - Ct[3] = (m_lm.*m_ctxt->ttbl->rt)(ituv[1], ituv[3], m_ctxt->TEX0, m_de.TEXA); - } - - Vertex::Vector ft = t - t.floor(); - - Ct[0] = Ct[0] + (Ct[1] - Ct[0]) * ft.x; - Ct[2] = Ct[2] + (Ct[3] - Ct[2]) * ft.x; - Ct[0] = Ct[0] + (Ct[2] - Ct[0]) * ft.y; - } - else - { - if(0 && m_pTexture) - { - Ct[0] = m_pTexture[(ituv[2] << m_ctxt->TEX0.TW) + ituv[0]]; - } - else - { - Ct[0] = (m_lm.*m_ctxt->ttbl->rt)(ituv[0], ituv[2], m_ctxt->TEX0, m_de.TEXA); - } - } - - Vertex::Scalar a = Cf.a; - - switch(iTFX) - { - case 0: - Cf = (Cf * Ct[0] >> 7); - if(!bTCC) Cf.a = a; - break; - case 1: - Cf = Ct[0]; - break; - case 2: - Cf = (Cf * Ct[0] >> 7) + Cf.a; - Cf.a = !bTCC ? a : (Ct[0].a + a); - break; - case 3: - Cf = (Cf * Ct[0] >> 7) + Cf.a; - Cf.a = !bTCC ? a : Ct[0].a; - break; - default: - __assume(0); - } - - Cf.sat(); -} - -template -void GSRendererSoft::SetupTexture() -{ - if(!m_pPRIM->TME) return; - - m_lm.SetupCLUT32(m_ctxt->TEX0, m_de.TEXA); - - // - - int tw = 1 << m_ctxt->TEX0.TW; - int th = 1 << m_ctxt->TEX0.TH; - - switch(m_ctxt->CLAMP.WMS) - { - case 0: m_uv->and[0] = (short)(tw-1); m_uv->or[0] = 0; m_uv->mask[0] = 0xffff; break; - case 1: m_uv->min[0] = 0; m_uv->max[0] = (short)(tw-1); m_uv->mask[0] = 0; break; - case 2: m_uv->min[0] = (short)m_ctxt->CLAMP.MINU; m_uv->max[0] = (short)m_ctxt->CLAMP.MAXU; m_uv->mask[0] = 0; break; - case 3: m_uv->and[0] = (short)m_ctxt->CLAMP.MINU; m_uv->or[0] = (short)m_ctxt->CLAMP.MAXU; m_uv->mask[0] = 0xffff; break; - default: __assume(0); - } - - m_uv->and[1] = m_uv->and[0]; - m_uv->or[1] = m_uv->or[0]; - m_uv->min[1] = m_uv->min[0]; - m_uv->max[1] = m_uv->max[0]; - m_uv->mask[1] = m_uv->mask[0]; - - switch(m_ctxt->CLAMP.WMT) - { - case 0: m_uv->and[2] = (short)(th-1); m_uv->or[2] = 0; m_uv->mask[2] = 0xffff; break; - case 1: m_uv->min[2] = 0; m_uv->max[2] = (short)(th-1); m_uv->mask[2] = 0; break; - case 2: m_uv->min[2] = (short)m_ctxt->CLAMP.MINV; m_uv->max[2] = (short)m_ctxt->CLAMP.MAXV; m_uv->mask[2] = 0; break; - case 3: m_uv->and[2] = (short)m_ctxt->CLAMP.MINV; m_uv->or[2] = (short)m_ctxt->CLAMP.MAXV; m_uv->mask[2] = 0xffff; break; - default: __assume(0); - } - - m_uv->and[3] = m_uv->and[2]; - m_uv->or[3] = m_uv->or[2]; - m_uv->min[3] = m_uv->min[2]; - m_uv->max[3] = m_uv->max[2]; - m_uv->mask[3] = m_uv->mask[2]; -} - -// -// GSRendererSoftFP -// - -GSRendererSoftFP::GSRendererSoftFP(HWND hWnd, HRESULT& hr) - : GSRendererSoft(hWnd, hr) -{ -} - -void GSRendererSoftFP::VertexKick(bool fSkip) -{ - GSSoftVertexFP& v = m_vl.AddTail(); - - v.c = (DWORD)m_v.RGBAQ.ai32[0]; - - v.p.x = (int)m_v.XYZ.X - (int)m_ctxt->XYOFFSET.OFX; - v.p.y = (int)m_v.XYZ.Y - (int)m_ctxt->XYOFFSET.OFY; - v.p *= GSSoftVertexFP::Scalar(1.0f/16); - v.p.z = (float)(m_v.XYZ.Z >> 16); - v.p.q = (float)(m_v.XYZ.Z & 0xffff); - - if(m_pPRIM->TME) - { - if(m_pPRIM->FST) - { - v.t.x = (float)(int)m_v.UV.U; - v.t.y = (float)(int)m_v.UV.V; - v.t *= GSSoftVertexFP::Scalar(1.0f/16); - v.t.q = 1.0f; - } - else - { - v.t.x = m_v.ST.S * (1 << m_ctxt->TEX0.TW); - v.t.y = m_v.ST.T * (1 << m_ctxt->TEX0.TH); - v.t.q = m_v.RGBAQ.Q; - } - } - - if(m_pPRIM->FGE) - { - v.t.z = (float)m_v.FOG.F * (1.0f/255); - } - - __super::VertexKick(fSkip); -} -/* -// -// GSRendererSoftFX -// - -GSRendererSoftFX::GSRendererSoftFX(HWND hWnd, HRESULT& hr) - : GSRendererSoft(hWnd, hr) -{ -} - -void GSRendererSoftFX::VertexKick(bool fSkip) -{ - GSSoftVertexFX& v = m_vl.AddTail(); - - v.c = (DWORD)m_v.RGBAQ.ai32[0]; - - v.p.x = ((int)m_v.XYZ.X - (int)m_ctxt->XYOFFSET.OFX) << 12; - v.p.y = ((int)m_v.XYZ.Y - (int)m_ctxt->XYOFFSET.OFY) << 12; - v.p.z = (int)((m_v.XYZ.Z & 0xffff0000) >> 1); - v.p.q = (int)((m_v.XYZ.Z & 0x0000ffff) << 15); - - if(m_pPRIM->TME) - { - if(m_pPRIM->FST) - { - v.t.x = ((int)m_v.UV.U << (12 >> m_ctxt->TEX0.TW)); - v.t.y = ((int)m_v.UV.V << (12 >> m_ctxt->TEX0.TH)); - v.t.q = 1<<16; - } - else - { - // TODO - v.t.x = m_v.ST.S; - v.t.y = m_v.ST.T; - v.t.q = m_v.RGBAQ.Q; - } - } - - if(m_pPRIM->FGE) - { - v.t.z = (int)m_v.FOG.F << 8; - } - - __super::VertexKick(fSkip); -} -*/ \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSRendererSoft.h b/plugins/gs/gsdx9/GSRendererSoft.h deleted file mode 100644 index 978258ca8a..0000000000 --- a/plugins/gs/gsdx9/GSRendererSoft.h +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "GSRenderer.h" - -template -class GSRendererSoft : public GSRenderer -{ -protected: - void Reset(); - int DrawingKick(bool fSkip); - void FlushPrim(); - void Flip(); - void EndFrame(); - - enum {PRIM_NONE, PRIM_SPRITE, PRIM_TRIANGLE, PRIM_LINE, PRIM_POINT} m_primtype; - - DWORD m_faddr_x0, m_faddr; - DWORD m_zaddr_x0, m_zaddr; - int* m_faddr_ro; - int* m_zaddr_ro; - int m_fx, m_fy; - void RowInit(int x, int y); - void RowStep(); - - void DrawPoint(Vertex* v); - void DrawLine(Vertex* v); - void DrawTriangle(Vertex* v); - void DrawSprite(Vertex* v); - bool DrawFilledRect(int left, int top, int right, int bottom, const Vertex& v); - - template - void DrawVertex(const Vertex& v); - - typedef void (GSRendererSoft::*DrawVertexPtr)(const Vertex& v); - DrawVertexPtr m_dv[4][8], m_pDrawVertex; - - template - void DrawVertexTFX(typename Vertex::Vector& Cf, const Vertex& v); - - typedef void (GSRendererSoft::*DrawVertexTFXPtr)(typename Vertex::Vector& Cf, const Vertex& v); - DrawVertexTFXPtr m_dvtfx[4][2][2][4], m_pDrawVertexTFX; - - CComPtr m_pRT[2]; - - DWORD* m_pTexture; - void SetupTexture(); - - struct uv_wrap_t {union {struct {short min[8], max[8];}; struct {short and[8], or[8];};}; unsigned short mask[8];}* m_uv; - - CRect m_scissor; - BYTE m_clip[65536]; - BYTE m_mask[65536]; - BYTE* m_clamp; - -public: - GSRendererSoft(HWND hWnd, HRESULT& hr); - ~GSRendererSoft(); - - HRESULT ResetDevice(bool fForceWindowed = false); - - void LOGVERTEX(Vertex& v, LPCTSTR type) - { - int tw = 1, th = 1; - if(m_de.PRIM.TME) {tw = 1<TEX0.TW; th = 1<TEX0.TH;} - LOG2(_T("- %s (%.2f, %.2f, %.2f, %.2f) (%08x) (%.3f, %.3f) (%.2f, %.2f)\n"), - type, - (float)v.p.x, (float)v.p.y, (float)v.p.z / UINT_MAX, (float)v.t.q, - (DWORD)v.c, - (float)v.t.x/tw, (float)v.t.y/th, (float)v.t.x, (float)v.t.y); - } -}; - -class GSRendererSoftFP : public GSRendererSoft -{ -protected: - void VertexKick(bool fSkip); - -public: - GSRendererSoftFP(HWND hWnd, HRESULT& hr); -}; -/* -class GSRendererSoftFX : public GSRendererSoft -{ -protected: - void VertexKick(bool fSkip); - //void DrawVertex(int x, int y, GSSoftVertexFX& v); - -public: - GSRendererSoftFX(HWND hWnd, HRESULT& hr); -}; -*/ \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSSettingsDlg.cpp b/plugins/gs/gsdx9/GSSettingsDlg.cpp deleted file mode 100644 index dad31f3424..0000000000 --- a/plugins/gs/gsdx9/GSSettingsDlg.cpp +++ /dev/null @@ -1,239 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" -#include "GSdx9.h" -#include "GSSettingsDlg.h" -#include - -static struct {int id; const TCHAR* name;} s_renderers[] = -{ - {RENDERER_D3D_HW, "Direct3D"}, - // {RENDERER_D3D_SW_FX, "Software (fixed)"}, - {RENDERER_D3D_SW_FP, "Software (float)"}, - {RENDERER_D3D_NULL, "Do not render"}, -}; - -static struct {DWORD id; const TCHAR* name;} s_psversions[] = -{ - {D3DPS_VERSION(3, 0), _T("Pixel Shader 3.0")}, - {D3DPS_VERSION(2, 0), _T("Pixel Shader 2.0")}, - {D3DPS_VERSION(1, 4), _T("Pixel Shader 1.4")}, - {D3DPS_VERSION(1, 1), _T("Pixel Shader 1.1")}, - {D3DPS_VERSION(0, 0), _T("Fixed Pipeline (bogus)")}, -}; - -IMPLEMENT_DYNAMIC(CGSSettingsDlg, CDialog) -CGSSettingsDlg::CGSSettingsDlg(CWnd* pParent /*=NULL*/) - : CDialog(CGSSettingsDlg::IDD, pParent) - , m_fEnablePalettizedTextures(FALSE) - , m_fEnableTvOut(FALSE) - , m_fNloopHack(FALSE) - , m_fRecordState(FALSE) - , m_fLinearTexFilter(TRUE) -{ -} - -CGSSettingsDlg::~CGSSettingsDlg() -{ -} - -void CGSSettingsDlg::DoDataExchange(CDataExchange* pDX) -{ - CDialog::DoDataExchange(pDX); - DDX_Control(pDX, IDC_COMBO3, m_resolution); - DDX_Control(pDX, IDC_COMBO1, m_renderer); - DDX_Control(pDX, IDC_COMBO4, m_psversion); - DDX_Check(pDX, IDC_CHECK1, m_fEnablePalettizedTextures); - DDX_Check(pDX, IDC_CHECK3, m_fEnableTvOut); - DDX_Check(pDX, IDC_CHECK2, m_fRecordState); - DDX_Check(pDX, IDC_CHECK5, m_fNloopHack); - DDX_Text(pDX, IDC_EDIT1, m_strRecordState); - DDX_Check(pDX, IDC_CHECK4, m_fLinearTexFilter); -} - -BEGIN_MESSAGE_MAP(CGSSettingsDlg, CDialog) - ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1) -END_MESSAGE_MAP() - -// CGSSettingsDlg message handlers - -BOOL CGSSettingsDlg::OnInitDialog() -{ - __super::OnInitDialog(); - - CWinApp* pApp = AfxGetApp(); - - D3DCAPS9 caps; - ZeroMemory(&caps, sizeof(caps)); - caps.PixelShaderVersion = D3DPS_VERSION(0, 0); - - m_modes.RemoveAll(); - - // windowed - - { - D3DDISPLAYMODE mode; - memset(&mode, 0, sizeof(mode)); - m_modes.AddTail(mode); - - int iItem = m_resolution.AddString(_T("Windowed")); - m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition()); - m_resolution.SetCurSel(iItem); - } - - // fullscreen - - if(CComPtr pD3D = Direct3DCreate9(D3D_SDK_VERSION)) - { - int ModeWidth = pApp->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0); - int ModeHeight = pApp->GetProfileInt(_T("Settings"), _T("ModeHeight"), 0); - int ModeRefreshRate = pApp->GetProfileInt(_T("Settings"), _T("ModeRefreshRate"), 0); - - UINT nModes = pD3D->GetAdapterModeCount(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8); - for(UINT i = 0; i < nModes; i++) - { - D3DDISPLAYMODE mode; - if(S_OK == pD3D->EnumAdapterModes(D3DADAPTER_DEFAULT, D3DFMT_X8R8G8B8, i, &mode)) - { - CString str; - str.Format(_T("%dx%d %dHz"), mode.Width, mode.Height, mode.RefreshRate); - int iItem = m_resolution.AddString(str); - - m_modes.AddTail(mode); - m_resolution.SetItemDataPtr(iItem, m_modes.GetTailPosition()); - - if(ModeWidth == mode.Width && ModeHeight == mode.Height && ModeRefreshRate == mode.RefreshRate) - m_resolution.SetCurSel(iItem); - } - } - - pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, &caps); - } - - // renderer - - int renderer_id = pApp->GetProfileInt(_T("Settings"), _T("Renderer"), RENDERER_D3D_HW); - - for(int i = 0; i < countof(s_renderers); i++) - { - int iItem = m_renderer.AddString(s_renderers[i].name); - m_renderer.SetItemData(iItem, s_renderers[i].id); - if(s_renderers[i].id == renderer_id) m_renderer.SetCurSel(iItem); - } - - // shader - - DWORD psversion_id = pApp->GetProfileInt(_T("Settings"), _T("PixelShaderVersion2"), D3DPS_VERSION(2, 0)); - - for(int i = 0; i < countof(s_psversions); i++) - { - if(s_psversions[i].id > caps.PixelShaderVersion) continue; - int iItem = m_psversion.AddString(s_psversions[i].name); - m_psversion.SetItemData(iItem, s_psversions[i].id); - if(s_psversions[i].id == psversion_id) m_psversion.SetCurSel(iItem); - } - - // - - m_fEnablePalettizedTextures = pApp->GetProfileInt(_T("Settings"), _T("fEnablePalettizedTextures"), FALSE); - - // - - m_fLinearTexFilter = (D3DTEXTUREFILTERTYPE)pApp->GetProfileInt(_T("Settings"), _T("TexFilter"), D3DTEXF_LINEAR) == D3DTEXF_LINEAR; - - // - - m_fEnableTvOut = pApp->GetProfileInt(_T("Settings"), _T("fEnableTvOut"), FALSE); - - // - m_fNloopHack = pApp->GetProfileInt(_T("Settings"), _T("fNloopHack"), FALSE); - - // - m_fRecordState = pApp->GetProfileInt(_T("Settings"), _T("RecordState"), FALSE); - m_strRecordState = pApp->GetProfileString(_T("Settings"), _T("RecordStatePath"), _T("")); - - // - - UpdateData(FALSE); - - return TRUE; // return TRUE unless you set the focus to a control - // EXCEPTION: OCX Property Pages should return FALSE -} - -void CGSSettingsDlg::OnOK() -{ - CWinApp* pApp = AfxGetApp(); - - UpdateData(); - - if(m_resolution.GetCurSel() >= 0) - { - D3DDISPLAYMODE& mode = m_modes.GetAt((POSITION)m_resolution.GetItemData(m_resolution.GetCurSel())); - pApp->WriteProfileInt(_T("Settings"), _T("ModeWidth"), mode.Width); - pApp->WriteProfileInt(_T("Settings"), _T("ModeHeight"), mode.Height); - pApp->WriteProfileInt(_T("Settings"), _T("ModeRefreshRate"), mode.RefreshRate); - } - - if(m_renderer.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("Settings"), _T("Renderer"), m_renderer.GetItemData(m_renderer.GetCurSel())); - } - - if(m_psversion.GetCurSel() >= 0) - { - pApp->WriteProfileInt(_T("Settings"), _T("PixelShaderVersion2"), m_psversion.GetItemData(m_psversion.GetCurSel())); - } - - pApp->WriteProfileInt(_T("Settings"), _T("fEnablePalettizedTextures"), m_fEnablePalettizedTextures); - - pApp->WriteProfileInt(_T("Settings"), _T("TexFilter"), m_fLinearTexFilter ? D3DTEXF_LINEAR : D3DTEXF_POINT); - - pApp->WriteProfileInt(_T("Settings"), _T("fEnableTvOut"), m_fEnableTvOut); - pApp->WriteProfileInt(_T("Settings"), _T("fNloopHack"), m_fNloopHack); - pApp->WriteProfileInt(_T("Settings"), _T("RecordState"), m_fRecordState); - pApp->WriteProfileString(_T("Settings"), _T("RecordStatePath"), m_strRecordState); - - __super::OnOK(); -} - -void CGSSettingsDlg::OnBnClickedButton1() -{ - TCHAR path[MAX_PATH]; - - BROWSEINFO bi; - bi.hwndOwner = m_hWnd; - bi.pidlRoot = NULL; - bi.pszDisplayName = path; - bi.lpszTitle = _T("Select path for the state file"); - bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_VALIDATE | BIF_USENEWUI; - bi.lpfn = NULL; - bi.lParam = 0; - bi.iImage = 0; - - LPITEMIDLIST iil; - if(iil = SHBrowseForFolder(&bi)) - { - SHGetPathFromIDList(iil, path); - m_strRecordState = path; - UpdateData(FALSE); - } -} diff --git a/plugins/gs/gsdx9/GSSettingsDlg.h b/plugins/gs/gsdx9/GSSettingsDlg.h deleted file mode 100644 index d310cb10e6..0000000000 --- a/plugins/gs/gsdx9/GSSettingsDlg.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "resource.h" -#include "afxwin.h" - -class CGSSettingsDlg : public CDialog -{ - DECLARE_DYNAMIC(CGSSettingsDlg) - -private: - CList m_modes; - -public: - CGSSettingsDlg(CWnd* pParent = NULL); // standard constructor - virtual ~CGSSettingsDlg(); - -// Dialog Data - enum { IDD = IDD_CONFIG }; - CComboBox m_resolution; - CComboBox m_renderer; - CComboBox m_psversion; - BOOL m_fEnablePalettizedTextures; - BOOL m_fEnableTvOut; - BOOL m_fRecordState; - BOOL m_fNloopHack; - CString m_strRecordState; - BOOL m_fLinearTexFilter; - -protected: - virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support - virtual BOOL OnInitDialog(); - virtual void OnOK(); - - DECLARE_MESSAGE_MAP() -public: - afx_msg void OnBnClickedButton1(); -}; diff --git a/plugins/gs/gsdx9/GSSoftVertex.cpp b/plugins/gs/gsdx9/GSSoftVertex.cpp deleted file mode 100644 index 7fa406e44c..0000000000 --- a/plugins/gs/gsdx9/GSSoftVertex.cpp +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSSoftVertex.h" - -const __m128i _80000000 = _mm_set1_epi32(0x80000000); -const __m128i _4b000000 = _mm_set1_epi32(0x4b000000); -const __m128i _3f800000 = _mm_set1_epi32(0x3f800000); diff --git a/plugins/gs/gsdx9/GSSoftVertex.h b/plugins/gs/gsdx9/GSSoftVertex.h deleted file mode 100644 index e505a4c38d..0000000000 --- a/plugins/gs/gsdx9/GSSoftVertex.h +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -// -// GSSoftVertexFP -// - -extern const __m128i _80000000, _4b000000, _3f800000; - -__declspec(align(16)) union GSSoftVertexFP -{ - class __declspec(novtable) Scalar - { - float val; - - public: - Scalar() {} - explicit Scalar(float f) {val = f;} - explicit Scalar(int i) {val = (float)i;} - - float Value() const {return val;} - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - void sat() {_mm_store_ss(&val, _mm_min_ss(_mm_max_ss(_mm_set_ss(val), _mm_setzero_ps()), _mm_set_ss(255)));} - void rcp() {_mm_store_ss(&val, _mm_rcp_ss(_mm_set_ss(val)));} -#else - void sat() {val = val < 0 ? 0 : val > 255 ? 255 : val;} - void rcp() {val = 1.0f / val;} -#endif - void abs() {val = fabs(val);} - - Scalar floor_s() const {return Scalar(floor(val));} - int floor_i() const {return (int)floor(val);} - - Scalar ceil_s() const {return Scalar(-floor(-val));} - int ceil_i() const {return -(int)floor(-val);} - - void operator = (float f) {val = f;} - void operator = (int i) {val = (float)i;} - - operator float() const {return val;} - operator int() const {return (int)val;} - - void operator += (const Scalar& s) {val += s.val;} - void operator -= (const Scalar& s) {val -= s.val;} - void operator *= (const Scalar& s) {val *= s.val;} - void operator /= (const Scalar& s) {val /= s.val;} - - friend Scalar operator + (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val + s2.val);} - friend Scalar operator - (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val - s2.val);} - friend Scalar operator * (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val * s2.val);} - friend Scalar operator / (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val / s2.val);} - - friend Scalar operator + (const Scalar& s, int i) {return Scalar(s.val + i);} - friend Scalar operator - (const Scalar& s, int i) {return Scalar(s.val - i);} - friend Scalar operator * (const Scalar& s, int i) {return Scalar(s.val * i);} - friend Scalar operator / (const Scalar& s, int i) {return Scalar(s.val / i);} - - friend Scalar operator << (const Scalar& s, int i) {return Scalar(s.val * (1<> (const Scalar& s, int i) {return Scalar(s.val / (1<= 2 || defined(_M_AMD64) - union {__m128 xyzq; __m128 rgba;}; -#endif - }; - - Vector() {} - Vector(const Vector& v) {*this = v;} - Vector(Scalar s) {*this = s;} - Vector(Scalar s0, Scalar s1, Scalar s2, Scalar s3) {x = s0; y = s1; z = s2; q = s3;} - explicit Vector(DWORD dw) {*this = dw;} -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - Vector(__m128 f0123) {*this = f0123;} -#endif - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - - void operator = (const Vector& v) {xyzq = v.xyzq;} - void operator = (Scalar s) {xyzq = _mm_set1_ps(s);} - - void operator = (__m128 f0123) {xyzq = f0123;} - operator __m128() const {return xyzq;} - - void operator = (DWORD dw) {__m128i zero = _mm_setzero_si128(); xyzq = _mm_cvtepi32_ps(_mm_unpacklo_epi16(_mm_unpacklo_epi8(_mm_cvtsi32_si128(dw), zero), zero));} - operator DWORD() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); r0 = _mm_packus_epi16(r0, r0); return (DWORD)_mm_cvtsi128_si32(r0);} - operator UINT64() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); return *(UINT64*)&r0;} - - void sat() {xyzq = _mm_min_ps(_mm_max_ps(xyzq, _mm_setzero_ps()), _mm_set1_ps(255));} - void rcp() {xyzq = _mm_rcp_ps(xyzq);} - - Vector floor() - { - __m128 sign = _mm_and_ps(xyzq, *(__m128*)&_80000000); - __m128 r0 = _mm_or_ps(sign, *(__m128*)&_4b000000); - __m128 r1 = _mm_sub_ps(_mm_add_ps(xyzq, r0), r0); - __m128 r2 = _mm_sub_ps(r1, xyzq); - __m128 r3 = _mm_and_ps(_mm_cmpnle_ps(r2, sign), *(__m128*)&_3f800000); - __m128 r4 = _mm_sub_ps(r1, r3); - return r4; - } - - void operator += (const Vector& v) {xyzq = _mm_add_ps(xyzq, v);} - void operator -= (const Vector& v) {xyzq = _mm_sub_ps(xyzq, v);} - void operator *= (const Vector& v) {xyzq = _mm_mul_ps(xyzq, v);} - void operator /= (const Vector& v) {xyzq = _mm_div_ps(xyzq, v);} - -#else - - void operator = (const Vector& v) {x = v.x; y = v.y; z = v.z; q = v.q;} - void operator = (Scalar s) {x = y = z = q = s;} - - void operator = (DWORD dw) - { - x = Scalar((int)((dw>>0)&0xff)); - y = Scalar((int)((dw>>8)&0xff)); - z = Scalar((int)((dw>>16)&0xff)); - q = Scalar((int)((dw>>24)&0xff)); - } - - operator DWORD() const - { - return (DWORD)( - (((DWORD)(int)x&0xff)<<0) | - (((DWORD)(int)y&0xff)<<8) | - (((DWORD)(int)z&0xff)<<16) | - (((DWORD)(int)q&0xff)<<24)); - } - - operator UINT64() const - { - return (DWORD)( - (((UINT64)(int)x&0xffff)<<0) | - (((UINT64)(int)y&0xffff)<<16) | - (((UINT64)(int)z&0xffff)<<32) | - (((UINT64)(int)q&0xffff)<<48)); - } - - void sat() {x.sat(); y.sat(); z.sat(); q.sat();} - void rcp() {x.rcp(); y.rcp(); z.rcp(); q.rcp();} - - Vector floor() {return Vector(x.floor_s(), y.floor_s(), z.floor_s(), q.floor_s());} - - void operator += (const Vector& v) {*this = *this + v;} - void operator -= (const Vector& v) {*this = *this - v;} - void operator *= (const Vector& v) {*this = *this * v;} - void operator /= (const Vector& v) {*this = *this / v;} - -#endif - - friend Vector operator + (const Vector& v1, const Vector& v2); - friend Vector operator - (const Vector& v1, const Vector& v2); - friend Vector operator * (const Vector& v1, const Vector& v2); - friend Vector operator / (const Vector& v1, const Vector& v2); - - friend Vector operator + (const Vector& v, Scalar s); - friend Vector operator - (const Vector& v, Scalar s); - friend Vector operator * (const Vector& v, Scalar s); - friend Vector operator / (const Vector& v, Scalar s); - }; - - struct {__declspec(align(16)) Vector c, p, t;}; - struct {__declspec(align(16)) Vector sv[3];}; - struct {__declspec(align(16)) Scalar s[12];}; - - GSSoftVertexFP() {} - GSSoftVertexFP(const GSSoftVertexFP& v) {*this = v;} - - void operator = (const GSSoftVertexFP& v) {c = v.c; p = v.p; t = v.t;} - void operator += (const GSSoftVertexFP& v) {c += v.c; p += v.p; t += v.t;} - - operator CPoint() const {return CPoint((int)p.x, (int)p.y);} - - __forceinline DWORD GetZ() const - { - ASSERT((float)p.z >= 0 && (float)p.q >= 0); -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - __m128 z = _mm_shuffle_ps(p, p, _MM_SHUFFLE(2,2,2,2)); - __m128 q = _mm_shuffle_ps(p, p, _MM_SHUFFLE(3,3,3,3)); - // TODO: check if our floor is faster than doing ss->si->ss - int zh = _mm_cvttss_si32(z); - __m128 zhi = _mm_cvtsi32_ss(zhi, zh); - __m128 zhf = _mm_mul_ss(_mm_sub_ss(z, zhi), _mm_set_ss(65536)); - int zl = _mm_cvtss_si32(_mm_add_ss(zhf, q)); - return ((DWORD)zh << 16) + (DWORD)zl; -#else - // return ((DWORD)(int)p.z << 16) + (DWORD)(int)((p.z - p.z.floor_s())*65536 + p.q); - - int z = (int)p.z; - return ((DWORD)z << 16) + (DWORD)(((float)p.z - z)*65536 + (float)p.q); -#endif - } - -}; - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_add_ps(v1, v2));} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_sub_ps(v1, v2));} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_mul_ps(v1, v2));} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_div_ps(v1, v2));} - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_add_ps(v, _mm_set1_ps(s)));} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_sub_ps(v, _mm_set1_ps(s)));} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(s)));} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_div_ps(v, _mm_set1_ps(s)));} - -__forceinline GSSoftVertexFP::Vector operator << (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps((float)(1 << i))));} -__forceinline GSSoftVertexFP::Vector operator >> (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(1.0f / (1 << i))));} - -#else - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.q + v2.q);} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.q - v2.q);} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.q * v2.q);} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.q / v2.q);} - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x + s, v.y + s, v.z + s, v.q + s);} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x - s, v.y - s, v.z - s, v.q - s);} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x * s, v.y * s, v.z * s, v.q * s);} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x / s, v.y / s, v.z / s, v.q / s);} - -__forceinline GSSoftVertexFP::Vector operator << (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(v.x << i, v.y << i, v.z << i, v.q << i);} -__forceinline GSSoftVertexFP::Vector operator >> (const GSSoftVertexFP::Vector& v, int i) {return GSSoftVertexFP::Vector(v.x >> i, v.y >> i, v.z >> i, v.q >> i);} - -#endif - -// - -template -__forceinline Vertex operator + (const Vertex& v1, const Vertex& v2) -{ - Vertex v0; - v0.c = v1.c + v2.c; - v0.p = v1.p + v2.p; - v0.t = v1.t + v2.t; - return v0; -} - -template -__forceinline Vertex operator - (const Vertex& v1, const Vertex& v2) -{ - Vertex v0; - v0.c = v1.c - v2.c; - v0.p = v1.p - v2.p; - v0.t = v1.t - v2.t; - return v0; -} - -template -__forceinline Vertex operator * (const Vertex& v, typename Vertex::Scalar s) -{ - Vertex v0; - Vertex::Vector vs(s); - v0.c = v.c * vs; - v0.p = v.p * vs; - v0.t = v.t * vs; - return v0; -} - -template -__forceinline Vertex operator / (const Vertex& v, typename Vertex::Scalar s) -{ - Vertex v0; - Vertex::Vector vs(s); - v0.c = v.c / vs; - v0.p = v.p / vs; - v0.t = v.t / vs; - return v0; -} - -template -__forceinline void Exchange(Vertex* RESTRICT v1, Vertex* RESTRICT v2) -{ - typename Vertex::Vector c = v1->c, p = v1->p, t = v1->t; - v1->c = v2->c; v1->p = v2->p; v1->t = v2->t; - v2->c = c; v2->p = p; v2->t = t; -} diff --git a/plugins/gs/gsdx9/GSSoftVertexFP.h b/plugins/gs/gsdx9/GSSoftVertexFP.h deleted file mode 100644 index 10269456db..0000000000 --- a/plugins/gs/gsdx9/GSSoftVertexFP.h +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -// -// GSSoftVertexFP -// - -__declspec(align(16)) union GSSoftVertexFP -{ - class __declspec(novtable) Scalar - { - float val; - - public: - Scalar() {} - explicit Scalar(float f) {val = f;} - explicit Scalar(int i) {val = (float)i;} - - float Value() const {return val;} - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - void sat() {_mm_store_ss(&val, _mm_min_ss(_mm_max_ss(_mm_set_ss(val), _mm_setzero_ps()), _mm_set_ss(255)));} - void rcp() {_mm_store_ss(&val, _mm_rcp_ss(_mm_set_ss(val)));} -#else - void sat() {val = val < 0 ? 0 : val > 255 ? 255 : val;} - void rcp() {val = 1.0f / val;} -#endif - - void abss() {val = abs(val);} - - Scalar floors() const {return Scalar(floor(val));} - int floori() const {return (int)floor(val);} - - Scalar ceils() const {return Scalar(-floor(-val));} - int ceili() const {return -(int)floor(-val);} - - void operator = (float f) {val = f;} - void operator = (int i) {val = (float)i;} - - operator float() const {return val;} - operator int() const {return (int)val;} - - void operator += (const Scalar& s) {val += s.val;} - void operator -= (const Scalar& s) {val -= s.val;} - void operator *= (const Scalar& s) {val *= s.val;} - void operator /= (const Scalar& s) {val /= s.val;} - - friend Scalar operator + (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val + s2.val);} - friend Scalar operator - (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val - s2.val);} - friend Scalar operator * (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val * s2.val);} - friend Scalar operator / (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val / s2.val);} - - friend Scalar operator + (const Scalar& s1, int i) {return Scalar(s1.val + i);} - friend Scalar operator - (const Scalar& s1, int i) {return Scalar(s1.val - i);} - friend Scalar operator * (const Scalar& s1, int i) {return Scalar(s1.val * i);} - friend Scalar operator / (const Scalar& s1, int i) {return Scalar(s1.val / i);} - - friend bool operator == (const Scalar& s1, const Scalar& s2) {return s1.val == s2.val;} - friend bool operator <= (const Scalar& s1, const Scalar& s2) {return s1.val <= s2.val;} - friend bool operator < (const Scalar& s1, const Scalar& s2) {return s1.val < s2.val;} - }; - - __declspec(align(16)) class __declspec(novtable) Vector - { - public: - union - { - union {struct {Scalar x, y, z, q;}; struct {Scalar r, g, b, a;};}; - union {struct {Scalar v[4];}; struct {Scalar c[4];};}; -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - union {__m128 xyzq; __m128 rgba;}; -#endif - }; - - Vector() {} - Vector(const Vector& v) {*this = v;} - Vector(Scalar s) {*this = s;} - Vector(Scalar s0, Scalar s1, Scalar s2, Scalar s3) {x = s0; y = s1; z = s2; q = s3;} - explicit Vector(DWORD dw) {*this = dw;} -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - Vector(__m128 f0123) {*this = f0123;} -#endif - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - - void operator = (const Vector& v) {xyzq = v.xyzq;} - void operator = (__m128 f0123) {xyzq = f0123;} - void operator = (Scalar s) {xyzq = _mm_set1_ps(s);} - void operator = (DWORD dw) {__m128i zero = _mm_setzero_si128(); xyzq = _mm_cvtepi32_ps(_mm_unpacklo_epi16(_mm_unpacklo_epi8(_mm_cvtsi32_si128(dw), zero), zero));} - - operator __m128() const {return xyzq;} - operator DWORD() const {__m128i r0 = _mm_cvttps_epi32(xyzq); r0 = _mm_packs_epi32(r0, r0); r0 = _mm_packus_epi16(r0, r0); return (DWORD)_mm_cvtsi128_si32(r0);} - - void sat() {xyzq = _mm_min_ps(_mm_max_ps(xyzq, _mm_setzero_ps()), _mm_set1_ps(255));} - void rcp() {xyzq = _mm_rcp_ps(xyzq);} - - void operator += (const Vector& v) {xyzq = _mm_add_ps(xyzq, v);} - void operator -= (const Vector& v) {xyzq = _mm_sub_ps(xyzq, v);} - void operator *= (const Vector& v) {xyzq = _mm_mul_ps(xyzq, v);} - void operator /= (const Vector& v) {xyzq = _mm_div_ps(xyzq, v);} - -#else - - void operator = (const Vector& v) {x = v.x; y = v.y; z = v.z; q = v.q;} - void operator = (Scalar s) {x = y = z = q = s;} - void operator = (DWORD dw) - { - x = Scalar((int)(dw&0xff)); - y = Scalar((int)((dw>>8)&0xff)); - z = Scalar((int)((dw>>16)&0xff)); - q = Scalar((int)((dw>>24)&0xff)); - } - - operator DWORD() const - { - return (DWORD)((((DWORD)(int)x&0xff)<<0) | (((DWORD)(int)y&0xff)<<8) | (((DWORD)(int)z&0xff)<<16) | (((DWORD)(int)q&0xff)<<24)); - } - - void sat() {x.sat(); y.sat(); z.sat(); q.sat();} - void rcp() {x.rcp(); y.rcp(); z.rcp(); q.rcp();} - - void operator += (const Vector& v) {*this = *this + v;} - void operator -= (const Vector& v) {*this = *this - v;} - void operator *= (const Vector& v) {*this = *this * v;} - void operator /= (const Vector& v) {*this = *this / v;} - -#endif - - void absv() {x.abss(); y.abss(); z.abss(); q.abss();} - - friend Vector operator + (const Vector& v1, const Vector& v2); - friend Vector operator - (const Vector& v1, const Vector& v2); - friend Vector operator * (const Vector& v1, const Vector& v2); - friend Vector operator / (const Vector& v1, const Vector& v2); - - friend Vector operator + (const Vector& v, Scalar s); - friend Vector operator - (const Vector& v, Scalar s); - friend Vector operator * (const Vector& v, Scalar s); - friend Vector operator / (const Vector& v, Scalar s); - }; - - struct {__declspec(align(16)) Vector c, p, t;}; - struct {__declspec(align(16)) Vector sv[3];}; - struct {__declspec(align(16)) Scalar s[12];}; - - GSSoftVertexFP() {} - GSSoftVertexFP(const GSSoftVertexFP& v) {*this = v;} - - void operator = (const GSSoftVertexFP& v) {c = v.c; p = v.p; t = v.t;} - void operator += (const GSSoftVertexFP& v) {c += v.c; p += v.p; t += v.t;} - - operator CPoint() const {return CPoint((int)p.x, (int)p.y);} - - friend GSSoftVertexFP operator + (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2); - friend GSSoftVertexFP operator - (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2); - - friend GSSoftVertexFP operator * (const GSSoftVertexFP& v, Scalar s); - friend GSSoftVertexFP operator / (const GSSoftVertexFP& v, Scalar s); - - static void Exchange(GSSoftVertexFP* __restrict v1, GSSoftVertexFP* __restrict v2) - { - // GSSoftVertexFP v = *v1; *v1 = *v2; *v2 = v; - Vector c = v1->c, p = v1->p, t = v1->t; - v1->c = v2->c; v1->p = v2->p; v1->t = v2->t; - v2->c = c; v2->p = p; v2->t = t; - } - - //__forceinline DWORD GetZ() const {return ((DWORD)p.z<<16) + (DWORD)((p.z - floorf(p.z))*65536 + p.q);} - __forceinline DWORD GetZ() const - { - ASSERT((float)p.z >= 0 && (float)p.q >= 0); - int z = (int)p.z; - return ((DWORD)z << 16) + (DWORD)(((float)p.z - z)*65536 + (float)p.q); - } -}; - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_add_ps(v1, v2));} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_sub_ps(v1, v2));} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_mul_ps(v1, v2));} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(_mm_div_ps(v1, v2));} - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_add_ps(v, _mm_set1_ps(s)));} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_sub_ps(v, _mm_set1_ps(s)));} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_mul_ps(v, _mm_set1_ps(s)));} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(_mm_div_ps(v, _mm_set1_ps(s)));} - -#else - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.q + v2.q);} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.q - v2.q);} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.q * v2.q);} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v1, const GSSoftVertexFP::Vector& v2) {return GSSoftVertexFP::Vector(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.q / v2.q);} - -__forceinline GSSoftVertexFP::Vector operator + (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x + s, v.y + s, v.z + s, v.q + s);} -__forceinline GSSoftVertexFP::Vector operator - (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x - s, v.y - s, v.z - s, v.q - s);} -__forceinline GSSoftVertexFP::Vector operator * (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x * s, v.y * s, v.z * s, v.q * s);} -__forceinline GSSoftVertexFP::Vector operator / (const GSSoftVertexFP::Vector& v, GSSoftVertexFP::Scalar s) {return GSSoftVertexFP::Vector(v.x / s, v.y / s, v.z / s, v.q / s);} - -#endif - -__forceinline GSSoftVertexFP operator + (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2) -{ - GSSoftVertexFP v0; - v0.c = v1.c + v2.c; - v0.p = v1.p + v2.p; - v0.t = v1.t + v2.t; - return v0; -} - -__forceinline GSSoftVertexFP operator - (const GSSoftVertexFP& v1, const GSSoftVertexFP& v2) -{ - GSSoftVertexFP v0; - v0.c = v1.c - v2.c; - v0.p = v1.p - v2.p; - v0.t = v1.t - v2.t; - return v0; -} - -__forceinline GSSoftVertexFP operator * (const GSSoftVertexFP& v, GSSoftVertexFP::Scalar s) -{ - GSSoftVertexFP v0; - GSSoftVertexFP::Vector vs(s); - v0.c = v.c * vs; - v0.p = v.p * vs; - v0.t = v.t * vs; - return v0; -} - -__forceinline GSSoftVertexFP operator / (const GSSoftVertexFP& v, GSSoftVertexFP::Scalar s) -{ - GSSoftVertexFP v0; - GSSoftVertexFP::Vector vs(s); - v0.c = v.c / vs; - v0.p = v.p / vs; - v0.t = v.t / vs; - return v0; -} diff --git a/plugins/gs/gsdx9/GSSoftVertexFX.h b/plugins/gs/gsdx9/GSSoftVertexFX.h deleted file mode 100644 index b803426d9b..0000000000 --- a/plugins/gs/gsdx9/GSSoftVertexFX.h +++ /dev/null @@ -1,377 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once -/* -inline int fixmul(int x, int y) -{ -#ifndef _M_AMD64 - __asm - { - mov eax, x - imul y - add eax, 0x8000 - adc edx, 0 - shrd eax, edx, 16 - } -#else - return (int)(((__int64)x * y + 0x8000) >> 16); -#endif -} -*/ -inline int fixmul(int x, int y) -{ -#ifndef _M_AMD64 - _asm - { - mov eax, x - imul y - shrd eax, edx, 16 - sar edx, 15 - jz Out2 - cmp edx, -1 - jz Out2 - ; call _set_errno_erange - mov eax, 0x7FFFFFFF - cmp x, 0 - jge Out1 - neg eax - Out1: - cmp y, 0 - jge Out2 - neg eax - Out2: - } -#else - return (int)(((__int64)x * y + 0x8000) >> 16); -#endif -} - -inline int fixdiv(int x, int y) -{ -#ifndef _M_AMD64 - _asm - { - push esi - - mov ecx, y - xor esi, esi - mov eax, x - or eax, eax - jns Out1 - neg eax - inc esi - Out1: - or ecx, ecx - jns Out2 - neg ecx - inc esi - Out2: - mov edx, eax - shr edx, 0x10 - shl eax, 0x10 - cmp edx, ecx - jae Out3 - div ecx - or eax, eax - jns Out4 - Out3: - ; call _set_errno_erange - mov eax, 0x7FFFFFFF - Out4: - test esi, 1 - je Out5 - neg eax - Out5: - pop esi - } -#else - return (int)(((__int64)x << 16) / y); -#endif -} - -// -// GSSoftVertexFX -// - -__declspec(align(16)) union GSSoftVertexFX -{ - class __declspec(novtable) Scalar - { - int val; - - public: - Scalar() {} - explicit Scalar(float f) {val = (int)(f*65536);} - explicit Scalar(int i) {val = i;} - - int Value() const {return val;} - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - void sat() {ASSERT(0); val = val < 0 ? 0 : val > (255<<16) ? (255<<16) : val;} // TODO - void rcp() {val = (int)(65536.0f*65536.0f / val);} // TODO -#else - void sat() {val = val < 0 ? 0 : val > (255<<16) ? (255<<16) : val;} - void rcp() {val = (int)(65536.0f*65536.0f / val);} -#endif - void abss() {val = abs(val);} - - Scalar floors() const {Scalar s; s.val = val & 0xffff0000; return s;} - int floori() const {return val >> 16;} - - Scalar ceils() const {Scalar s; s.val = (val + 0xffff) & 0xffff0000; return s;} - int ceili() const {return (val + 0xffff) >> 16;} - - void operator = (float f) {val = (int)(f*65536);} - void operator = (int i) {val = i;} - - operator float() const {return (float)val / 65536;} - operator int() const {return val >> 16;} - - void operator += (const Scalar& s) {val += s.val;} - void operator -= (const Scalar& s) {val -= s.val;} - void operator *= (const Scalar& s) {val = fixmul(val, s.val);} - void operator /= (const Scalar& s) {val = fixdiv(val, s.val);} - - friend Scalar operator + (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val + s2.val);} - friend Scalar operator - (const Scalar& s1, const Scalar& s2) {return Scalar(s1.val - s2.val);} - friend Scalar operator * (const Scalar& s1, const Scalar& s2) {return Scalar(fixmul(s1.val, s2.val));} - friend Scalar operator / (const Scalar& s1, const Scalar& s2) {return Scalar(fixdiv(s1.val, s2.val));} - - friend Scalar operator + (const Scalar& s1, int i) {return Scalar(s1.val + i);} - friend Scalar operator - (const Scalar& s1, int i) {return Scalar(s1.val - i);} - friend Scalar operator * (const Scalar& s1, int i) {return Scalar(s1.val * i);} - friend Scalar operator / (const Scalar& s1, int i) {return Scalar(s1.val / i);} - - friend bool operator == (const Scalar& s1, const Scalar& s2) {return s1.val == s2.val;} - friend bool operator <= (const Scalar& s1, const Scalar& s2) {return s1.val <= s2.val;} - friend bool operator < (const Scalar& s1, const Scalar& s2) {return s1.val < s2.val;} - }; - - __declspec(align(16)) class __declspec(novtable) Vector - { - public: - union - { - union {struct {Scalar x, y, z, q;}; struct {Scalar r, g, b, a;};}; - union {struct {Scalar v[4];}; struct {Scalar c[4];};}; -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - union {__m128i xyzq; __m128i rgba;}; -#endif - }; - - Vector() {} - Vector(const Vector& v) {*this = v;} - Vector(Scalar s) {*this = s;} - Vector(Scalar s0, Scalar s1, Scalar s2, Scalar s3) {x = s0; y = s1; z = s2; q = s3;} - explicit Vector(DWORD dw) {*this = dw;} -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - Vector(__m128i i0123) {*this = i0123;} -#endif - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - - void operator = (const Vector& v) {xyzq = v.xyzq;} - void operator = (__m128i i0123) {xyzq = i0123;} - void operator = (Scalar s) {xyzq = _mm_set1_epi32(s.Value());} - void operator = (DWORD dw) - { - __m128i zero = _mm_setzero_si128(); - xyzq = _mm_unpacklo_epi16(zero, _mm_unpacklo_epi8(_mm_cvtsi32_si128(dw), zero)); - } - - operator __m128i() const {return xyzq;} - operator DWORD() const - { - __m128i r0 = xyzq; - r0 = _mm_srli_si128(r0, 2); - r0 = _mm_packs_epi32(r0, r0); - r0 = _mm_packus_epi16(r0, r0); - return (DWORD)_mm_cvtsi128_si32(r0); - } - - void sat() {xyzq = _mm_and_si128(_mm_min_epi16(_mm_max_epi16(xyzq, _mm_setzero_si128()), _mm_set1_epi32(0x00ff0000)), _mm_set1_epi32(0xffff0000));} - void rcp() {ASSERT(0);} // TODO {xyzq = _mm_rcp_ps(xyzq);} - -#else - - void operator = (const Vector& v) {x = v.x; y = v.y; z = v.z; q = v.q;} - void operator = (Scalar s) {x = y = z = q = s;} - void operator = (DWORD dw) - { - x = (int)((dw & 0x000000ff) << 16); - y = (int)((dw & 0x0000ff00) << 8); - z = (int)((dw & 0x00ff0000) << 0); - q = (int)((dw & 0xff000000) >> 8); - } - - operator DWORD() const - { - return (DWORD)((((DWORD)(int)x&0xff)<<0) | (((DWORD)(int)y&0xff)<<8) | (((DWORD)(int)z&0xff)<<16) | (((DWORD)(int)q&0xff)<<24)); - } - - void sat() {x.sat(); y.sat(); z.sat(); q.sat();} - void rcp() {x.rcp(); y.rcp(); z.rcp(); q.rcp();} - -#endif - // TODO - void operator += (const Vector& v) {*this = *this + v;} - void operator -= (const Vector& v) {*this = *this - v;} - void operator *= (const Vector& v) {*this = *this * v;} - void operator /= (const Vector& v) {*this = *this / v;} - - void absv() {x.abss(); y.abss(); z.abss(); q.abss();} - - friend Vector operator + (const Vector& v1, const Vector& v2); - friend Vector operator - (const Vector& v1, const Vector& v2); - friend Vector operator * (const Vector& v1, const Vector& v2); - friend Vector operator / (const Vector& v1, const Vector& v2); - - friend Vector operator + (const Vector& v, Scalar s); - friend Vector operator - (const Vector& v, Scalar s); - friend Vector operator * (const Vector& v, Scalar s); - friend Vector operator / (const Vector& v, Scalar s); - }; - - struct {__declspec(align(16)) Vector c, p, t;}; - struct {__declspec(align(16)) Vector sv[3];}; - struct {__declspec(align(16)) Scalar s[12];}; - - GSSoftVertexFX() {} - GSSoftVertexFX(const GSSoftVertexFX& v) {*this = v;} - - void operator = (const GSSoftVertexFX& v) {c = v.c; p = v.p; t = v.t;} - void operator += (const GSSoftVertexFX& v) {c += v.c; p += v.p; t += v.t;} - - operator CPoint() const {return CPoint((int)p.x, (int)p.y);} - - friend GSSoftVertexFX operator + (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2); - friend GSSoftVertexFX operator - (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2); - - friend GSSoftVertexFX operator * (const GSSoftVertexFX& v, Scalar s); - friend GSSoftVertexFX operator / (const GSSoftVertexFX& v, Scalar s); - - static void Exchange(GSSoftVertexFX* __restrict v1, GSSoftVertexFX* __restrict v2) - { - // GSSoftVertexFX v = *v1; *v1 = *v2; *v2 = v; - Vector c = v1->c, p = v1->p, t = v1->t; - v1->c = v2->c; v1->p = v2->p; v1->t = v2->t; - v2->c = c; v2->p = p; v2->t = t; - } - - __forceinline DWORD GetZ() const - { - ASSERT((int)p.z >= 0 && (int)p.q >= 0); - return ((DWORD)(int)p.z << 1) + ((DWORD)(int)p.q >> 15); - } -}; - -#if _M_IX86_FP >= 2 || defined(_M_AMD64) - -__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(_mm_add_epi32(v1, v2));} -__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(_mm_sub_epi32(v1, v2));} -__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) -{ - // TODO - __m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v1), _mm_set1_ps(1.0f/65536)); - __m128 r2 = _mm_cvtepi32_ps(v2); - __m128i r0 = _mm_cvtps_epi32(_mm_mul_ps(r1, r2)); - return GSSoftVertexFX::Vector(r0); -} -__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) -{ - // TODO - __m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v1), _mm_set1_ps(65536)); - __m128 r2 = _mm_cvtepi32_ps(v2); - __m128i r0 = _mm_cvtps_epi32(_mm_div_ps(r1, r2)); - return GSSoftVertexFX::Vector(r0); -} - -__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(_mm_add_epi32(v, _mm_set1_epi32(s.Value())));} -__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(_mm_sub_epi32(v, _mm_set1_epi32(s.Value())));} -__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s) -{ - // TODO - __m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v), _mm_set1_ps(1.0f/65536)); - __m128 r2 = _mm_cvtepi32_ps(_mm_set1_epi32(s.Value())); - __m128i r0 = _mm_cvtps_epi32(_mm_mul_ps(r1, r2)); - return GSSoftVertexFX::Vector(r0); -} -__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v, const GSSoftVertexFX::Scalar s) -{ - // TODO - __m128 r1 = _mm_mul_ps(_mm_cvtepi32_ps(v), _mm_set1_ps(65536)); - __m128 r2 = _mm_cvtepi32_ps(_mm_set1_epi32(s.Value())); - __m128i r0 = _mm_cvtps_epi32(_mm_div_ps(r1, r2)); - return GSSoftVertexFX::Vector(r0); -} - -#else - -__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x + v2.x, v1.y + v2.y, v1.z + v2.z, v1.q + v2.q);} -__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x - v2.x, v1.y - v2.y, v1.z - v2.z, v1.q - v2.q);} -__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x * v2.x, v1.y * v2.y, v1.z * v2.z, v1.q * v2.q);} -__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v1, const GSSoftVertexFX::Vector& v2) {return GSSoftVertexFX::Vector(v1.x / v2.x, v1.y / v2.y, v1.z / v2.z, v1.q / v2.q);} - -__forceinline GSSoftVertexFX::Vector operator + (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x + s, v.y + s, v.z + s, v.q + s);} -__forceinline GSSoftVertexFX::Vector operator - (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x - s, v.y - s, v.z - s, v.q - s);} -__forceinline GSSoftVertexFX::Vector operator * (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x * s, v.y * s, v.z * s, v.q * s);} -__forceinline GSSoftVertexFX::Vector operator / (const GSSoftVertexFX::Vector& v, GSSoftVertexFX::Scalar s) {return GSSoftVertexFX::Vector(v.x / s, v.y / s, v.z / s, v.q / s);} - -#endif - -__forceinline GSSoftVertexFX operator + (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2) -{ - GSSoftVertexFX v0; - v0.c = v1.c + v2.c; - v0.p = v1.p + v2.p; - v0.t = v1.t + v2.t; - return v0; -} - -__forceinline GSSoftVertexFX operator - (const GSSoftVertexFX& v1, const GSSoftVertexFX& v2) -{ - GSSoftVertexFX v0; - v0.c = v1.c - v2.c; - v0.p = v1.p - v2.p; - v0.t = v1.t - v2.t; - return v0; -} - -__forceinline GSSoftVertexFX operator * (const GSSoftVertexFX& v, GSSoftVertexFX::Scalar s) -{ - GSSoftVertexFX v0; - GSSoftVertexFX::Vector vs(s); - v0.c = v.c * vs; - v0.p = v.p * vs; - v0.t = v.t * vs; - return v0; -} - -__forceinline GSSoftVertexFX operator / (const GSSoftVertexFX& v, GSSoftVertexFX::Scalar s) -{ - GSSoftVertexFX v0; - GSSoftVertexFX::Vector vs(s); - v0.c = v.c / vs; - v0.p = v.p / vs; - v0.t = v.t / vs; - return v0; -} diff --git a/plugins/gs/gsdx9/GSState.cpp b/plugins/gs/gsdx9/GSState.cpp deleted file mode 100644 index bd0fdc9871..0000000000 --- a/plugins/gs/gsdx9/GSState.cpp +++ /dev/null @@ -1,1135 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSState.h" -#include "GSdx9.h" -#include "GSUtil.h" -#include "resource.h" - -// -// GSState -// - -GSState::GSState(int w, int h, HWND hWnd, HRESULT& hr) - : m_hWnd(hWnd) - , m_width(w) - , m_height(h) - , m_sfp(NULL) - , m_fp(NULL) - , m_iOSD(1) -{ - hr = E_FAIL; - - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - - CWinApp* pApp = AfxGetApp(); - - m_v.RGBAQ.Q = m_q = 1.0f; - - memset(m_path, 0, sizeof(m_path)); - - m_de.PRMODECONT.AC = 1; - m_pPRIM = &m_de.PRIM; - m_PRIM = 8; - - m_fpGSirq = NULL; - - m_ctxt = &m_de.CTXT[0]; - - m_pTrBuff = (BYTE*)_aligned_malloc(1024*1024*4, 16); - m_nTrBytes = 0; - - for(int i = 0; i < countof(m_fpGIFPackedRegHandlers); i++) - m_fpGIFPackedRegHandlers[i] = &GSState::GIFPackedRegHandlerNull; - - m_fpGIFPackedRegHandlers[GIF_REG_PRIM] = &GSState::GIFPackedRegHandlerPRIM; - m_fpGIFPackedRegHandlers[GIF_REG_RGBA] = &GSState::GIFPackedRegHandlerRGBA; - m_fpGIFPackedRegHandlers[GIF_REG_STQ] = &GSState::GIFPackedRegHandlerSTQ; - m_fpGIFPackedRegHandlers[GIF_REG_UV] = &GSState::GIFPackedRegHandlerUV; - m_fpGIFPackedRegHandlers[GIF_REG_XYZF2] = &GSState::GIFPackedRegHandlerXYZF2; - m_fpGIFPackedRegHandlers[GIF_REG_XYZ2] = &GSState::GIFPackedRegHandlerXYZ2; - m_fpGIFPackedRegHandlers[GIF_REG_TEX0_1] = &GSState::GIFPackedRegHandlerTEX0_1; - m_fpGIFPackedRegHandlers[GIF_REG_TEX0_2] = &GSState::GIFPackedRegHandlerTEX0_2; - m_fpGIFPackedRegHandlers[GIF_REG_CLAMP_1] = &GSState::GIFPackedRegHandlerCLAMP_1; - m_fpGIFPackedRegHandlers[GIF_REG_CLAMP_2] = &GSState::GIFPackedRegHandlerCLAMP_2; - m_fpGIFPackedRegHandlers[GIF_REG_FOG] = &GSState::GIFPackedRegHandlerFOG; - m_fpGIFPackedRegHandlers[GIF_REG_XYZF3] = &GSState::GIFPackedRegHandlerXYZF3; - m_fpGIFPackedRegHandlers[GIF_REG_XYZ3] = &GSState::GIFPackedRegHandlerXYZ3; - m_fpGIFPackedRegHandlers[GIF_REG_A_D] = &GSState::GIFPackedRegHandlerA_D; - m_fpGIFPackedRegHandlers[GIF_REG_NOP] = &GSState::GIFPackedRegHandlerNOP; - - for(int i = 0; i < countof(m_fpGIFRegHandlers); i++) - m_fpGIFRegHandlers[i] = &GSState::GIFRegHandlerNull; - - m_fpGIFRegHandlers[GIF_A_D_REG_PRIM] = &GSState::GIFRegHandlerPRIM; - m_fpGIFRegHandlers[GIF_A_D_REG_RGBAQ] = &GSState::GIFRegHandlerRGBAQ; - m_fpGIFRegHandlers[GIF_A_D_REG_ST] = &GSState::GIFRegHandlerST; - m_fpGIFRegHandlers[GIF_A_D_REG_UV] = &GSState::GIFRegHandlerUV; - m_fpGIFRegHandlers[GIF_A_D_REG_XYZF2] = &GSState::GIFRegHandlerXYZF2; - m_fpGIFRegHandlers[GIF_A_D_REG_XYZ2] = &GSState::GIFRegHandlerXYZ2; - m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_1] = &GSState::GIFRegHandlerTEX0_1; - m_fpGIFRegHandlers[GIF_A_D_REG_TEX0_2] = &GSState::GIFRegHandlerTEX0_2; - m_fpGIFRegHandlers[GIF_A_D_REG_CLAMP_1] = &GSState::GIFRegHandlerCLAMP_1; - m_fpGIFRegHandlers[GIF_A_D_REG_CLAMP_2] = &GSState::GIFRegHandlerCLAMP_2; - m_fpGIFRegHandlers[GIF_A_D_REG_FOG] = &GSState::GIFRegHandlerFOG; - m_fpGIFRegHandlers[GIF_A_D_REG_XYZF3] = &GSState::GIFRegHandlerXYZF3; - m_fpGIFRegHandlers[GIF_A_D_REG_XYZ3] = &GSState::GIFRegHandlerXYZ3; - m_fpGIFRegHandlers[GIF_A_D_REG_NOP] = &GSState::GIFRegHandlerNOP; - m_fpGIFRegHandlers[GIF_A_D_REG_TEX1_1] = &GSState::GIFRegHandlerTEX1_1; - m_fpGIFRegHandlers[GIF_A_D_REG_TEX1_2] = &GSState::GIFRegHandlerTEX1_2; - m_fpGIFRegHandlers[GIF_A_D_REG_TEX2_1] = &GSState::GIFRegHandlerTEX2_1; - m_fpGIFRegHandlers[GIF_A_D_REG_TEX2_2] = &GSState::GIFRegHandlerTEX2_2; - m_fpGIFRegHandlers[GIF_A_D_REG_XYOFFSET_1] = &GSState::GIFRegHandlerXYOFFSET_1; - m_fpGIFRegHandlers[GIF_A_D_REG_XYOFFSET_2] = &GSState::GIFRegHandlerXYOFFSET_2; - m_fpGIFRegHandlers[GIF_A_D_REG_PRMODECONT] = &GSState::GIFRegHandlerPRMODECONT; - m_fpGIFRegHandlers[GIF_A_D_REG_PRMODE] = &GSState::GIFRegHandlerPRMODE; - m_fpGIFRegHandlers[GIF_A_D_REG_TEXCLUT] = &GSState::GIFRegHandlerTEXCLUT; - m_fpGIFRegHandlers[GIF_A_D_REG_SCANMSK] = &GSState::GIFRegHandlerSCANMSK; - m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP1_1] = &GSState::GIFRegHandlerMIPTBP1_1; - m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP1_2] = &GSState::GIFRegHandlerMIPTBP1_2; - m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP2_1] = &GSState::GIFRegHandlerMIPTBP2_1; - m_fpGIFRegHandlers[GIF_A_D_REG_MIPTBP2_2] = &GSState::GIFRegHandlerMIPTBP2_2; - m_fpGIFRegHandlers[GIF_A_D_REG_TEXA] = &GSState::GIFRegHandlerTEXA; - m_fpGIFRegHandlers[GIF_A_D_REG_FOGCOL] = &GSState::GIFRegHandlerFOGCOL; - m_fpGIFRegHandlers[GIF_A_D_REG_TEXFLUSH] = &GSState::GIFRegHandlerTEXFLUSH; - m_fpGIFRegHandlers[GIF_A_D_REG_SCISSOR_1] = &GSState::GIFRegHandlerSCISSOR_1; - m_fpGIFRegHandlers[GIF_A_D_REG_SCISSOR_2] = &GSState::GIFRegHandlerSCISSOR_2; - m_fpGIFRegHandlers[GIF_A_D_REG_ALPHA_1] = &GSState::GIFRegHandlerALPHA_1; - m_fpGIFRegHandlers[GIF_A_D_REG_ALPHA_2] = &GSState::GIFRegHandlerALPHA_2; - m_fpGIFRegHandlers[GIF_A_D_REG_DIMX] = &GSState::GIFRegHandlerDIMX; - m_fpGIFRegHandlers[GIF_A_D_REG_DTHE] = &GSState::GIFRegHandlerDTHE; - m_fpGIFRegHandlers[GIF_A_D_REG_COLCLAMP] = &GSState::GIFRegHandlerCOLCLAMP; - m_fpGIFRegHandlers[GIF_A_D_REG_TEST_1] = &GSState::GIFRegHandlerTEST_1; - m_fpGIFRegHandlers[GIF_A_D_REG_TEST_2] = &GSState::GIFRegHandlerTEST_2; - m_fpGIFRegHandlers[GIF_A_D_REG_PABE] = &GSState::GIFRegHandlerPABE; - m_fpGIFRegHandlers[GIF_A_D_REG_FBA_1] = &GSState::GIFRegHandlerFBA_1; - m_fpGIFRegHandlers[GIF_A_D_REG_FBA_2] = &GSState::GIFRegHandlerFBA_2; - m_fpGIFRegHandlers[GIF_A_D_REG_FRAME_1] = &GSState::GIFRegHandlerFRAME_1; - m_fpGIFRegHandlers[GIF_A_D_REG_FRAME_2] = &GSState::GIFRegHandlerFRAME_2; - m_fpGIFRegHandlers[GIF_A_D_REG_ZBUF_1] = &GSState::GIFRegHandlerZBUF_1; - m_fpGIFRegHandlers[GIF_A_D_REG_ZBUF_2] = &GSState::GIFRegHandlerZBUF_2; - m_fpGIFRegHandlers[GIF_A_D_REG_BITBLTBUF] = &GSState::GIFRegHandlerBITBLTBUF; - m_fpGIFRegHandlers[GIF_A_D_REG_TRXPOS] = &GSState::GIFRegHandlerTRXPOS; - m_fpGIFRegHandlers[GIF_A_D_REG_TRXREG] = &GSState::GIFRegHandlerTRXREG; - m_fpGIFRegHandlers[GIF_A_D_REG_TRXDIR] = &GSState::GIFRegHandlerTRXDIR; - m_fpGIFRegHandlers[GIF_A_D_REG_HWREG] = &GSState::GIFRegHandlerHWREG; - m_fpGIFRegHandlers[GIF_A_D_REG_SIGNAL] = &GSState::GIFRegHandlerSIGNAL; - m_fpGIFRegHandlers[GIF_A_D_REG_FINISH] = &GSState::GIFRegHandlerFINISH; - m_fpGIFRegHandlers[GIF_A_D_REG_LABEL] = &GSState::GIFRegHandlerLABEL; - - // DD - - CComPtr pDD; - if(FAILED(DirectDrawCreateEx(0, (void**)&pDD, IID_IDirectDraw7, 0))) - return; - - m_ddcaps.dwSize = sizeof(DDCAPS); - if(FAILED(pDD->GetCaps(&m_ddcaps, NULL))) - return; - - pDD = NULL; - - // D3D - - if(!(m_pD3D = Direct3DCreate9(D3D_SDK_VERSION)) - && !(m_pD3D = Direct3DCreate9(D3D9b_SDK_VERSION))) - return; - - ZeroMemory(&m_caps, sizeof(m_caps)); - m_pD3D->GetDeviceCaps(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, &m_caps); - - m_fmtDepthStencil = - IsDepthFormatOk(m_pD3D, D3DFMT_D32, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8) ? D3DFMT_D32 : - IsDepthFormatOk(m_pD3D, D3DFMT_D24X8, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8) ? D3DFMT_D24X8 : - D3DFMT_D16; - - // D3D Device - - if(FAILED(ResetDevice(true))) - return; - - // Shaders - - DWORD PixelShaderVersion = pApp->GetProfileInt(_T("Settings"), _T("PixelShaderVersion2"), D3DPS_VERSION(2, 0)); - - if(PixelShaderVersion > m_caps.PixelShaderVersion) - { - CString str; - str.Format(_T("Supported pixel shader version is too low!\n\nSupported: %d.%d\nSelected: %d.%d"), - D3DSHADER_VERSION_MAJOR(m_caps.PixelShaderVersion), D3DSHADER_VERSION_MINOR(m_caps.PixelShaderVersion), - D3DSHADER_VERSION_MAJOR(PixelShaderVersion), D3DSHADER_VERSION_MINOR(PixelShaderVersion)); - AfxMessageBox(str); - m_pD3DDev = NULL; - return; - } - - m_caps.PixelShaderVersion = min(PixelShaderVersion, m_caps.PixelShaderVersion); - - static const TCHAR* hlsl_tfx[] = - { - _T("main_tfx0_32"), _T("main_tfx1_32"), _T("main_tfx2_32"), _T("main_tfx3_32"), - _T("main_tfx0_24"), _T("main_tfx1_24"), _T("main_tfx2_24"), _T("main_tfx3_24"), - _T("main_tfx0_24AEM"), _T("main_tfx1_24AEM"), _T("main_tfx2_24AEM"), _T("main_tfx3_24AEM"), - _T("main_tfx0_16"), _T("main_tfx1_16"), _T("main_tfx2_16"), _T("main_tfx3_16"), - _T("main_tfx0_16AEM"), _T("main_tfx1_16AEM"), _T("main_tfx2_16AEM"), _T("main_tfx3_16AEM"), - _T("main_tfx0_8P_pt"), _T("main_tfx1_8P_pt"), _T("main_tfx2_8P_pt"), _T("main_tfx3_8P_pt"), - _T("main_tfx0_8P_ln"), _T("main_tfx1_8P_ln"), _T("main_tfx2_8P_ln"), _T("main_tfx3_8P_ln"), - _T("main_tfx0_8HP_pt"), _T("main_tfx1_8HP_pt"), _T("main_tfx2_8HP_pt"), _T("main_tfx3_8HP_pt"), - _T("main_tfx0_8HP_ln"), _T("main_tfx1_8HP_ln"), _T("main_tfx2_8HP_ln"), _T("main_tfx3_8HP_ln"), - _T("main_notfx"), - _T("main_8PTo32"), - }; - - // ps_3_0 - - if(m_caps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) - { - for(int i = 0; i < countof(hlsl_tfx); i++) - { - if(m_pHLSLTFX[i]) continue; - - CompileShaderFromResource(m_pD3DDev, IDR_HLSL_TFX, hlsl_tfx[i], _T("ps_3_0"), - D3DXSHADER_AVOID_FLOW_CONTROL|D3DXSHADER_PARTIALPRECISION, &m_pHLSLTFX[i]); - } - - for(int i = 0; i < 3; i++) - { - if(m_pHLSLMerge[i]) continue; - - CString main; - main.Format(_T("main%d"), i); - CompileShaderFromResource(m_pD3DDev, IDR_HLSL_MERGE, main, _T("ps_3_0"), - D3DXSHADER_AVOID_FLOW_CONTROL|D3DXSHADER_PARTIALPRECISION, &m_pHLSLMerge[i]); - } - } - - // ps_2_0 - - if(m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0)) - { - for(int i = 0; i < countof(hlsl_tfx); i++) - { - if(m_pHLSLTFX[i]) continue; - - CompileShaderFromResource(m_pD3DDev, IDR_HLSL_TFX, hlsl_tfx[i], _T("ps_2_0"), - D3DXSHADER_PARTIALPRECISION, &m_pHLSLTFX[i]); - } - - for(int i = 0; i < 3; i++) - { - if(m_pHLSLMerge[i]) continue; - - CString main; - main.Format(_T("main%d"), i); - CompileShaderFromResource(m_pD3DDev, IDR_HLSL_MERGE, main, _T("ps_2_0"), - D3DXSHADER_PARTIALPRECISION, &m_pHLSLMerge[i]); - } - } - - // ps_1_1 + ps_1_4 - - if(m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)) - { - static const UINT nShaderIDs[] = - { - IDR_PS11_TFX000, IDR_PS11_TFX010, IDR_PS11_TFX011, - IDR_PS11_TFX1x0, IDR_PS11_TFX1x1, - IDR_PS11_TFX200, IDR_PS11_TFX210, IDR_PS11_TFX211, - IDR_PS11_TFX300, IDR_PS11_TFX310, IDR_PS11_TFX311, - IDR_PS11_TFX4xx, - IDR_PS11_EN11, IDR_PS11_EN01, IDR_PS11_EN10, IDR_PS11_EN00, - IDR_PS14_EN11, IDR_PS14_EN01, IDR_PS14_EN10, IDR_PS14_EN00 - }; - - for(int i = 0; i < countof(nShaderIDs); i++) - { - if(m_pPixelShaders[i]) continue; - AssembleShaderFromResource(m_pD3DDev, nShaderIDs[i], 0, &m_pPixelShaders[i]); - } - - if(!m_pHLSLRedBlue) - { - CompileShaderFromResource(m_pD3DDev, IDR_HLSL_RB, _T("main"), _T("ps_1_1"), - D3DXSHADER_PARTIALPRECISION, &m_pHLSLRedBlue); - } - } - - // - - m_strDefaultTitle.ReleaseBufferSetLength(GetWindowText(m_hWnd, m_strDefaultTitle.GetBuffer(256), 256)); - - m_fEnablePalettizedTextures = !!pApp->GetProfileInt(_T("Settings"), _T("fEnablePalettizedTextures"), FALSE); - - m_fNloopHack = pApp->GetProfileInt(_T("Settings"), _T("fNloopHack"), FALSE); - - - // - - hr = S_OK; - - Reset(); - -#if defined(DEBUG_LOG) || defined(DEBUG_LOG2) - ::DeleteFile(_T("g:\\gs.txt")); - m_fp = _tfopen(_T("g:\\gs.txt"), _T("at")); -#endif - -// m_rs.pCSR->rREV = 0x20; - -/* - GSLocalMemory lm; - - int w = 512, h = 512; - - for(int y = 0; y < h; y++) - { - for(int x = 0; x < w; x++) - { - lm.writePixel24(x, y, (x * 255 / w) | ((y * 255 / h) << 8), 0x500, 8); - } - } - - for(int i = 16; i > 0; i--) - { - CString fn; - fn.Format(_T("g:/%02d.bmp"), i); - lm.SaveBMP(m_pD3DDev, fn, 0x500, i, PSM_PSMCT24, i*64, 512); - } -*/ -} - -GSState::~GSState() -{ - Reset(); - _aligned_free(m_pTrBuff); - if(m_sfp) fclose(m_sfp); - if(m_fp) fclose(m_fp); -} - -HRESULT GSState::ResetDevice(bool fForceWindowed) -{ - AFX_MANAGE_STATE(AfxGetStaticModuleState()); - HMODULE hModule = AfxGetResourceHandle(); - CWinApp* pApp = AfxGetApp(); - - HRESULT hr; - - if(!m_pD3D) - return E_FAIL; - - m_pOrgRenderTarget = NULL; - m_pTmpRenderTarget = NULL; - m_pD3DXFont = NULL; - - ZeroMemory(&m_d3dpp, sizeof(m_d3dpp)); - m_d3dpp.Windowed = TRUE; - m_d3dpp.hDeviceWindow = m_hWnd; - m_d3dpp.SwapEffect = /*D3DSWAPEFFECT_COPY*/D3DSWAPEFFECT_DISCARD/*D3DSWAPEFFECT_FLIP*/; - m_d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8; - m_d3dpp.BackBufferWidth = m_width; - m_d3dpp.BackBufferHeight = m_height; - //m_d3dpp.BackBufferCount = 3; - m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_IMMEDIATE; - - if(!!pApp->GetProfileInt(_T("Settings"), _T("fEnableTvOut"), FALSE)) - m_d3dpp.Flags |= D3DPRESENTFLAG_VIDEO; - - int ModeWidth = pApp->GetProfileInt(_T("Settings"), _T("ModeWidth"), 0); - int ModeHeight = pApp->GetProfileInt(_T("Settings"), _T("ModeHeight"), 0); - int ModeRefreshRate = pApp->GetProfileInt(_T("Settings"), _T("ModeRefreshRate"), 0); - - if(!fForceWindowed && ModeWidth > 0 && ModeHeight > 0 && ModeRefreshRate >= 0) - { - m_d3dpp.Windowed = FALSE; - m_d3dpp.BackBufferWidth = ModeWidth; - m_d3dpp.BackBufferHeight = ModeHeight; - m_d3dpp.FullScreen_RefreshRateInHz = ModeRefreshRate; - m_d3dpp.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - - ::SetWindowLong(m_hWnd, GWL_STYLE, ::GetWindowLong(m_hWnd, GWL_STYLE) & ~(WS_CAPTION|WS_THICKFRAME)); - ::SetWindowPos(m_hWnd, NULL, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE); - ::SetMenu(m_hWnd, NULL); - - m_iOSD = 0; - } - - if(!m_pD3DDev) - { - if(FAILED(hr = m_pD3D->CreateDevice( - // m_pD3D->GetAdapterCount()-1, D3DDEVTYPE_REF, - D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, - m_hWnd, - m_caps.VertexProcessingCaps ? D3DCREATE_HARDWARE_VERTEXPROCESSING : D3DCREATE_SOFTWARE_VERTEXPROCESSING, - &m_d3dpp, &m_pD3DDev))) - return hr; - } - else - { - if(FAILED(hr = m_pD3DDev->Reset(&m_d3dpp))) - { - if(D3DERR_DEVICELOST == hr) - { - Sleep(1000); - if(FAILED(hr = m_pD3DDev->Reset(&m_d3dpp))) - return hr; - } - else - { - return hr; - } - } - } - - CComPtr pBackBuff; - hr = m_pD3DDev->GetBackBuffer(0, 0, D3DBACKBUFFER_TYPE_MONO, &pBackBuff); - - ZeroMemory(&m_bd, sizeof(m_bd)); - pBackBuff->GetDesc(&m_bd); - - hr = m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET, 0, 1.0f, 0); - - hr = m_pD3DDev->GetRenderTarget(0, &m_pOrgRenderTarget); - - if(m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1) && m_caps.PixelShaderVersion <= D3DPS_VERSION(1, 3) - && m_pHLSLRedBlue) - { - hr = m_pD3DDev->CreateTexture( - m_bd.Width, m_bd.Height, 0, D3DUSAGE_RENDERTARGET, D3DFMT_X8R8G8B8, - D3DPOOL_DEFAULT, &m_pTmpRenderTarget, NULL); - } - - D3DXFONT_DESC fd; - memset(&fd, 0, sizeof(fd)); - _tcscpy(fd.FaceName, _T("Arial")); - fd.Height = -(int)(sqrt((float)m_bd.Height) * 0.7); - hr = D3DXCreateFontIndirect(m_pD3DDev, &fd, &m_pD3DXFont); - - hr = m_pD3DDev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - hr = m_pD3DDev->SetRenderState(D3DRS_LIGHTING, FALSE); - - m_texfilter = (D3DTEXTUREFILTERTYPE)pApp->GetProfileInt(_T("Settings"), _T("TexFilter"), D3DTEXF_LINEAR); - - for(int i = 0; i < 8; i++) - { - hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_MAGFILTER, m_texfilter); - hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_MINFILTER, m_texfilter); - // hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_MIPFILTER, m_texfilter); - hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - hr = m_pD3DDev->SetSamplerState(i, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - } - - hr = m_pD3DDev->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - hr = m_pD3DDev->SetRenderState(D3DRS_BLENDOPALPHA, D3DBLENDOP_ADD); - hr = m_pD3DDev->SetRenderState(D3DRS_SRCBLENDALPHA, D3DBLEND_ONE); - hr = m_pD3DDev->SetRenderState(D3DRS_DESTBLENDALPHA, D3DBLEND_ZERO); - - return S_OK; -} - -UINT32 GSState::Freeze(freezeData* fd, bool fSizeOnly) -{ - int size = sizeof(m_version) - + sizeof(m_de) + sizeof(m_v) - + sizeof(m_x) + sizeof(m_y) + 1024*1024*4 - + sizeof(m_path) + sizeof(m_q) - /*+ sizeof(m_vl)*/; - - if(fSizeOnly) - { - fd->size = size; - return 0; - } - else if(!fd->data || fd->size < size) - { - return -1; - } - - FlushWriteTransfer(); - - FlushPrimInternal(); - - BYTE* data = fd->data; - memcpy(data, &m_version, sizeof(m_version)); data += sizeof(m_version); - memcpy(data, &m_de, sizeof(m_de)); data += sizeof(m_de); - memcpy(data, &m_v, sizeof(m_v)); data += sizeof(m_v); - memcpy(data, &m_x, sizeof(m_x)); data += sizeof(m_x); - memcpy(data, &m_y, sizeof(m_y)); data += sizeof(m_y); - memcpy(data, m_lm.GetVM(), 1024*1024*4); data += 1024*1024*4; - memcpy(data, m_path, sizeof(m_path)); data += sizeof(m_path); - memcpy(data, &m_q, sizeof(m_q)); data += sizeof(m_q); - // memcpy(data, &m_vl, sizeof(m_vl)); data += sizeof(m_vl); - - return 0; -} - -UINT32 GSState::Defrost(const freezeData* fd) -{ - if(!fd || !fd->data || fd->size == 0) - return -1; - - int size = sizeof(m_version) - + sizeof(m_de) + sizeof(m_v) - + sizeof(m_x) + sizeof(m_y) + 1024*1024*4 - + sizeof(m_path) - + sizeof(m_q) - /*+ sizeof(m_vl)*/; - - if(fd->size != size) - return -1; - - BYTE* data = fd->data; - - int version = 0; - memcpy(&version, data, sizeof(version)); data += sizeof(version); - if(m_version != version) return -1; - - FlushPrimInternal(); - - memcpy(&m_de, data, sizeof(m_de)); data += sizeof(m_de); - memcpy(&m_v, data, sizeof(m_v)); data += sizeof(m_v); - memcpy(&m_x, data, sizeof(m_x)); data += sizeof(m_x); - memcpy(&m_y, data, sizeof(m_y)); data += sizeof(m_y); - memcpy(m_lm.GetVM(), data, 1024*1024*4); data += 1024*1024*4; - memcpy(&m_path, data, sizeof(m_path)); data += sizeof(m_path); - memcpy(&m_q, data, sizeof(m_q)); data += sizeof(m_q); - // memcpy(&m_vl, data, sizeof(m_vl)); data += sizeof(m_vl); - - m_pPRIM = !m_de.PRMODECONT.AC ? (GIFRegPRIM*)&m_de.PRMODE : &m_de.PRIM; - - m_ctxt = &m_de.CTXT[m_pPRIM->CTXT]; - - m_de.CTXT[0].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].FRAME.PSM]; - m_de.CTXT[0].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].ZBUF.PSM]; - m_de.CTXT[0].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].TEX0.PSM]; - - m_de.CTXT[1].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].FRAME.PSM]; - m_de.CTXT[1].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].ZBUF.PSM]; - m_de.CTXT[1].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].TEX0.PSM]; - - return 0; -} - -void GSState::WriteCSR(UINT32 csr) -{ - m_rs.pCSR->ai32[1] = csr; -} - -void GSState::ReadFIFO(BYTE* pMem) -{ - GSPerfMonAutoTimer at(m_perfmon); - - FlushWriteTransfer(); - - LOG(_T("*** WARNING *** ReadFIFO(%08x)\n"), pMem); - ReadTransfer(pMem, 16); -} - -__declspec(align(16)) static BYTE tr1_buff[0x4000]; - -void GSState::Transfer1(BYTE* pMem, UINT32 addr) -{ -// GSPerfMonAutoTimer at(m_perfmon); - - LOG(_T("Transfer1(%08x, %d)\n"), pMem, addr); - - // TODO: this is too cheap... - addr &= 0x3fff; - memcpy(tr1_buff, pMem + addr, 0x4000 - addr); - memcpy(tr1_buff + 0x4000 - addr, pMem, addr); -/* - if((m_tag).NLOOP - && ((GIFTag*)tr1_buff)->NLOOP == 8 && ((GIFTag*)tr1_buff)->PRIM == 0x5b - && ((GIFTag*)tr1_buff)->NREG == 9 && ((GIFTag*)tr1_buff)->REGS == 0x0000000412412412ui64) - { - ASSERT(0); - } -*/ - ASSERT(m_path[1].m_tag.NLOOP == 0 && m_path[2].m_tag.NLOOP == 0); - - Transfer(tr1_buff, -1, m_path[0]); -} - -void GSState::Transfer2(BYTE* pMem, UINT32 size) -{ - ASSERT(m_path[0].m_tag.NLOOP == 0 && m_path[2].m_tag.NLOOP == 0); - - Transfer(pMem, size, m_path[1]); -} - -void GSState::Transfer3(BYTE* pMem, UINT32 size) -{ - ASSERT(m_path[0].m_tag.NLOOP == 0 && m_path[1].m_tag.NLOOP == 0); - - Transfer(pMem, size, m_path[2]); -} - -int Path3hack = 0; - -void GSState::Transfer(BYTE* pMem, UINT32 size, GIFPath& path) -{ - GSPerfMonAutoTimer at(m_perfmon); - - BYTE* pMemOrg = pMem; - UINT32 sizeOrg = size; - - while(size > 0) - { - LOG(_T("Transfer(%08x, %d) START\n"), pMem, size); - - bool fEOP = false; - - if(path.m_tag.NLOOP == 0) - { - path.m_tag = *(GIFTag*)pMem; - path.m_nreg = 0; - m_q = 1.0f; -/* - LOG(_T("GIFTag NLOOP=%x EOP=%x PRE=%x PRIM=%x FLG=%x NREG=%x REGS=%x\n"), - m_tag.NLOOP, - m_tag.EOP, - m_tag.PRE, - m_tag.PRIM, - m_tag.FLG, - m_tag.NREG, - m_tag.REGS); -*/ - pMem += sizeof(GIFTag); - size--; - if(&path == &m_path[2] && path.m_tag.EOP) Path3hack = 1; - if(path.m_tag.PRE) - { - LOG(_T("PRE ")); - GIFReg r; - r.i64 = path.m_tag.PRIM; - (this->*m_fpGIFRegHandlers[GIF_A_D_REG_PRIM])(&r); - } - - if(path.m_tag.EOP) - { - LOG(_T("EOP\n")); - fEOP = true; - } - else if(path.m_tag.NLOOP == 0) - { - if(m_fNloopHack && &path == &m_path[0]) - continue; - - LOG(_T("*** WARNING *** m_tag.NLOOP == 0 && EOP == 0\n")); - fEOP = true; - // ASSERT(0); - } - } - - UINT32 size_msb = size & (1<<31); - - switch(path.m_tag.FLG) - { - case GIF_FLG_PACKED: - for(GIFPackedReg* r = (GIFPackedReg*)pMem; path.m_tag.NLOOP > 0 && size > 0; r++, size--, pMem += sizeof(GIFPackedReg)) - { - DWORD reg = GET_GIF_REG(path.m_tag, path.m_nreg); - (this->*m_fpGIFPackedRegHandlers[reg])(r); - if((path.m_nreg = (path.m_nreg+1)&0xf) == path.m_tag.NREG) {path.m_nreg = 0; path.m_tag.NLOOP--;} - } - break; - case GIF_FLG_REGLIST: - size *= 2; - for(GIFReg* r = (GIFReg*)pMem; path.m_tag.NLOOP > 0 && size > 0; r++, size--, pMem += sizeof(GIFReg)) - { - DWORD reg = GET_GIF_REG(path.m_tag, path.m_nreg); - (this->*m_fpGIFRegHandlers[reg])(r); - if((path.m_nreg = (path.m_nreg+1)&0xf) == path.m_tag.NREG) {path.m_nreg = 0; path.m_tag.NLOOP--;} - } - if(size&1) pMem += sizeof(GIFReg); - size /= 2; - size |= size_msb; // a bit lame :P - break; - case GIF_FLG_IMAGE2: - LOG(_T("*** WARNING **** Unexpected GIFTag flag\n")); -path.m_tag.NLOOP = 0; -break; - ASSERT(0); - case GIF_FLG_IMAGE: - { - int len = min(size, path.m_tag.NLOOP); - //ASSERT(!(len&3)); - switch(m_de.TRXDIR.XDIR) - { - case 0: - WriteTransfer(pMem, len*16); - break; - case 1: - ReadTransfer(pMem, len*16); - break; - case 2: - //MoveTransfer(); - break; - case 3: - ASSERT(0); - break; - default: - __assume(0); - } - pMem += len*16; - path.m_tag.NLOOP -= len; - size -= len; - } - break; - default: - __assume(0); - } - - LOG(_T("Transfer(%08x, %d) END\n"), pMem, size); - - if(fEOP && (INT32)size <= 0) - { - break; - } - } - -#ifdef ENABLE_CAPTURE_STATE - if(m_sfp) - { - fputc(ST_TRANSFER, m_sfp); - fwrite(&sizeOrg, 4, 1, m_sfp); - UINT32 len = (UINT32)(pMem - pMemOrg); - fwrite(&len, 4, 1, m_sfp); - fwrite(pMemOrg, len, 1, m_sfp); - } -#endif -} - -UINT32 GSState::MakeSnapshot(char* path) -{ - GSPerfMonAutoTimer at(m_perfmon); - - CString fn; - fn.Format(_T("%sgsdx9_%s.bmp"), CString(path), CTime::GetCurrentTime().Format(_T("%Y%m%d%H%M%S"))); - return D3DXSaveSurfaceToFile(fn, D3DXIFF_BMP, m_pOrgRenderTarget, NULL, NULL); -} - -void GSState::Capture() -{ - GSPerfMonAutoTimer at(m_perfmon); - - if(!m_capture.IsCapturing()) m_capture.BeginCapture(m_pD3DDev, m_rs.GetFPS()); - else m_capture.EndCapture(); -} - -void GSState::ToggleOSD() -{ - if(m_d3dpp.Windowed) - { - if(m_iOSD == 1) SetWindowText(m_hWnd, m_strDefaultTitle); - m_iOSD = ++m_iOSD % 3; - } - else - { - m_iOSD = m_iOSD ? 0 : 2; - } -} - -void GSState::CaptureState(CString fn) -{ -#ifdef ENABLE_CAPTURE_STATE - if(!m_sfp) m_sfp = !fn.IsEmpty() ? _tfopen(fn, _T("wb")) : NULL; -#endif -} - -void GSState::VSync(int field) -{ - GSPerfMonAutoTimer at(m_perfmon); - - LOG(_T("VSync(%d) %d\n"), field, m_perfmon.GetFrame()); - - m_fField = !!field; - -#ifdef ENABLE_CAPTURE_STATE - if(m_sfp) fputc(ST_VSYNC, m_sfp); -#endif - - FlushPrimInternal(); - - Flip(); - - EndFrame(); -} - -void GSState::Reset() -{ - GSPerfMonAutoTimer at(m_perfmon); - - memset(&m_de, 0, sizeof(m_de)); - memset(m_path, 0, sizeof(m_path)); - memset(&m_v, 0, sizeof(m_v)); - -// m_de.PRMODECONT.AC = 1; - -// m_pPRIM = &m_de.PRIM; - m_PRIM = 8; - - m_ctxt = &m_de.CTXT[0]; - - m_de.CTXT[0].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].FRAME.PSM]; - m_de.CTXT[0].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].ZBUF.PSM]; - m_de.CTXT[0].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[0].TEX0.PSM]; - - m_de.CTXT[1].ftbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].FRAME.PSM]; - m_de.CTXT[1].ztbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].ZBUF.PSM]; - m_de.CTXT[1].ttbl = &GSLocalMemory::m_psmtbl[m_de.CTXT[1].TEX0.PSM]; - - if(m_pD3DDev) m_pD3DDev->Clear(0, NULL, D3DCLEAR_TARGET/*|D3DCLEAR_ZBUFFER|D3DCLEAR_STENCIL*/, 0, 1.0f, 0); -} - -void GSState::FinishFlip(FlipInfo rt[2]) -{ - HRESULT hr; - - bool fEN[2]; - CRect src[2]; - - for(int i = 0; i < countof(fEN); i++) - { - fEN[i] = m_rs.IsEnabled(i) && rt[i].pRT; - - if(fEN[i]) - { - CRect r = m_rs.GetDispRect(i); - - src[i] = CRect( - (int)(rt[i].scale.x * r.left), - (int)(rt[i].scale.y * r.top), - (int)(rt[i].scale.x * r.right), - (int)(rt[i].scale.y * r.bottom)); - - if(m_rs.pSMODE2->INT && m_rs.pSMODE2->FFMD) - src[i].bottom /= 2; - } - else - { - rt[i].rd.Width = rt[i].rd.Height = 1; // to avoid div by zero below - } - } - - CRect dst(0, 0, m_bd.Width, m_bd.Height); - - struct - { - float x, y, z, rhw; - float tu1, tv1; - float tu2, tv2; - } - pVertices[] = - { - {(float)dst.left, (float)dst.top, 0.5f, 2.0f, - (float)src[0].left / rt[0].rd.Width, (float)src[0].top / rt[0].rd.Height, - (float)src[1].left / rt[1].rd.Width, (float)src[1].top / rt[1].rd.Height}, - {(float)dst.right, (float)dst.top, 0.5f, 2.0f, - (float)src[0].right / rt[0].rd.Width, (float)src[0].top / rt[0].rd.Height, - (float)src[1].right / rt[1].rd.Width, (float)src[1].top / rt[1].rd.Height}, - {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, - (float)src[0].left / rt[0].rd.Width, (float)src[0].bottom / rt[0].rd.Height, - (float)src[1].left / rt[1].rd.Width, (float)src[1].bottom / rt[1].rd.Height}, - {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, - (float)src[0].right / rt[0].rd.Width, (float)src[0].bottom / rt[0].rd.Height, - (float)src[1].right / rt[1].rd.Width, (float)src[1].bottom / rt[1].rd.Height}, - }; - -/* - if(m_rs.pSMODE2->INT) - { - if(!m_rs.pSMODE2->FFMD) - { - // m_rs.pCSR->rFIELD = 1 - m_rs.pCSR->rFIELD; - } - else if(!m_rs.pCSR->rFIELD) - { - // if(m_rs.pCSR->rFIELD == 0) m_rs.pCSR->rFIELD = 1; // FIXME: might stop a few games, but this is the only way to stop shaking the bios or sfae - - for(int i = 0; i < countof(pVertices); i++) - { - pVertices[i].tv1 += rt[0].scale.y*0.5f / rt[0].rd.Height; - pVertices[i].tv2 += rt[1].scale.y*0.5f / rt[1].rd.Height; - } - } - } -*/ - - if(m_fField /*m_rs.pCSR->rFIELD*/ && m_rs.pSMODE2->INT /*&& m_rs.pSMODE2->FFMD*/) - { - for(int i = 0; i < countof(pVertices); i++) - { - pVertices[i].tv1 += rt[0].scale.y*0.5f / rt[0].rd.Height; - pVertices[i].tv2 += rt[1].scale.y*0.5f / rt[1].rd.Height; - } - } - - hr = m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - hr = m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - hr = m_pD3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - hr = m_pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RGBA); - - hr = m_pD3DDev->SetTexture(0, rt[0].pRT); - hr = m_pD3DDev->SetTexture(1, rt[1].pRT); - - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); - hr = m_pD3DDev->SetTextureStageState(1, D3DTSS_TEXCOORDINDEX, 1); - - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - hr = m_pD3DDev->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - - IDirect3DPixelShader9* pPixelShader = NULL; - - if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(2, 0) && m_pHLSLMerge[PS_M32]) - { - pPixelShader = m_pHLSLMerge[PS_M32]; - } - - if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 4)) - { - if(fEN[0] && fEN[1]) // RAO1 + RAO2 - { - pPixelShader = m_pPixelShaders[PS14_EN11]; - } - else if(fEN[0]) // RAO1 - { - pPixelShader = m_pPixelShaders[PS14_EN10]; - } - else if(fEN[1]) // RAO2 - { - pPixelShader = m_pPixelShaders[PS14_EN01]; - } - } - - if(!pPixelShader && m_caps.PixelShaderVersion >= D3DPS_VERSION(1, 1)) - { - if(fEN[0] && fEN[1]) // RAO1 + RAO2 - { - pPixelShader = m_pPixelShaders[PS11_EN11]; - } - else if(fEN[0]) // RAO1 - { - pPixelShader = m_pPixelShaders[PS11_EN10]; - } - else if(fEN[1]) // RAO2 - { - pPixelShader = m_pPixelShaders[PS11_EN01]; - } - } - - if(!pPixelShader) - { - int stage = 0; - - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - stage++; - - if(fEN[0] && fEN[1]) // RAO1 + RAO2 - { - if(m_rs.pPMODE->ALP < 0xff) - { - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_LERP); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_CURRENT); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, m_rs.pPMODE->SLBG ? D3DTA_CONSTANT : D3DTA_TEXTURE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG0, D3DTA_ALPHAREPLICATE|(m_rs.pPMODE->MMOD ? D3DTA_CONSTANT : D3DTA_TEXTURE)); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_CONSTANT, D3DCOLOR_ARGB(m_rs.pPMODE->ALP, m_rs.pBGCOLOR->R, m_rs.pBGCOLOR->G, m_rs.pBGCOLOR->B)); - stage++; - } - } - else if(fEN[0]) // RAO1 - { - if(m_rs.pPMODE->ALP < 0xff) - { - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_MODULATE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG1, D3DTA_CURRENT); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLORARG2, D3DTA_ALPHAREPLICATE|(m_rs.pPMODE->MMOD ? D3DTA_CONSTANT : D3DTA_TEXTURE)); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_CONSTANT, D3DCOLOR_ARGB(m_rs.pPMODE->ALP, 0, 0, 0)); - stage++; - } - } - else if(fEN[1]) // RAO2 - { - hr = m_pD3DDev->SetTexture(0, rt[1].pRT); - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 1); - - // FIXME - hr = m_pD3DDev->SetTextureStageState(0, D3DTSS_TEXCOORDINDEX, 0); - for(int i = 0; i < countof(pVertices); i++) - { - pVertices[i].tu1 = pVertices[i].tu2; - pVertices[i].tv1 = pVertices[i].tv2; - } - } - - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_COLOROP, D3DTOP_DISABLE); - hr = m_pD3DDev->SetTextureStageState(stage, D3DTSS_ALPHAOP, D3DTOP_DISABLE); - } - - if(pPixelShader) - { - const float c[] = - { - (float)m_rs.pBGCOLOR->B / 255, (float)m_rs.pBGCOLOR->G / 255, (float)m_rs.pBGCOLOR->R / 255, (float)m_rs.pPMODE->ALP / 255, - (float)m_rs.pPMODE->AMOD - 0.1f, (float)m_rs.IsEnabled(0), (float)m_rs.IsEnabled(1), (float)m_rs.pPMODE->MMOD - 0.1f, - (float)m_de.TEXA.AEM, (float)m_de.TEXA.TA0 / 255, (float)m_de.TEXA.TA1 / 255, (float)m_rs.pPMODE->SLBG - 0.1f - }; - - hr = m_pD3DDev->SetPixelShaderConstantF(0, c, countof(c)/4); - } - - if(fEN[0] || fEN[1]) - { - if(m_pTmpRenderTarget && m_pHLSLRedBlue) - { - CComPtr pSurf; - hr = m_pTmpRenderTarget->GetSurfaceLevel(0, &pSurf); - hr = m_pD3DDev->SetRenderTarget(0, pSurf); - } - else - { - hr = m_pD3DDev->SetRenderTarget(0, m_pOrgRenderTarget); - } - - hr = m_pD3DDev->BeginScene(); - - hr = m_pD3DDev->SetPixelShader(pPixelShader); - hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW|D3DFVF_TEX2); - hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0])); - - int w, h; - CComPtr pRTSurf; - - if(m_capture.BeginFrame(w, h, &pRTSurf)) - { - pVertices[0].x = pVertices[0].y = pVertices[2].x = pVertices[1].y = 0; - pVertices[1].x = pVertices[3].x = (float)w; - pVertices[2].y = pVertices[3].y = (float)h; - for(int i = 0; i < countof(pVertices); i++) {pVertices[i].x -= 0.5; pVertices[i].y -= 0.5;} - hr = m_pD3DDev->SetRenderTarget(0, pRTSurf); - hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0])); - m_capture.EndFrame(); - } - - hr = m_pD3DDev->EndScene(); - - if(m_pTmpRenderTarget && m_pHLSLRedBlue) - { - hr = m_pD3DDev->SetRenderTarget(0, m_pOrgRenderTarget); - hr = m_pD3DDev->SetTexture(0, m_pTmpRenderTarget); - - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - hr = m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - - hr = m_pD3DDev->SetPixelShader(m_pHLSLRedBlue); - - struct - { - float x, y, z, rhw; - float tu, tv; - } - pVertices[] = - { - {0, 0, 0.5f, 2.0f, 0, 0}, - {(float)m_bd.Width, 0, 0.5f, 2.0f, 1, 0}, - {0, (float)m_bd.Height, 0.5f, 2.0f, 0, 1}, - {(float)m_bd.Width, (float)m_bd.Height, 0.5f, 2.0f, 1, 1}, - }; - - hr = m_pD3DDev->BeginScene(); - hr = m_pD3DDev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - hr = m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0])); - hr = m_pD3DDev->EndScene(); - } - } - - // - - m_perfmon.IncCounter(GSPerfMon::c_frame); - - static CString s_stats; - - if(!(m_perfmon.GetFrame()&15)) - { - s_stats = m_perfmon.ToString(m_rs.GetFPS()); - // stats.Format(_T("%s - %.2f MB"), CString(stats), 1.0f*m_pD3DDev->GetAvailableTextureMem()/1024/1024); - - if(m_iOSD == 1) - { - SetWindowText(m_hWnd, s_stats); - } - } - - if(m_iOSD == 2) - { - CString str; - str.Format( - _T("\n") - _T("SMODE2.INT=%d, SMODE2.FFMD=%d, XYOFFSET.OFY=%.2f, CSR.FIELD=%d, m_fField = %d\n") - _T("[%c] DBX=%d, DBY=%d, DW=%d, DH=%d | [%c] DBX=%d, DBY=%d, DW=%d, DH=%d\n"), - m_rs.pSMODE2->INT, m_rs.pSMODE2->FFMD, (float)m_ctxt->XYOFFSET.OFY / 16, m_rs.pCSR->rFIELD, m_fField, - fEN[0] ? 'o' : 'x', m_rs.pDISPFB[0]->DBX, m_rs.pDISPFB[0]->DBY, m_rs.pDISPLAY[0]->DW + 1, m_rs.pDISPLAY[0]->DH + 1, - fEN[1] ? 'o' : 'x', m_rs.pDISPFB[1]->DBX, m_rs.pDISPFB[1]->DBY, m_rs.pDISPLAY[1]->DW + 1, m_rs.pDISPLAY[1]->DH + 1); - - str = s_stats + str; - - hr = m_pD3DDev->BeginScene(); - CRect r = dst; - D3DCOLOR c = D3DCOLOR_ARGB(255, 0, 255, 0); - if(m_pD3DXFont->DrawText(NULL, str, -1, &r, DT_CALCRECT|DT_LEFT|DT_WORDBREAK, c)) - m_pD3DXFont->DrawText(NULL, str, -1, &r, DT_LEFT|DT_WORDBREAK, c); - hr = m_pD3DDev->EndScene(); - } -/* - // this suxx - - REFERENCE_TIME rtTimePerFrame = 10000000i64 / m_rs.GetFPS(); - - REFERENCE_TIME rtNow = 0; - hr = m_pRefClock->GetTime(&rtNow); - - DWORD_PTR dwAdviseCookie = 0; - hr = m_pRefClock->AdviseTime((rtNow / rtTimePerFrame + 1) * rtTimePerFrame, 0, (HEVENT)(HANDLE)m_evVSync, &dwAdviseCookie); - if(!m_evVSync.Wait((DWORD)(rtTimePerFrame / 10000))) hr = m_pRefClock->Unadvise(dwAdviseCookie); -*/ - // - - hr = m_pD3DDev->Present(NULL, NULL, NULL, NULL); -} - -void GSState::FlushPrimInternal() -{ - FlushWriteTransfer(); - - FlushPrim(); -} diff --git a/plugins/gs/gsdx9/GSState.h b/plugins/gs/gsdx9/GSState.h deleted file mode 100644 index 4699760b57..0000000000 --- a/plugins/gs/gsdx9/GSState.h +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "GS.h" -#include "GSWnd.h" -#include "GSLocalMemory.h" -#include "GSTextureCache.h" -#include "GSSoftVertex.h" -#include "GSVertexList.h" -#include "GSCapture.h" -#include "GSPerfMon.h" -// -//#define ENABLE_CAPTURE_STATE -// - -/* -//#define DEBUG_SAVETEXTURES -#define DEBUG_LOG -#define DEBUG_LOG2 -#define DEBUG_LOGVERTICES -#define DEBUG_RENDERTARGETS -*/ - -#define D3DCOLORWRITEENABLE_RGB (D3DCOLORWRITEENABLE_RED|D3DCOLORWRITEENABLE_GREEN|D3DCOLORWRITEENABLE_BLUE) -#define D3DCOLORWRITEENABLE_RGBA (D3DCOLORWRITEENABLE_RGB|D3DCOLORWRITEENABLE_ALPHA) - -struct GSDrawingContext -{ - struct GSDrawingContext() {memset(this, 0, sizeof(*this));} - - GIFRegXYOFFSET XYOFFSET; - GIFRegTEX0 TEX0; - GIFRegTEX1 TEX1; - GIFRegTEX2 TEX2; - GIFRegCLAMP CLAMP; - GIFRegMIPTBP1 MIPTBP1; - GIFRegMIPTBP2 MIPTBP2; - GIFRegSCISSOR SCISSOR; - GIFRegALPHA ALPHA; - GIFRegTEST TEST; - GIFRegFBA FBA; - GIFRegFRAME FRAME; - GIFRegZBUF ZBUF; - - GSLocalMemory::psmtbl_t* ftbl; - GSLocalMemory::psmtbl_t* ztbl; - GSLocalMemory::psmtbl_t* ttbl; -}; - -struct GSDrawingEnvironment -{ - struct GSDrawingEnvironment() {memset(this, 0, sizeof(*this));} - - GIFRegPRIM PRIM; - GIFRegPRMODE PRMODE; - GIFRegPRMODECONT PRMODECONT; - GIFRegTEXCLUT TEXCLUT; - GIFRegSCANMSK SCANMSK; - GIFRegTEXA TEXA; - GIFRegFOGCOL FOGCOL; - GIFRegDIMX DIMX; - GIFRegDTHE DTHE; - GIFRegCOLCLAMP COLCLAMP; - GIFRegPABE PABE; - GSDrawingContext CTXT[2]; - - GIFRegBITBLTBUF BITBLTBUF; - GIFRegTRXDIR TRXDIR; - GIFRegTRXPOS TRXPOS; - GIFRegTRXREG TRXREG, TRXREG2; -}; - -struct GSRegSet -{ - GSRegPMODE* pPMODE; - GSRegSMODE1* pSMODE1; - GSRegSMODE2* pSMODE2; - GSRegDISPFB* pDISPFB[2]; - GSRegDISPLAY* pDISPLAY[2]; - GSRegEXTBUF* pEXTBUF; - GSRegEXTDATA* pEXTDATA; - GSRegEXTWRITE* pEXTWRITE; - GSRegBGCOLOR* pBGCOLOR; - GSRegCSR* pCSR; - GSRegIMR* pIMR; - GSRegBUSDIR* pBUSDIR; - GSRegSIGLBLID* pSIGLBLID; - - struct GSRegSet() - { - memset(this, 0, sizeof(*this)); - - extern BYTE* g_pBasePS2Mem; - - ASSERT(g_pBasePS2Mem); - - pPMODE = (GSRegPMODE*)(g_pBasePS2Mem + GS_PMODE); - pSMODE1 = (GSRegSMODE1*)(g_pBasePS2Mem + GS_SMODE1); - pSMODE2 = (GSRegSMODE2*)(g_pBasePS2Mem + GS_SMODE2); - // pSRFSH = (GSRegPMODE*)(g_pBasePS2Mem + GS_SRFSH); - // pSYNCH1 = (GSRegPMODE*)(g_pBasePS2Mem + GS_SYNCH1); - // pSYNCH2 = (GSRegPMODE*)(g_pBasePS2Mem + GS_SYNCH2); - // pSYNCV = (GSRegPMODE*)(g_pBasePS2Mem + GS_SYNCV); - pDISPFB[0] = (GSRegDISPFB*)(g_pBasePS2Mem + GS_DISPFB1); - pDISPFB[1] = (GSRegDISPFB*)(g_pBasePS2Mem + GS_DISPFB2); - pDISPLAY[0] = (GSRegDISPLAY*)(g_pBasePS2Mem + GS_DISPLAY1); - pDISPLAY[1] = (GSRegDISPLAY*)(g_pBasePS2Mem + GS_DISPLAY2); - pEXTBUF = (GSRegEXTBUF*)(g_pBasePS2Mem + GS_EXTBUF); - pEXTDATA = (GSRegEXTDATA*)(g_pBasePS2Mem + GS_EXTDATA); - pEXTWRITE = (GSRegEXTWRITE*)(g_pBasePS2Mem + GS_EXTWRITE); - pBGCOLOR = (GSRegBGCOLOR*)(g_pBasePS2Mem + GS_BGCOLOR); - pCSR = (GSRegCSR*)(g_pBasePS2Mem + GS_CSR); - pIMR = (GSRegIMR*)(g_pBasePS2Mem + GS_IMR); - pBUSDIR = (GSRegBUSDIR*)(g_pBasePS2Mem + GS_BUSDIR); - pSIGLBLID = (GSRegSIGLBLID*)(g_pBasePS2Mem + GS_SIGLBLID); - } - - CSize GetDispSize(int en) - { - ASSERT(en >= 0 && en < 2); - CSize size; - size.cx = (pDISPLAY[en]->DW + 1) / (pDISPLAY[en]->MAGH + 1); - size.cy = (pDISPLAY[en]->DH + 1) / (pDISPLAY[en]->MAGV + 1); - //if(pSMODE2->INT && pSMODE2->FFMD && size.cy > 1) size.cy >>= 1; - return size; - } - - CRect GetDispRect(int en) - { - ASSERT(en >= 0 && en < 2); - return CRect(CPoint(pDISPFB[en]->DBX, pDISPFB[en]->DBY), GetDispSize(en)); - } - - bool IsEnabled(int en) - { - ASSERT(en >= 0 && en < 2); - if(en == 0 && pPMODE->EN1) {return(pDISPLAY[0]->DW || pDISPLAY[0]->DH);} - else if(en == 1 && pPMODE->EN2) {return(pDISPLAY[1]->DW || pDISPLAY[1]->DH);} - return(false); - } - - int GetFPS() - { - return ((pSMODE1->CMOD&1) ? 50 : 60) / (pSMODE2->INT ? 1 : 2); - } -}; - -struct GSVertex -{ - GIFRegRGBAQ RGBAQ; - GIFRegST ST; - GIFRegUV UV; - GIFRegXYZ XYZ; - GIFRegFOG FOG; -}; - -struct GIFPath -{ - GIFTag m_tag; - int m_nreg; -}; - -class GSState -{ - friend class GSTextureCache; - -protected: - static const int m_version = 4; - - GIFPath m_path[3]; - GSLocalMemory m_lm; - GSDrawingEnvironment m_de; - GSDrawingContext* m_ctxt; - GSRegSet m_rs; - GSVertex m_v; - float m_q; - GSPerfMon m_perfmon; - GSCapture m_capture; - -private: - static const int m_nTrMaxBytes = 1024*1024*4; - int m_nTrBytes; - BYTE* m_pTrBuff; - int m_x, m_y; - void WriteStep(); - void ReadStep(); - void WriteTransfer(BYTE* pMem, int len); - void FlushWriteTransfer(); - void ReadTransfer(BYTE* pMem, int len); - void MoveTransfer(); - -protected: - HWND m_hWnd; - int m_width, m_height; - CComPtr m_pD3D; - CComPtr m_pD3DDev; - CComPtr m_pD3DXFont; - CComPtr m_pOrgRenderTarget; - CComPtr m_pTmpRenderTarget; - CComPtr m_pPixelShaders[20]; - CComPtr m_pHLSLTFX[38], m_pHLSLMerge[3], m_pHLSLRedBlue; - enum {PS11_EN11 = 12, PS11_EN01 = 13, PS11_EN10 = 14, PS11_EN00 = 15}; - enum {PS14_EN11 = 16, PS14_EN01 = 17, PS14_EN10 = 18, PS14_EN00 = 19}; - enum {PS_M16 = 0, PS_M24 = 1, PS_M32 = 2}; - D3DPRESENT_PARAMETERS m_d3dpp; - DDCAPS m_ddcaps; - D3DCAPS9 m_caps; - D3DSURFACE_DESC m_bd; - D3DFORMAT m_fmtDepthStencil; - bool m_fEnablePalettizedTextures; - bool m_fNloopHack; - bool m_fField; - D3DTEXTUREFILTERTYPE m_texfilter; - - virtual void VertexKick(bool fSkip) = 0; - virtual int DrawingKick(bool fSkip) = 0; - virtual void NewPrim() = 0; - virtual void FlushPrim() = 0; - virtual void Flip() = 0; - virtual void EndFrame() = 0; - virtual void InvalidateTexture(const GIFRegBITBLTBUF& BITBLTBUF, CRect r) {} - virtual void InvalidateLocalMem(DWORD TBP0, DWORD BW, DWORD PSM, CRect r) {} - virtual void MinMaxUV(int w, int h, CRect& r) {r.SetRect(0, 0, w, h);} - - struct FlipInfo {CComPtr pRT; D3DSURFACE_DESC rd; scale_t scale;}; - void FinishFlip(FlipInfo rt[2]); - - void FlushPrimInternal(); - - // - - - // FIXME: savestate - GIFRegPRIM* m_pPRIM; - UINT32 m_PRIM; - - void (*m_fpGSirq)(); - - typedef void (__fastcall GSState::*GIFPackedRegHandler)(GIFPackedReg* r); - GIFPackedRegHandler m_fpGIFPackedRegHandlers[16]; - - void __fastcall GIFPackedRegHandlerNull(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerPRIM(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerRGBA(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerSTQ(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerUV(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerXYZF2(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerXYZ2(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerTEX0_1(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerTEX0_2(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerCLAMP_1(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerCLAMP_2(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerFOG(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerXYZF3(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerXYZ3(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerA_D(GIFPackedReg* r); - void __fastcall GIFPackedRegHandlerNOP(GIFPackedReg* r); - - typedef void (__fastcall GSState::*GIFRegHandler)(GIFReg* r); - GIFRegHandler m_fpGIFRegHandlers[256]; - - void __fastcall GIFRegHandlerNull(GIFReg* r); - void __fastcall GIFRegHandlerPRIM(GIFReg* r); - void __fastcall GIFRegHandlerRGBAQ(GIFReg* r); - void __fastcall GIFRegHandlerST(GIFReg* r); - void __fastcall GIFRegHandlerUV(GIFReg* r); - void __fastcall GIFRegHandlerXYZF2(GIFReg* r); - void __fastcall GIFRegHandlerXYZ2(GIFReg* r); - void __fastcall GIFRegHandlerTEX0_1(GIFReg* r); - void __fastcall GIFRegHandlerTEX0_2(GIFReg* r); - void __fastcall GIFRegHandlerCLAMP_1(GIFReg* r); - void __fastcall GIFRegHandlerCLAMP_2(GIFReg* r); - void __fastcall GIFRegHandlerFOG(GIFReg* r); - void __fastcall GIFRegHandlerXYZF3(GIFReg* r); - void __fastcall GIFRegHandlerXYZ3(GIFReg* r); - void __fastcall GIFRegHandlerNOP(GIFReg* r); - void __fastcall GIFRegHandlerTEX1_1(GIFReg* r); - void __fastcall GIFRegHandlerTEX1_2(GIFReg* r); - void __fastcall GIFRegHandlerTEX2_1(GIFReg* r); - void __fastcall GIFRegHandlerTEX2_2(GIFReg* r); - void __fastcall GIFRegHandlerXYOFFSET_1(GIFReg* r); - void __fastcall GIFRegHandlerXYOFFSET_2(GIFReg* r); - void __fastcall GIFRegHandlerPRMODECONT(GIFReg* r); - void __fastcall GIFRegHandlerPRMODE(GIFReg* r); - void __fastcall GIFRegHandlerTEXCLUT(GIFReg* r); - void __fastcall GIFRegHandlerSCANMSK(GIFReg* r); - void __fastcall GIFRegHandlerMIPTBP1_1(GIFReg* r); - void __fastcall GIFRegHandlerMIPTBP1_2(GIFReg* r); - void __fastcall GIFRegHandlerMIPTBP2_1(GIFReg* r); - void __fastcall GIFRegHandlerMIPTBP2_2(GIFReg* r); - void __fastcall GIFRegHandlerTEXA(GIFReg* r); - void __fastcall GIFRegHandlerFOGCOL(GIFReg* r); - void __fastcall GIFRegHandlerTEXFLUSH(GIFReg* r); - void __fastcall GIFRegHandlerSCISSOR_1(GIFReg* r); - void __fastcall GIFRegHandlerSCISSOR_2(GIFReg* r); - void __fastcall GIFRegHandlerALPHA_1(GIFReg* r); - void __fastcall GIFRegHandlerALPHA_2(GIFReg* r); - void __fastcall GIFRegHandlerDIMX(GIFReg* r); - void __fastcall GIFRegHandlerDTHE(GIFReg* r); - void __fastcall GIFRegHandlerCOLCLAMP(GIFReg* r); - void __fastcall GIFRegHandlerTEST_1(GIFReg* r); - void __fastcall GIFRegHandlerTEST_2(GIFReg* r); - void __fastcall GIFRegHandlerPABE(GIFReg* r); - void __fastcall GIFRegHandlerFBA_1(GIFReg* r); - void __fastcall GIFRegHandlerFBA_2(GIFReg* r); - void __fastcall GIFRegHandlerFRAME_1(GIFReg* r); - void __fastcall GIFRegHandlerFRAME_2(GIFReg* r); - void __fastcall GIFRegHandlerZBUF_1(GIFReg* r); - void __fastcall GIFRegHandlerZBUF_2(GIFReg* r); - void __fastcall GIFRegHandlerBITBLTBUF(GIFReg* r); - void __fastcall GIFRegHandlerTRXPOS(GIFReg* r); - void __fastcall GIFRegHandlerTRXREG(GIFReg* r); - void __fastcall GIFRegHandlerTRXDIR(GIFReg* r); - void __fastcall GIFRegHandlerHWREG(GIFReg* r); - void __fastcall GIFRegHandlerSIGNAL(GIFReg* r); - void __fastcall GIFRegHandlerFINISH(GIFReg* r); - void __fastcall GIFRegHandlerLABEL(GIFReg* r); - -public: - GSState(int w, int h, HWND hWnd, HRESULT& hr); - virtual ~GSState(); - - bool m_fMultiThreaded; - - virtual HRESULT ResetDevice(bool fForceWindowed = false); - - UINT32 Freeze(freezeData* fd, bool fSizeOnly); - UINT32 Defrost(const freezeData* fd); - virtual void Reset(); - void WriteCSR(UINT32 csr); - void ReadFIFO(BYTE* pMem); - void Transfer1(BYTE* pMem, UINT32 addr); - void Transfer2(BYTE* pMem, UINT32 size); - void Transfer3(BYTE* pMem, UINT32 size); - void Transfer(BYTE* pMem, UINT32 size, GIFPath& path); - void VSync(int field); - - void GSirq(void (*fpGSirq)()) {m_fpGSirq = fpGSirq;} - - UINT32 MakeSnapshot(char* path); - void Capture(); - - CString m_strDefaultTitle; - int m_iOSD; - void ToggleOSD(); - - // state - void CaptureState(CString fn); - FILE* m_sfp; - - // logging - FILE* m_fp; - -#ifdef DEBUG_LOGVERTICES - #define LOGV(_x_) LOGVERTEX _x_ -#else - #define LOGV(_x_) -#endif - -#ifdef DEBUG_LOG - void LOG(LPCTSTR fmt, ...) - { - va_list args; - va_start(args, fmt); - //////////// -/* - if(_tcsstr(fmt, _T("VSync")) - || _tcsstr(fmt, _T("*** WARNING ***")) - // || _tcsstr(fmt, _T("Flush")) - || _tcsstr(fmt, _T("CSR")) - || _tcsstr(fmt, _T("DISP")) - || _tcsstr(fmt, _T("FRAME")) - || _tcsstr(fmt, _T("ZBUF")) - || _tcsstr(fmt, _T("SMODE")) - || _tcsstr(fmt, _T("PMODE")) - || _tcsstr(fmt, _T("BITBLTBUF")) - || _tcsstr(fmt, _T("TRX")) - // || _tcsstr(fmt, _T("PRIM")) - // || _tcsstr(fmt, _T("RGB")) - // || _tcsstr(fmt, _T("XYZ")) - // || _tcsstr(fmt, _T("ST")) - // || _tcsstr(fmt, _T("XYOFFSET")) - // || _tcsstr(fmt, _T("TEX")) - || _tcsstr(fmt, _T("TEX0")) - // || _tcsstr(fmt, _T("TEX2")) - // || _tcsstr(fmt, _T("TEXFLUSH")) - // || _tcsstr(fmt, _T("UV")) - // || _tcsstr(fmt, _T("FOG")) - // || _tcsstr(fmt, _T("ALPHA")) - // || _tcsstr(fmt, _T("TBP0")) == fmt - // || _tcsstr(fmt, _T("CBP")) == fmt - // || _tcsstr(fmt, _T("*TC2 ")) == fmt - ) -*/ - if(m_fp) - { - TCHAR buff[2048]; - _stprintf(buff, _T("%d: "), clock()); - _vstprintf(buff + strlen(buff), fmt, args); - _fputts(buff, m_fp); - fflush(m_fp); - } - va_end(args); - } -#else -#define LOG __noop -#endif - -#ifdef DEBUG_LOG2 - void LOG2(LPCTSTR fmt, ...) - { - va_list args; - va_start(args, fmt); - if(m_fp) - { - TCHAR buff[2048]; - _stprintf(buff, _T("%d: "), clock()); - _vstprintf(buff + strlen(buff), fmt, args); - _fputts(buff, m_fp); - } - va_end(args); - } -#else -#define LOG2 __noop -#endif -}; diff --git a/plugins/gs/gsdx9/GSTables.cpp b/plugins/gs/gsdx9/GSTables.cpp deleted file mode 100644 index 9457505986..0000000000 --- a/plugins/gs/gsdx9/GSTables.cpp +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "gstables.h" - -DWORD blockTable32[4][8] = { - { 0, 1, 4, 5, 16, 17, 20, 21}, - { 2, 3, 6, 7, 18, 19, 22, 23}, - { 8, 9, 12, 13, 24, 25, 28, 29}, - { 10, 11, 14, 15, 26, 27, 30, 31} -}; - -DWORD blockTable32Z[4][8] = { - { 24, 25, 28, 29, 8, 9, 12, 13}, - { 26, 27, 30, 31, 10, 11, 14, 15}, - { 16, 17, 20, 21, 0, 1, 4, 5}, - { 18, 19, 22, 23, 2, 3, 6, 7} -}; - -DWORD blockTable16[8][4] = { - { 0, 2, 8, 10 }, - { 1, 3, 9, 11 }, - { 4, 6, 12, 14 }, - { 5, 7, 13, 15 }, - { 16, 18, 24, 26 }, - { 17, 19, 25, 27 }, - { 20, 22, 28, 30 }, - { 21, 23, 29, 31 } -}; - -DWORD blockTable16S[8][4] = { - { 0, 2, 16, 18 }, - { 1, 3, 17, 19 }, - { 8, 10, 24, 26 }, - { 9, 11, 25, 27 }, - { 4, 6, 20, 22 }, - { 5, 7, 21, 23 }, - { 12, 14, 28, 30 }, - { 13, 15, 29, 31 } -}; - -DWORD blockTable16Z[8][4] = { - { 24, 26, 16, 18 }, - { 25, 27, 17, 19 }, - { 28, 30, 20, 22 }, - { 29, 31, 21, 23 }, - { 8, 10, 0, 2 }, - { 9, 11, 1, 3 }, - { 12, 14, 4, 6 }, - { 13, 15, 5, 7 } -}; - -DWORD blockTable16SZ[8][4] = { - { 24, 26, 8, 10 }, - { 25, 27, 9, 11 }, - { 16, 18, 0, 2 }, - { 17, 19, 1, 3 }, - { 28, 30, 12, 14 }, - { 29, 31, 13, 15 }, - { 20, 22, 4, 6 }, - { 21, 23, 5, 7 } -}; - -DWORD blockTable8[4][8] = { - { 0, 1, 4, 5, 16, 17, 20, 21}, - { 2, 3, 6, 7, 18, 19, 22, 23}, - { 8, 9, 12, 13, 24, 25, 28, 29}, - { 10, 11, 14, 15, 26, 27, 30, 31} -}; - -DWORD blockTable4[8][4] = { - { 0, 2, 8, 10 }, - { 1, 3, 9, 11 }, - { 4, 6, 12, 14 }, - { 5, 7, 13, 15 }, - { 16, 18, 24, 26 }, - { 17, 19, 25, 27 }, - { 20, 22, 28, 30 }, - { 21, 23, 29, 31 } -}; - -DWORD columnTable32[8][8] = { - { 0, 1, 4, 5, 8, 9, 12, 13 }, - { 2, 3, 6, 7, 10, 11, 14, 15 }, - { 16, 17, 20, 21, 24, 25, 28, 29 }, - { 18, 19, 22, 23, 26, 27, 30, 31 }, - { 32, 33, 36, 37, 40, 41, 44, 45 }, - { 34, 35, 38, 39, 42, 43, 46, 47 }, - { 48, 49, 52, 53, 56, 57, 60, 61 }, - { 50, 51, 54, 55, 58, 59, 62, 63 }, -}; - -DWORD columnTable16[8][16] = { - { 0, 2, 8, 10, 16, 18, 24, 26, - 1, 3, 9, 11, 17, 19, 25, 27 }, - { 4, 6, 12, 14, 20, 22, 28, 30, - 5, 7, 13, 15, 21, 23, 29, 31 }, - { 32, 34, 40, 42, 48, 50, 56, 58, - 33, 35, 41, 43, 49, 51, 57, 59 }, - { 36, 38, 44, 46, 52, 54, 60, 62, - 37, 39, 45, 47, 53, 55, 61, 63 }, - { 64, 66, 72, 74, 80, 82, 88, 90, - 65, 67, 73, 75, 81, 83, 89, 91 }, - { 68, 70, 76, 78, 84, 86, 92, 94, - 69, 71, 77, 79, 85, 87, 93, 95 }, - { 96, 98, 104, 106, 112, 114, 120, 122, - 97, 99, 105, 107, 113, 115, 121, 123 }, - { 100, 102, 108, 110, 116, 118, 124, 126, - 101, 103, 109, 111, 117, 119, 125, 127 }, -}; - -DWORD columnTable8[16][16] = { - { 0, 4, 16, 20, 32, 36, 48, 52, // column 0 - 2, 6, 18, 22, 34, 38, 50, 54 }, - { 8, 12, 24, 28, 40, 44, 56, 60, - 10, 14, 26, 30, 42, 46, 58, 62 }, - { 33, 37, 49, 53, 1, 5, 17, 21, - 35, 39, 51, 55, 3, 7, 19, 23 }, - { 41, 45, 57, 61, 9, 13, 25, 29, - 43, 47, 59, 63, 11, 15, 27, 31 }, - { 96, 100, 112, 116, 64, 68, 80, 84, // column 1 - 98, 102, 114, 118, 66, 70, 82, 86 }, - { 104, 108, 120, 124, 72, 76, 88, 92, - 106, 110, 122, 126, 74, 78, 90, 94 }, - { 65, 69, 81, 85, 97, 101, 113, 117, - 67, 71, 83, 87, 99, 103, 115, 119 }, - { 73, 77, 89, 93, 105, 109, 121, 125, - 75, 79, 91, 95, 107, 111, 123, 127 }, - { 128, 132, 144, 148, 160, 164, 176, 180, // column 2 - 130, 134, 146, 150, 162, 166, 178, 182 }, - { 136, 140, 152, 156, 168, 172, 184, 188, - 138, 142, 154, 158, 170, 174, 186, 190 }, - { 161, 165, 177, 181, 129, 133, 145, 149, - 163, 167, 179, 183, 131, 135, 147, 151 }, - { 169, 173, 185, 189, 137, 141, 153, 157, - 171, 175, 187, 191, 139, 143, 155, 159 }, - { 224, 228, 240, 244, 192, 196, 208, 212, // column 3 - 226, 230, 242, 246, 194, 198, 210, 214 }, - { 232, 236, 248, 252, 200, 204, 216, 220, - 234, 238, 250, 254, 202, 206, 218, 222 }, - { 193, 197, 209, 213, 225, 229, 241, 245, - 195, 199, 211, 215, 227, 231, 243, 247 }, - { 201, 205, 217, 221, 233, 237, 249, 253, - 203, 207, 219, 223, 235, 239, 251, 255 }, -}; - -DWORD columnTable4[16][32] = { - { 0, 8, 32, 40, 64, 72, 96, 104, // column 0 - 2, 10, 34, 42, 66, 74, 98, 106, - 4, 12, 36, 44, 68, 76, 100, 108, - 6, 14, 38, 46, 70, 78, 102, 110 }, - { 16, 24, 48, 56, 80, 88, 112, 120, - 18, 26, 50, 58, 82, 90, 114, 122, - 20, 28, 52, 60, 84, 92, 116, 124, - 22, 30, 54, 62, 86, 94, 118, 126 }, - { 65, 73, 97, 105, 1, 9, 33, 41, - 67, 75, 99, 107, 3, 11, 35, 43, - 69, 77, 101, 109, 5, 13, 37, 45, - 71, 79, 103, 111, 7, 15, 39, 47 }, - { 81, 89, 113, 121, 17, 25, 49, 57, - 83, 91, 115, 123, 19, 27, 51, 59, - 85, 93, 117, 125, 21, 29, 53, 61, - 87, 95, 119, 127, 23, 31, 55, 63 }, - { 192, 200, 224, 232, 128, 136, 160, 168, // column 1 - 194, 202, 226, 234, 130, 138, 162, 170, - 196, 204, 228, 236, 132, 140, 164, 172, - 198, 206, 230, 238, 134, 142, 166, 174 }, - { 208, 216, 240, 248, 144, 152, 176, 184, - 210, 218, 242, 250, 146, 154, 178, 186, - 212, 220, 244, 252, 148, 156, 180, 188, - 214, 222, 246, 254, 150, 158, 182, 190 }, - { 129, 137, 161, 169, 193, 201, 225, 233, - 131, 139, 163, 171, 195, 203, 227, 235, - 133, 141, 165, 173, 197, 205, 229, 237, - 135, 143, 167, 175, 199, 207, 231, 239 }, - { 145, 153, 177, 185, 209, 217, 241, 249, - 147, 155, 179, 187, 211, 219, 243, 251, - 149, 157, 181, 189, 213, 221, 245, 253, - 151, 159, 183, 191, 215, 223, 247, 255 }, - { 256, 264, 288, 296, 320, 328, 352, 360, // column 2 - 258, 266, 290, 298, 322, 330, 354, 362, - 260, 268, 292, 300, 324, 332, 356, 364, - 262, 270, 294, 302, 326, 334, 358, 366 }, - { 272, 280, 304, 312, 336, 344, 368, 376, - 274, 282, 306, 314, 338, 346, 370, 378, - 276, 284, 308, 316, 340, 348, 372, 380, - 278, 286, 310, 318, 342, 350, 374, 382 }, - { 321, 329, 353, 361, 257, 265, 289, 297, - 323, 331, 355, 363, 259, 267, 291, 299, - 325, 333, 357, 365, 261, 269, 293, 301, - 327, 335, 359, 367, 263, 271, 295, 303 }, - { 337, 345, 369, 377, 273, 281, 305, 313, - 339, 347, 371, 379, 275, 283, 307, 315, - 341, 349, 373, 381, 277, 285, 309, 317, - 343, 351, 375, 383, 279, 287, 311, 319 }, - { 448, 456, 480, 488, 384, 392, 416, 424, // column 3 - 450, 458, 482, 490, 386, 394, 418, 426, - 452, 460, 484, 492, 388, 396, 420, 428, - 454, 462, 486, 494, 390, 398, 422, 430 }, - { 464, 472, 496, 504, 400, 408, 432, 440, - 466, 474, 498, 506, 402, 410, 434, 442, - 468, 476, 500, 508, 404, 412, 436, 444, - 470, 478, 502, 510, 406, 414, 438, 446 }, - { 385, 393, 417, 425, 449, 457, 481, 489, - 387, 395, 419, 427, 451, 459, 483, 491, - 389, 397, 421, 429, 453, 461, 485, 493, - 391, 399, 423, 431, 455, 463, 487, 495 }, - { 401, 409, 433, 441, 465, 473, 497, 505, - 403, 411, 435, 443, 467, 475, 499, 507, - 405, 413, 437, 445, 469, 477, 501, 509, - 407, 415, 439, 447, 471, 479, 503, 511 }, -}; diff --git a/plugins/gs/gsdx9/GSTables.h b/plugins/gs/gsdx9/GSTables.h deleted file mode 100644 index 73709c05d1..0000000000 --- a/plugins/gs/gsdx9/GSTables.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -extern DWORD blockTable32[4][8]; -extern DWORD blockTable32Z[4][8]; -extern DWORD blockTable16[8][4]; -extern DWORD blockTable16S[8][4]; -extern DWORD blockTable16Z[8][4]; -extern DWORD blockTable16SZ[8][4]; -extern DWORD blockTable8[4][8]; -extern DWORD blockTable4[8][4]; -extern DWORD columnTable32[8][8]; -extern DWORD columnTable16[8][16]; -extern DWORD columnTable8[16][16]; -extern DWORD columnTable4[16][32]; diff --git a/plugins/gs/gsdx9/GSTextureCache.cpp b/plugins/gs/gsdx9/GSTextureCache.cpp deleted file mode 100644 index ede3304a8e..0000000000 --- a/plugins/gs/gsdx9/GSTextureCache.cpp +++ /dev/null @@ -1,1226 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSTextureCache.h" -#include "GSHash.h" -#include "GSRendererHW.h" - -// - -bool IsRenderTarget(IDirect3DTexture9* pTexture) -{ - D3DSURFACE_DESC desc; - memset(&desc, 0, sizeof(desc)); - return pTexture && S_OK == pTexture->GetLevelDesc(0, &desc) && (desc.Usage&D3DUSAGE_RENDERTARGET); -} - -bool HasSharedBits(DWORD sbp, DWORD spsm, DWORD dbp, DWORD dpsm) -{ - if(sbp != dbp) return false; - - switch(spsm) - { - case PSM_PSMCT32: - case PSM_PSMCT16: - case PSM_PSMCT16S: - case PSM_PSMT8: - case PSM_PSMT4: - return true; - case PSM_PSMCT24: - return !(dpsm == PSM_PSMT8H || dpsm == PSM_PSMT4HL || dpsm == PSM_PSMT4HH); - case PSM_PSMT8H: - return !(dpsm == PSM_PSMCT24); - case PSM_PSMT4HL: - return !(dpsm == PSM_PSMCT24 || dpsm == PSM_PSMT4HH); - case PSM_PSMT4HH: - return !(dpsm == PSM_PSMCT24 || dpsm == PSM_PSMT4HL); - } - - return true; -} - -// - -GSDirtyRect::GSDirtyRect(DWORD PSM, CRect r) -{ - m_PSM = PSM; - m_rcDirty = r; -} - -CRect GSDirtyRect::GetDirtyRect(const GIFRegTEX0& TEX0) -{ - CRect rcDirty = m_rcDirty; - - CSize src = GSLocalMemory::m_psmtbl[m_PSM].bs; - rcDirty.left = (rcDirty.left) & ~(src.cx-1); - rcDirty.right = (rcDirty.right + (src.cx-1) /* + 1 */) & ~(src.cx-1); - rcDirty.top = (rcDirty.top) & ~(src.cy-1); - rcDirty.bottom = (rcDirty.bottom + (src.cy-1) /* + 1 */) & ~(src.cy-1); - - if(m_PSM != TEX0.PSM) - { - CSize dst = GSLocalMemory::m_psmtbl[TEX0.PSM].bs; - rcDirty.left = MulDiv(m_rcDirty.left, dst.cx, src.cx); - rcDirty.right = MulDiv(m_rcDirty.right, dst.cx, src.cx); - rcDirty.top = MulDiv(m_rcDirty.top, dst.cy, src.cy); - rcDirty.bottom = MulDiv(m_rcDirty.bottom, dst.cy, src.cy); - } - - rcDirty &= CRect(0, 0, 1<m_pTexture) {ASSERT(0); return E_FAIL;} - - int w = 1 << pt->m_TEX0.TW; - int h = 1 << pt->m_TEX0.TH; - - int bpp = 0; - D3DFORMAT fmt = D3DFMT_UNKNOWN; - D3DFORMAT palfmt = D3DFMT_UNKNOWN; - - switch(PSM) - { - default: - case PSM_PSMCT32: - bpp = 32; - fmt = D3DFMT_A8R8G8B8; - break; - case PSM_PSMCT24: - bpp = 32; - fmt = D3DFMT_X8R8G8B8; - break; - case PSM_PSMCT16: - case PSM_PSMCT16S: - bpp = 16; - fmt = D3DFMT_A1R5G5B5; - break; - case PSM_PSMT8: - case PSM_PSMT4: - case PSM_PSMT8H: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - bpp = 8; - fmt = D3DFMT_L8; - palfmt = CPSM == PSM_PSMCT32 ? D3DFMT_A8R8G8B8 : D3DFMT_A1R5G5B5; - break; - } - - pt->m_nBytes = w*h*bpp>>3; - - POSITION pos = m_pTexturePool.GetHeadPosition(); - while(pos) - { - IDirect3DTexture9* pTexture = m_pTexturePool.GetNext(pos); - - D3DSURFACE_DESC desc; - memset(&desc, 0, sizeof(desc)); - pTexture->GetLevelDesc(0, &desc); - - if(w == desc.Width && h == desc.Height && fmt == desc.Format && !IsTextureInCache(pTexture)) - { - pt->m_pTexture = pTexture; - pt->m_desc = desc; - break; - } - } - - if(!pt->m_pTexture) - { - while(m_pTexturePool.GetCount() > 20) - m_pTexturePool.RemoveTail(); - - if(FAILED(s->m_pD3DDev->CreateTexture(w, h, 1, 0, fmt, D3DPOOL_MANAGED, &pt->m_pTexture, NULL))) - return E_FAIL; - - pt->m_pTexture->GetLevelDesc(0, &pt->m_desc); - - m_pTexturePool.AddHead(pt->m_pTexture); - } - - if(bpp == 8) - { - if(FAILED(s->m_pD3DDev->CreateTexture(256, 1, 1, 0, palfmt, D3DPOOL_MANAGED, &pt->m_pPalette, NULL))) - { - pt->m_pTexture = NULL; - return E_FAIL; - } - } - - return S_OK; -} - -bool GSTextureCache::IsTextureInCache(IDirect3DTexture9* pTexture) -{ - POSITION pos = GetHeadPosition(); - while(pos) - { - if(GetNext(pos)->m_pTexture == pTexture) - return true; - } - - return false; -} - -void GSTextureCache::RemoveOldTextures(GSState* s) -{ - DWORD nBytes = 0; - - POSITION pos = GetHeadPosition(); - while(pos) nBytes += GetNext(pos)->m_nBytes; - - pos = GetTailPosition(); - while(pos && nBytes > 96*1024*1024/*s->m_ddcaps.dwVidMemTotal*/) - { -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 too many textures in cache (%d, %.2f MB)\n"), GetCount(), 1.0f*nBytes/1024/1024); -#endif - POSITION cur = pos; - - GSTexture* pt = GetPrev(pos); - if(!pt->m_fRT) - { - nBytes -= pt->m_nBytes; - RemoveAt(cur); - delete pt; - } - } -} - -static bool RectInRect(const RECT& inner, const RECT& outer) -{ - return outer.left <= inner.left && inner.right <= outer.right - && outer.top <= inner.top && inner.bottom <= outer.bottom; -} - -static bool RectInRectH(const RECT& inner, const RECT& outer) -{ - return outer.top <= inner.top && inner.bottom <= outer.bottom; -} - -static bool RectInRectV(const RECT& inner, const RECT& outer) -{ - return outer.left <= inner.left && inner.right <= outer.right; -} - -bool GSTextureCache::GetDirtyRect(GSState* s, GSTexture* pt, CRect& r) -{ - int w = 1 << pt->m_TEX0.TW; - int h = 1 << pt->m_TEX0.TH; - - r.SetRect(0, 0, w, h); - -// FIXME: kyo's left hand after being selected for player one (PS2-SNK_Vs_Capcom_SVC_Chaos_PAL_CDFull.iso) -// return true; - - s->MinMaxUV(w, h, r); - - CRect rcDirty = pt->m_rcDirty.GetDirtyRect(pt->m_TEX0); - CRect rcValid = pt->m_rcValid; - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 used %d,%d-%d,%d (%dx%d), valid %d,%d-%d,%d, dirty %d,%d-%d,%d\n"), r, w, h, rcValid, rcDirty); -#endif - - if(RectInRect(r, rcValid)) - { - if(rcDirty.IsRectEmpty()) return false; - else if(RectInRect(rcDirty, r)) r = rcDirty; - else if(RectInRect(rcDirty, rcValid)) r |= rcDirty; - else r = rcValid | rcDirty; - } - else - { - if(RectInRectH(r, rcValid) && (r.left >= rcValid.left || r.right <= rcValid.right)) - { - r.top = rcValid.top; - r.bottom = rcValid.bottom; - if(r.left < rcValid.left) r.right = rcValid.left; - else /*if(r.right > rcValid.right)*/ r.left = rcValid.right; - } - else if(RectInRectV(r, rcValid) && (r.top >= rcValid.top || r.bottom <= rcValid.bottom)) - { - r.left = rcValid.left; - r.right = rcValid.right; - if(r.top < rcValid.top) r.bottom = rcValid.top; - else /*if(r.bottom > rcValid.bottom)*/ r.top = rcValid.bottom; - } - else - { - r |= rcValid; - } - } - - return true; -} - -DWORD GSTextureCache::HashTexture(const CRect& r, int pitch, void* bits) -{ - // TODO: make the hash more unique - - BYTE* p = (BYTE*)bits; - DWORD hash = r.left + r.right + r.top + r.bottom + pitch + *(BYTE*)bits; - - if(r.Width() > 0) - { - int size = r.Width()*r.Height(); -/* - if(size <= 8*8) return rand(); // :P - else -*/ - if(size <= 16*16) hash += hash_crc(r, pitch, p); - else if(size <= 32*32) hash += hash_adler(r, pitch, p); - else hash += hash_checksum(r, pitch, p); - } - - return hash; -} - -HRESULT GSTextureCache::UpdateTexture(GSState* s, GSTexture* pt, GSLocalMemory::readTexture rt) -{ - CRect r; - if(!GetDirtyRect(s, pt, r)) - return S_OK; - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 updating texture %d,%d-%d,%d (%dx%d)\n"), r.left, r.top, r.right, r.bottom, 1 << pt->m_TEX0.TW, 1 << pt->m_TEX0.TH); -#endif - - int bpp = 0; - - switch(pt->m_desc.Format) - { - case D3DFMT_A8R8G8B8: bpp = 32; break; - case D3DFMT_X8R8G8B8: bpp = 32; break; - case D3DFMT_A1R5G5B5: bpp = 16; break; - case D3DFMT_L8: bpp = 8; break; - default: ASSERT(0); return E_FAIL; - } - - D3DLOCKED_RECT lr; - if(FAILED(pt->m_pTexture->LockRect(0, &lr, &r, D3DLOCK_NO_DIRTY_UPDATE))) {ASSERT(0); return E_FAIL;} - (s->m_lm.*rt)(r, (BYTE*)lr.pBits, lr.Pitch, s->m_ctxt->TEX0, s->m_de.TEXA, s->m_ctxt->CLAMP); - s->m_perfmon.IncCounter(GSPerfMon::c_unswizzle, r.Width()*r.Height()*bpp>>3); - pt->m_pTexture->UnlockRect(0); - - pt->m_rcValid |= r; - pt->m_rcDirty.RemoveAll(); - - const static DWORD limit = 7; - - if((pt->m_nHashDiff & limit) && pt->m_nHashDiff >= limit && pt->m_rcHash == pt->m_rcValid) // predicted to be dirty - { - pt->m_nHashDiff++; - } - else - { - if(FAILED(pt->m_pTexture->LockRect(0, &lr, &pt->m_rcValid, D3DLOCK_NO_DIRTY_UPDATE|D3DLOCK_READONLY))) {ASSERT(0); return E_FAIL;} - DWORD dwHash = HashTexture( - CRect((pt->m_rcValid.left>>2)*(bpp>>3), pt->m_rcValid.top, (pt->m_rcValid.right>>2)*(bpp>>3), pt->m_rcValid.bottom), - lr.Pitch, lr.pBits); - pt->m_pTexture->UnlockRect(0); - - if(pt->m_rcHash != pt->m_rcValid) - { - pt->m_nHashDiff = 0; - pt->m_nHashSame = 0; - pt->m_rcHash = pt->m_rcValid; - pt->m_dwHash = dwHash; - } - else - { - if(pt->m_dwHash != dwHash) - { - pt->m_nHashDiff++; - pt->m_nHashSame = 0; - pt->m_dwHash = dwHash; - } - else - { - if(pt->m_nHashDiff < limit) r.SetRect(0, 0, 1, 1); - // else pt->m_dwHash is not reliable, must update - pt->m_nHashDiff = 0; - pt->m_nHashSame++; - } - } - } - - pt->m_pTexture->AddDirtyRect(&r); - pt->m_pTexture->PreLoad(); - s->m_perfmon.IncCounter(GSPerfMon::c_texture, r.Width()*r.Height()*bpp>>3); - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 texture was updated, valid %d,%dx%d,%d\n"), pt->m_rcValid); -#endif - -#ifdef DEBUG_SAVETEXTURES -if(s->m_ctxt->FRAME.Block() == 0x00000 && pt->m_TEX0.TBP0 == 0x02800) -{ - CString fn; - fn.Format(_T("c:\\%08I64x_%I64d_%I64d_%I64d_%I64d_%I64d_%I64d_%I64d-%I64d_%I64d-%I64d.bmp"), - pt->m_TEX0.TBP0, pt->m_TEX0.PSM, pt->m_TEX0.TBW, - pt->m_TEX0.TW, pt->m_TEX0.TH, - pt->m_CLAMP.WMS, pt->m_CLAMP.WMT, pt->m_CLAMP.MINU, pt->m_CLAMP.MAXU, pt->m_CLAMP.MINV, pt->m_CLAMP.MAXV); - D3DXSaveTextureToFile(fn, D3DXIFF_BMP, pt->m_pTexture, NULL); -} -#endif - - return S_OK; -} - -GSTexture* GSTextureCache::ConvertRTPitch(GSState* s, GSTexture* pt) -{ - if(pt->m_TEX0.TBW == s->m_ctxt->TEX0.TBW) - return pt; - - // sfex3 uses this trick (bw: 10 -> 5, wraps the right side below the left) - ASSERT(pt->m_TEX0.TBW > s->m_ctxt->TEX0.TBW); // otherwise scale.x need to be reduced to make the larger texture fit (TODO) - - int bw = 64; - int bh = s->m_ctxt->TEX0.PSM == PSM_PSMCT32 || s->m_ctxt->TEX0.PSM == PSM_PSMCT24 ? 32 : 64; - - int sw = pt->m_TEX0.TBW << 6; - - int dw = s->m_ctxt->TEX0.TBW << 6; - int dh = 1 << s->m_ctxt->TEX0.TH; - - // TRACE(_T("ConvertRT: %05x %x %d -> %d\n"), (DWORD)s->m_ctxt->TEX0.TBP0, (DWORD)s->m_ctxt->TEX0.PSM, (DWORD)pt->m_TEX0.TBW, (DWORD)s->m_ctxt->TEX0.TBW); - - HRESULT hr; -/* -if(s->m_perfmon.GetFrame() > 400) -hr = D3DXSaveTextureToFile(_T("g:/1.bmp"), D3DXIFF_BMP, pt->m_pTexture, NULL); -*/ - D3DSURFACE_DESC desc; - hr = pt->m_pTexture->GetLevelDesc(0, &desc); - if(FAILED(hr)) return NULL; - - CComPtr pRT; - if(FAILED(hr = CreateRT(s, desc.Width, desc.Height, &pRT))) - return NULL; - - CComPtr pSrc, pDst; - hr = pRT->GetSurfaceLevel(0, &pSrc); - if(FAILED(hr)) return NULL; - hr = pt->m_pTexture->GetSurfaceLevel(0, &pDst); - if(FAILED(hr)) return NULL; - - hr = s->m_pD3DDev->StretchRect(pDst, NULL, pSrc, NULL, D3DTEXF_POINT); - if(FAILED(hr)) return NULL; - - scale_t scale(pt->m_pTexture); - - for(int dy = 0; dy < dh; dy += bh) - { - for(int dx = 0; dx < dw; dx += bw) - { - int o = dy * dw / bh + dx; - - int sx = o % sw; - int sy = o / sw; - - // TRACE(_T("%d,%d - %d,%d <= %d,%d - %d,%d\n"), dx, dy, dx + bw, dy + bh, sx, sy, sx + bw, sy + bh); - - CRect src, dst; - - src.left = (LONG)(scale.x * sx + 0.5f); - src.top = (LONG)(scale.y * sy + 0.5f); - src.right = (LONG)(scale.x * (sx + bw) + 0.5f); - src.bottom = (LONG)(scale.y * (sy + bh) + 0.5f); - - dst.left = (LONG)(scale.x * dx + 0.5f); - dst.top = (LONG)(scale.y * dy + 0.5f); - dst.right = (LONG)(scale.x * (dx + bw) + 0.5f); - dst.bottom = (LONG)(scale.y * (dy + bh) + 0.5f); - - hr = s->m_pD3DDev->StretchRect(pSrc, src, pDst, dst, D3DTEXF_POINT); - - // TODO: this is quite a lot of StretchRect call, do it with one DrawPrimUP - } - } - - pt->m_TEX0.TW = s->m_ctxt->TEX0.TW; - pt->m_TEX0.TBW = s->m_ctxt->TEX0.TBW; -/* -if(s->m_perfmon.GetFrame() > 400) -hr = D3DXSaveTextureToFile(_T("g:/2.bmp"), D3DXIFF_BMP, pt->m_pTexture, NULL); -*/ - - return pt; -} - -GSTexture* GSTextureCache::ConvertRTWidthHeight(GSState* s, GSTexture* pt) -{ - int tw = pt->m_scale.x * (1 << s->m_ctxt->TEX0.TW); - int th = pt->m_scale.y * (1 << s->m_ctxt->TEX0.TH); - - int rw = pt->m_desc.Width; - int rh = pt->m_desc.Height; - - if(tw != rw || th != rh) - //if(tw < rw && th <= rh || tw <= rw && th < rh) - { - GSTexture* pt2 = new GSTexture(); - - pt2->m_pPalette = pt->m_pPalette; - pt2->m_fRT = pt->m_pPalette == NULL; - pt2->m_scale = pt->m_scale; - pt2->m_fTemp = true; - - POSITION pos = pt->m_pSubTextures.GetHeadPosition(); - while(pos) - { - IDirect3DTexture9* pTexture = pt->m_pSubTextures.GetNext(pos); - pTexture->GetLevelDesc(0, &pt2->m_desc); - scale_t scale(pTexture); - if(pt2->m_desc.Width == tw && pt2->m_desc.Height == th - && pt2->m_scale.x == scale.x && pt2->m_scale.y == scale.y) - { - pt2->m_pTexture = pTexture; - break; - } - } - - if(!pt2->m_pTexture) - { - CRect dst(0, 0, tw, th); - - if(tw > rw) - { - pt2->m_scale.x = pt2->m_scale.x * rw / tw; - dst.right = rw * rw / tw; - tw = rw; - } - - if(th > rh) - { - pt2->m_scale.y = pt2->m_scale.y * rh / th; - dst.bottom = rh * rh / th; - th = rh; - } - - CRect src(0, 0, tw, th); - - HRESULT hr; - - if(FAILED(hr = CreateRT(s, tw, th, &pt2->m_pTexture)) || FAILED(hr = pt2->m_pTexture->GetLevelDesc(0, &pt2->m_desc))) - { - delete pt2; - return false; - } - - CComPtr pSrc, pDst; - hr = pt->m_pTexture->GetSurfaceLevel(0, &pSrc); - hr = pt2->m_pTexture->GetSurfaceLevel(0, &pDst); - - ASSERT(pSrc); - ASSERT(pDst); - - hr = s->m_pD3DDev->StretchRect(pSrc, src, pDst, dst, src == dst ? D3DTEXF_POINT : D3DTEXF_LINEAR); - - pt2->m_scale.Set(pt2->m_pTexture); - pt->m_pSubTextures.AddTail(pt2->m_pTexture); - } - - pt = pt2; - } - - return pt; -} - -HRESULT GSTextureCache::CreateRT(GSState* s, int w, int h, IDirect3DTexture9** ppRT) -{ - ASSERT(ppRT && *ppRT == NULL); - - HRESULT hr; - - POSITION pos = m_pRTPool.GetHeadPosition(); - while(pos) - { - IDirect3DTexture9* pRT = m_pRTPool.GetNext(pos); - D3DSURFACE_DESC desc; - pRT->GetLevelDesc(0, &desc); - if(desc.Width == w && desc.Height == h) - { - (*ppRT = pRT)->AddRef(); - return S_OK; - } - } - - hr = s->m_pD3DDev->CreateTexture(w, h, 1, D3DUSAGE_RENDERTARGET, D3DFMT_A8R8G8B8, D3DPOOL_DEFAULT, ppRT, NULL); - if(FAILED(hr)) return hr; -/**/ - m_pRTPool.AddHead(*ppRT); - while(m_pRTPool.GetCount() > 3) m_pRTPool.RemoveTail(); - - return S_OK; -} - -GSTexture* GSTextureCache::ConvertRT(GSState* s, GSTexture* pt) -{ - ASSERT(pt->m_fRT); - - // FIXME: RT + 8h,4hl,4hh - - if(s->m_ctxt->TEX0.PSM == PSM_PSMT8H) - { - if(!pt->m_pPalette) - { - if(FAILED(s->m_pD3DDev->CreateTexture(256, 1, 1, 0, s->m_ctxt->TEX0.CPSM == PSM_PSMCT32 ? D3DFMT_A8R8G8B8 : D3DFMT_A1R5G5B5, D3DPOOL_MANAGED, &pt->m_pPalette, NULL))) - return NULL; - } - } - else if(GSLocalMemory::m_psmtbl[s->m_ctxt->TEX0.PSM].pal) - { - return NULL; - } - - pt = ConvertRTPitch(s, pt); - - pt = ConvertRTWidthHeight(s, pt); - - return pt; -} - -bool GSTextureCache::Fetch(GSState* s, GSTextureBase& t) -{ - GSTexture* pt = NULL; - - int nPaletteEntries = GSLocalMemory::m_psmtbl[s->m_ctxt->TEX0.PSM].pal; - - DWORD clut[256]; - - if(nPaletteEntries) - { - s->m_lm.SetupCLUT32(s->m_ctxt->TEX0, s->m_de.TEXA); - s->m_lm.CopyCLUT32(clut, nPaletteEntries); - } - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 Fetch %dx%d %05I64x %I64d (%d)\n"), - 1 << s->m_ctxt->TEX0.TW, 1 << s->m_ctxt->TEX0.TH, - s->m_ctxt->TEX0.TBP0, s->m_ctxt->TEX0.PSM, nPaletteEntries); -#endif - - enum lookupresult {notfound, needsupdate, found} lr = notfound; - - POSITION pos = GetHeadPosition(); - while(pos && !pt) - { - POSITION cur = pos; - pt = GetNext(pos); - - if(HasSharedBits(pt->m_TEX0.TBP0, pt->m_TEX0.PSM, s->m_ctxt->TEX0.TBP0, s->m_ctxt->TEX0.PSM)) - { - if(pt->m_fRT) - { - lr = found; - - if(!(pt = ConvertRT(s, pt))) - return false; - } - else if(s->m_ctxt->TEX0.PSM == pt->m_TEX0.PSM && pt->m_TEX0.TBW == s->m_ctxt->TEX0.TBW - && s->m_ctxt->TEX0.TW == pt->m_TEX0.TW && s->m_ctxt->TEX0.TH == pt->m_TEX0.TH - && (!(s->m_ctxt->CLAMP.WMS&2) && !(pt->m_CLAMP.WMS&2) && !(s->m_ctxt->CLAMP.WMT&2) && !(pt->m_CLAMP.WMT&2) || s->m_ctxt->CLAMP.i64 == pt->m_CLAMP.i64) - && s->m_de.TEXA.TA0 == pt->m_TEXA.TA0 && s->m_de.TEXA.TA1 == pt->m_TEXA.TA1 && s->m_de.TEXA.AEM == pt->m_TEXA.AEM - && (!nPaletteEntries || s->m_ctxt->TEX0.CPSM == pt->m_TEX0.CPSM && !memcmp(pt->m_clut, clut, nPaletteEntries*sizeof(clut[0])))) - { - lr = needsupdate; - } - } - - if(lr != notfound) {MoveToHead(cur); break;} - - pt = NULL; - } - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 lr = %s\n"), lr == found ? _T("found") : lr == needsupdate ? _T("needsupdate") : _T("notfound")); -#endif - - if(lr == notfound) - { - pt = new GSTexture(); - - pt->m_TEX0 = s->m_ctxt->TEX0; - pt->m_CLAMP = s->m_ctxt->CLAMP; - pt->m_TEXA = s->m_de.TEXA; - - if(!SUCCEEDED(CreateTexture(s, pt, PSM_PSMCT32))) - { - delete pt; - return false; - } - - RemoveOldTextures(s); - - AddHead(pt); - - lr = needsupdate; - } - - ASSERT(pt); - - if(pt && nPaletteEntries) - { - memcpy(pt->m_clut, clut, nPaletteEntries*sizeof(clut[0])); - } - - if(lr == needsupdate) - { - UpdateTexture(s, pt, &GSLocalMemory::ReadTexture); - - lr = found; - } - - if(lr == found) - { -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 texture was found, age %d -> 0\n"), pt->m_nAge); -#endif - pt->m_nAge = 0; - t = *pt; - if(pt->m_fTemp) delete pt; - return true; - } - - return false; -} - -bool GSTextureCache::FetchP(GSState* s, GSTextureBase& t) -{ - GSTexture* pt = NULL; - - int nPaletteEntries = GSLocalMemory::m_psmtbl[s->m_ctxt->TEX0.PSM].pal; - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 Fetch %dx%d %05I64x %I64d (%d)\n"), - 1 << s->m_ctxt->TEX0.TW, 1 << s->m_ctxt->TEX0.TH, - s->m_ctxt->TEX0.TBP0, s->m_ctxt->TEX0.PSM, nPaletteEntries); -#endif - - enum lookupresult {notfound, needsupdate, found} lr = notfound; - - POSITION pos = GetHeadPosition(); - while(pos && !pt) - { - POSITION cur = pos; - pt = GetNext(pos); - - if(HasSharedBits(pt->m_TEX0.TBP0, pt->m_TEX0.PSM, s->m_ctxt->TEX0.TBP0, s->m_ctxt->TEX0.PSM)) - { - if(pt->m_fRT) - { - lr = found; - - if(!(pt = ConvertRT(s, pt))) - return false; - } - else if(s->m_ctxt->TEX0.PSM == pt->m_TEX0.PSM && pt->m_TEX0.TBW == s->m_ctxt->TEX0.TBW - && s->m_ctxt->TEX0.TW == pt->m_TEX0.TW && s->m_ctxt->TEX0.TH == pt->m_TEX0.TH - && (!(s->m_ctxt->CLAMP.WMS&2) && !(pt->m_CLAMP.WMS&2) && !(s->m_ctxt->CLAMP.WMT&2) && !(pt->m_CLAMP.WMT&2) || s->m_ctxt->CLAMP.i64 == pt->m_CLAMP.i64)) - { - lr = needsupdate; - } - } - - if(lr != notfound) {MoveToHead(cur); break;} - - pt = NULL; - } - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 lr = %s\n"), lr == found ? _T("found") : lr == needsupdate ? _T("needsupdate") : _T("notfound")); -#endif - - if(lr == notfound) - { - pt = new GSTexture(); - - pt->m_TEX0 = s->m_ctxt->TEX0; - pt->m_CLAMP = s->m_ctxt->CLAMP; - // pt->m_TEXA = s->m_de.TEXA; - - if(!SUCCEEDED(CreateTexture(s, pt, s->m_ctxt->TEX0.PSM, PSM_PSMCT32))) - { - delete pt; - return false; - } - - RemoveOldTextures(s); - - AddHead(pt); - - lr = needsupdate; - } - - ASSERT(pt); - - if(pt && pt->m_pPalette) - { - D3DLOCKED_RECT r; - if(FAILED(pt->m_pPalette->LockRect(0, &r, NULL, 0))) - return false; - s->m_lm.ReadCLUT32(s->m_ctxt->TEX0, s->m_de.TEXA, (DWORD*)r.pBits); - pt->m_pPalette->UnlockRect(0); - s->m_perfmon.IncCounter(GSPerfMon::c_texture, 256*4); - } - - if(lr == needsupdate) - { - UpdateTexture(s, pt, &GSLocalMemory::ReadTextureP); - - lr = found; - } - - if(lr == found) - { -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 texture was found, age %d -> 0\n"), pt->m_nAge); -#endif - pt->m_nAge = 0; - t = *pt; - if(pt->m_fTemp) delete pt; - return true; - } - - return false; -} - -bool GSTextureCache::FetchNP(GSState* s, GSTextureBase& t) -{ - GSTexture* pt = NULL; - - int nPaletteEntries = GSLocalMemory::m_psmtbl[s->m_ctxt->TEX0.PSM].pal; - - DWORD clut[256]; - - if(nPaletteEntries) - { - s->m_lm.SetupCLUT(s->m_ctxt->TEX0, s->m_de.TEXA); - s->m_lm.CopyCLUT32(clut, nPaletteEntries); - } - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 Fetch %dx%d %05I64x %I64d (%d)\n"), - 1 << s->m_ctxt->TEX0.TW, 1 << s->m_ctxt->TEX0.TH, - s->m_ctxt->TEX0.TBP0, s->m_ctxt->TEX0.PSM, nPaletteEntries); -#endif - - enum lookupresult {notfound, needsupdate, found} lr = notfound; - - POSITION pos = GetHeadPosition(); - while(pos && !pt) - { - POSITION cur = pos; - pt = GetNext(pos); - - if(HasSharedBits(pt->m_TEX0.TBP0, pt->m_TEX0.PSM, s->m_ctxt->TEX0.TBP0, s->m_ctxt->TEX0.PSM)) - { - if(pt->m_fRT) - { - lr = found; - - if(!(pt = ConvertRT(s, pt))) - return false; - } - else if(s->m_ctxt->TEX0.PSM == pt->m_TEX0.PSM && pt->m_TEX0.TBW == s->m_ctxt->TEX0.TBW - && s->m_ctxt->TEX0.TW == pt->m_TEX0.TW && s->m_ctxt->TEX0.TH == pt->m_TEX0.TH - && (!(s->m_ctxt->CLAMP.WMS&2) && !(pt->m_CLAMP.WMS&2) && !(s->m_ctxt->CLAMP.WMT&2) && !(pt->m_CLAMP.WMT&2) || s->m_ctxt->CLAMP.i64 == pt->m_CLAMP.i64) - // && s->m_de.TEXA.TA0 == pt->m_TEXA.TA0 && s->m_de.TEXA.TA1 == pt->m_TEXA.TA1 && s->m_de.TEXA.AEM == pt->m_TEXA.AEM - && (!nPaletteEntries || s->m_ctxt->TEX0.CPSM == pt->m_TEX0.CPSM && !memcmp(pt->m_clut, clut, nPaletteEntries*sizeof(clut[0])))) - { - lr = needsupdate; - } - } - - if(lr != notfound) {MoveToHead(cur); break;} - - pt = NULL; - } - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 lr = %s\n"), lr == found ? _T("found") : lr == needsupdate ? _T("needsupdate") : _T("notfound")); -#endif - - if(lr == notfound) - { - pt = new GSTexture(); - - pt->m_TEX0 = s->m_ctxt->TEX0; - pt->m_CLAMP = s->m_ctxt->CLAMP; - // pt->m_TEXA = s->m_de.TEXA; - - DWORD psm = s->m_ctxt->TEX0.PSM; - - switch(psm) - { - case PSM_PSMT8: - case PSM_PSMT8H: - case PSM_PSMT4: - case PSM_PSMT4HL: - case PSM_PSMT4HH: - psm = s->m_ctxt->TEX0.CPSM; - break; - } - - if(!SUCCEEDED(CreateTexture(s, pt, psm))) - { - delete pt; - return false; - } - - RemoveOldTextures(s); - - AddHead(pt); - - lr = needsupdate; - } - - ASSERT(pt); - - if(pt && nPaletteEntries) - { - memcpy(pt->m_clut, clut, nPaletteEntries*sizeof(clut[0])); - } - - if(lr == needsupdate) - { - UpdateTexture(s, pt, &GSLocalMemory::ReadTextureNP); - - lr = found; - } - - if(lr == found) - { -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 texture was found, age %d -> 0\n"), pt->m_nAge); -#endif - pt->m_nAge = 0; - t = *pt; - if(pt->m_fTemp) delete pt; - return true; - } - - return false; -} - -void GSTextureCache::IncAge(CSurfMap& pRTs) -{ - POSITION pos = GetHeadPosition(); - while(pos) - { - POSITION cur = pos; - GSTexture* pt = GetNext(pos); - pt->m_nAge++; - pt->m_nVsyncs++; - if(pt->m_nAge > 10 && (!pt->m_fRT || pRTs.GetCount() > 3)) - { - pRTs.RemoveKey(pt->m_TEX0.TBP0); - RemoveAt(cur); - delete pt; - } - } -} - -void GSTextureCache::ResetAge(DWORD TBP0) -{ - POSITION pos = GetHeadPosition(); - while(pos) - { - GSTexture* pt = GetNext(pos); - if(pt->m_TEX0.TBP0 == TBP0) pt->m_nAge = 0; - } -} - -void GSTextureCache::RemoveAll() -{ - while(GetCount()) delete RemoveHead(); - m_pTexturePool.RemoveAll(); - m_pRTPool.RemoveAll(); -} - -void GSTextureCache::InvalidateTexture(GSState* s, const GIFRegBITBLTBUF& BITBLTBUF, const CRect& r) -{ - GIFRegTEX0 TEX0; - TEX0.TBP0 = BITBLTBUF.DBP; - TEX0.TBW = BITBLTBUF.DBW; - TEX0.PSM = BITBLTBUF.DPSM; - TEX0.TCC = 0; - -#ifdef DEBUG_LOG - s->LOG(_T("*TC2 invalidate %05x %x (%d,%d-%d,%d)\n"), TEX0.TBP0, TEX0.PSM, r.left, r.top, r.right, r.bottom); -#endif - - POSITION pos = GetHeadPosition(); - while(pos) - { - POSITION cur = pos; - GSTexture* pt = GetNext(pos); - if(HasSharedBits(TEX0.TBP0, TEX0.PSM, pt->m_TEX0.TBP0, pt->m_TEX0.PSM)) - { - if(TEX0.TBW != pt->m_TEX0.TBW) - { - // if TEX0.TBW != pt->m_TEX0.TBW then this render target is more likely to - // be discarded by the game (means it doesn't want to transfer an image over - // another pre-rendered image) and can be refetched from local mem safely. - - RemoveAt(cur); - delete pt; - } - else if(pt->m_fRT) - { - // TEX0.TBW = pt->m_TEX0.TBW; - TEX0.PSM = pt->m_TEX0.PSM; - - if(TEX0.PSM == PSM_PSMCT32 || TEX0.PSM == PSM_PSMCT24 - || TEX0.PSM == PSM_PSMCT16 || TEX0.PSM == PSM_PSMCT16S) - { -// pt->m_rcDirty.AddHead(GSDirtyRect(PSM, r)); - - HRESULT hr; - - int tw = (r.Width() + 3) & ~3; - int th = r.Height(); - - CComPtr pSrc; - hr = s->m_pD3DDev->CreateTexture(tw, th, 1, 0, D3DFMT_A8R8G8B8, D3DPOOL_MANAGED, &pSrc, NULL); - - D3DLOCKED_RECT lr; - if(pSrc && SUCCEEDED(pSrc->LockRect(0, &lr, NULL, 0))) - { - GIFRegTEXA TEXA; - TEXA.AEM = 1; - TEXA.TA0 = 0; - TEXA.TA1 = 0x80; - - GIFRegCLAMP CLAMP; - CLAMP.WMS = 0; - CLAMP.WMT = 0; - - s->m_lm.ReadTexture(r, (BYTE*)lr.pBits, lr.Pitch, TEX0, TEXA, CLAMP); - s->m_perfmon.IncCounter(GSPerfMon::c_unswizzle, r.Width()*r.Height()*4); - - pSrc->UnlockRect(0); - - scale_t scale(pt->m_pTexture); - - CRect dst; - dst.left = (long)(scale.x * r.left + 0.5); - dst.top = (long)(scale.y * r.top + 0.5); - dst.right = (long)(scale.x * r.right + 0.5); - dst.bottom = (long)(scale.y * r.bottom + 0.5); - - // - - CComPtr pRTSurf; - hr = pt->m_pTexture->GetSurfaceLevel(0, &pRTSurf); - hr = s->m_pD3DDev->SetRenderTarget(0, pRTSurf); - hr = s->m_pD3DDev->SetDepthStencilSurface(NULL); - - hr = s->m_pD3DDev->SetTexture(0, pSrc); - hr = s->m_pD3DDev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - hr = s->m_pD3DDev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - hr = s->m_pD3DDev->SetRenderState(D3DRS_ZENABLE, FALSE); - hr = s->m_pD3DDev->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - hr = s->m_pD3DDev->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - hr = s->m_pD3DDev->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - hr = s->m_pD3DDev->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE); - hr = s->m_pD3DDev->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ZERO); - hr = s->m_pD3DDev->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - hr = s->m_pD3DDev->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_RGBA); - - hr = s->m_pD3DDev->SetPixelShader(NULL); - - struct - { - float x, y, z, rhw; - float tu, tv; - } - pVertices[] = - { - {(float)dst.left, (float)dst.top, 0.5f, 2.0f, 0, 0}, - {(float)dst.right, (float)dst.top, 0.5f, 2.0f, 1.0f * r.Width() / tw, 0}, - {(float)dst.left, (float)dst.bottom, 0.5f, 2.0f, 0, 1}, - {(float)dst.right, (float)dst.bottom, 0.5f, 2.0f, 1.0f * r.Width() / tw, 1}, - }; - - hr = s->m_pD3DDev->BeginScene(); - hr = s->m_pD3DDev->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - hr = s->m_pD3DDev->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, pVertices, sizeof(pVertices[0])); - hr = s->m_pD3DDev->EndScene(); - - } - } - else - { - RemoveAt(cur); - delete pt; - } - } - else - { - pt->m_rcDirty.AddHead(GSDirtyRect(TEX0.PSM, r)); - } - } - } -} - -void GSTextureCache::InvalidateLocalMem(GSState* s, DWORD TBP0, DWORD BW, DWORD PSM, const CRect& r) -{ - CComPtr pRT; - - POSITION pos = GetHeadPosition(); - while(pos) - { - POSITION cur = pos; - GSTexture* pt = GetNext(pos); - if(pt->m_TEX0.TBP0 == TBP0 && pt->m_fRT) - { - pRT = pt->m_pTexture; - break; - } - } - - if(!pRT) return; - - // TODO: add resizing -/* - HRESULT hr; - - D3DSURFACE_DESC desc; - hr = pRT->GetLevelDesc(0, &desc); - if(FAILED(hr)) return; - - CComPtr pVidMem; - hr = pRT->GetSurfaceLevel(0, &pVidMem); - if(FAILED(hr)) return; - - CComPtr pSysMem; - hr = s->m_pD3DDev->CreateOffscreenPlainSurface(desc.Width, desc.Height, D3DFMT_A8R8G8B8, D3DPOOL_SYSTEMMEM, &pSysMem, NULL); - if(FAILED(hr)) return; - - hr = s->m_pD3DDev->GetRenderTargetData(pVidMem, pSysMem); - if(FAILED(hr)) return; - - D3DLOCKED_RECT lr; - hr = pSysMem->LockRect(&lr, &r, D3DLOCK_READONLY|D3DLOCK_NO_DIRTY_UPDATE); - if(SUCCEEDED(hr)) - { - BYTE* p = (BYTE*)lr.pBits; - - if(0 && r.left == 0 && r.top == 0 && PSM == PSM_PSMCT32) - { - } - else - { - GSLocalMemory::writeFrame wf = s->m_lm.GetWriteFrame(PSM); - - for(int y = r.top; y < r.bottom; y++, p += lr.Pitch) - { - for(int x = r.left; x < r.right; x++) - { - (s->m_lm.*wf)(x, y, ((DWORD*)p)[x], TBP0, BW); - } - } - } - - pSysMem->UnlockRect(); - } - */ -} - -void GSTextureCache::AddRT(GIFRegTEX0& TEX0, IDirect3DTexture9* pRT, scale_t scale) -{ - POSITION pos = GetHeadPosition(); - while(pos) - { - POSITION cur = pos; - GSTexture* pt = GetNext(pos); - if(HasSharedBits(TEX0.TBP0, TEX0.PSM, pt->m_TEX0.TBP0, pt->m_TEX0.PSM)) - { - RemoveAt(cur); - delete pt; - } - } - - GSTexture* pt = new GSTexture(); - pt->m_TEX0 = TEX0; - pt->m_pTexture = pRT; - pt->m_pTexture->GetLevelDesc(0, &pt->m_desc); - pt->m_scale = scale; - pt->m_fRT = true; - - AddHead(pt); -} diff --git a/plugins/gs/gsdx9/GSTextureCache.h b/plugins/gs/gsdx9/GSTextureCache.h deleted file mode 100644 index 45c4ac42ab..0000000000 --- a/plugins/gs/gsdx9/GSTextureCache.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "GS.h" -#include "GSLocalMemory.h" - -template class CSurfMap : public CMap, CComPtr& > {}; - -extern bool IsRenderTarget(IDirect3DTexture9* pTexture); -extern bool HasSharedBits(DWORD sbp, DWORD spsm, DWORD dbp, DWORD dpsm); - -// TODO: get rid of this *PrivateData - -#ifdef __INTEL_COMPILER -struct __declspec(uuid("5D5EFE0E-5407-4BCF-855D-C46CBCD075FA")) -#else -[uuid("5D5EFE0E-5407-4BCF-855D-C46CBCD075FA")] struct -#endif -scale_t -{ - float x, y; - struct scale_t() {x = y = 1;} - struct scale_t(float x, float y) {this->x = x; this->y = y;} - struct scale_t(IDirect3DResource9* p) {Get(p);} - bool operator == (const struct scale_t& s) {return fabs(x - s.x) < 0.001 && fabs(y - s.y) < 0.001;} - void Set(IDirect3DResource9* p) {p->SetPrivateData(__uuidof(*this), this, sizeof(*this), 0);} - void Get(IDirect3DResource9* p) {DWORD size = sizeof(*this); p->GetPrivateData(__uuidof(*this), this, &size);} -}; - -class GSDirtyRect -{ - DWORD m_PSM; - CRect m_rcDirty; - -public: - GSDirtyRect() : m_PSM(PSM_PSMCT32), m_rcDirty(0, 0, 0, 0) {} - GSDirtyRect(DWORD PSM, CRect r); - CRect GetDirtyRect(const GIFRegTEX0& TEX0); -}; - -class GSDirtyRectList : public CAtlList -{ -public: - GSDirtyRectList() {} - GSDirtyRectList(const GSDirtyRectList& l) {*this = l;} - void operator = (const GSDirtyRectList& l); - CRect GetDirtyRect(const GIFRegTEX0& TEX0); -}; - -struct GSTextureBase -{ - CComPtr m_pTexture, m_pPalette; - scale_t m_scale; - bool m_fRT; - D3DSURFACE_DESC m_desc; - - GSTextureBase(); -}; - -struct GSTexture : public GSTextureBase -{ - GIFRegCLAMP m_CLAMP; - GIFRegTEX0 m_TEX0; - GIFRegTEXA m_TEXA; // * - DWORD m_clut[256]; // * - GSDirtyRectList m_rcDirty; - CRect m_rcValid; - CRect m_rcHash; - DWORD m_dwHash, m_nHashDiff, m_nHashSame; - DWORD m_nBytes; - int m_nAge, m_nVsyncs; - CInterfaceList m_pSubTextures; - bool m_fTemp; - - GSTexture(); -}; - -class GSState; - -class GSTextureCache : private CAtlList -{ -protected: - CInterfaceList m_pTexturePool; - HRESULT CreateTexture(GSState* s, GSTexture* pt, DWORD PSM, DWORD CPSM = PSM_PSMCT32); - bool IsTextureInCache(IDirect3DTexture9* pTexture); - void RemoveOldTextures(GSState* s); - bool GetDirtyRect(GSState* s, GSTexture* pt, CRect& r); - - DWORD HashTexture(const CRect& r, int pitch, void* bits); - HRESULT UpdateTexture(GSState* s, GSTexture* pt, GSLocalMemory::readTexture rt); - - GSTexture* ConvertRT(GSState* s, GSTexture* pt); - GSTexture* ConvertRTPitch(GSState* s, GSTexture* pt); - GSTexture* ConvertRTWidthHeight(GSState* s, GSTexture* pt); - - CInterfaceList m_pRTPool; - HRESULT CreateRT(GSState* s, int w, int h, IDirect3DTexture9** ppRT); - -public: - GSTextureCache(); - ~GSTextureCache(); - - bool Fetch(GSState* s, GSTextureBase& t); - bool FetchP(GSState* s, GSTextureBase& t); - bool FetchNP(GSState* s, GSTextureBase& t); - - void IncAge(CSurfMap& pRTs); - void ResetAge(DWORD TBP0); - void RemoveAll(); - void InvalidateTexture(GSState* s, const GIFRegBITBLTBUF& BITBLTBUF, const CRect& r); - void InvalidateLocalMem(GSState* s, DWORD TBP0, DWORD BW, DWORD PSM, const CRect& r); - void AddRT(GIFRegTEX0& TEX0, IDirect3DTexture9* pRT, scale_t scale); -}; diff --git a/plugins/gs/gsdx9/GSTransfer.cpp b/plugins/gs/gsdx9/GSTransfer.cpp deleted file mode 100644 index d7c5efd507..0000000000 --- a/plugins/gs/gsdx9/GSTransfer.cpp +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" -#include "GSState.h" - -void GSState::WriteStep() -{ -// if(m_y == m_de.TRXREG.RRH && m_x == m_de.TRXPOS.DSAX) ASSERT(0); - - if(++m_x == m_de.TRXREG.RRW) - { - m_x = m_de.TRXPOS.DSAX; - m_y++; - } -} - -void GSState::ReadStep() -{ -// if(m_y == m_de.TRXREG.RRH && m_x == m_de.TRXPOS.SSAX) ASSERT(0); - - if(++m_x == m_de.TRXREG.RRW) - { - m_x = m_de.TRXPOS.SSAX; - m_y++; - } -} - -void GSState::WriteTransfer(BYTE* pMem, int len) -{ - LOG(_T("*TC2 WriteTransfer %d,%d (psm=%d rr=%dx%d len=%d)\n"), m_x, m_y, m_de.BITBLTBUF.DPSM, m_de.TRXREG.RRW, m_de.TRXREG.RRH, len); - - if(len == 0) return; - - // TODO: hmmmm - if(m_pPRIM->TME && (m_de.BITBLTBUF.DBP == m_ctxt->TEX0.TBP0 || m_de.BITBLTBUF.DBP == m_ctxt->TEX0.CBP)) - FlushPrim(); - - int bpp = GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].trbpp; - int pitch = (m_de.TRXREG.RRW - m_de.TRXPOS.DSAX)*bpp>>3; - int height = len / pitch; - - if(m_nTrBytes > 0 || height < m_de.TRXREG.RRH - m_de.TRXPOS.DSAY) - { - LOG(_T("*TC2 WriteTransfer delayed\n")); - - ASSERT(len <= m_nTrMaxBytes); // transferring more than 4mb into a 4mb local mem doesn't make any sense - - len = min(m_nTrMaxBytes, len); - - if(m_nTrBytes + len > m_nTrMaxBytes) - FlushWriteTransfer(); - - memcpy(&m_pTrBuff[m_nTrBytes], pMem, len); - m_nTrBytes += len; - } - else - { - int x = m_x, y = m_y; - - (m_lm.*GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].st)(m_x, m_y, pMem, len, m_de.BITBLTBUF, m_de.TRXPOS, m_de.TRXREG); - - m_perfmon.IncCounter(GSPerfMon::c_swizzle, len); - - //ASSERT(m_de.TRXREG.RRH >= m_y - y); - - CRect r(m_de.TRXPOS.DSAX, y, m_de.TRXREG.RRW, min(m_x == m_de.TRXPOS.DSAX ? m_y : m_y+1, m_de.TRXREG.RRH)); - InvalidateTexture(m_de.BITBLTBUF, r); - - m_lm.InvalidateCLUT(); - } -} - -void GSState::FlushWriteTransfer() -{ - if(!m_nTrBytes) return; - - int x = m_x, y = m_y; - - LOG(_T("*TC2 FlushWriteTransfer %d,%d-%d,%d (psm=%d rr=%dx%d len=%d)\n"), x, y, m_x, m_y, m_de.BITBLTBUF.DPSM, m_de.TRXREG.RRW, m_de.TRXREG.RRH, m_nTrBytes); - - (m_lm.*GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].st)(m_x, m_y, m_pTrBuff, m_nTrBytes, m_de.BITBLTBUF, m_de.TRXPOS, m_de.TRXREG); - - m_perfmon.IncCounter(GSPerfMon::c_swizzle, m_nTrBytes); - - m_nTrBytes = 0; - - //ASSERT(m_de.TRXREG.RRH >= m_y - y); - - CRect r(m_de.TRXPOS.DSAX, y, m_de.TRXREG.RRW, min(m_x == m_de.TRXPOS.DSAX ? m_y : m_y+1, m_de.TRXREG.RRH)); - InvalidateTexture(m_de.BITBLTBUF, r); - - m_lm.InvalidateCLUT(); -} - -void GSState::ReadTransfer(BYTE* pMem, int len) -{ - BYTE* pb = (BYTE*)pMem; - WORD* pw = (WORD*)pMem; - DWORD* pd = (DWORD*)pMem; - - if(m_y >= (int)m_de.TRXREG.RRH) {ASSERT(0); return;} - - if(m_x == m_de.TRXPOS.SSAX && m_y == m_de.TRXPOS.SSAY) - { - CRect r(m_de.TRXPOS.SSAX, m_de.TRXPOS.SSAY, m_de.TRXREG.RRW, m_de.TRXREG.RRH); - InvalidateLocalMem(m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW, m_de.BITBLTBUF.SPSM, r); - } - - switch(m_de.BITBLTBUF.SPSM) - { - case PSM_PSMCT32: - for(len /= 4; len-- > 0; ReadStep(), pd++) - *pd = m_lm.readPixel32(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - case PSM_PSMCT24: - for(len /= 3; len-- > 0; ReadStep(), pb+=3) - { - DWORD dw = m_lm.readPixel24(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - pb[0] = ((BYTE*)&dw)[0]; pb[1] = ((BYTE*)&dw)[1]; pb[2] = ((BYTE*)&dw)[2]; - } - break; - case PSM_PSMCT16: - for(len /= 2; len-- > 0; ReadStep(), pw++) - *pw = (WORD)m_lm.readPixel16(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - case PSM_PSMCT16S: - for(len /= 2; len-- > 0; ReadStep(), pw++) - *pw = (WORD)m_lm.readPixel16S(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - case PSM_PSMT8: - for(; len-- > 0; ReadStep(), pb++) - *pb = (BYTE)m_lm.readPixel8(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - case PSM_PSMT4: - for(; len-- > 0; ReadStep(), ReadStep(), pb++) - *pb = (BYTE)(m_lm.readPixel4(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)&0x0f) - | (BYTE)(m_lm.readPixel4(m_x+1, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)<<4); - break; - case PSM_PSMT8H: - for(; len-- > 0; ReadStep(), pb++) - *pb = (BYTE)m_lm.readPixel8H(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - case PSM_PSMT4HL: - for(; len-- > 0; ReadStep(), ReadStep(), pb++) - *pb = (BYTE)(m_lm.readPixel4HL(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)&0x0f) - | (BYTE)(m_lm.readPixel4HL(m_x+1, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)<<4); - break; - case PSM_PSMT4HH: - for(; len-- > 0; ReadStep(), ReadStep(), pb++) - *pb = (BYTE)(m_lm.readPixel4HH(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)&0x0f) - | (BYTE)(m_lm.readPixel4HH(m_x+1, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW)<<4); - break; - case PSM_PSMZ32: - for(len /= 4; len-- > 0; ReadStep(), pd++) - *pd = m_lm.readPixel32Z(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - case PSM_PSMZ24: - for(len /= 3; len-- > 0; ReadStep(), pb+=3) - { - DWORD dw = m_lm.readPixel24Z(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - pb[0] = ((BYTE*)&dw)[0]; pb[1] = ((BYTE*)&dw)[1]; pb[2] = ((BYTE*)&dw)[2]; - } - break; - case PSM_PSMZ16: - for(len /= 2; len-- > 0; ReadStep(), pw++) - *pw = (WORD)m_lm.readPixel16Z(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - case PSM_PSMZ16S: - for(len /= 2; len-- > 0; ReadStep(), pw++) - *pw = (WORD)m_lm.readPixel16SZ(m_x, m_y, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW); - break; - } -} - -void GSState::MoveTransfer() -{ - GSLocalMemory::readPixel rp = GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.SPSM].rp; - GSLocalMemory::writePixel wp = GSLocalMemory::m_psmtbl[m_de.BITBLTBUF.DPSM].wp; - - int sx = m_de.TRXPOS.SSAX; - int dx = m_de.TRXPOS.DSAX; - int sy = m_de.TRXPOS.SSAY; - int dy = m_de.TRXPOS.DSAY; - int w = m_de.TRXREG.RRW; - int h = m_de.TRXREG.RRH; - int xinc = 1; - int yinc = 1; - - if(sx < dx) sx += w-1, dx += w-1, xinc = -1; - if(sy < dy) sy += h-1, dy += h-1, yinc = -1; - - for(int y = 0; y < h; y++, sy += yinc, dy += yinc, sx -= xinc*w, dx -= xinc*w) - for(int x = 0; x < w; x++, sx += xinc, dx += xinc) - (m_lm.*wp)(dx, dy, (m_lm.*rp)(sx, sy, m_de.BITBLTBUF.SBP, m_de.BITBLTBUF.SBW), m_de.BITBLTBUF.DBP, m_de.BITBLTBUF.DBW); -} - - diff --git a/plugins/gs/gsdx9/GSUtil.cpp b/plugins/gs/gsdx9/GSUtil.cpp deleted file mode 100644 index 1b4186d9cc..0000000000 --- a/plugins/gs/gsdx9/GSUtil.cpp +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" -#include "GSdx9.h" -#include "GSState.h" - -BOOL IsDepthFormatOk(IDirect3D9* pD3D, D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat) -{ - // Verify that the depth format exists. - HRESULT hr = pD3D->CheckDeviceFormat(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, AdapterFormat, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, DepthFormat); - if(FAILED(hr)) return FALSE; - - // Verify that the depth format is compatible. - hr = pD3D->CheckDepthStencilMatch(D3DADAPTER_DEFAULT, CGSdx9App::D3DDEVTYPE_X, AdapterFormat, BackBufferFormat, DepthFormat); - return SUCCEEDED(hr); -} - -HRESULT CompileShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, CString entry, CString target, UINT flags, IDirect3DPixelShader9** ppPixelShader) -{ - CheckPointer(pD3DDev, E_POINTER); - CheckPointer(ppPixelShader, E_POINTER); - - CComPtr pShader, pErrorMsgs; - HRESULT hr = D3DXCompileShaderFromResource( - AfxGetResourceHandle(), MAKEINTRESOURCE(id), - NULL, NULL, - entry, target, flags, - &pShader, &pErrorMsgs, NULL); - ASSERT(SUCCEEDED(hr)); - - if(SUCCEEDED(hr)) - { - hr = pD3DDev->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), ppPixelShader); - ASSERT(SUCCEEDED(hr)); - } - - return hr; -} - -HRESULT AssembleShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, UINT flags, IDirect3DPixelShader9** ppPixelShader) -{ - CheckPointer(pD3DDev, E_POINTER); - CheckPointer(ppPixelShader, E_POINTER); - - CComPtr pShader, pErrorMsgs; - HRESULT hr = D3DXAssembleShaderFromResource( - AfxGetResourceHandle(), MAKEINTRESOURCE(id), - NULL, NULL, - flags, - &pShader, &pErrorMsgs); - ASSERT(SUCCEEDED(hr)); - - if(SUCCEEDED(hr)) - { - hr = pD3DDev->CreatePixelShader((DWORD*)pShader->GetBufferPointer(), ppPixelShader); - ASSERT(SUCCEEDED(hr)); - } - - return hr; -} diff --git a/plugins/gs/gsdx9/GSUtil.h b/plugins/gs/gsdx9/GSUtil.h deleted file mode 100644 index b238b12cc6..0000000000 --- a/plugins/gs/gsdx9/GSUtil.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -extern BOOL IsDepthFormatOk(IDirect3D9* pD3D, D3DFORMAT DepthFormat, D3DFORMAT AdapterFormat, D3DFORMAT BackBufferFormat); -extern HRESULT CompileShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, CString entry, CString target, UINT flags, IDirect3DPixelShader9** ppPixelShader); -extern HRESULT AssembleShaderFromResource(IDirect3DDevice9* pD3DDev, UINT id, UINT flags, IDirect3DPixelShader9** ppPixelShader); diff --git a/plugins/gs/gsdx9/GSVertexList.cpp b/plugins/gs/gsdx9/GSVertexList.cpp deleted file mode 100644 index a9e1e3bb23..0000000000 --- a/plugins/gs/gsdx9/GSVertexList.cpp +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "StdAfx.h" -#include "GSVertexList.h" \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSVertexList.h b/plugins/gs/gsdx9/GSVertexList.h deleted file mode 100644 index 88ba2d4ea1..0000000000 --- a/plugins/gs/gsdx9/GSVertexList.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -template class GSVertexList -{ - VERTEX* m_v; - int m_head, m_tail, m_count; - -public: - GSVertexList() - { - m_v = (VERTEX*)_aligned_malloc(sizeof(VERTEX)*4, 16); - RemoveAll(); - } - - ~GSVertexList() - { - _aligned_free(m_v); - } - - void RemoveAll() - { - m_head = m_tail = m_count = 0; - } - - VERTEX& AddTail() - { - ASSERT(m_count < 4); - VERTEX& v = m_v[m_tail]; - m_tail = (m_tail+1)&3; - m_count++; - return v; - } - - void AddTail(VERTEX& v) - { - ASSERT(m_count < 4); - m_v[m_tail] = v; - m_tail = (m_tail+1)&3; - m_count++; - } - - void RemoveAt(int i, VERTEX& v) - { - GetAt(i, v); - i = (m_head+i)&3; - if(i == m_head) m_head = (m_head+1)&3; - else for(m_tail = (m_tail+4-1)&3; i != m_tail; i = (i+1)&3) m_v[i] = m_v[(i+1)&3]; - m_count--; - } - - void GetAt(int i, VERTEX& v) - { - ASSERT(m_count > 0); - v = m_v[(m_head+i)&3]; - } - - int GetCount() - { - return m_count; - } -}; \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSWnd.cpp b/plugins/gs/gsdx9/GSWnd.cpp deleted file mode 100644 index 5e74d1c82d..0000000000 --- a/plugins/gs/gsdx9/GSWnd.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" -#include "GSWnd.h" - -IMPLEMENT_DYNCREATE(CGSWnd, CWnd) - -CGSWnd::CGSWnd() -{ -} - -BOOL CGSWnd::Create(LPCSTR pTitle) -{ - CRect r; - GetDesktopWindow()->GetWindowRect(r); - // r.DeflateRect(r.Width()*3/8, r.Height()*3/8); - r.DeflateRect(r.Width()/3, r.Height()/3); - LPCTSTR wndclass = AfxRegisterWndClass(CS_VREDRAW|CS_HREDRAW|CS_DBLCLKS, AfxGetApp()->LoadStandardCursor(IDC_ARROW), 0/*(HBRUSH)(COLOR_BTNFACE + 1)*/, 0); - return CreateEx(0, wndclass, pTitle, WS_OVERLAPPEDWINDOW, r, NULL, 0); -} - -void CGSWnd::Show(bool bShow) -{ - if(bShow) - { - SetWindowPos(&wndTop, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE); - SetForegroundWindow(); - ShowWindow(SW_SHOWNORMAL); - } - else - { - ShowWindow(SW_HIDE); - } -} - -BEGIN_MESSAGE_MAP(CGSWnd, CWnd) - ON_WM_CLOSE() -END_MESSAGE_MAP() - -void CGSWnd::OnClose() -{ - PostMessage(WM_QUIT); -} diff --git a/plugins/gs/gsdx9/GSWnd.h b/plugins/gs/gsdx9/GSWnd.h deleted file mode 100644 index 82eb774859..0000000000 --- a/plugins/gs/gsdx9/GSWnd.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -class CGSWnd : public CWnd -{ - DECLARE_DYNCREATE(CGSWnd) - -public: - CGSWnd(); - - BOOL Create(LPCSTR pTitle); - void Show(bool bShow = true); - - DECLARE_MESSAGE_MAP() - - afx_msg void OnClose(); -}; diff --git a/plugins/gs/gsdx9/GSdx9.cpp b/plugins/gs/gsdx9/GSdx9.cpp deleted file mode 100644 index b07ab5e6a1..0000000000 --- a/plugins/gs/gsdx9/GSdx9.cpp +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - * Special Notes: - * - */ - -#include "stdafx.h" -#include "afxwin.h" -#include "GSdx9.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -// -// Note! -// -// If this DLL is dynamically linked against the MFC -// DLLs, any functions exported from this DLL which -// call into MFC must have the AFX_MANAGE_STATE macro -// added at the very beginning of the function. -// -// For example: -// -// extern "C" BOOL PASCAL EXPORT ExportedFunction() -// { -// AFX_MANAGE_STATE(AfxGetStaticModuleState()); -// // normal function body here -// } -// -// It is very important that this macro appear in each -// function, prior to any calls into MFC. This means that -// it must appear as the first statement within the -// function, even before any object variable declarations -// as their constructors may generate calls into the MFC -// DLL. -// -// Please see MFC Technical Notes 33 and 58 for additional -// details. -// - -// CGSdx9App - -BEGIN_MESSAGE_MAP(CGSdx9App, CWinApp) -END_MESSAGE_MAP() - -D3DDEVTYPE CGSdx9App::D3DDEVTYPE_X; - -// CGSdx9App construction - -CGSdx9App::CGSdx9App() -{ - // TODO: add construction code here, - // Place all significant initialization in InitInstance -} - - -// The one and only CGSdx9App object - -CGSdx9App theApp; - -// CGSdx9App initialization - -BOOL CGSdx9App::InitInstance() -{ - __super::InitInstance(); - - D3DDEVTYPE_X = D3DDEVTYPE_HAL; - - if(GetSystemMetrics(SM_REMOTESESSION)) - { - D3DDEVTYPE_X = D3DDEVTYPE_REF; - } - - return TRUE; -} diff --git a/plugins/gs/gsdx9/GSdx9.def b/plugins/gs/gsdx9/GSdx9.def deleted file mode 100644 index 218e2b1859..0000000000 --- a/plugins/gs/gsdx9/GSdx9.def +++ /dev/null @@ -1,31 +0,0 @@ -; GSdx9.def : Declares the module parameters for the DLL. - -LIBRARY "GSdx9" - -EXPORTS - ; Explicit exports can go here - PS2EgetLibType - PS2EgetLibName - PS2EgetLibVersion2 - PS2EgetCpuPlatform - GSsetBaseMem - GSinit - GSshutdown - GSopen - GSclose - GSreset - GSwriteCSR - GSgifTransfer1 - GSgifTransfer2 - GSgifTransfer3 - GSvsync - GSmakeSnapshot - GSkeyEvent - GSfreeze - GSconfigure - GStest - GSabout - GSreadFIFO - GSirqCallback - GSgetLastTag - ; GSReplay \ No newline at end of file diff --git a/plugins/gs/gsdx9/GSdx9.h b/plugins/gs/gsdx9/GSdx9.h deleted file mode 100644 index 73fe174bbb..0000000000 --- a/plugins/gs/gsdx9/GSdx9.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#ifndef __AFXWIN_H__ - #error include 'stdafx.h' before including this file for PCH -#endif - -#include "resource.h" // main symbols - - -// CGSdx9App -// See GSdx9.cpp for the implementation of this class -// - -class CGSdx9App : public CWinApp -{ -public: - CGSdx9App(); - - static D3DDEVTYPE D3DDEVTYPE_X; - -// Overrides -public: - virtual BOOL InitInstance(); - - DECLARE_MESSAGE_MAP() -}; - -enum -{ - RENDERER_D3D_NULL, - RENDERER_D3D_SW_FX, - RENDERER_D3D_SW_FP, - RENDERER_D3D_HW -}; diff --git a/plugins/gs/gsdx9/GSdx9.icproj b/plugins/gs/gsdx9/GSdx9.icproj deleted file mode 100644 index fdf2a5314b..0000000000 --- a/plugins/gs/gsdx9/GSdx9.icproj +++ /dev/null @@ -1,539 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/gs/gsdx9/GSdx9.rc b/plugins/gs/gsdx9/GSdx9.rc deleted file mode 100644 index f113b4a5fe..0000000000 --- a/plugins/gs/gsdx9/GSdx9.rc +++ /dev/null @@ -1,220 +0,0 @@ -// Microsoft Visual C++ generated resource script. -// -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 2 resource. -// -#include "afxres.h" - -///////////////////////////////////////////////////////////////////////////// -#undef APSTUDIO_READONLY_SYMBOLS - -///////////////////////////////////////////////////////////////////////////// -// Hungarian resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_HUN) -#ifdef _WIN32 -LANGUAGE LANG_HUNGARIAN, SUBLANG_DEFAULT -#pragma code_page(1250) -#endif //_WIN32 - -#ifdef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// TEXTINCLUDE -// - -1 TEXTINCLUDE -BEGIN - "resource.h\0" -END - -2 TEXTINCLUDE -BEGIN - "#include ""afxres.h""\r\n" - "\0" -END - -3 TEXTINCLUDE -BEGIN - "#define _AFX_NO_SPLITTER_RESOURCES\r\n" - "#define _AFX_NO_OLE_RESOURCES\r\n" - "#define _AFX_NO_TRACKER_RESOURCES\r\n" - "#define _AFX_NO_PROPERTY_RESOURCES\r\n" - "\r\n" - "#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)\r\n" - "LANGUAGE 9, 1\r\n" - "#pragma code_page(1252)\r\n" - "#include ""res\\GSdx9.rc2"" // non-Microsoft Visual C++ edited resources\r\n" - "#include ""afxres.rc"" // Standard components\r\n" - "#endif\r\n" - "\0" -END - -#endif // APSTUDIO_INVOKED - -#endif // Hungarian resources -///////////////////////////////////////////////////////////////////////////// - - -///////////////////////////////////////////////////////////////////////////// -// English (U.S.) resources - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -#ifdef _WIN32 -LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US -#pragma code_page(1252) -#endif //_WIN32 - -///////////////////////////////////////////////////////////////////////////// -// -// Bitmap -// - -IDB_LOGO1 BITMAP "res\\logo1.bmp" - -///////////////////////////////////////////////////////////////////////////// -// -// Dialog -// - -IDD_CONFIG DIALOGEX 0, 0, 189, 209 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | - WS_SYSMENU -CAPTION "Settings..." -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - PUSHBUTTON "Cancel",IDCANCEL,43,188,50,14 - DEFPUSHBUTTON "OK",IDOK,98,188,50,14 - COMBOBOX IDC_COMBO1,64,72,118,69,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Renderer:",IDC_STATIC,7,74,34,8 - LTEXT "Resolution:",IDC_STATIC,7,59,37,8 - COMBOBOX IDC_COMBO3,64,57,118,125,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - LTEXT "Shader:",IDC_STATIC,7,89,26,8 - COMBOBOX IDC_COMBO4,64,87,118,98,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - EDITTEXT IDC_EDIT1,64,158,100,13,ES_AUTOHSCROLL | ES_READONLY - PUSHBUTTON "...",IDC_BUTTON1,165,158,17,14 - CONTROL "Record state",IDC_CHECK2,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,7,158,53,10 - CONTROL "Enable tv-out",IDC_CHECK3,"Button",BS_AUTOCHECKBOX | - WS_TABSTOP,7,132,57,10 - CONTROL "Enable palettized textures (D3D PS v2.0+, slow)", - IDC_CHECK1,"Button",BS_AUTOCHECKBOX | BS_TOP | - WS_TABSTOP,7,105,175,10 - LTEXT """rundll32 gsdx9.dll,GSReplay gsdx9_*.gs"" to replay", - IDC_STATIC,14,174,168,9 - CONTROL "Linear texture filtering",IDC_CHECK4,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,118,87,10 - CONTROL 2024,IDC_STATIC,"Static",SS_BITMAP,7,7,175,44 - CONTROL "NLOOP 0 hack (fixes FFX)",IDC_CHECK5,"Button", - BS_AUTOCHECKBOX | WS_TABSTOP,7,145,98,10 -END - -IDD_CAPTURE DIALOGEX 0, 0, 279, 67 -STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_CAPTION | - WS_SYSMENU -CAPTION "Capture settings" -FONT 8, "MS Shell Dlg", 400, 0, 0x1 -BEGIN - DEFPUSHBUTTON "OK",IDOK,140,46,50,14 - PUSHBUTTON "Cancel",IDCANCEL,88,46,50,14 - COMBOBOX IDC_COMBO1,7,27,207,122,CBS_DROPDOWNLIST | WS_VSCROLL | - WS_TABSTOP - EDITTEXT IDC_EDIT1,7,7,207,14,ES_AUTOHSCROLL - PUSHBUTTON "Browse...",IDC_BUTTON1,222,7,50,14 - PUSHBUTTON "Config...",IDC_BUTTON2,222,26,50,14 -END - - -///////////////////////////////////////////////////////////////////////////// -// -// DESIGNINFO -// - -#ifdef APSTUDIO_INVOKED -GUIDELINES DESIGNINFO -BEGIN - IDD_CONFIG, DIALOG - BEGIN - LEFTMARGIN, 7 - RIGHTMARGIN, 182 - VERTGUIDE, 64 - VERTGUIDE, 182 - TOPMARGIN, 7 - BOTTOMMARGIN, 202 - HORZGUIDE, 150 - END -END -#endif // APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// -// Version -// - -VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,0,0,9 - PRODUCTVERSION 1,0,0,9 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS 0x1L -#else - FILEFLAGS 0x0L -#endif - FILEOS 0x4L - FILETYPE 0x2L - FILESUBTYPE 0x0L -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904e4" - BEGIN - VALUE "Comments", "http://gabest.org/" - VALUE "CompanyName", "Gabest" - VALUE "FileDescription", "GS plugin for ps2 emulators" - VALUE "FileVersion", "1, 0, 0, 9" - VALUE "InternalName", "GSdx9.dll" - VALUE "LegalCopyright", "Copyright (c) 2004-2005 Gabest. All rights reserved." - VALUE "OriginalFilename", "GSdx9.dll" - VALUE "ProductName", "GSdx9" - VALUE "ProductVersion", "1, 0, 0, 9" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1252 - END -END - -#endif // English (U.S.) resources -///////////////////////////////////////////////////////////////////////////// - - - -#ifndef APSTUDIO_INVOKED -///////////////////////////////////////////////////////////////////////////// -// -// Generated from the TEXTINCLUDE 3 resource. -// -#define _AFX_NO_SPLITTER_RESOURCES -#define _AFX_NO_OLE_RESOURCES -#define _AFX_NO_TRACKER_RESOURCES -#define _AFX_NO_PROPERTY_RESOURCES - -#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) -LANGUAGE 9, 1 -#pragma code_page(1252) -#include "res\GSdx9.rc2" // non-Microsoft Visual C++ edited resources -#include "afxres.rc" // Standard components -#endif - -///////////////////////////////////////////////////////////////////////////// -#endif // not APSTUDIO_INVOKED - diff --git a/plugins/gs/gsdx9/GSdx9_vs2005.sln b/plugins/gs/gsdx9/GSdx9_vs2005.sln deleted file mode 100644 index 516d5d1098..0000000000 --- a/plugins/gs/gsdx9/GSdx9_vs2005.sln +++ /dev/null @@ -1,54 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 9.00 -# Visual Studio 2005 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "GSdx9", "GSdx9_vs2005.vcproj", "{345C9F24-0B9A-4289-B375-ADD3B63461B7}" - ProjectSection(ProjectDependencies) = postProject - {7CDC5863-9F36-468D-A634-6D7799E0A15E} = {7CDC5863-9F36-468D-A634-6D7799E0A15E} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "BaseClasses", "baseclasses\baseclasses.vcproj", "{7CDC5863-9F36-468D-A634-6D7799E0A15E}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Win32 = Debug|Win32 - Debug|x64 = Debug|x64 - DebugSSE2|Win32 = DebugSSE2|Win32 - DebugSSE2|x64 = DebugSSE2|x64 - Release|Win32 = Release|Win32 - Release|x64 = Release|x64 - ReleaseSSE2|Win32 = ReleaseSSE2|Win32 - ReleaseSSE2|x64 = ReleaseSSE2|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|Win32.ActiveCfg = Debug|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|Win32.Build.0 = Debug|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|x64.ActiveCfg = Debug|x64 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Debug|x64.Build.0 = Debug|x64 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|Win32.ActiveCfg = DebugSSE2|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|Win32.Build.0 = DebugSSE2|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|x64.ActiveCfg = DebugSSE2|x64 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.DebugSSE2|x64.Build.0 = DebugSSE2|x64 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|Win32.ActiveCfg = Release|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|Win32.Build.0 = Release|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|x64.ActiveCfg = Release|x64 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.Release|x64.Build.0 = Release|x64 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|Win32.ActiveCfg = ReleaseSSE2|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|Win32.Build.0 = ReleaseSSE2|Win32 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|x64.ActiveCfg = ReleaseSSE2|x64 - {345C9F24-0B9A-4289-B375-ADD3B63461B7}.ReleaseSSE2|x64.Build.0 = ReleaseSSE2|x64 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.Debug|Win32.ActiveCfg = Debug|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.Debug|Win32.Build.0 = Debug|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.Debug|x64.ActiveCfg = Debug|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.DebugSSE2|Win32.ActiveCfg = Debug|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.DebugSSE2|Win32.Build.0 = Debug|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.DebugSSE2|x64.ActiveCfg = Debug|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.Release|Win32.ActiveCfg = Release|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.Release|Win32.Build.0 = Release|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.Release|x64.ActiveCfg = Release|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.ReleaseSSE2|Win32.ActiveCfg = Release|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.ReleaseSSE2|Win32.Build.0 = Release|Win32 - {7CDC5863-9F36-468D-A634-6D7799E0A15E}.ReleaseSSE2|x64.ActiveCfg = Release|Win32 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection -EndGlobal diff --git a/plugins/gs/gsdx9/GSdx9_vs2005.vcproj b/plugins/gs/gsdx9/GSdx9_vs2005.vcproj deleted file mode 100644 index a646bc0c1b..0000000000 --- a/plugins/gs/gsdx9/GSdx9_vs2005.vcproj +++ /dev/null @@ -1,1429 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/gs/gsdx9/baseclasses/Amvideo.h b/plugins/gs/gsdx9/baseclasses/Amvideo.h deleted file mode 100644 index d173c330a7..0000000000 --- a/plugins/gs/gsdx9/baseclasses/Amvideo.h +++ /dev/null @@ -1,433 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMVideo.h -// -// Desc: Video related definitions and interfaces for ActiveMovie. -// -// Copyright (c) 1992 - 2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __AMVIDEO__ -#define __AMVIDEO__ - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include - - -// This is an interface on the video renderer that provides information about -// DirectDraw with respect to its use by the renderer. For example it allows -// an application to get details of the surface and any hardware capabilities -// that are available. It also allows someone to adjust the surfaces that the -// renderer should use and furthermore even set the DirectDraw instance. We -// allow someone to set the DirectDraw instance because DirectDraw can only -// be opened once per process so it helps resolve conflicts. There is some -// duplication in this interface as the hardware/emulated/FOURCCs available -// can all be found through the IDirectDraw interface, this interface allows -// simple access to that information without calling the DirectDraw provider -// itself. The AMDDS prefix is ActiveMovie DirectDraw Switches abbreviated. - -#define AMDDS_NONE 0x00 // No use for DCI/DirectDraw -#define AMDDS_DCIPS 0x01 // Use DCI primary surface -#define AMDDS_PS 0x02 // Use DirectDraw primary -#define AMDDS_RGBOVR 0x04 // RGB overlay surfaces -#define AMDDS_YUVOVR 0x08 // YUV overlay surfaces -#define AMDDS_RGBOFF 0x10 // RGB offscreen surfaces -#define AMDDS_YUVOFF 0x20 // YUV offscreen surfaces -#define AMDDS_RGBFLP 0x40 // RGB flipping surfaces -#define AMDDS_YUVFLP 0x80 // YUV flipping surfaces -#define AMDDS_ALL 0xFF // ALL the previous flags -#define AMDDS_DEFAULT AMDDS_ALL // Use all available surfaces - -#define AMDDS_YUV (AMDDS_YUVOFF | AMDDS_YUVOVR | AMDDS_YUVFLP) -#define AMDDS_RGB (AMDDS_RGBOFF | AMDDS_RGBOVR | AMDDS_RGBFLP) -#define AMDDS_PRIMARY (AMDDS_DCIPS | AMDDS_PS) - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IDirectDrawVideo - -DECLARE_INTERFACE_(IDirectDrawVideo, IUnknown) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // IDirectDrawVideo methods - - STDMETHOD(GetSwitches)(THIS_ DWORD *pSwitches) PURE; - STDMETHOD(SetSwitches)(THIS_ DWORD Switches) PURE; - STDMETHOD(GetCaps)(THIS_ DDCAPS *pCaps) PURE; - STDMETHOD(GetEmulatedCaps)(THIS_ DDCAPS *pCaps) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ DDSURFACEDESC *pSurfaceDesc) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ DWORD *pCount,DWORD *pCodes) PURE; - STDMETHOD(SetDirectDraw)(THIS_ LPDIRECTDRAW pDirectDraw) PURE; - STDMETHOD(GetDirectDraw)(THIS_ LPDIRECTDRAW *ppDirectDraw) PURE; - STDMETHOD(GetSurfaceType)(THIS_ DWORD *pSurfaceType) PURE; - STDMETHOD(SetDefault)(THIS) PURE; - STDMETHOD(UseScanLine)(THIS_ long UseScanLine) PURE; - STDMETHOD(CanUseScanLine)(THIS_ long *UseScanLine) PURE; - STDMETHOD(UseOverlayStretch)(THIS_ long UseOverlayStretch) PURE; - STDMETHOD(CanUseOverlayStretch)(THIS_ long *UseOverlayStretch) PURE; - STDMETHOD(UseWhenFullScreen)(THIS_ long UseWhenFullScreen) PURE; - STDMETHOD(WillUseFullScreen)(THIS_ long *UseWhenFullScreen) PURE; -}; - - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IQualProp - -DECLARE_INTERFACE_(IQualProp, IUnknown) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // Compare these with the functions in class CGargle in gargle.h - - STDMETHOD(get_FramesDroppedInRenderer)(THIS_ int *pcFrames) PURE; // Out - STDMETHOD(get_FramesDrawn)(THIS_ int *pcFramesDrawn) PURE; // Out - STDMETHOD(get_AvgFrameRate)(THIS_ int *piAvgFrameRate) PURE; // Out - STDMETHOD(get_Jitter)(THIS_ int *iJitter) PURE; // Out - STDMETHOD(get_AvgSyncOffset)(THIS_ int *piAvg) PURE; // Out - STDMETHOD(get_DevSyncOffset)(THIS_ int *piDev) PURE; // Out -}; - - -// This interface allows an application or plug in distributor to control a -// full screen renderer. The Modex renderer supports this interface. When -// connected a renderer should load the display modes it has available -// The number of modes available can be obtained through CountModes. Then -// information on each individual mode is available by calling GetModeInfo -// and IsModeAvailable. An application may enable and disable any modes -// by calling the SetEnabled flag with OATRUE or OAFALSE (not C/C++ TRUE -// and FALSE values) - the current value may be queried by IsModeEnabled - -// A more generic way of setting the modes enabled that is easier to use -// when writing applications is the clip loss factor. This defines the -// amount of video that can be lost when deciding which display mode to -// use. Assuming the decoder cannot compress the video then playing an -// MPEG file (say 352x288) into a 320x200 display will lose about 25% of -// the image. The clip loss factor specifies the upper range permissible. -// To allow typical MPEG video to be played in 320x200 it defaults to 25% - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IFullScreenVideo - -DECLARE_INTERFACE_(IFullScreenVideo, IUnknown) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // IFullScreenVideo methods - - STDMETHOD(CountModes)(THIS_ long *pModes) PURE; - STDMETHOD(GetModeInfo)(THIS_ long Mode,long *pWidth,long *pHeight,long *pDepth) PURE; - STDMETHOD(GetCurrentMode)(THIS_ long *pMode) PURE; - STDMETHOD(IsModeAvailable)(THIS_ long Mode) PURE; - STDMETHOD(IsModeEnabled)(THIS_ long Mode) PURE; - STDMETHOD(SetEnabled)(THIS_ long Mode,long bEnabled) PURE; - STDMETHOD(GetClipFactor)(THIS_ long *pClipFactor) PURE; - STDMETHOD(SetClipFactor)(THIS_ long ClipFactor) PURE; - STDMETHOD(SetMessageDrain)(THIS_ HWND hwnd) PURE; - STDMETHOD(GetMessageDrain)(THIS_ HWND *hwnd) PURE; - STDMETHOD(SetMonitor)(THIS_ long Monitor) PURE; - STDMETHOD(GetMonitor)(THIS_ long *Monitor) PURE; - STDMETHOD(HideOnDeactivate)(THIS_ long Hide) PURE; - STDMETHOD(IsHideOnDeactivate)(THIS) PURE; - STDMETHOD(SetCaption)(THIS_ BSTR strCaption) PURE; - STDMETHOD(GetCaption)(THIS_ BSTR *pstrCaption) PURE; - STDMETHOD(SetDefault)(THIS) PURE; -}; - - -// This adds the accelerator table capabilities in fullscreen. This is being -// added between the original runtime release and the full SDK release. We -// cannot just add the method to IFullScreenVideo as we don't want to force -// applications to have to ship the ActiveMovie support DLLs - this is very -// important to applications that plan on being downloaded over the Internet - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IFullScreenVideoEx - -DECLARE_INTERFACE_(IFullScreenVideoEx, IFullScreenVideo) -{ - // IUnknown methods - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - // IFullScreenVideo methods - - STDMETHOD(CountModes)(THIS_ long *pModes) PURE; - STDMETHOD(GetModeInfo)(THIS_ long Mode,long *pWidth,long *pHeight,long *pDepth) PURE; - STDMETHOD(GetCurrentMode)(THIS_ long *pMode) PURE; - STDMETHOD(IsModeAvailable)(THIS_ long Mode) PURE; - STDMETHOD(IsModeEnabled)(THIS_ long Mode) PURE; - STDMETHOD(SetEnabled)(THIS_ long Mode,long bEnabled) PURE; - STDMETHOD(GetClipFactor)(THIS_ long *pClipFactor) PURE; - STDMETHOD(SetClipFactor)(THIS_ long ClipFactor) PURE; - STDMETHOD(SetMessageDrain)(THIS_ HWND hwnd) PURE; - STDMETHOD(GetMessageDrain)(THIS_ HWND *hwnd) PURE; - STDMETHOD(SetMonitor)(THIS_ long Monitor) PURE; - STDMETHOD(GetMonitor)(THIS_ long *Monitor) PURE; - STDMETHOD(HideOnDeactivate)(THIS_ long Hide) PURE; - STDMETHOD(IsHideOnDeactivate)(THIS) PURE; - STDMETHOD(SetCaption)(THIS_ BSTR strCaption) PURE; - STDMETHOD(GetCaption)(THIS_ BSTR *pstrCaption) PURE; - STDMETHOD(SetDefault)(THIS) PURE; - - // IFullScreenVideoEx - - STDMETHOD(SetAcceleratorTable)(THIS_ HWND hwnd,HACCEL hAccel) PURE; - STDMETHOD(GetAcceleratorTable)(THIS_ HWND *phwnd,HACCEL *phAccel) PURE; - STDMETHOD(KeepPixelAspectRatio)(THIS_ long KeepAspect) PURE; - STDMETHOD(IsKeepPixelAspectRatio)(THIS_ long *pKeepAspect) PURE; -}; - - -// The SDK base classes contain a base video mixer class. Video mixing in a -// software environment is tricky because we typically have multiple streams -// each sending data at unpredictable times. To work with this we defined a -// pin that is the lead pin, when data arrives on this pin we do a mix. As -// an alternative we may not want to have a lead pin but output samples at -// predefined spaces, like one every 1/15 of a second, this interfaces also -// supports that mode of operations (there is a working video mixer sample) - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IBaseVideoMixer - -DECLARE_INTERFACE_(IBaseVideoMixer, IUnknown) -{ - STDMETHOD(SetLeadPin)(THIS_ int iPin) PURE; - STDMETHOD(GetLeadPin)(THIS_ int *piPin) PURE; - STDMETHOD(GetInputPinCount)(THIS_ int *piPinCount) PURE; - STDMETHOD(IsUsingClock)(THIS_ int *pbValue) PURE; - STDMETHOD(SetUsingClock)(THIS_ int bValue) PURE; - STDMETHOD(GetClockPeriod)(THIS_ int *pbValue) PURE; - STDMETHOD(SetClockPeriod)(THIS_ int bValue) PURE; -}; - -#define iPALETTE_COLORS 256 // Maximum colours in palette -#define iEGA_COLORS 16 // Number colours in EGA palette -#define iMASK_COLORS 3 // Maximum three components -#define iTRUECOLOR 16 // Minimum true colour device -#define iRED 0 // Index position for RED mask -#define iGREEN 1 // Index position for GREEN mask -#define iBLUE 2 // Index position for BLUE mask -#define iPALETTE 8 // Maximum colour depth using a palette -#define iMAXBITS 8 // Maximum bits per colour component - - -// Used for true colour images that also have a palette - -typedef struct tag_TRUECOLORINFO { - DWORD dwBitMasks[iMASK_COLORS]; - RGBQUAD bmiColors[iPALETTE_COLORS]; -} TRUECOLORINFO; - - -// The BITMAPINFOHEADER contains all the details about the video stream such -// as the actual image dimensions and their pixel depth. A source filter may -// also request that the sink take only a section of the video by providing a -// clipping rectangle in rcSource. In the worst case where the sink filter -// forgets to check this on connection it will simply render the whole thing -// which isn't a disaster. Ideally a sink filter will check the rcSource and -// if it doesn't support image extraction and the rectangle is not empty then -// it will reject the connection. A filter should use SetRectEmpty to reset a -// rectangle to all zeroes (and IsRectEmpty to later check the rectangle). -// The rcTarget specifies the destination rectangle for the video, for most -// source filters they will set this to all zeroes, a downstream filter may -// request that the video be placed in a particular area of the buffers it -// supplies in which case it will call QueryAccept with a non empty target - -typedef struct tagVIDEOINFOHEADER { - - RECT rcSource; // The bit we really want to use - RECT rcTarget; // Where the video should go - DWORD dwBitRate; // Approximate bit data rate - DWORD dwBitErrorRate; // Bit error rate for this stream - REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units) - - BITMAPINFOHEADER bmiHeader; - -} VIDEOINFOHEADER; - -// make sure the pbmi is initialized before using these macros -#define TRUECOLOR(pbmi) ((TRUECOLORINFO *)(((LPBYTE)&((pbmi)->bmiHeader)) \ - + (pbmi)->bmiHeader.biSize)) -#define COLORS(pbmi) ((RGBQUAD *)(((LPBYTE)&((pbmi)->bmiHeader)) \ - + (pbmi)->bmiHeader.biSize)) -#define BITMASKS(pbmi) ((DWORD *)(((LPBYTE)&((pbmi)->bmiHeader)) \ - + (pbmi)->bmiHeader.biSize)) - -// All the image based filters use this to communicate their media types. It's -// centred principally around the BITMAPINFO. This structure always contains a -// BITMAPINFOHEADER followed by a number of other fields depending on what the -// BITMAPINFOHEADER contains. If it contains details of a palettised format it -// will be followed by one or more RGBQUADs defining the palette. If it holds -// details of a true colour format then it may be followed by a set of three -// DWORD bit masks that specify where the RGB data can be found in the image -// (For more information regarding BITMAPINFOs see the Win32 documentation) - -// The rcSource and rcTarget fields are not for use by filters supplying the -// data. The destination (target) rectangle should be set to all zeroes. The -// source may also be zero filled or set with the dimensions of the video. So -// if the video is 352x288 pixels then set it to (0,0,352,288). These fields -// are mainly used by downstream filters that want to ask the source filter -// to place the image in a different position in an output buffer. So when -// using for example the primary surface the video renderer may ask a filter -// to place the video images in a destination position of (100,100,452,388) -// on the display since that's where the window is positioned on the display - -// !!! WARNING !!! -// DO NOT use this structure unless you are sure that the BITMAPINFOHEADER -// has a normal biSize == sizeof(BITMAPINFOHEADER) ! -// !!! WARNING !!! - -typedef struct tagVIDEOINFO { - - RECT rcSource; // The bit we really want to use - RECT rcTarget; // Where the video should go - DWORD dwBitRate; // Approximate bit data rate - DWORD dwBitErrorRate; // Bit error rate for this stream - REFERENCE_TIME AvgTimePerFrame; // Average time per frame (100ns units) - - BITMAPINFOHEADER bmiHeader; - - union { - RGBQUAD bmiColors[iPALETTE_COLORS]; // Colour palette - DWORD dwBitMasks[iMASK_COLORS]; // True colour masks - TRUECOLORINFO TrueColorInfo; // Both of the above - }; - -} VIDEOINFO; - -// These macros define some standard bitmap format sizes - -#define SIZE_EGA_PALETTE (iEGA_COLORS * sizeof(RGBQUAD)) -#define SIZE_PALETTE (iPALETTE_COLORS * sizeof(RGBQUAD)) -#define SIZE_MASKS (iMASK_COLORS * sizeof(DWORD)) -#define SIZE_PREHEADER (FIELD_OFFSET(VIDEOINFOHEADER,bmiHeader)) -#define SIZE_VIDEOHEADER (sizeof(BITMAPINFOHEADER) + SIZE_PREHEADER) -// !!! for abnormal biSizes -// #define SIZE_VIDEOHEADER(pbmi) ((pbmi)->bmiHeader.biSize + SIZE_PREHEADER) - -// DIBSIZE calculates the number of bytes required by an image - -#define WIDTHBYTES(bits) ((DWORD)(((bits)+31) & (~31)) / 8) -#define DIBWIDTHBYTES(bi) (DWORD)WIDTHBYTES((DWORD)(bi).biWidth * (DWORD)(bi).biBitCount) -#define _DIBSIZE(bi) (DIBWIDTHBYTES(bi) * (DWORD)(bi).biHeight) -#define DIBSIZE(bi) ((bi).biHeight < 0 ? (-1)*(_DIBSIZE(bi)) : _DIBSIZE(bi)) - -// This compares the bit masks between two VIDEOINFOHEADERs - -#define BIT_MASKS_MATCH(pbmi1,pbmi2) \ - (((pbmi1)->dwBitMasks[iRED] == (pbmi2)->dwBitMasks[iRED]) && \ - ((pbmi1)->dwBitMasks[iGREEN] == (pbmi2)->dwBitMasks[iGREEN]) && \ - ((pbmi1)->dwBitMasks[iBLUE] == (pbmi2)->dwBitMasks[iBLUE])) - -// These zero fill different parts of the VIDEOINFOHEADER structure - -// Only use these macros for pbmi's with a normal BITMAPINFOHEADER biSize -#define RESET_MASKS(pbmi) (ZeroMemory((PVOID)(pbmi)->dwBitFields,SIZE_MASKS)) -#define RESET_HEADER(pbmi) (ZeroMemory((PVOID)(pbmi),SIZE_VIDEOHEADER)) -#define RESET_PALETTE(pbmi) (ZeroMemory((PVOID)(pbmi)->bmiColors,SIZE_PALETTE)); - -#if 0 -// !!! This is the right way to do it, but may break existing code -#define RESET_MASKS(pbmi) (ZeroMemory((PVOID)(((LPBYTE)(pbmi)->bmiHeader) + \ - (pbmi)->bmiHeader.biSize,SIZE_MASKS))) -#define RESET_HEADER(pbmi) (ZeroMemory((PVOID)(pbmi), SIZE_PREHEADER + \ - sizeof(BITMAPINFOHEADER))) -#define RESET_PALETTE(pbmi) (ZeroMemory((PVOID)(((LPBYTE)(pbmi)->bmiHeader) + \ - (pbmi)->bmiHeader.biSize,SIZE_PALETTE)) -#endif - -// Other (hopefully) useful bits and bobs - -#define PALETTISED(pbmi) ((pbmi)->bmiHeader.biBitCount <= iPALETTE) -#define PALETTE_ENTRIES(pbmi) ((DWORD) 1 << (pbmi)->bmiHeader.biBitCount) - -// Returns the address of the BITMAPINFOHEADER from the VIDEOINFOHEADER -#define HEADER(pVideoInfo) (&(((VIDEOINFOHEADER *) (pVideoInfo))->bmiHeader)) - - -// MPEG variant - includes a DWORD length followed by the -// video sequence header after the video header. -// -// The sequence header includes the sequence header start code and the -// quantization matrices associated with the first sequence header in the -// stream so is a maximum of 140 bytes long. - -typedef struct tagMPEG1VIDEOINFO { - - VIDEOINFOHEADER hdr; // Compatible with VIDEOINFO - DWORD dwStartTimeCode; // 25-bit Group of pictures time code - // at start of data - DWORD cbSequenceHeader; // Length in bytes of bSequenceHeader - BYTE bSequenceHeader[1]; // Sequence header including - // quantization matrices if any -} MPEG1VIDEOINFO; - -#define MAX_SIZE_MPEG1_SEQUENCE_INFO 140 -#define SIZE_MPEG1VIDEOINFO(pv) (FIELD_OFFSET(MPEG1VIDEOINFO, bSequenceHeader[0]) + (pv)->cbSequenceHeader) -#define MPEG1_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->bSequenceHeader) - - -// Analog video variant - Use this when the format is FORMAT_AnalogVideo -// -// rcSource defines the portion of the active video signal to use -// rcTarget defines the destination rectangle -// both of the above are relative to the dwActiveWidth and dwActiveHeight fields -// dwActiveWidth is currently set to 720 for all formats (but could change for HDTV) -// dwActiveHeight is 483 for NTSC and 575 for PAL/SECAM (but could change for HDTV) - -typedef struct tagAnalogVideoInfo { - RECT rcSource; // Width max is 720, height varies w/ TransmissionStd - RECT rcTarget; // Where the video should go - DWORD dwActiveWidth; // Always 720 (CCIR-601 active samples per line) - DWORD dwActiveHeight; // 483 for NTSC, 575 for PAL/SECAM - REFERENCE_TIME AvgTimePerFrame; // Normal ActiveMovie units (100 nS) -} ANALOGVIDEOINFO; - -// -// AM_KSPROPSETID_FrameStep property set definitions -// -typedef enum { - // Step - AM_PROPERTY_FRAMESTEP_STEP = 0x01, - AM_PROPERTY_FRAMESTEP_CANCEL = 0x02, - - // S_OK for these 2 means we can - S_FALSE if we can't - AM_PROPERTY_FRAMESTEP_CANSTEP = 0x03, - AM_PROPERTY_FRAMESTEP_CANSTEPMULTIPLE = 0x04 -} AM_PROPERTY_FRAMESTEP; - -typedef struct _AM_FRAMESTEP_STEP -{ - // 1 means step 1 frame forward - // 0 is invalid - // n (n > 1) means skip n - 1 frames and show the nth - DWORD dwFramesToStep; -} AM_FRAMESTEP_STEP; - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // __AMVIDEO__ - diff --git a/plugins/gs/gsdx9/baseclasses/activex.rcv b/plugins/gs/gsdx9/baseclasses/activex.rcv deleted file mode 100644 index 8aef99bfa5..0000000000 --- a/plugins/gs/gsdx9/baseclasses/activex.rcv +++ /dev/null @@ -1,142 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Activex.rcv -// -// Desc: DirectShow base classes - this file defines the version resource -// used for the application. -// -// NOTE: All strings MUST have an explicit \0 for termination! -// -// For a complete description of the Version Resource, search the -// Microsoft Developer's Network (MSDN) CD-ROM for 'version resource'.. -// -// Copyright (c) 1992 - 2002, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef _ACTIVEX_RCV_ -#define _ACTIVEX_RCV_ - -#ifndef WIN32 -#define WIN32 -#endif -#include - -#ifndef _ACTIVEX_VER_ -#include -#endif - -// -// Version flags. -// -// OFFICIAL and FINAL should be defined when appropriate. -// - -#ifndef OFFICIAL -#define VER_PRIVATEBUILD VS_FF_PRIVATEBUILD -#else -#define VER_PRIVATEBUILD 0 -#endif - -#ifndef FINAL -#define VER_PRERELEASE VS_FF_PRERELEASE -#else -#define VER_PRERELEASE 0 -#endif - -#ifdef DEBUG -#define VER_DEBUG VS_FF_DEBUG -#else -#define VER_DEBUG 0 -#endif - -// -// Version definitions -// - -#define VERSION_RES_FLAGSMASK 0x0030003FL -#define VERSION_RES_FLAGS (VER_PRIVATEBUILD|VER_PRERELEASE|VER_DEBUG) - -#ifndef VERSION_RES_OS -#define VERSION_RES_OS VOS__WINDOWS32 -#endif - -#ifndef VERSION_RES_TYPE -#define VERSION_RES_TYPE VFT_DLL -#endif - -#ifndef VERSION_RES_SUBTYPE -#define VERSION_RES_SUBTYPE VFT2_UNKNOWN -#endif - -#define VERSION_RES_LANGUAGE 0x409 - -#ifndef VERSION_RES_CHARSET -#ifdef UNICODE -#define VERSION_RES_CHARSET 1200 -#else -#define VERSION_RES_CHARSET 1252 -#endif -#endif - -#ifndef VERSION_RES_ACTIVEX -#define VERSION_RES_ACTIVEX "Filter dll\0" -#endif - -#ifdef AMOVIE_SELF_REGISTER -#ifndef OLE_SELF_REGISTER -#define OLE_SELF_REGISTER -#endif -#endif - -#ifdef OLE_SELF_REGISTER -#ifdef AMOVIE_SELF_REGISTER -#define VERSION_RES_SELFREGISTER "AM20\0" -#else -#define VERSION_RES_SELFREGISTER "\0" -#endif -#endif - -// -// Version resource -// - -VS_VERSION_INFO VERSIONINFO -FILEVERSION VERSION_RES_MAJOR_VER, VERSION_RES_MINOR_VER, 0, VERSION_RES_BUILD -PRODUCTVERSION VERSION_RES_MAJOR_VER, VERSION_RES_MINOR_VER, 0, VERSION_RES_BUILD -FILEFLAGSMASK VERSION_RES_FLAGSMASK -FILEFLAGS VERSION_RES_FLAGS -FILEOS VERSION_RES_OS -FILETYPE VERSION_RES_TYPE -FILESUBTYPE VERSION_RES_SUBTYPE -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904E4" - BEGIN - VALUE "CompanyName", VERSION_RES_COMPANY_NAME - VALUE "Comment", VERSION_RES_COMMENT - VALUE "FileDescription", VERSION_RES_BIN_DESCRIPTION - VALUE "FileVersion", VERSION_RES_STRING - VALUE "InternalName", VERSION_RES_BIN_NAME - VALUE "LegalCopyright", VERSION_RES_COPYRIGHT - VALUE "OriginalFilename", VERSION_RES_BIN_NAME - VALUE "ProductName", VERSION_RES_PRODUCT_NAME -#ifdef DEBUG - VALUE "ProductVersion", VERSION_RES_STRING_D -#else - VALUE "ProductVersion", VERSION_RES_STRING -#endif - VALUE "ActiveMovie", VERSION_RES_ACTIVEX -#ifdef OLE_SELF_REGISTER - VALUE "OLESelfRegister", VERSION_RES_SELFREGISTER -#endif - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", VERSION_RES_LANGUAGE, VERSION_RES_CHARSET - END -END - -#endif -// _ACTIVEX_RCV_ diff --git a/plugins/gs/gsdx9/baseclasses/activex.ver b/plugins/gs/gsdx9/baseclasses/activex.ver deleted file mode 100644 index 4786f68eea..0000000000 --- a/plugins/gs/gsdx9/baseclasses/activex.ver +++ /dev/null @@ -1,56 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Activex.ver -// -// Desc: DirectShow base classes - common versioning information for -// ACTIVEX binaries. -// -// Copyright (c) 1996-2002, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef _ACTIVEX_VER_ -#define _ACTIVEX_VER_ - -// NOTE: all string resources that will be used in ACTIVEX.RCV for the -// version resource information *MUST* have an explicit \0 terminator! - -#define VERSION_RES_MAJOR_VER 9 -#define VERSION_RES_MINOR_VER 0 -#define VERSION_RES_BUILD 0 - -#define VERSION_RES_STRING_D "9.00 (Debug)\0" -#define VERSION_RES_STRING "9.00\0" - -#define VERSION_RES_PRODUCT_NAME "DirectX 9.0 Sample\0" -#define VERSION_RES_COMMENT "DirectShow Sample\0" -#define VERSION_RES_COMPANY_NAME "Microsoft Corporation\0" -#define VERSION_RES_COPYRIGHT "Copyright (C) 1992-2002 Microsoft Corporation\0" - -// The following defines are required on a file-by-file basis -// -// #define VERSION_RES_BIN_NAME "sample.ax\0" -// #define VERSION_RES_BIN_DESCRIPTION "Sample Filter\0" -// -// Also required, if you don't want the defaults, are -// -// #define VERSION_RES_ACTIVEX "Filter dll\0" (the default value) -// -// A string defining the type of component. -// -// #define VERSION_RES_TYPE VFT_DLL (default) -// VFT_APP -// VFT_VXD -// VFT_DRV -// VFT_FONT -// VFT_STATIC_LIB -// VFT_UNKNOWN -// -// #define VERSION_RES_SUBTYPE VFT2_UNKNOWN (default) -// VFT2_DRV_INSTALLABLE -// VFT2_DRV_SOUND -// -// -// See winver.h for further details - -#endif - diff --git a/plugins/gs/gsdx9/baseclasses/amaudio.h b/plugins/gs/gsdx9/baseclasses/amaudio.h deleted file mode 100644 index 77fdd76569..0000000000 --- a/plugins/gs/gsdx9/baseclasses/amaudio.h +++ /dev/null @@ -1,54 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMAudio.h -// -// Desc: Audio related definitions and interfaces for ActiveMovie. -// -// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __AMAUDIO__ -#define __AMAUDIO__ - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#include -#include - -// This is the interface the audio renderer supports to give the application -// access to the direct sound object and the buffers it is using, to allow the -// application to use things like the 3D features of Direct Sound for the -// soundtrack of a movie being played with Active Movie. - -// be nice to our friends in C -#undef INTERFACE -#define INTERFACE IAMDirectSound - -DECLARE_INTERFACE_(IAMDirectSound,IUnknown) -{ - /* IUnknown methods */ - - STDMETHOD(QueryInterface)(THIS_ REFIID riid, LPVOID *ppvObj) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - - /* IAMDirectSound methods */ - - STDMETHOD(GetDirectSoundInterface)(THIS_ LPDIRECTSOUND *lplpds) PURE; - STDMETHOD(GetPrimaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER *lplpdsb) PURE; - STDMETHOD(GetSecondaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER *lplpdsb) PURE; - STDMETHOD(ReleaseDirectSoundInterface)(THIS_ LPDIRECTSOUND lpds) PURE; - STDMETHOD(ReleasePrimaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER lpdsb) PURE; - STDMETHOD(ReleaseSecondaryBufferInterface)(THIS_ LPDIRECTSOUNDBUFFER lpdsb) PURE; - STDMETHOD(SetFocusWindow)(THIS_ HWND, BOOL) PURE ; - STDMETHOD(GetFocusWindow)(THIS_ HWND *, BOOL*) PURE ; -}; - - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // __AMAUDIO__ - diff --git a/plugins/gs/gsdx9/baseclasses/amextra.cpp b/plugins/gs/gsdx9/baseclasses/amextra.cpp deleted file mode 100644 index a242cee859..0000000000 --- a/plugins/gs/gsdx9/baseclasses/amextra.cpp +++ /dev/null @@ -1,111 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMExtra.cpp -// -// Desc: DirectShow base classes - implements CRenderedInputPin class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include // DirectShow base class definitions -#include // Needed for definition of timeGetTime -#include // Standard data type limit definitions -#include // Used for time critical log functions - -#include "amextra.h" - -#pragma warning(disable:4355) - -// Implements CRenderedInputPin class - -CRenderedInputPin::CRenderedInputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseInputPin(pObjectName, pFilter, pLock, phr, pName), - m_bAtEndOfStream(FALSE), - m_bCompleteNotified(FALSE) -{ -} -#ifdef UNICODE -CRenderedInputPin::CRenderedInputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseInputPin(pObjectName, pFilter, pLock, phr, pName), - m_bAtEndOfStream(FALSE), - m_bCompleteNotified(FALSE) -{ -} -#endif - -// Flush end of stream condition - caller should do any -// necessary stream level locking before calling this - -STDMETHODIMP CRenderedInputPin::EndOfStream() -{ - HRESULT hr = CheckStreaming(); - - // Do EC_COMPLETE handling for rendered pins - if (S_OK == hr && !m_bAtEndOfStream) { - m_bAtEndOfStream = TRUE; - FILTER_STATE fs; - EXECUTE_ASSERT(SUCCEEDED(m_pFilter->GetState(0, &fs))); - if (fs == State_Running) { - DoCompleteHandling(); - } - } - return hr; -} - - -// Called to complete the flush - -STDMETHODIMP CRenderedInputPin::EndFlush() -{ - CAutoLock lck(m_pLock); - - // Clean up renderer state - m_bAtEndOfStream = FALSE; - m_bCompleteNotified = FALSE; - - return CBaseInputPin::EndFlush(); -} - - -// Notify of Run() from filter - -HRESULT CRenderedInputPin::Run(REFERENCE_TIME tStart) -{ - UNREFERENCED_PARAMETER(tStart); - m_bCompleteNotified = FALSE; - if (m_bAtEndOfStream) { - DoCompleteHandling(); - } - return S_OK; -} - - -// Clear status on going into paused state - -HRESULT CRenderedInputPin::Active() -{ - m_bAtEndOfStream = FALSE; - m_bCompleteNotified = FALSE; - return CBaseInputPin::Active(); -} - - -// Do stuff to deliver end of stream - -void CRenderedInputPin::DoCompleteHandling() -{ - ASSERT(m_bAtEndOfStream); - if (!m_bCompleteNotified) { - m_bCompleteNotified = TRUE; - m_pFilter->NotifyEvent(EC_COMPLETE, S_OK, (LONG_PTR)(IBaseFilter *)m_pFilter); - } -} - diff --git a/plugins/gs/gsdx9/baseclasses/amextra.h b/plugins/gs/gsdx9/baseclasses/amextra.h deleted file mode 100644 index ddb067ffcf..0000000000 --- a/plugins/gs/gsdx9/baseclasses/amextra.h +++ /dev/null @@ -1,56 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMExtra.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __AMEXTRA__ -#define __AMEXTRA__ - -// Simple rendered input pin -// -// NOTE if your filter queues stuff before rendering then it may not be -// appropriate to use this class -// -// In that case queue the end of stream condition until the last sample -// is actually rendered and flush the condition appropriately - -class CRenderedInputPin : public CBaseInputPin -{ -public: - - CRenderedInputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#ifdef UNICODE - CRenderedInputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - - // Override methods to track end of stream state - STDMETHODIMP EndOfStream(); - STDMETHODIMP EndFlush(); - - HRESULT Active(); - HRESULT Run(REFERENCE_TIME tStart); - -protected: - - // Member variables to track state - BOOL m_bAtEndOfStream; // Set by EndOfStream - BOOL m_bCompleteNotified; // Set when we notify for EC_COMPLETE - -private: - void DoCompleteHandling(); -}; - -#endif // __AMEXTRA__ - diff --git a/plugins/gs/gsdx9/baseclasses/amfilter.cpp b/plugins/gs/gsdx9/baseclasses/amfilter.cpp deleted file mode 100644 index eb26cd276f..0000000000 --- a/plugins/gs/gsdx9/baseclasses/amfilter.cpp +++ /dev/null @@ -1,5203 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMFilter.cpp -// -// Desc: DirectShow base classes - implements class hierarchy for streams -// architecture. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -//===================================================================== -//===================================================================== -// The following classes are declared in this header: -// -// -// CBaseMediaFilter Basic IMediaFilter support (abstract class) -// CBaseFilter Support for IBaseFilter (incl. IMediaFilter) -// CEnumPins Enumerate input and output pins -// CEnumMediaTypes Enumerate the preferred pin formats -// CBasePin Abstract base class for IPin interface -// CBaseOutputPin Adds data provider member functions -// CBaseInputPin Implements IMemInputPin interface -// CMediaSample Basic transport unit for IMemInputPin -// CBaseAllocator General list guff for most allocators -// CMemAllocator Implements memory buffer allocation -// -//===================================================================== -//===================================================================== - -#include - - - -//===================================================================== -// Helpers -//===================================================================== -STDAPI CreateMemoryAllocator(IMemAllocator **ppAllocator) -{ - return CoCreateInstance(CLSID_MemoryAllocator, - 0, - CLSCTX_INPROC_SERVER, - IID_IMemAllocator, - (void **)ppAllocator); -} - -// Put this one here rather than in ctlutil.cpp to avoid linking -// anything brought in by ctlutil.cpp -STDAPI CreatePosPassThru( - LPUNKNOWN pAgg, - BOOL bRenderer, - IPin *pPin, - IUnknown **ppPassThru -) -{ - *ppPassThru = NULL; - IUnknown *pUnkSeek; - HRESULT hr = CoCreateInstance(CLSID_SeekingPassThru, - pAgg, - CLSCTX_INPROC_SERVER, - IID_IUnknown, - (void **)&pUnkSeek - ); - if (FAILED(hr)) { - return hr; - } - - ISeekingPassThru *pPassThru; - hr = pUnkSeek->QueryInterface(IID_ISeekingPassThru, (void**)&pPassThru); - if (FAILED(hr)) { - pUnkSeek->Release(); - return hr; - } - hr = pPassThru->Init(bRenderer, pPin); - pPassThru->Release(); - if (FAILED(hr)) { - pUnkSeek->Release(); - return hr; - } - *ppPassThru = pUnkSeek; - return S_OK; -} - - - -#define CONNECT_TRACE_LEVEL 3 - -//===================================================================== -//===================================================================== -// Implements CBaseMediaFilter -//===================================================================== -//===================================================================== - - -/* Constructor */ - -CBaseMediaFilter::CBaseMediaFilter(const TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid) : - CUnknown(pName, pUnk), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL) -{ -} - - -/* Destructor */ - -CBaseMediaFilter::~CBaseMediaFilter() -{ - // must be stopped, but can't call Stop here since - // our critsec has been destroyed. - - /* Release any clock we were using */ - - if (m_pClock) { - m_pClock->Release(); - m_pClock = NULL; - } -} - - -/* Override this to say what interfaces we support and where */ - -STDMETHODIMP -CBaseMediaFilter::NonDelegatingQueryInterface( - REFIID riid, - void ** ppv) -{ - if (riid == IID_IMediaFilter) { - return GetInterface((IMediaFilter *) this, ppv); - } else if (riid == IID_IPersist) { - return GetInterface((IPersist *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - -/* Return the filter's clsid */ -STDMETHODIMP -CBaseMediaFilter::GetClassID(CLSID *pClsID) -{ - CheckPointer(pClsID,E_POINTER); - ValidateReadWritePtr(pClsID,sizeof(CLSID)); - *pClsID = m_clsid; - return NOERROR; -} - -/* Override this if your state changes are not done synchronously */ - -STDMETHODIMP -CBaseMediaFilter::GetState(DWORD dwMSecs, FILTER_STATE *State) -{ - UNREFERENCED_PARAMETER(dwMSecs); - CheckPointer(State,E_POINTER); - ValidateReadWritePtr(State,sizeof(FILTER_STATE)); - - *State = m_State; - return S_OK; -} - - -/* Set the clock we will use for synchronisation */ - -STDMETHODIMP -CBaseMediaFilter::SetSyncSource(IReferenceClock *pClock) -{ - CAutoLock cObjectLock(m_pLock); - - // Ensure the new one does not go away - even if the same as the old - if (pClock) { - pClock->AddRef(); - } - - // if we have a clock, release it - if (m_pClock) { - m_pClock->Release(); - } - - // Set the new reference clock (might be NULL) - // Should we query it to ensure it is a clock? Consider for a debug build. - m_pClock = pClock; - - return NOERROR; -} - -/* Return the clock we are using for synchronisation */ -STDMETHODIMP -CBaseMediaFilter::GetSyncSource(IReferenceClock **pClock) -{ - CheckPointer(pClock,E_POINTER); - ValidateReadWritePtr(pClock,sizeof(IReferenceClock *)); - CAutoLock cObjectLock(m_pLock); - - if (m_pClock) { - // returning an interface... addref it... - m_pClock->AddRef(); - } - *pClock = (IReferenceClock*)m_pClock; - return NOERROR; -} - - -/* Put the filter into a stopped state */ - -STDMETHODIMP -CBaseMediaFilter::Stop() -{ - CAutoLock cObjectLock(m_pLock); - - m_State = State_Stopped; - return S_OK; -} - - -/* Put the filter into a paused state */ - -STDMETHODIMP -CBaseMediaFilter::Pause() -{ - CAutoLock cObjectLock(m_pLock); - - m_State = State_Paused; - return S_OK; -} - - -// Put the filter into a running state. - -// The time parameter is the offset to be added to the samples' -// stream time to get the reference time at which they should be presented. -// -// you can either add these two and compare it against the reference clock, -// or you can call CBaseMediaFilter::StreamTime and compare that against -// the sample timestamp. - -STDMETHODIMP -CBaseMediaFilter::Run(REFERENCE_TIME tStart) -{ - CAutoLock cObjectLock(m_pLock); - - // remember the stream time offset - m_tStart = tStart; - - if (m_State == State_Stopped){ - HRESULT hr = Pause(); - - if (FAILED(hr)) { - return hr; - } - } - m_State = State_Running; - return S_OK; -} - - -// -// return the current stream time - samples with start timestamps of this -// time or before should be rendered by now -HRESULT -CBaseMediaFilter::StreamTime(CRefTime& rtStream) -{ - // Caller must lock for synchronization - // We can't grab the filter lock because we want to be able to call - // this from worker threads without deadlocking - - if (m_pClock == NULL) { - return VFW_E_NO_CLOCK; - } - - // get the current reference time - HRESULT hr = m_pClock->GetTime((REFERENCE_TIME*)&rtStream); - if (FAILED(hr)) { - return hr; - } - - // subtract the stream offset to get stream time - rtStream -= m_tStart; - - return S_OK; -} - - -//===================================================================== -//===================================================================== -// Implements CBaseFilter -//===================================================================== -//===================================================================== - - -/* Override this to say what interfaces we support and where */ - -STDMETHODIMP CBaseFilter::NonDelegatingQueryInterface(REFIID riid, - void **ppv) -{ - /* Do we have this interface */ - - if (riid == IID_IBaseFilter) { - return GetInterface((IBaseFilter *) this, ppv); - } else if (riid == IID_IMediaFilter) { - return GetInterface((IMediaFilter *) this, ppv); - } else if (riid == IID_IPersist) { - return GetInterface((IPersist *) this, ppv); - } else if (riid == IID_IAMovieSetup) { - return GetInterface((IAMovieSetup *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - -#ifdef DEBUG -STDMETHODIMP_(ULONG) CBaseFilter::NonDelegatingRelease() -{ - if (m_cRef == 1) { - KASSERT(m_pGraph == NULL); - } - return CUnknown::NonDelegatingRelease(); -} -#endif - - -/* Constructor */ - -CBaseFilter::CBaseFilter(const TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); -} - -/* Passes in a redundant HRESULT argument */ - -CBaseFilter::CBaseFilter(TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid, - HRESULT *phr) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); - UNREFERENCED_PARAMETER(phr); -} - -#ifdef UNICODE -CBaseFilter::CBaseFilter(const CHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); -} -CBaseFilter::CBaseFilter(CHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid, - HRESULT *phr) : - CUnknown( pName, pUnk ), - m_pLock(pLock), - m_clsid(clsid), - m_State(State_Stopped), - m_pClock(NULL), - m_pGraph(NULL), - m_pSink(NULL), - m_pName(NULL), - m_PinVersion(1) -{ - - ASSERT(pLock != NULL); - UNREFERENCED_PARAMETER(phr); -} -#endif - -/* Destructor */ - -CBaseFilter::~CBaseFilter() -{ - - // NOTE we do NOT hold references on the filtergraph for m_pGraph or m_pSink - // When we did we had the circular reference problem. Nothing would go away. - - delete[] m_pName; - - // must be stopped, but can't call Stop here since - // our critsec has been destroyed. - - /* Release any clock we were using */ - if (m_pClock) { - m_pClock->Release(); - m_pClock = NULL; - } -} - -/* Return the filter's clsid */ -STDMETHODIMP -CBaseFilter::GetClassID(CLSID *pClsID) -{ - CheckPointer(pClsID,E_POINTER); - ValidateReadWritePtr(pClsID,sizeof(CLSID)); - *pClsID = m_clsid; - return NOERROR; -} - -/* Override this if your state changes are not done synchronously */ -STDMETHODIMP -CBaseFilter::GetState(DWORD dwMSecs, FILTER_STATE *State) -{ - UNREFERENCED_PARAMETER(dwMSecs); - CheckPointer(State,E_POINTER); - ValidateReadWritePtr(State,sizeof(FILTER_STATE)); - - *State = m_State; - return S_OK; -} - - -/* Set the clock we will use for synchronisation */ - -STDMETHODIMP -CBaseFilter::SetSyncSource(IReferenceClock *pClock) -{ - CAutoLock cObjectLock(m_pLock); - - // Ensure the new one does not go away - even if the same as the old - if (pClock) { - pClock->AddRef(); - } - - // if we have a clock, release it - if (m_pClock) { - m_pClock->Release(); - } - - // Set the new reference clock (might be NULL) - // Should we query it to ensure it is a clock? Consider for a debug build. - m_pClock = pClock; - - return NOERROR; -} - -/* Return the clock we are using for synchronisation */ -STDMETHODIMP -CBaseFilter::GetSyncSource(IReferenceClock **pClock) -{ - CheckPointer(pClock,E_POINTER); - ValidateReadWritePtr(pClock,sizeof(IReferenceClock *)); - CAutoLock cObjectLock(m_pLock); - - if (m_pClock) { - // returning an interface... addref it... - m_pClock->AddRef(); - } - *pClock = (IReferenceClock*)m_pClock; - return NOERROR; -} - - - -// override CBaseMediaFilter Stop method, to deactivate any pins this -// filter has. -STDMETHODIMP -CBaseFilter::Stop() -{ - CAutoLock cObjectLock(m_pLock); - HRESULT hr = NOERROR; - - // notify all pins of the state change - if (m_State != State_Stopped) { - int cPins = GetPinCount(); - for (int c = 0; c < cPins; c++) { - - CBasePin *pPin = GetPin(c); - - // Disconnected pins are not activated - this saves pins worrying - // about this state themselves. We ignore the return code to make - // sure everyone is inactivated regardless. The base input pin - // class can return an error if it has no allocator but Stop can - // be used to resync the graph state after something has gone bad - - if (pPin->IsConnected()) { - HRESULT hrTmp = pPin->Inactive(); - if (FAILED(hrTmp) && SUCCEEDED(hr)) { - hr = hrTmp; - } - } - } - } - - - m_State = State_Stopped; - return hr; -} - - -// override CBaseMediaFilter Pause method to activate any pins -// this filter has (also called from Run) - -STDMETHODIMP -CBaseFilter::Pause() -{ - CAutoLock cObjectLock(m_pLock); - - // notify all pins of the change to active state - if (m_State == State_Stopped) { - int cPins = GetPinCount(); - for (int c = 0; c < cPins; c++) { - - CBasePin *pPin = GetPin(c); - - // Disconnected pins are not activated - this saves pins - // worrying about this state themselves - - if (pPin->IsConnected()) { - HRESULT hr = pPin->Active(); - if (FAILED(hr)) { - return hr; - } - } - } - } - - - - m_State = State_Paused; - return S_OK; -} - -// Put the filter into a running state. - -// The time parameter is the offset to be added to the samples' -// stream time to get the reference time at which they should be presented. -// -// you can either add these two and compare it against the reference clock, -// or you can call CBaseFilter::StreamTime and compare that against -// the sample timestamp. - -STDMETHODIMP -CBaseFilter::Run(REFERENCE_TIME tStart) -{ - CAutoLock cObjectLock(m_pLock); - - // remember the stream time offset - m_tStart = tStart; - - if (m_State == State_Stopped){ - HRESULT hr = Pause(); - - if (FAILED(hr)) { - return hr; - } - } - // notify all pins of the change to active state - if (m_State != State_Running) { - int cPins = GetPinCount(); - for (int c = 0; c < cPins; c++) { - - CBasePin *pPin = GetPin(c); - - // Disconnected pins are not activated - this saves pins - // worrying about this state themselves - - if (pPin->IsConnected()) { - HRESULT hr = pPin->Run(tStart); - if (FAILED(hr)) { - return hr; - } - } - } - } - - - m_State = State_Running; - return S_OK; -} - -// -// return the current stream time - samples with start timestamps of this -// time or before should be rendered by now -HRESULT -CBaseFilter::StreamTime(CRefTime& rtStream) -{ - // Caller must lock for synchronization - // We can't grab the filter lock because we want to be able to call - // this from worker threads without deadlocking - - if (m_pClock == NULL) { - return VFW_E_NO_CLOCK; - } - - // get the current reference time - HRESULT hr = m_pClock->GetTime((REFERENCE_TIME*)&rtStream); - if (FAILED(hr)) { - return hr; - } - - // subtract the stream offset to get stream time - rtStream -= m_tStart; - - return S_OK; -} - - -/* Create an enumerator for the pins attached to this filter */ - -STDMETHODIMP -CBaseFilter::EnumPins(IEnumPins **ppEnum) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumPins *)); - - /* Create a new ref counted enumerator */ - - *ppEnum = new CEnumPins(this, - NULL); - - return *ppEnum == NULL ? E_OUTOFMEMORY : NOERROR; -} - - -// default behaviour of FindPin is to assume pins are named -// by their pin names -STDMETHODIMP -CBaseFilter::FindPin( - LPCWSTR Id, - IPin ** ppPin -) -{ - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - - // We're going to search the pin list so maintain integrity - CAutoLock lck(m_pLock); - int iCount = GetPinCount(); - for (int i = 0; i < iCount; i++) { - CBasePin *pPin = GetPin(i); - ASSERT(pPin != NULL); - - if (0 == lstrcmpW(pPin->Name(), Id)) { - // Found one that matches - // - // AddRef() and return it - *ppPin = pPin; - pPin->AddRef(); - return S_OK; - } - } - *ppPin = NULL; - return VFW_E_NOT_FOUND; -} - -/* Return information about this filter */ - -STDMETHODIMP -CBaseFilter::QueryFilterInfo(FILTER_INFO * pInfo) -{ - CheckPointer(pInfo,E_POINTER); - ValidateReadWritePtr(pInfo,sizeof(FILTER_INFO)); - - if (m_pName) { - lstrcpynW(pInfo->achName, m_pName, sizeof(pInfo->achName)/sizeof(WCHAR)); - } else { - pInfo->achName[0] = L'\0'; - } - pInfo->pGraph = m_pGraph; - if (m_pGraph) - m_pGraph->AddRef(); - return NOERROR; -} - - -/* Provide the filter with a filter graph */ - -STDMETHODIMP -CBaseFilter::JoinFilterGraph( - IFilterGraph * pGraph, - LPCWSTR pName) -{ - CAutoLock cObjectLock(m_pLock); - - // NOTE: we no longer hold references on the graph (m_pGraph, m_pSink) - - m_pGraph = pGraph; - if (m_pGraph) { - HRESULT hr = m_pGraph->QueryInterface(IID_IMediaEventSink, - (void**) &m_pSink); - if (FAILED(hr)) { - ASSERT(m_pSink == NULL); - } - else m_pSink->Release(); // we do NOT keep a reference on it. - } else { - // if graph pointer is null, then we should - // also release the IMediaEventSink on the same object - we don't - // refcount it, so just set it to null - m_pSink = NULL; - } - - - if (m_pName) { - delete[] m_pName; - m_pName = NULL; - } - - if (pName) { - DWORD nameLen = lstrlenW(pName)+1; - m_pName = new WCHAR[nameLen]; - if (m_pName) { - CopyMemory(m_pName, pName, nameLen*sizeof(WCHAR)); - } else { - // !!! error here? - ASSERT(FALSE); - } - } - - - return NOERROR; -} - - -// return a Vendor information string. Optional - may return E_NOTIMPL. -// memory returned should be freed using CoTaskMemFree -// default implementation returns E_NOTIMPL -STDMETHODIMP -CBaseFilter::QueryVendorInfo( - LPWSTR* pVendorInfo) -{ - UNREFERENCED_PARAMETER(pVendorInfo); - return E_NOTIMPL; -} - - -// send an event notification to the filter graph if we know about it. -// returns S_OK if delivered, S_FALSE if the filter graph does not sink -// events, or an error otherwise. -HRESULT -CBaseFilter::NotifyEvent( - long EventCode, - LONG_PTR EventParam1, - LONG_PTR EventParam2) -{ - // Snapshot so we don't have to lock up - IMediaEventSink *pSink = m_pSink; - if (pSink) { - if (EC_COMPLETE == EventCode) { - EventParam2 = (LONG_PTR)(IBaseFilter*)this; - } - - return pSink->Notify(EventCode, EventParam1, EventParam2); - } else { - return E_NOTIMPL; - } -} - -// Request reconnect -// pPin is the pin to reconnect -// pmt is the type to reconnect with - can be NULL -// Calls ReconnectEx on the filter graph -HRESULT -CBaseFilter::ReconnectPin( - IPin *pPin, - AM_MEDIA_TYPE const *pmt -) -{ - IFilterGraph2 *pGraph2; - if (m_pGraph != NULL) { - HRESULT hr = m_pGraph->QueryInterface(IID_IFilterGraph2, (void **)&pGraph2); - if (SUCCEEDED(hr)) { - hr = pGraph2->ReconnectEx(pPin, pmt); - pGraph2->Release(); - return hr; - } else { - return m_pGraph->Reconnect(pPin); - } - } else { - return E_NOINTERFACE; - } -} - - - -/* This is the same idea as the media type version does for type enumeration - on pins but for the list of pins available. So if the list of pins you - provide changes dynamically then either override this virtual function - to provide the version number, or more simply call IncrementPinVersion */ - -LONG CBaseFilter::GetPinVersion() -{ - return m_PinVersion; -} - - -/* Increment the current pin version cookie */ - -void CBaseFilter::IncrementPinVersion() -{ - InterlockedIncrement(&m_PinVersion); -} - -/* register filter */ - -STDMETHODIMP CBaseFilter::Register() -{ - // get setup data, if it exists - // - LPAMOVIESETUP_FILTER psetupdata = GetSetupData(); - - // check we've got data - // - if( NULL == psetupdata ) return S_FALSE; - - // init is ref counted so call just in case - // we're being called cold. - // - HRESULT hr = CoInitialize( (LPVOID)NULL ); - ASSERT( SUCCEEDED(hr) ); - - // get hold of IFilterMapper - // - IFilterMapper *pIFM; - hr = CoCreateInstance( CLSID_FilterMapper - , NULL - , CLSCTX_INPROC_SERVER - , IID_IFilterMapper - , (void **)&pIFM ); - if( SUCCEEDED(hr) ) - { - hr = AMovieSetupRegisterFilter( psetupdata, pIFM, TRUE ); - pIFM->Release(); - } - - // and clear up - // - CoFreeUnusedLibraries(); - CoUninitialize(); - - return NOERROR; -} - - -/* unregister filter */ - -STDMETHODIMP CBaseFilter::Unregister() -{ - // get setup data, if it exists - // - LPAMOVIESETUP_FILTER psetupdata = GetSetupData(); - - // check we've got data - // - if( NULL == psetupdata ) return S_FALSE; - - // OLE init is ref counted so call - // just in case we're being called cold. - // - HRESULT hr = CoInitialize( (LPVOID)NULL ); - ASSERT( SUCCEEDED(hr) ); - - // get hold of IFilterMapper - // - IFilterMapper *pIFM; - hr = CoCreateInstance( CLSID_FilterMapper - , NULL - , CLSCTX_INPROC_SERVER - , IID_IFilterMapper - , (void **)&pIFM ); - if( SUCCEEDED(hr) ) - { - hr = AMovieSetupRegisterFilter( psetupdata, pIFM, FALSE ); - - // release interface - // - pIFM->Release(); - } - - // clear up - // - CoFreeUnusedLibraries(); - CoUninitialize(); - - // handle one acceptable "error" - that - // of filter not being registered! - // (couldn't find a suitable #define'd - // name for the error!) - // - if( 0x80070002 == hr) - return NOERROR; - else - return hr; -} - - -//===================================================================== -//===================================================================== -// Implements CEnumPins -//===================================================================== -//===================================================================== - - -CEnumPins::CEnumPins(CBaseFilter *pFilter, - CEnumPins *pEnumPins) : - m_Position(0), - m_PinCount(0), - m_pFilter(pFilter), - m_cRef(1), // Already ref counted - m_PinCache(NAME("Pin Cache")) -{ - -#ifdef DEBUG - m_dwCookie = DbgRegisterObjectCreation("CEnumPins", 0); -#endif - - /* We must be owned by a filter derived from CBaseFilter */ - - ASSERT(pFilter != NULL); - - /* Hold a reference count on our filter */ - m_pFilter->AddRef(); - - /* Are we creating a new enumerator */ - - if (pEnumPins == NULL) { - m_Version = m_pFilter->GetPinVersion(); - m_PinCount = m_pFilter->GetPinCount(); - } else { - ASSERT(m_Position <= m_PinCount); - m_Position = pEnumPins->m_Position; - m_PinCount = pEnumPins->m_PinCount; - m_Version = pEnumPins->m_Version; - m_PinCache.AddTail(&(pEnumPins->m_PinCache)); - } -} - - -/* Destructor releases the reference count on our filter NOTE since we hold - a reference count on the filter who created us we know it is safe to - release it, no access can be made to it afterwards though as we have just - caused the last reference count to go and the object to be deleted */ - -CEnumPins::~CEnumPins() -{ - m_pFilter->Release(); - -#ifdef DEBUG - DbgRegisterObjectDestruction(m_dwCookie); -#endif -} - - -/* Override this to say what interfaces we support where */ - -STDMETHODIMP -CEnumPins::QueryInterface(REFIID riid,void **ppv) -{ - CheckPointer(ppv, E_POINTER); - - /* Do we have this interface */ - - if (riid == IID_IEnumPins || riid == IID_IUnknown) { - return GetInterface((IEnumPins *) this, ppv); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } -} - -STDMETHODIMP_(ULONG) -CEnumPins::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) -CEnumPins::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - delete this; - } - return cRef; -} - -/* One of an enumerator's basic member functions allows us to create a cloned - interface that initially has the same state. Since we are taking a snapshot - of an object (current position and all) we must lock access at the start */ - -STDMETHODIMP -CEnumPins::Clone(IEnumPins **ppEnum) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumPins *)); - HRESULT hr = NOERROR; - - /* Check we are still in sync with the filter */ - if (AreWeOutOfSync() == TRUE) { - *ppEnum = NULL; - hr = VFW_E_ENUM_OUT_OF_SYNC; - } else { - - *ppEnum = new CEnumPins(m_pFilter, - this); - if (*ppEnum == NULL) { - hr = E_OUTOFMEMORY; - } - } - return hr; -} - - -/* Return the next pin after the current position */ - -STDMETHODIMP -CEnumPins::Next(ULONG cPins, // place this many pins... - IPin **ppPins, // ...in this array - ULONG *pcFetched) // actual count passed returned here -{ - CheckPointer(ppPins,E_POINTER); - ValidateReadWritePtr(ppPins,cPins * sizeof(IPin *)); - - ASSERT(ppPins); - - if (pcFetched!=NULL) { - ValidateWritePtr(pcFetched, sizeof(ULONG)); - *pcFetched = 0; // default unless we succeed - } - // now check that the parameter is valid - else if (cPins>1) { // pcFetched == NULL - return E_INVALIDARG; - } - ULONG cFetched = 0; // increment as we get each one. - - /* Check we are still in sync with the filter */ - if (AreWeOutOfSync() == TRUE) { - // If we are out of sync, we should refresh the enumerator. - // This will reset the position and update the other members, but - // will not clear cache of pins we have already returned. - Refresh(); - } - - /* Calculate the number of available pins */ - - int cRealPins = min(m_PinCount - m_Position, (int) cPins); - if (cRealPins == 0) { - return S_FALSE; - } - - /* Return each pin interface NOTE GetPin returns CBasePin * not addrefed - so we must QI for the IPin (which increments its reference count) - If while we are retrieving a pin from the filter an error occurs we - assume that our internal state is stale with respect to the filter - (for example someone has deleted a pin) so we - return VFW_E_ENUM_OUT_OF_SYNC */ - - while (cRealPins && (m_PinCount - m_Position)) { - - /* Get the next pin object from the filter */ - - CBasePin *pPin = m_pFilter->GetPin(m_Position++); - if (pPin == NULL) { - // If this happend, and it's not the first time through, then we've got a problem, - // since we should really go back and release the iPins, which we have previously - // AddRef'ed. - ASSERT( cFetched==0 ); - return VFW_E_ENUM_OUT_OF_SYNC; - } - - /* We only want to return this pin, if it is not in our cache */ - if (0 == m_PinCache.Find(pPin)) - { - /* From the object get an IPin interface */ - - *ppPins = pPin; - pPin->AddRef(); - - cFetched++; - ppPins++; - - m_PinCache.AddTail(pPin); - - cRealPins--; - - } - } - - if (pcFetched!=NULL) { - *pcFetched = cFetched; - } - - return (cPins==cFetched ? NOERROR : S_FALSE); -} - - -/* Skip over one or more entries in the enumerator */ - -STDMETHODIMP -CEnumPins::Skip(ULONG cPins) -{ - /* Check we are still in sync with the filter */ - if (AreWeOutOfSync() == TRUE) { - return VFW_E_ENUM_OUT_OF_SYNC; - } - - /* Work out how many pins are left to skip over */ - /* We could position at the end if we are asked to skip too many... */ - /* ..which would match the base implementation for CEnumMediaTypes::Skip */ - - ULONG PinsLeft = m_PinCount - m_Position; - if (cPins > PinsLeft) { - return S_FALSE; - } - m_Position += cPins; - return NOERROR; -} - - -/* Set the current position back to the start */ -/* Reset has 4 simple steps: - * - * Set position to head of list - * Sync enumerator with object being enumerated - * Clear the cache of pins already returned - * return S_OK - */ - -STDMETHODIMP -CEnumPins::Reset() -{ - m_Version = m_pFilter->GetPinVersion(); - m_PinCount = m_pFilter->GetPinCount(); - - m_Position = 0; - - // Clear the cache - m_PinCache.RemoveAll(); - - return S_OK; -} - - -/* Set the current position back to the start */ -/* Refresh has 3 simple steps: - * - * Set position to head of list - * Sync enumerator with object being enumerated - * return S_OK - */ - -STDMETHODIMP -CEnumPins::Refresh() -{ - m_Version = m_pFilter->GetPinVersion(); - m_PinCount = m_pFilter->GetPinCount(); - - m_Position = 0; - return S_OK; -} - - -//===================================================================== -//===================================================================== -// Implements CEnumMediaTypes -//===================================================================== -//===================================================================== - - -CEnumMediaTypes::CEnumMediaTypes(CBasePin *pPin, - CEnumMediaTypes *pEnumMediaTypes) : - m_Position(0), - m_pPin(pPin), - m_cRef(1) -{ - -#ifdef DEBUG - m_dwCookie = DbgRegisterObjectCreation("CEnumMediaTypes", 0); -#endif - - /* We must be owned by a pin derived from CBasePin */ - - ASSERT(pPin != NULL); - - /* Hold a reference count on our pin */ - m_pPin->AddRef(); - - /* Are we creating a new enumerator */ - - if (pEnumMediaTypes == NULL) { - m_Version = m_pPin->GetMediaTypeVersion(); - return; - } - - m_Position = pEnumMediaTypes->m_Position; - m_Version = pEnumMediaTypes->m_Version; -} - - -/* Destructor releases the reference count on our base pin. NOTE since we hold - a reference count on the pin who created us we know it is safe to release - it, no access can be made to it afterwards though as we might have just - caused the last reference count to go and the object to be deleted */ - -CEnumMediaTypes::~CEnumMediaTypes() -{ -#ifdef DEBUG - DbgRegisterObjectDestruction(m_dwCookie); -#endif - m_pPin->Release(); -} - - -/* Override this to say what interfaces we support where */ - -STDMETHODIMP -CEnumMediaTypes::QueryInterface(REFIID riid,void **ppv) -{ - CheckPointer(ppv, E_POINTER); - - /* Do we have this interface */ - - if (riid == IID_IEnumMediaTypes || riid == IID_IUnknown) { - return GetInterface((IEnumMediaTypes *) this, ppv); - } else { - *ppv = NULL; - return E_NOINTERFACE; - } -} - -STDMETHODIMP_(ULONG) -CEnumMediaTypes::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - -STDMETHODIMP_(ULONG) -CEnumMediaTypes::Release() -{ - ULONG cRef = InterlockedDecrement(&m_cRef); - if (cRef == 0) { - delete this; - } - return cRef; -} - -/* One of an enumerator's basic member functions allows us to create a cloned - interface that initially has the same state. Since we are taking a snapshot - of an object (current position and all) we must lock access at the start */ - -STDMETHODIMP -CEnumMediaTypes::Clone(IEnumMediaTypes **ppEnum) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumMediaTypes *)); - HRESULT hr = NOERROR; - - /* Check we are still in sync with the pin */ - if (AreWeOutOfSync() == TRUE) { - *ppEnum = NULL; - hr = VFW_E_ENUM_OUT_OF_SYNC; - } else { - - *ppEnum = new CEnumMediaTypes(m_pPin, - this); - - if (*ppEnum == NULL) { - hr = E_OUTOFMEMORY; - } - } - return hr; -} - - -/* Enumerate the next pin(s) after the current position. The client using this - interface passes in a pointer to an array of pointers each of which will - be filled in with a pointer to a fully initialised media type format - Return NOERROR if it all works, - S_FALSE if fewer than cMediaTypes were enumerated. - VFW_E_ENUM_OUT_OF_SYNC if the enumerator has been broken by - state changes in the filter - The actual count always correctly reflects the number of types in the array. -*/ - -STDMETHODIMP -CEnumMediaTypes::Next(ULONG cMediaTypes, // place this many types... - AM_MEDIA_TYPE **ppMediaTypes, // ...in this array - ULONG *pcFetched) // actual count passed -{ - CheckPointer(ppMediaTypes,E_POINTER); - ValidateReadWritePtr(ppMediaTypes,cMediaTypes * sizeof(AM_MEDIA_TYPE *)); - /* Check we are still in sync with the pin */ - if (AreWeOutOfSync() == TRUE) { - return VFW_E_ENUM_OUT_OF_SYNC; - } - - if (pcFetched!=NULL) { - ValidateWritePtr(pcFetched, sizeof(ULONG)); - *pcFetched = 0; // default unless we succeed - } - // now check that the parameter is valid - else if (cMediaTypes>1) { // pcFetched == NULL - return E_INVALIDARG; - } - ULONG cFetched = 0; // increment as we get each one. - - /* Return each media type by asking the filter for them in turn - If we - have an error code retured to us while we are retrieving a media type - we assume that our internal state is stale with respect to the filter - (for example the window size changing) so we return - VFW_E_ENUM_OUT_OF_SYNC */ - - while (cMediaTypes) { - - CMediaType cmt; - - HRESULT hr = m_pPin->GetMediaType(m_Position++, &cmt); - if (S_OK != hr) { - break; - } - - /* We now have a CMediaType object that contains the next media type - but when we assign it to the array position we CANNOT just assign - the AM_MEDIA_TYPE structure because as soon as the object goes out of - scope it will delete the memory we have just copied. The function - we use is CreateMediaType which allocates a task memory block */ - - /* Transfer across the format block manually to save an allocate - and free on the format block and generally go faster */ - - *ppMediaTypes = (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - if (*ppMediaTypes == NULL) { - break; - } - - /* Do a regular copy */ - **ppMediaTypes = (AM_MEDIA_TYPE)cmt; - - /* Make sure the destructor doesn't free these */ - cmt.pbFormat = NULL; - cmt.cbFormat = NULL; - cmt.pUnk = NULL; - - - ppMediaTypes++; - cFetched++; - cMediaTypes--; - } - - if (pcFetched!=NULL) { - *pcFetched = cFetched; - } - - return ( cMediaTypes==0 ? NOERROR : S_FALSE ); -} - - -/* Skip over one or more entries in the enumerator */ - -STDMETHODIMP -CEnumMediaTypes::Skip(ULONG cMediaTypes) -{ - // If we're skipping 0 elements we're guaranteed to skip the - // correct number of elements - if (cMediaTypes == 0) { - return S_OK; - } - - /* Check we are still in sync with the pin */ - if (AreWeOutOfSync() == TRUE) { - return VFW_E_ENUM_OUT_OF_SYNC; - } - - m_Position += cMediaTypes; - - /* See if we're over the end */ - CMediaType cmt; - return S_OK == m_pPin->GetMediaType(m_Position - 1, &cmt) ? S_OK : S_FALSE; -} - - -/* Set the current position back to the start */ -/* Reset has 3 simple steps: - * - * set position to head of list - * sync enumerator with object being enumerated - * return S_OK - */ - -STDMETHODIMP -CEnumMediaTypes::Reset() - -{ - m_Position = 0; - - // Bring the enumerator back into step with the current state. This - // may be a noop but ensures that the enumerator will be valid on the - // next call. - m_Version = m_pPin->GetMediaTypeVersion(); - return NOERROR; -} - - -//===================================================================== -//===================================================================== -// Implements CBasePin -//===================================================================== -//===================================================================== - - -/* NOTE The implementation of this class calls the CUnknown constructor with - a NULL outer unknown pointer. This has the effect of making us a self - contained class, ie any QueryInterface, AddRef or Release calls will be - routed to the class's NonDelegatingUnknown methods. You will typically - find that the classes that do this then override one or more of these - virtual functions to provide more specialised behaviour. A good example - of this is where a class wants to keep the QueryInterface internal but - still wants its lifetime controlled by the external object */ - -/* Constructor */ - -CBasePin::CBasePin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName, - PIN_DIRECTION dir) : - CUnknown( pObjectName, NULL ), - m_pFilter(pFilter), - m_pLock(pLock), - m_pName(NULL), - m_Connected(NULL), - m_dir(dir), - m_bRunTimeError(FALSE), - m_pQSink(NULL), - m_TypeVersion(1), - m_tStart(), - m_tStop(MAX_TIME), - m_bCanReconnectWhenActive(false), - m_bTryMyTypesFirst(false), - m_dRate(1.0) -{ - /* WARNING - pFilter is often not a properly constituted object at - this state (in particular QueryInterface may not work) - this - is because its owner is often its containing object and we - have been called from the containing object's constructor so - the filter's owner has not yet had its CUnknown constructor - called - */ - - ASSERT(pFilter != NULL); - ASSERT(pLock != NULL); - - if (pName) { - DWORD nameLen = lstrlenW(pName)+1; - m_pName = new WCHAR[nameLen]; - if (m_pName) { - CopyMemory(m_pName, pName, nameLen*sizeof(WCHAR)); - } - } - -#ifdef DEBUG - m_cRef = 0; -#endif -} - -#ifdef UNICODE -CBasePin::CBasePin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName, - PIN_DIRECTION dir) : - CUnknown( pObjectName, NULL ), - m_pFilter(pFilter), - m_pLock(pLock), - m_pName(NULL), - m_Connected(NULL), - m_dir(dir), - m_bRunTimeError(FALSE), - m_pQSink(NULL), - m_TypeVersion(1), - m_tStart(), - m_tStop(MAX_TIME), - m_bCanReconnectWhenActive(false), - m_bTryMyTypesFirst(false), - m_dRate(1.0) -{ - /* WARNING - pFilter is often not a properly constituted object at - this state (in particular QueryInterface may not work) - this - is because its owner is often its containing object and we - have been called from the containing object's constructor so - the filter's owner has not yet had its CUnknown constructor - called - */ - - ASSERT(pFilter != NULL); - ASSERT(pLock != NULL); - - if (pName) { - DWORD nameLen = lstrlenW(pName)+1; - m_pName = new WCHAR[nameLen]; - if (m_pName) { - CopyMemory(m_pName, pName, nameLen*sizeof(WCHAR)); - } - } - -#ifdef DEBUG - m_cRef = 0; -#endif -} -#endif - -/* Destructor since a connected pin holds a reference count on us there is - no way that we can be deleted unless we are not currently connected */ - -CBasePin::~CBasePin() -{ - - // We don't call disconnect because if the filter is going away - // all the pins must have a reference count of zero so they must - // have been disconnected anyway - (but check the assumption) - ASSERT(m_Connected == FALSE); - - delete[] m_pName; - - // check the internal reference count is consistent - ASSERT(m_cRef == 0); -} - - -/* Override this to say what interfaces we support and where */ - -STDMETHODIMP -CBasePin::NonDelegatingQueryInterface(REFIID riid, void ** ppv) -{ - /* Do we have this interface */ - - if (riid == IID_IPin) { - return GetInterface((IPin *) this, ppv); - } else if (riid == IID_IQualityControl) { - return GetInterface((IQualityControl *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -/* Override to increment the owning filter's reference count */ - -STDMETHODIMP_(ULONG) -CBasePin::NonDelegatingAddRef() -{ - ASSERT(InterlockedIncrement(&m_cRef) > 0); - return m_pFilter->AddRef(); -} - - -/* Override to decrement the owning filter's reference count */ - -STDMETHODIMP_(ULONG) -CBasePin::NonDelegatingRelease() -{ - ASSERT(InterlockedDecrement(&m_cRef) >= 0); - return m_pFilter->Release(); -} - - -/* Displays pin connection information */ - -#ifdef DEBUG -void -CBasePin::DisplayPinInfo(IPin *pReceivePin) -{ - - if (DbgCheckModuleLevel(LOG_TRACE, CONNECT_TRACE_LEVEL)) { - PIN_INFO ConnectPinInfo; - PIN_INFO ReceivePinInfo; - - if (FAILED(QueryPinInfo(&ConnectPinInfo))) { - (void)StringCchCopyW(ConnectPinInfo.achName, NUMELMS(ConnectPinInfo.achName),L"Bad Pin"); - } else { - QueryPinInfoReleaseFilter(ConnectPinInfo); - } - - if (FAILED(pReceivePin->QueryPinInfo(&ReceivePinInfo))) { - (void)StringCchCopyW(ReceivePinInfo.achName, NUMELMS(ReceivePinInfo.achName),L"Bad Pin"); - } else { - QueryPinInfoReleaseFilter(ReceivePinInfo); - } - - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Trying to connect Pins :"))); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" <%ls>"), ConnectPinInfo.achName)); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" <%ls>"), ReceivePinInfo.achName)); - } -} -#endif - - -/* Displays general information on the pin media type */ - -#ifdef DEBUG -void CBasePin::DisplayTypeInfo(IPin *pPin, const CMediaType *pmt) -{ - UNREFERENCED_PARAMETER(pPin); - if (DbgCheckModuleLevel(LOG_TRACE, CONNECT_TRACE_LEVEL)) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Trying media type:"))); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" major type: %hs"), - GuidNames[*pmt->Type()])); - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT(" sub type : %hs"), - GuidNames[*pmt->Subtype()])); - } -} -#endif - -/* Asked to connect to a pin. A pin is always attached to an owning filter - object so we always delegate our locking to that object. We first of all - retrieve a media type enumerator for the input pin and see if we accept - any of the formats that it would ideally like, failing that we retrieve - our enumerator and see if it will accept any of our preferred types */ - -STDMETHODIMP -CBasePin::Connect( - IPin * pReceivePin, - const AM_MEDIA_TYPE *pmt // optional media type -) -{ - CheckPointer(pReceivePin,E_POINTER); - ValidateReadPtr(pReceivePin,sizeof(IPin)); - CAutoLock cObjectLock(m_pLock); - DisplayPinInfo(pReceivePin); - - /* See if we are already connected */ - - if (m_Connected) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Already connected"))); - return VFW_E_ALREADY_CONNECTED; - } - - /* See if the filter is active */ - if (!IsStopped() && !m_bCanReconnectWhenActive) { - return VFW_E_NOT_STOPPED; - } - - - // Find a mutually agreeable media type - - // Pass in the template media type. If this is partially specified, - // each of the enumerated media types will need to be checked against - // it. If it is non-null and fully specified, we will just try to connect - // with this. - - const CMediaType * ptype = (CMediaType*)pmt; - HRESULT hr = AgreeMediaType(pReceivePin, ptype); - if (FAILED(hr)) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Failed to agree type"))); - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - - return hr; - } - - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Connection succeeded"))); - - - return NOERROR; -} - -// given a specific media type, attempt a connection (includes -// checking that the type is acceptable to this pin) -HRESULT -CBasePin::AttemptConnection( - IPin* pReceivePin, // connect to this pin - const CMediaType* pmt // using this type -) -{ - // The caller should hold the filter lock becasue this function - // uses m_Connected. The caller should also hold the filter lock - // because this function calls SetMediaType(), IsStopped() and - // CompleteConnect(). - ASSERT(CritCheckIn(m_pLock)); - - // Check that the connection is valid -- need to do this for every - // connect attempt since BreakConnect will undo it. - HRESULT hr = CheckConnect(pReceivePin); - if (FAILED(hr)) { - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("CheckConnect failed"))); - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - return hr; - } - - DisplayTypeInfo(pReceivePin, pmt); - - /* Check we will accept this media type */ - - hr = CheckMediaType(pmt); - if (hr == NOERROR) { - - /* Make ourselves look connected otherwise ReceiveConnection - may not be able to complete the connection - */ - m_Connected = pReceivePin; - m_Connected->AddRef(); - hr = SetMediaType(pmt); - if (SUCCEEDED(hr)) { - /* See if the other pin will accept this type */ - - hr = pReceivePin->ReceiveConnection((IPin *)this, pmt); - if (SUCCEEDED(hr)) { - /* Complete the connection */ - - hr = CompleteConnect(pReceivePin); - if (SUCCEEDED(hr)) { - return hr; - } else { - DbgLog((LOG_TRACE, - CONNECT_TRACE_LEVEL, - TEXT("Failed to complete connection"))); - pReceivePin->Disconnect(); - } - } - } - } else { - // we cannot use this media type - - // return a specific media type error if there is one - // or map a general failure code to something more helpful - // (in particular S_FALSE gets changed to an error code) - if (SUCCEEDED(hr) || - (hr == E_FAIL) || - (hr == E_INVALIDARG)) { - hr = VFW_E_TYPE_NOT_ACCEPTED; - } - } - - // BreakConnect and release any connection here in case CheckMediaType - // failed, or if we set anything up during a call back during - // ReceiveConnection. - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - /* If failed then undo our state */ - if (m_Connected) { - m_Connected->Release(); - m_Connected = NULL; - } - - return hr; -} - -/* Given an enumerator we cycle through all the media types it proposes and - firstly suggest them to our derived pin class and if that succeeds try - them with the pin in a ReceiveConnection call. This means that if our pin - proposes a media type we still check in here that we can support it. This - is deliberate so that in simple cases the enumerator can hold all of the - media types even if some of them are not really currently available */ - -HRESULT CBasePin::TryMediaTypes( - IPin *pReceivePin, - const CMediaType *pmt, - IEnumMediaTypes *pEnum) -{ - /* Reset the current enumerator position */ - - HRESULT hr = pEnum->Reset(); - if (FAILED(hr)) { - return hr; - } - - CMediaType *pMediaType = NULL; - ULONG ulMediaCount = 0; - - // attempt to remember a specific error code if there is one - HRESULT hrFailure = S_OK; - - for (;;) { - - /* Retrieve the next media type NOTE each time round the loop the - enumerator interface will allocate another AM_MEDIA_TYPE structure - If we are successful then we copy it into our output object, if - not then we must delete the memory allocated before returning */ - - hr = pEnum->Next(1, (AM_MEDIA_TYPE**)&pMediaType,&ulMediaCount); - if (hr != S_OK) { - if (S_OK == hrFailure) { - hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; - } - return hrFailure; - } - - - ASSERT(ulMediaCount == 1); - ASSERT(pMediaType); - - // check that this matches the partial type (if any) - - if ((pmt == NULL) || - pMediaType->MatchesPartial(pmt)) { - - hr = AttemptConnection(pReceivePin, pMediaType); - - // attempt to remember a specific error code - if (FAILED(hr) && - SUCCEEDED(hrFailure) && - (hr != E_FAIL) && - (hr != E_INVALIDARG) && - (hr != VFW_E_TYPE_NOT_ACCEPTED)) { - hrFailure = hr; - } - } else { - hr = VFW_E_NO_ACCEPTABLE_TYPES; - } - - DeleteMediaType(pMediaType); - - if (S_OK == hr) { - return hr; - } - } -} - - -/* This is called to make the connection, including the taask of finding - a media type for the pin connection. pmt is the proposed media type - from the Connect call: if this is fully specified, we will try that. - Otherwise we enumerate and try all the input pin's types first and - if that fails we then enumerate and try all our preferred media types. - For each media type we check it against pmt (if non-null and partially - specified) as well as checking that both pins will accept it. - */ - -HRESULT CBasePin::AgreeMediaType( - IPin *pReceivePin, - const CMediaType *pmt) -{ - ASSERT(pReceivePin); - IEnumMediaTypes *pEnumMediaTypes = NULL; - - // if the media type is fully specified then use that - if ( (pmt != NULL) && (!pmt->IsPartiallySpecified())) { - - // if this media type fails, then we must fail the connection - // since if pmt is nonnull we are only allowed to connect - // using a type that matches it. - - return AttemptConnection(pReceivePin, pmt); - } - - - /* Try the other pin's enumerator */ - - HRESULT hrFailure = VFW_E_NO_ACCEPTABLE_TYPES; - - for (int i = 0; i < 2; i++) { - HRESULT hr; - if (i == (int)m_bTryMyTypesFirst) { - hr = pReceivePin->EnumMediaTypes(&pEnumMediaTypes); - } else { - hr = EnumMediaTypes(&pEnumMediaTypes); - } - if (SUCCEEDED(hr)) { - ASSERT(pEnumMediaTypes); - hr = TryMediaTypes(pReceivePin,pmt,pEnumMediaTypes); - pEnumMediaTypes->Release(); - if (SUCCEEDED(hr)) { - return NOERROR; - } else { - // try to remember specific error codes if there are any - if ((hr != E_FAIL) && - (hr != E_INVALIDARG) && - (hr != VFW_E_TYPE_NOT_ACCEPTED)) { - hrFailure = hr; - } - } - } - } - - return hrFailure; -} - - -/* Called when we want to complete a connection to another filter. Failing - this will also fail the connection and disconnect the other pin as well */ - -HRESULT -CBasePin::CompleteConnect(IPin *pReceivePin) -{ - UNREFERENCED_PARAMETER(pReceivePin); - return NOERROR; -} - - -/* This is called to set the format for a pin connection - CheckMediaType - will have been called to check the connection format and if it didn't - return an error code then this (virtual) function will be invoked */ - -HRESULT -CBasePin::SetMediaType(const CMediaType *pmt) -{ - HRESULT hr = m_mt.Set(*pmt); - if (FAILED(hr)) { - return hr; - } - - return NOERROR; -} - - -/* This is called during Connect() to provide a virtual method that can do - any specific check needed for connection such as QueryInterface. This - base class method just checks that the pin directions don't match */ - -HRESULT -CBasePin::CheckConnect(IPin * pPin) -{ - /* Check that pin directions DONT match */ - - PIN_DIRECTION pd; - pPin->QueryDirection(&pd); - - ASSERT((pd == PINDIR_OUTPUT) || (pd == PINDIR_INPUT)); - ASSERT((m_dir == PINDIR_OUTPUT) || (m_dir == PINDIR_INPUT)); - - // we should allow for non-input and non-output connections? - if (pd == m_dir) { - return VFW_E_INVALID_DIRECTION; - } - return NOERROR; -} - - -/* This is called when we realise we can't make a connection to the pin and - must undo anything we did in CheckConnect - override to release QIs done */ - -HRESULT -CBasePin::BreakConnect() -{ - return NOERROR; -} - - -/* Called normally by an output pin on an input pin to try and establish a - connection. -*/ - -STDMETHODIMP -CBasePin::ReceiveConnection( - IPin * pConnector, // this is the pin who we will connect to - const AM_MEDIA_TYPE *pmt // this is the media type we will exchange -) -{ - CheckPointer(pConnector,E_POINTER); - CheckPointer(pmt,E_POINTER); - ValidateReadPtr(pConnector,sizeof(IPin)); - ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE)); - CAutoLock cObjectLock(m_pLock); - - /* Are we already connected */ - if (m_Connected) { - return VFW_E_ALREADY_CONNECTED; - } - - /* See if the filter is active */ - if (!IsStopped() && !m_bCanReconnectWhenActive) { - return VFW_E_NOT_STOPPED; - } - - HRESULT hr = CheckConnect(pConnector); - if (FAILED(hr)) { - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - - return hr; - } - - /* Ask derived class if this media type is ok */ - - CMediaType * pcmt = (CMediaType*) pmt; - hr = CheckMediaType(pcmt); - if (hr != NOERROR) { - // no -we don't support this media type - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - // return a specific media type error if there is one - // or map a general failure code to something more helpful - // (in particular S_FALSE gets changed to an error code) - if (SUCCEEDED(hr) || - (hr == E_FAIL) || - (hr == E_INVALIDARG)) { - hr = VFW_E_TYPE_NOT_ACCEPTED; - } - - - return hr; - } - - /* Complete the connection */ - - m_Connected = pConnector; - m_Connected->AddRef(); - hr = SetMediaType(pcmt); - if (SUCCEEDED(hr)) { - hr = CompleteConnect(pConnector); - if (SUCCEEDED(hr)) { - - - return NOERROR; - } - } - - DbgLog((LOG_TRACE, CONNECT_TRACE_LEVEL, TEXT("Failed to set the media type or failed to complete the connection."))); - m_Connected->Release(); - m_Connected = NULL; - - // Since the procedure is already returning an error code, there - // is nothing else this function can do to report the error. - EXECUTE_ASSERT( SUCCEEDED( BreakConnect() ) ); - - - return hr; -} - - -/* Called when we want to terminate a pin connection */ - -STDMETHODIMP -CBasePin::Disconnect() -{ - CAutoLock cObjectLock(m_pLock); - - /* See if the filter is active */ - if (!IsStopped()) { - return VFW_E_NOT_STOPPED; - } - - return DisconnectInternal(); -} - -STDMETHODIMP -CBasePin::DisconnectInternal() -{ - ASSERT(CritCheckIn(m_pLock)); - - if (m_Connected) { - HRESULT hr = BreakConnect(); - if( FAILED( hr ) ) { - - - // There is usually a bug in the program if BreakConnect() fails. - DbgBreak( "WARNING: BreakConnect() failed in CBasePin::Disconnect()." ); - return hr; - } - - m_Connected->Release(); - m_Connected = NULL; - - - return S_OK; - } else { - // no connection - not an error - - - return S_FALSE; - } -} - - -/* Return an AddRef()'d pointer to the connected pin if there is one */ -STDMETHODIMP -CBasePin::ConnectedTo( - IPin **ppPin -) -{ - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - // - // It's pointless to lock here. - // The caller should ensure integrity. - // - - IPin *pPin = m_Connected; - *ppPin = pPin; - if (pPin != NULL) { - pPin->AddRef(); - return S_OK; - } else { - ASSERT(*ppPin == NULL); - return VFW_E_NOT_CONNECTED; - } -} - -/* Return the media type of the connection */ -STDMETHODIMP -CBasePin::ConnectionMediaType( - AM_MEDIA_TYPE *pmt -) -{ - CheckPointer(pmt,E_POINTER); - ValidateReadWritePtr(pmt,sizeof(AM_MEDIA_TYPE)); - CAutoLock cObjectLock(m_pLock); - - /* Copy constructor of m_mt allocates the memory */ - if (IsConnected()) { - CopyMediaType( pmt, &m_mt ); - return S_OK; - } else { - ((CMediaType *)pmt)->InitMediaType(); - return VFW_E_NOT_CONNECTED; - } -} - -/* Return information about the filter we are connect to */ - -STDMETHODIMP -CBasePin::QueryPinInfo( - PIN_INFO * pInfo -) -{ - CheckPointer(pInfo,E_POINTER); - ValidateReadWritePtr(pInfo,sizeof(PIN_INFO)); - - pInfo->pFilter = m_pFilter; - if (m_pFilter) { - m_pFilter->AddRef(); - } - - if (m_pName) { - lstrcpynW(pInfo->achName, m_pName, sizeof(pInfo->achName)/sizeof(WCHAR)); - } else { - pInfo->achName[0] = L'\0'; - } - - pInfo->dir = m_dir; - - return NOERROR; -} - -STDMETHODIMP -CBasePin::QueryDirection( - PIN_DIRECTION * pPinDir -) -{ - CheckPointer(pPinDir,E_POINTER); - ValidateReadWritePtr(pPinDir,sizeof(PIN_DIRECTION)); - - *pPinDir = m_dir; - return NOERROR; -} - -// Default QueryId to return the pin's name -STDMETHODIMP -CBasePin::QueryId( - LPWSTR * Id -) -{ - // We're not going away because someone's got a pointer to us - // so there's no need to lock - - return AMGetWideString(Name(), Id); -} - -/* Does this pin support this media type WARNING this interface function does - not lock the main object as it is meant to be asynchronous by nature - if - the media types you support depend on some internal state that is updated - dynamically then you will need to implement locking in a derived class */ - -STDMETHODIMP -CBasePin::QueryAccept( - const AM_MEDIA_TYPE *pmt -) -{ - CheckPointer(pmt,E_POINTER); - ValidateReadPtr(pmt,sizeof(AM_MEDIA_TYPE)); - - /* The CheckMediaType method is valid to return error codes if the media - type is horrible, an example might be E_INVALIDARG. What we do here - is map all the error codes into either S_OK or S_FALSE regardless */ - - HRESULT hr = CheckMediaType((CMediaType*)pmt); - if (FAILED(hr)) { - return S_FALSE; - } - // note that the only defined success codes should be S_OK and S_FALSE... - return hr; -} - - -/* This can be called to return an enumerator for the pin's list of preferred - media types. An input pin is not obliged to have any preferred formats - although it can do. For example, the window renderer has a preferred type - which describes a video image that matches the current window size. All - output pins should expose at least one preferred format otherwise it is - possible that neither pin has any types and so no connection is possible */ - -STDMETHODIMP -CBasePin::EnumMediaTypes( - IEnumMediaTypes **ppEnum -) -{ - CheckPointer(ppEnum,E_POINTER); - ValidateReadWritePtr(ppEnum,sizeof(IEnumMediaTypes *)); - - /* Create a new ref counted enumerator */ - - *ppEnum = new CEnumMediaTypes(this, - NULL); - - if (*ppEnum == NULL) { - return E_OUTOFMEMORY; - } - - return NOERROR; -} - - - -/* This is a virtual function that returns a media type corresponding with - place iPosition in the list. This base class simply returns an error as - we support no media types by default but derived classes should override */ - -HRESULT CBasePin::GetMediaType(int iPosition, CMediaType *pMediaType) -{ - UNREFERENCED_PARAMETER(iPosition); - UNREFERENCED_PARAMETER(pMediaType); - return E_UNEXPECTED; -} - - -/* This is a virtual function that returns the current media type version. - The base class initialises the media type enumerators with the value 1 - By default we always returns that same value. A Derived class may change - the list of media types available and after doing so it should increment - the version either in a method derived from this, or more simply by just - incrementing the m_TypeVersion base pin variable. The type enumerators - call this when they want to see if their enumerations are out of date */ - -LONG CBasePin::GetMediaTypeVersion() -{ - return m_TypeVersion; -} - - -/* Increment the cookie representing the current media type version */ - -void CBasePin::IncrementTypeVersion() -{ - InterlockedIncrement(&m_TypeVersion); -} - - -/* Called by IMediaFilter implementation when the state changes from Stopped - to either paused or running and in derived classes could do things like - commit memory and grab hardware resource (the default is to do nothing) */ - -HRESULT -CBasePin::Active(void) -{ - return NOERROR; -} - -/* Called by IMediaFilter implementation when the state changes from - to either paused to running and in derived classes could do things like - commit memory and grab hardware resource (the default is to do nothing) */ - -HRESULT -CBasePin::Run(REFERENCE_TIME tStart) -{ - UNREFERENCED_PARAMETER(tStart); - return NOERROR; -} - - -/* Also called by the IMediaFilter implementation when the state changes to - Stopped at which point you should decommit allocators and free hardware - resources you grabbed in the Active call (default is also to do nothing) */ - -HRESULT -CBasePin::Inactive(void) -{ - m_bRunTimeError = FALSE; - return NOERROR; -} - - -// Called when no more data will arrive -STDMETHODIMP -CBasePin::EndOfStream(void) -{ - return S_OK; -} - - -STDMETHODIMP -CBasePin::SetSink(IQualityControl * piqc) -{ - CAutoLock cObjectLock(m_pLock); - if (piqc) ValidateReadPtr(piqc,sizeof(IQualityControl)); - m_pQSink = piqc; - return NOERROR; -} // SetSink - - -STDMETHODIMP -CBasePin::Notify(IBaseFilter * pSender, Quality q) -{ - UNREFERENCED_PARAMETER(q); - UNREFERENCED_PARAMETER(pSender); - DbgBreak("IQualityControl::Notify not over-ridden from CBasePin. (IGNORE is OK)"); - return E_NOTIMPL; -} //Notify - - -// NewSegment notifies of the start/stop/rate applying to the data -// about to be received. Default implementation records data and -// returns S_OK. -// Override this to pass downstream. -STDMETHODIMP -CBasePin::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) -{ - m_tStart = tStart; - m_tStop = tStop; - m_dRate = dRate; - - return S_OK; -} - - -//===================================================================== -//===================================================================== -// Implements CBaseOutputPin -//===================================================================== -//===================================================================== - - -CBaseOutputPin::CBaseOutputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBasePin(pObjectName, pFilter, pLock, phr, pName, PINDIR_OUTPUT), - m_pAllocator(NULL), - m_pInputPin(NULL) -{ - ASSERT(pFilter); -} - -#ifdef UNICODE -CBaseOutputPin::CBaseOutputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBasePin(pObjectName, pFilter, pLock, phr, pName, PINDIR_OUTPUT), - m_pAllocator(NULL), - m_pInputPin(NULL) -{ - ASSERT(pFilter); -} -#endif - -/* This is called after a media type has been proposed - - Try to complete the connection by agreeing the allocator -*/ -HRESULT -CBaseOutputPin::CompleteConnect(IPin *pReceivePin) -{ - UNREFERENCED_PARAMETER(pReceivePin); - return DecideAllocator(m_pInputPin, &m_pAllocator); -} - - -/* This method is called when the output pin is about to try and connect to - an input pin. It is at this point that you should try and grab any extra - interfaces that you need, in this case IMemInputPin. Because this is - only called if we are not currently connected we do NOT need to call - BreakConnect. This also makes it easier to derive classes from us as - BreakConnect is only called when we actually have to break a connection - (or a partly made connection) and not when we are checking a connection */ - -/* Overriden from CBasePin */ - -HRESULT -CBaseOutputPin::CheckConnect(IPin * pPin) -{ - HRESULT hr = CBasePin::CheckConnect(pPin); - if (FAILED(hr)) { - return hr; - } - - // get an input pin and an allocator interface - hr = pPin->QueryInterface(IID_IMemInputPin, (void **) &m_pInputPin); - if (FAILED(hr)) { - return hr; - } - return NOERROR; -} - - -/* Overriden from CBasePin */ - -HRESULT -CBaseOutputPin::BreakConnect() -{ - /* Release any allocator we hold */ - - if (m_pAllocator) { - // Always decommit the allocator because a downstream filter may or - // may not decommit the connection's allocator. A memory leak could - // occur if the allocator is not decommited when a connection is broken. - HRESULT hr = m_pAllocator->Decommit(); - if( FAILED( hr ) ) { - return hr; - } - - m_pAllocator->Release(); - m_pAllocator = NULL; - } - - /* Release any input pin interface we hold */ - - if (m_pInputPin) { - m_pInputPin->Release(); - m_pInputPin = NULL; - } - return NOERROR; -} - - -/* This is called when the input pin didn't give us a valid allocator */ - -HRESULT -CBaseOutputPin::InitAllocator(IMemAllocator **ppAlloc) -{ - return CreateMemoryAllocator(ppAlloc); -} - - -/* Decide on an allocator, override this if you want to use your own allocator - Override DecideBufferSize to call SetProperties. If the input pin fails - the GetAllocator call then this will construct a CMemAllocator and call - DecideBufferSize on that, and if that fails then we are completely hosed. - If the you succeed the DecideBufferSize call, we will notify the input - pin of the selected allocator. NOTE this is called during Connect() which - therefore looks after grabbing and locking the object's critical section */ - -// We query the input pin for its requested properties and pass this to -// DecideBufferSize to allow it to fulfill requests that it is happy -// with (eg most people don't care about alignment and are thus happy to -// use the downstream pin's alignment request). - -HRESULT -CBaseOutputPin::DecideAllocator(IMemInputPin *pPin, IMemAllocator **ppAlloc) -{ - HRESULT hr = NOERROR; - *ppAlloc = NULL; - - // get downstream prop request - // the derived class may modify this in DecideBufferSize, but - // we assume that he will consistently modify it the same way, - // so we only get it once - ALLOCATOR_PROPERTIES prop; - ZeroMemory(&prop, sizeof(prop)); - - // whatever he returns, we assume prop is either all zeros - // or he has filled it out. - pPin->GetAllocatorRequirements(&prop); - - // if he doesn't care about alignment, then set it to 1 - if (prop.cbAlign == 0) { - prop.cbAlign = 1; - } - - /* Try the allocator provided by the input pin */ - - hr = pPin->GetAllocator(ppAlloc); - if (SUCCEEDED(hr)) { - - hr = DecideBufferSize(*ppAlloc, &prop); - if (SUCCEEDED(hr)) { - hr = pPin->NotifyAllocator(*ppAlloc, FALSE); - if (SUCCEEDED(hr)) { - return NOERROR; - } - } - } - - /* If the GetAllocator failed we may not have an interface */ - - if (*ppAlloc) { - (*ppAlloc)->Release(); - *ppAlloc = NULL; - } - - /* Try the output pin's allocator by the same method */ - - hr = InitAllocator(ppAlloc); - if (SUCCEEDED(hr)) { - - // note - the properties passed here are in the same - // structure as above and may have been modified by - // the previous call to DecideBufferSize - hr = DecideBufferSize(*ppAlloc, &prop); - if (SUCCEEDED(hr)) { - hr = pPin->NotifyAllocator(*ppAlloc, FALSE); - if (SUCCEEDED(hr)) { - return NOERROR; - } - } - } - - /* Likewise we may not have an interface to release */ - - if (*ppAlloc) { - (*ppAlloc)->Release(); - *ppAlloc = NULL; - } - return hr; -} - - -/* This returns an empty sample buffer from the allocator WARNING the same - dangers and restrictions apply here as described below for Deliver() */ - -HRESULT -CBaseOutputPin::GetDeliveryBuffer(IMediaSample ** ppSample, - REFERENCE_TIME * pStartTime, - REFERENCE_TIME * pEndTime, - DWORD dwFlags) -{ - if (m_pAllocator != NULL) { - return m_pAllocator->GetBuffer(ppSample,pStartTime,pEndTime,dwFlags); - } else { - return E_NOINTERFACE; - } -} - - -/* Deliver a filled-in sample to the connected input pin. NOTE the object must - have locked itself before calling us otherwise we may get halfway through - executing this method only to find the filter graph has got in and - disconnected us from the input pin. If the filter has no worker threads - then the lock is best applied on Receive(), otherwise it should be done - when the worker thread is ready to deliver. There is a wee snag to worker - threads that this shows up. The worker thread must lock the object when - it is ready to deliver a sample, but it may have to wait until a state - change has completed, but that may never complete because the state change - is waiting for the worker thread to complete. The way to handle this is for - the state change code to grab the critical section, then set an abort event - for the worker thread, then release the critical section and wait for the - worker thread to see the event we set and then signal that it has finished - (with another event). At which point the state change code can complete */ - -// note (if you've still got any breath left after reading that) that you -// need to release the sample yourself after this call. if the connected -// input pin needs to hold onto the sample beyond the call, it will addref -// the sample itself. - -// of course you must release this one and call GetDeliveryBuffer for the -// next. You cannot reuse it directly. - -HRESULT -CBaseOutputPin::Deliver(IMediaSample * pSample) -{ - if (m_pInputPin == NULL) { - return VFW_E_NOT_CONNECTED; - } - - - return m_pInputPin->Receive(pSample); -} - - -// called from elsewhere in our filter to pass EOS downstream to -// our connected input pin -HRESULT -CBaseOutputPin::DeliverEndOfStream(void) -{ - // remember this is on IPin not IMemInputPin - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->EndOfStream(); -} - - -/* Commit the allocator's memory, this is called through IMediaFilter - which is responsible for locking the object before calling us */ - -HRESULT -CBaseOutputPin::Active(void) -{ - if (m_pAllocator == NULL) { - return VFW_E_NO_ALLOCATOR; - } - return m_pAllocator->Commit(); -} - - -/* Free up or unprepare allocator's memory, this is called through - IMediaFilter which is responsible for locking the object first */ - -HRESULT -CBaseOutputPin::Inactive(void) -{ - m_bRunTimeError = FALSE; - if (m_pAllocator == NULL) { - return VFW_E_NO_ALLOCATOR; - } - return m_pAllocator->Decommit(); -} - -// we have a default handling of EndOfStream which is to return -// an error, since this should be called on input pins only -STDMETHODIMP -CBaseOutputPin::EndOfStream(void) -{ - return E_UNEXPECTED; -} - - -// BeginFlush should be called on input pins only -STDMETHODIMP -CBaseOutputPin::BeginFlush(void) -{ - return E_UNEXPECTED; -} - -// EndFlush should be called on input pins only -STDMETHODIMP -CBaseOutputPin::EndFlush(void) -{ - return E_UNEXPECTED; -} - -// call BeginFlush on the connected input pin -HRESULT -CBaseOutputPin::DeliverBeginFlush(void) -{ - // remember this is on IPin not IMemInputPin - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->BeginFlush(); -} - -// call EndFlush on the connected input pin -HRESULT -CBaseOutputPin::DeliverEndFlush(void) -{ - // remember this is on IPin not IMemInputPin - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->EndFlush(); -} -// deliver NewSegment to connected pin -HRESULT -CBaseOutputPin::DeliverNewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) -{ - if (m_Connected == NULL) { - return VFW_E_NOT_CONNECTED; - } - return m_Connected->NewSegment(tStart, tStop, dRate); -} - - -//===================================================================== -//===================================================================== -// Implements CBaseInputPin -//===================================================================== -//===================================================================== - - -/* Constructor creates a default allocator object */ - -CBaseInputPin::CBaseInputPin(TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pPinName) : - CBasePin(pObjectName, pFilter, pLock, phr, pPinName, PINDIR_INPUT), - m_pAllocator(NULL), - m_bReadOnly(FALSE), - m_bFlushing(FALSE) -{ - ZeroMemory(&m_SampleProps, sizeof(m_SampleProps)); -} - -#ifdef UNICODE -CBaseInputPin::CBaseInputPin(CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pPinName) : - CBasePin(pObjectName, pFilter, pLock, phr, pPinName, PINDIR_INPUT), - m_pAllocator(NULL), - m_bReadOnly(FALSE), - m_bFlushing(FALSE) -{ - ZeroMemory(&m_SampleProps, sizeof(m_SampleProps)); -} -#endif - -/* Destructor releases it's reference count on the default allocator */ - -CBaseInputPin::~CBaseInputPin() -{ - if (m_pAllocator != NULL) { - m_pAllocator->Release(); - m_pAllocator = NULL; - } -} - - -// override this to publicise our interfaces -STDMETHODIMP -CBaseInputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - /* Do we know about this interface */ - - if (riid == IID_IMemInputPin) { - return GetInterface((IMemInputPin *) this, ppv); - } else { - return CBasePin::NonDelegatingQueryInterface(riid, ppv); - } -} - - -/* Return the allocator interface that this input pin would like the output - pin to use. NOTE subsequent calls to GetAllocator should all return an - interface onto the SAME object so we create one object at the start - - Note: - The allocator is Release()'d on disconnect and replaced on - NotifyAllocator(). - - Override this to provide your own allocator. -*/ - -STDMETHODIMP -CBaseInputPin::GetAllocator( - IMemAllocator **ppAllocator) -{ - CheckPointer(ppAllocator,E_POINTER); - ValidateReadWritePtr(ppAllocator,sizeof(IMemAllocator *)); - CAutoLock cObjectLock(m_pLock); - - if (m_pAllocator == NULL) { - HRESULT hr = CreateMemoryAllocator(&m_pAllocator); - if (FAILED(hr)) { - return hr; - } - } - ASSERT(m_pAllocator != NULL); - *ppAllocator = m_pAllocator; - m_pAllocator->AddRef(); - return NOERROR; -} - - -/* Tell the input pin which allocator the output pin is actually going to use - Override this if you care - NOTE the locking we do both here and also in - GetAllocator is unnecessary but derived classes that do something useful - will undoubtedly have to lock the object so this might help remind people */ - -STDMETHODIMP -CBaseInputPin::NotifyAllocator( - IMemAllocator * pAllocator, - BOOL bReadOnly) -{ - CheckPointer(pAllocator,E_POINTER); - ValidateReadPtr(pAllocator,sizeof(IMemAllocator)); - CAutoLock cObjectLock(m_pLock); - - IMemAllocator *pOldAllocator = m_pAllocator; - pAllocator->AddRef(); - m_pAllocator = pAllocator; - - if (pOldAllocator != NULL) { - pOldAllocator->Release(); - } - - // the readonly flag indicates whether samples from this allocator should - // be regarded as readonly - if true, then inplace transforms will not be - // allowed. - m_bReadOnly = (BYTE)bReadOnly; - return NOERROR; -} - - -HRESULT -CBaseInputPin::BreakConnect() -{ - /* We don't need our allocator any more */ - if (m_pAllocator) { - // Always decommit the allocator because a downstream filter may or - // may not decommit the connection's allocator. A memory leak could - // occur if the allocator is not decommited when a pin is disconnected. - HRESULT hr = m_pAllocator->Decommit(); - if( FAILED( hr ) ) { - return hr; - } - - m_pAllocator->Release(); - m_pAllocator = NULL; - } - - return S_OK; -} - - -/* Do something with this media sample - this base class checks to see if the - format has changed with this media sample and if so checks that the filter - will accept it, generating a run time error if not. Once we have raised a - run time error we set a flag so that no more samples will be accepted - - It is important that any filter should override this method and implement - synchronization so that samples are not processed when the pin is - disconnected etc -*/ - -STDMETHODIMP -CBaseInputPin::Receive(IMediaSample *pSample) -{ - CheckPointer(pSample,E_POINTER); - ValidateReadPtr(pSample,sizeof(IMediaSample)); - ASSERT(pSample); - - HRESULT hr = CheckStreaming(); - if (S_OK != hr) { - return hr; - } - - - - /* Check for IMediaSample2 */ - IMediaSample2 *pSample2; - if (SUCCEEDED(pSample->QueryInterface(IID_IMediaSample2, (void **)&pSample2))) { - hr = pSample2->GetProperties(sizeof(m_SampleProps), (PBYTE)&m_SampleProps); - pSample2->Release(); - if (FAILED(hr)) { - return hr; - } - } else { - /* Get the properties the hard way */ - m_SampleProps.cbData = sizeof(m_SampleProps); - m_SampleProps.dwTypeSpecificFlags = 0; - m_SampleProps.dwStreamId = AM_STREAM_MEDIA; - m_SampleProps.dwSampleFlags = 0; - if (S_OK == pSample->IsDiscontinuity()) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_DATADISCONTINUITY; - } - if (S_OK == pSample->IsPreroll()) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_PREROLL; - } - if (S_OK == pSample->IsSyncPoint()) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_SPLICEPOINT; - } - if (SUCCEEDED(pSample->GetTime(&m_SampleProps.tStart, - &m_SampleProps.tStop))) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_TIMEVALID | - AM_SAMPLE_STOPVALID; - } - if (S_OK == pSample->GetMediaType(&m_SampleProps.pMediaType)) { - m_SampleProps.dwSampleFlags |= AM_SAMPLE_TYPECHANGED; - } - pSample->GetPointer(&m_SampleProps.pbBuffer); - m_SampleProps.lActual = pSample->GetActualDataLength(); - m_SampleProps.cbBuffer = pSample->GetSize(); - } - - /* Has the format changed in this sample */ - - if (!(m_SampleProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED)) { - return NOERROR; - } - - /* Check the derived class accepts this format */ - /* This shouldn't fail as the source must call QueryAccept first */ - - hr = CheckMediaType((CMediaType *)m_SampleProps.pMediaType); - - if (hr == NOERROR) { - return NOERROR; - } - - /* Raise a runtime error if we fail the media type */ - - m_bRunTimeError = TRUE; - EndOfStream(); - m_pFilter->NotifyEvent(EC_ERRORABORT,VFW_E_TYPE_NOT_ACCEPTED,0); - return VFW_E_INVALIDMEDIATYPE; -} - - -/* Receive multiple samples */ -STDMETHODIMP -CBaseInputPin::ReceiveMultiple ( - IMediaSample **pSamples, - long nSamples, - long *nSamplesProcessed) -{ - CheckPointer(pSamples,E_POINTER); - ValidateReadPtr(pSamples,nSamples * sizeof(IMediaSample *)); - - HRESULT hr = S_OK; - *nSamplesProcessed = 0; - while (nSamples-- > 0) { - hr = Receive(pSamples[*nSamplesProcessed]); - - /* S_FALSE means don't send any more */ - if (hr != S_OK) { - break; - } - (*nSamplesProcessed)++; - } - return hr; -} - -/* See if Receive() might block */ -STDMETHODIMP -CBaseInputPin::ReceiveCanBlock() -{ - /* Ask all the output pins if they block - If there are no output pin assume we do block - */ - int cPins = m_pFilter->GetPinCount(); - int cOutputPins = 0; - for (int c = 0; c < cPins; c++) { - CBasePin *pPin = m_pFilter->GetPin(c); - PIN_DIRECTION pd; - HRESULT hr = pPin->QueryDirection(&pd); - if (FAILED(hr)) { - return hr; - } - - if (pd == PINDIR_OUTPUT) { - - IPin *pConnected; - hr = pPin->ConnectedTo(&pConnected); - if (SUCCEEDED(hr)) { - ASSERT(pConnected != NULL); - cOutputPins++; - IMemInputPin *pInputPin; - hr = pConnected->QueryInterface( - IID_IMemInputPin, - (void **)&pInputPin); - pConnected->Release(); - if (SUCCEEDED(hr)) { - hr = pInputPin->ReceiveCanBlock(); - pInputPin->Release(); - if (hr != S_FALSE) { - return S_OK; - } - } else { - /* There's a transport we don't understand here */ - return S_OK; - } - } - } - } - return cOutputPins == 0 ? S_OK : S_FALSE; -} - -// Default handling for BeginFlush - call at the beginning -// of your implementation (makes sure that all Receive calls -// fail). After calling this, you need to free any queued data -// and then call downstream. -STDMETHODIMP -CBaseInputPin::BeginFlush(void) -{ - // BeginFlush is NOT synchronized with streaming but is part of - // a control action - hence we synchronize with the filter - CAutoLock lck(m_pLock); - - // if we are already in mid-flush, this is probably a mistake - // though not harmful - try to pick it up for now so I can think about it - ASSERT(!m_bFlushing); - - // first thing to do is ensure that no further Receive calls succeed - m_bFlushing = TRUE; - - // now discard any data and call downstream - must do that - // in derived classes - return S_OK; -} - -// default handling for EndFlush - call at end of your implementation -// - before calling this, ensure that there is no queued data and no thread -// pushing any more without a further receive, then call downstream, -// then call this method to clear the m_bFlushing flag and re-enable -// receives -STDMETHODIMP -CBaseInputPin::EndFlush(void) -{ - // Endlush is NOT synchronized with streaming but is part of - // a control action - hence we synchronize with the filter - CAutoLock lck(m_pLock); - - // almost certainly a mistake if we are not in mid-flush - ASSERT(m_bFlushing); - - // before calling, sync with pushing thread and ensure - // no more data is going downstream, then call EndFlush on - // downstream pins. - - // now re-enable Receives - m_bFlushing = FALSE; - - // No more errors - m_bRunTimeError = FALSE; - - return S_OK; -} - - -STDMETHODIMP -CBaseInputPin::Notify(IBaseFilter * pSender, Quality q) -{ - UNREFERENCED_PARAMETER(q); - CheckPointer(pSender,E_POINTER); - ValidateReadPtr(pSender,sizeof(IBaseFilter)); - DbgBreak("IQuality::Notify called on an input pin"); - return NOERROR; -} // Notify - -/* Free up or unprepare allocator's memory, this is called through - IMediaFilter which is responsible for locking the object first */ - -HRESULT -CBaseInputPin::Inactive(void) -{ - m_bRunTimeError = FALSE; - if (m_pAllocator == NULL) { - return VFW_E_NO_ALLOCATOR; - } - - m_bFlushing = FALSE; - - return m_pAllocator->Decommit(); -} - -// what requirements do we have of the allocator - override if you want -// to support other people's allocators but need a specific alignment -// or prefix. -STDMETHODIMP -CBaseInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps) -{ - UNREFERENCED_PARAMETER(pProps); - return E_NOTIMPL; -} - -// Check if it's OK to process data -// -HRESULT -CBaseInputPin::CheckStreaming() -{ - // Shouldn't be able to get any data if we're not connected! - ASSERT(IsConnected()); - - // Don't process stuff in Stopped state - if (IsStopped()) { - return VFW_E_WRONG_STATE; - } - if (m_bFlushing) { - return S_FALSE; - } - if (m_bRunTimeError) { - return VFW_E_RUNTIME_ERROR; - } - return S_OK; -} - -// Pass on the Quality notification q to -// a. Our QualityControl sink (if we have one) or else -// b. to our upstream filter -// and if that doesn't work, throw it away with a bad return code -HRESULT -CBaseInputPin::PassNotify(Quality& q) -{ - // We pass the message on, which means that we find the quality sink - // for our input pin and send it there - - DbgLog((LOG_TRACE,3,TEXT("Passing Quality notification through transform"))); - if (m_pQSink!=NULL) { - return m_pQSink->Notify(m_pFilter, q); - } else { - // no sink set, so pass it upstream - HRESULT hr; - IQualityControl * pIQC; - - hr = VFW_E_NOT_FOUND; // default - if (m_Connected) { - m_Connected->QueryInterface(IID_IQualityControl, (void**)&pIQC); - - if (pIQC!=NULL) { - hr = pIQC->Notify(m_pFilter, q); - pIQC->Release(); - } - } - return hr; - } - -} // PassNotify - -//===================================================================== -//===================================================================== -// Memory allocation class, implements CMediaSample -//===================================================================== -//===================================================================== - - -/* NOTE The implementation of this class calls the CUnknown constructor with - a NULL outer unknown pointer. This has the effect of making us a self - contained class, ie any QueryInterface, AddRef or Release calls will be - routed to the class's NonDelegatingUnknown methods. You will typically - find that the classes that do this then override one or more of these - virtual functions to provide more specialised behaviour. A good example - of this is where a class wants to keep the QueryInterface internal but - still wants it's lifetime controlled by the external object */ - -/* The last two parameters have default values of NULL and zero */ - -CMediaSample::CMediaSample(TCHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer, - LONG length) : - m_pBuffer(pBuffer), // Initialise the buffer - m_cbBuffer(length), // And it's length - m_lActual(length), // By default, actual = length - m_pMediaType(NULL), // No media type change - m_dwFlags(0), // Nothing set - m_cRef(0), // 0 ref count - m_dwTypeSpecificFlags(0), // Type specific flags - m_dwStreamId(AM_STREAM_MEDIA), // Stream id - m_pAllocator(pAllocator) // Allocator -{ - - /* We must have an owner and it must also be derived from class - CBaseAllocator BUT we do not hold a reference count on it */ - - ASSERT(pAllocator); -} - -#ifdef UNICODE -CMediaSample::CMediaSample(CHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer, - LONG length) : - m_pBuffer(pBuffer), // Initialise the buffer - m_cbBuffer(length), // And it's length - m_lActual(length), // By default, actual = length - m_pMediaType(NULL), // No media type change - m_dwFlags(0), // Nothing set - m_cRef(0), // 0 ref count - m_dwTypeSpecificFlags(0), // Type specific flags - m_dwStreamId(AM_STREAM_MEDIA), // Stream id - m_pAllocator(pAllocator) // Allocator -{ - - /* We must have an owner and it must also be derived from class - CBaseAllocator BUT we do not hold a reference count on it */ - - ASSERT(pAllocator); -} -#endif - -/* Destructor deletes the media type memory */ - -CMediaSample::~CMediaSample() -{ - - if (m_pMediaType) { - DeleteMediaType(m_pMediaType); - } -} - -/* Override this to publicise our interfaces */ - -STDMETHODIMP -CMediaSample::QueryInterface(REFIID riid, void **ppv) -{ - if (riid == IID_IMediaSample || - riid == IID_IMediaSample2 || - riid == IID_IUnknown) { - return GetInterface((IMediaSample *) this, ppv); - } else { - return E_NOINTERFACE; - } -} - -STDMETHODIMP_(ULONG) -CMediaSample::AddRef() -{ - return InterlockedIncrement(&m_cRef); -} - - -// -- CMediaSample lifetimes -- -// -// On final release of this sample buffer it is not deleted but -// returned to the freelist of the owning memory allocator -// -// The allocator may be waiting for the last buffer to be placed on the free -// list in order to decommit all the memory, so the ReleaseBuffer() call may -// result in this sample being deleted. We also need to hold a refcount on -// the allocator to stop that going away until we have finished with this. -// However, we cannot release the allocator before the ReleaseBuffer, as the -// release may cause us to be deleted. Similarly we can't do it afterwards. -// -// Thus we must leave it to the allocator to hold an addref on our behalf. -// When he issues us in GetBuffer, he addref's himself. When ReleaseBuffer -// is called, he releases himself, possibly causing us and him to be deleted. - - -STDMETHODIMP_(ULONG) -CMediaSample::Release() -{ - /* Decrement our own private reference count */ - LONG lRef; - if (m_cRef == 1) { - lRef = 0; - m_cRef = 0; - } else { - lRef = InterlockedDecrement(&m_cRef); - } - ASSERT(lRef >= 0); - - DbgLog((LOG_MEMORY,3,TEXT(" Unknown %X ref-- = %d"), - this, m_cRef)); - - /* Did we release our final reference count */ - if (lRef == 0) { - /* Free all resources */ - if (m_dwFlags & Sample_TypeChanged) { - SetMediaType(NULL); - } - ASSERT(m_pMediaType == NULL); - m_dwFlags = 0; - m_dwTypeSpecificFlags = 0; - m_dwStreamId = AM_STREAM_MEDIA; - - /* This may cause us to be deleted */ - // Our refcount is reliably 0 thus no-one will mess with us - m_pAllocator->ReleaseBuffer(this); - } - return (ULONG)lRef; -} - - -// set the buffer pointer and length. Used by allocators that -// want variable sized pointers or pointers into already-read data. -// This is only available through a CMediaSample* not an IMediaSample* -// and so cannot be changed by clients. -HRESULT -CMediaSample::SetPointer(BYTE * ptr, LONG cBytes) -{ - m_pBuffer = ptr; // new buffer area (could be null) - m_cbBuffer = cBytes; // length of buffer - m_lActual = cBytes; // length of data in buffer (assume full) - - return S_OK; -} - - -// get me a read/write pointer to this buffer's memory. I will actually -// want to use sizeUsed bytes. -STDMETHODIMP -CMediaSample::GetPointer(BYTE ** ppBuffer) -{ - ValidateReadWritePtr(ppBuffer,sizeof(BYTE *)); - - // creator must have set pointer either during - // constructor or by SetPointer - ASSERT(m_pBuffer); - - *ppBuffer = m_pBuffer; - return NOERROR; -} - - -// return the size in bytes of this buffer -STDMETHODIMP_(LONG) -CMediaSample::GetSize(void) -{ - return m_cbBuffer; -} - - -// get the stream time at which this sample should start and finish. -STDMETHODIMP -CMediaSample::GetTime( - REFERENCE_TIME * pTimeStart, // put time here - REFERENCE_TIME * pTimeEnd -) -{ - ValidateReadWritePtr(pTimeStart,sizeof(REFERENCE_TIME)); - ValidateReadWritePtr(pTimeEnd,sizeof(REFERENCE_TIME)); - - if (!(m_dwFlags & Sample_StopValid)) { - if (!(m_dwFlags & Sample_TimeValid)) { - return VFW_E_SAMPLE_TIME_NOT_SET; - } else { - *pTimeStart = m_Start; - - // Make sure old stuff works - *pTimeEnd = m_Start + 1; - return VFW_S_NO_STOP_TIME; - } - } - - *pTimeStart = m_Start; - *pTimeEnd = m_End; - return NOERROR; -} - - -// Set the stream time at which this sample should start and finish. -// NULL pointers means the time is reset -STDMETHODIMP -CMediaSample::SetTime( - REFERENCE_TIME * pTimeStart, - REFERENCE_TIME * pTimeEnd -) -{ - if (pTimeStart == NULL) { - ASSERT(pTimeEnd == NULL); - m_dwFlags &= ~(Sample_TimeValid | Sample_StopValid); - } else { - if (pTimeEnd == NULL) { - m_Start = *pTimeStart; - m_dwFlags |= Sample_TimeValid; - m_dwFlags &= ~Sample_StopValid; - } else { - ValidateReadPtr(pTimeStart,sizeof(REFERENCE_TIME)); - ValidateReadPtr(pTimeEnd,sizeof(REFERENCE_TIME)); - ASSERT(*pTimeEnd >= *pTimeStart); - - m_Start = *pTimeStart; - m_End = *pTimeEnd; - m_dwFlags |= Sample_TimeValid | Sample_StopValid; - } - } - return NOERROR; -} - - -// get the media times (eg bytes) for this sample -STDMETHODIMP -CMediaSample::GetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd -) -{ - ValidateReadWritePtr(pTimeStart,sizeof(LONGLONG)); - ValidateReadWritePtr(pTimeEnd,sizeof(LONGLONG)); - - if (!(m_dwFlags & Sample_MediaTimeValid)) { - return VFW_E_MEDIA_TIME_NOT_SET; - } - - *pTimeStart = m_MediaStart; - *pTimeEnd = (m_MediaStart + m_MediaEnd); - return NOERROR; -} - - -// Set the media times for this sample -STDMETHODIMP -CMediaSample::SetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd -) -{ - if (pTimeStart == NULL) { - ASSERT(pTimeEnd == NULL); - m_dwFlags &= ~Sample_MediaTimeValid; - } else { - ValidateReadPtr(pTimeStart,sizeof(LONGLONG)); - ValidateReadPtr(pTimeEnd,sizeof(LONGLONG)); - ASSERT(*pTimeEnd >= *pTimeStart); - - m_MediaStart = *pTimeStart; - m_MediaEnd = (LONG)(*pTimeEnd - *pTimeStart); - m_dwFlags |= Sample_MediaTimeValid; - } - return NOERROR; -} - - -STDMETHODIMP -CMediaSample::IsSyncPoint(void) -{ - if (m_dwFlags & Sample_SyncPoint) { - return S_OK; - } else { - return S_FALSE; - } -} - - -STDMETHODIMP -CMediaSample::SetSyncPoint(BOOL bIsSyncPoint) -{ - if (bIsSyncPoint) { - m_dwFlags |= Sample_SyncPoint; - } else { - m_dwFlags &= ~Sample_SyncPoint; - } - return NOERROR; -} - -// returns S_OK if there is a discontinuity in the data (this same is -// not a continuation of the previous stream of data -// - there has been a seek). -STDMETHODIMP -CMediaSample::IsDiscontinuity(void) -{ - if (m_dwFlags & Sample_Discontinuity) { - return S_OK; - } else { - return S_FALSE; - } -} - -// set the discontinuity property - TRUE if this sample is not a -// continuation, but a new sample after a seek. -STDMETHODIMP -CMediaSample::SetDiscontinuity(BOOL bDiscont) -{ - // should be TRUE or FALSE - if (bDiscont) { - m_dwFlags |= Sample_Discontinuity; - } else { - m_dwFlags &= ~Sample_Discontinuity; - } - return S_OK; -} - -STDMETHODIMP -CMediaSample::IsPreroll(void) -{ - if (m_dwFlags & Sample_Preroll) { - return S_OK; - } else { - return S_FALSE; - } -} - - -STDMETHODIMP -CMediaSample::SetPreroll(BOOL bIsPreroll) -{ - if (bIsPreroll) { - m_dwFlags |= Sample_Preroll; - } else { - m_dwFlags &= ~Sample_Preroll; - } - return NOERROR; -} - -STDMETHODIMP_(LONG) -CMediaSample::GetActualDataLength(void) -{ - return m_lActual; -} - - -STDMETHODIMP -CMediaSample::SetActualDataLength(LONG lActual) -{ - if (lActual > m_cbBuffer) { - ASSERT(lActual <= GetSize()); - return VFW_E_BUFFER_OVERFLOW; - } - m_lActual = lActual; - return NOERROR; -} - - -/* These allow for limited format changes in band */ - -STDMETHODIMP -CMediaSample::GetMediaType(AM_MEDIA_TYPE **ppMediaType) -{ - ValidateReadWritePtr(ppMediaType,sizeof(AM_MEDIA_TYPE *)); - ASSERT(ppMediaType); - - /* Do we have a new media type for them */ - - if (!(m_dwFlags & Sample_TypeChanged)) { - ASSERT(m_pMediaType == NULL); - *ppMediaType = NULL; - return S_FALSE; - } - - ASSERT(m_pMediaType); - - /* Create a copy of our media type */ - - *ppMediaType = CreateMediaType(m_pMediaType); - if (*ppMediaType == NULL) { - return E_OUTOFMEMORY; - } - return NOERROR; -} - - -/* Mark this sample as having a different format type */ - -STDMETHODIMP -CMediaSample::SetMediaType(AM_MEDIA_TYPE *pMediaType) -{ - /* Delete the current media type */ - - if (m_pMediaType) { - DeleteMediaType(m_pMediaType); - m_pMediaType = NULL; - } - - /* Mechanism for resetting the format type */ - - if (pMediaType == NULL) { - m_dwFlags &= ~Sample_TypeChanged; - return NOERROR; - } - - ASSERT(pMediaType); - ValidateReadPtr(pMediaType,sizeof(AM_MEDIA_TYPE)); - - /* Take a copy of the media type */ - - m_pMediaType = CreateMediaType(pMediaType); - if (m_pMediaType == NULL) { - m_dwFlags &= ~Sample_TypeChanged; - return E_OUTOFMEMORY; - } - - m_dwFlags |= Sample_TypeChanged; - return NOERROR; -} - -// Set and get properties (IMediaSample2) -STDMETHODIMP CMediaSample::GetProperties( - DWORD cbProperties, - BYTE * pbProperties -) -{ - if (0 != cbProperties) { - CheckPointer(pbProperties, E_POINTER); - // Return generic stuff up to the length - AM_SAMPLE2_PROPERTIES Props; - Props.cbData = (DWORD) (min(cbProperties, sizeof(Props))); - Props.dwSampleFlags = m_dwFlags & ~Sample_MediaTimeValid; - Props.dwTypeSpecificFlags = m_dwTypeSpecificFlags; - Props.pbBuffer = m_pBuffer; - Props.cbBuffer = m_cbBuffer; - Props.lActual = m_lActual; - Props.tStart = m_Start; - Props.tStop = m_End; - Props.dwStreamId = m_dwStreamId; - if (m_dwFlags & AM_SAMPLE_TYPECHANGED) { - Props.pMediaType = m_pMediaType; - } else { - Props.pMediaType = NULL; - } - CopyMemory(pbProperties, &Props, Props.cbData); - } - return S_OK; -} - -#define CONTAINS_FIELD(type, field, offset) \ - ((FIELD_OFFSET(type, field) + sizeof(((type *)0)->field)) <= offset) - -HRESULT CMediaSample::SetProperties( - DWORD cbProperties, - const BYTE * pbProperties -) -{ - - /* Generic properties */ - AM_MEDIA_TYPE *pMediaType = NULL; - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbData, cbProperties)) { - CheckPointer(pbProperties, E_POINTER); - AM_SAMPLE2_PROPERTIES *pProps = - (AM_SAMPLE2_PROPERTIES *)pbProperties; - - /* Don't use more data than is actually there */ - if (pProps->cbData < cbProperties) { - cbProperties = pProps->cbData; - } - /* We only handle IMediaSample2 */ - if (cbProperties > sizeof(*pProps) || - pProps->cbData > sizeof(*pProps)) { - return E_INVALIDARG; - } - /* Do checks first, the assignments (for backout) */ - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwSampleFlags, cbProperties)) { - /* Check the flags */ - if (pProps->dwSampleFlags & - (~Sample_ValidFlags | Sample_MediaTimeValid)) { - return E_INVALIDARG; - } - /* Check a flag isn't being set for a property - not being provided - */ - if ((pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID) && - !(m_dwFlags & AM_SAMPLE_TIMEVALID) && - !CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStop, cbProperties)) { - return E_INVALIDARG; - } - } - /* NB - can't SET the pointer or size */ - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pbBuffer, cbProperties)) { - - /* Check pbBuffer */ - if (pProps->pbBuffer != 0 && pProps->pbBuffer != m_pBuffer) { - return E_INVALIDARG; - } - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbBuffer, cbProperties)) { - - /* Check cbBuffer */ - if (pProps->cbBuffer != 0 && pProps->cbBuffer != m_cbBuffer) { - return E_INVALIDARG; - } - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, cbBuffer, cbProperties) && - CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, lActual, cbProperties)) { - - /* Check lActual */ - if (pProps->cbBuffer < pProps->lActual) { - return E_INVALIDARG; - } - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pMediaType, cbProperties)) { - - /* Check pMediaType */ - if (pProps->dwSampleFlags & AM_SAMPLE_TYPECHANGED) { - CheckPointer(pProps->pMediaType, E_POINTER); - pMediaType = CreateMediaType(pProps->pMediaType); - if (pMediaType == NULL) { - return E_OUTOFMEMORY; - } - } - } - - /* Now do the assignments */ - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwStreamId, cbProperties)) { - m_dwStreamId = pProps->dwStreamId; - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwSampleFlags, cbProperties)) { - /* Set the flags */ - m_dwFlags = pProps->dwSampleFlags | - (m_dwFlags & Sample_MediaTimeValid); - m_dwTypeSpecificFlags = pProps->dwTypeSpecificFlags; - } else { - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, dwTypeSpecificFlags, cbProperties)) { - m_dwTypeSpecificFlags = pProps->dwTypeSpecificFlags; - } - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, lActual, cbProperties)) { - /* Set lActual */ - m_lActual = pProps->lActual; - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStop, cbProperties)) { - - /* Set the times */ - m_End = pProps->tStop; - } - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, tStart, cbProperties)) { - - /* Set the times */ - m_Start = pProps->tStart; - } - - if (CONTAINS_FIELD(AM_SAMPLE2_PROPERTIES, pMediaType, cbProperties)) { - /* Set pMediaType */ - if (pProps->dwSampleFlags & AM_SAMPLE_TYPECHANGED) { - if (m_pMediaType != NULL) { - DeleteMediaType(m_pMediaType); - } - m_pMediaType = pMediaType; - } - } - - /* Fix up the type changed flag to correctly reflect the current state - If, for instance the input contained no type change but the - output does then if we don't do this we'd lose the - output media type. - */ - if (m_pMediaType) { - m_dwFlags |= Sample_TypeChanged; - } else { - m_dwFlags &= ~Sample_TypeChanged; - } - } - - return S_OK; -} - - -// -// The streaming thread calls IPin::NewSegment(), IPin::EndOfStream(), -// IMemInputPin::Receive() and IMemInputPin::ReceiveMultiple() on the -// connected input pin. The application thread calls Block(). The -// following class members can only be called by the streaming thread. -// -// Deliver() -// DeliverNewSegment() -// StartUsingOutputPin() -// StopUsingOutputPin() -// ChangeOutputFormat() -// ChangeMediaType() -// DynamicReconnect() -// -// The following class members can only be called by the application thread. -// -// Block() -// SynchronousBlockOutputPin() -// AsynchronousBlockOutputPin() -// - -CDynamicOutputPin::CDynamicOutputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseOutputPin(pObjectName, pFilter, pLock, phr, pName), - m_hStopEvent(NULL), - m_pGraphConfig(NULL), - m_bPinUsesReadOnlyAllocator(FALSE), - m_BlockState(NOT_BLOCKED), - m_hUnblockOutputPinEvent(NULL), - m_hNotifyCallerPinBlockedEvent(NULL), - m_dwBlockCallerThreadID(0), - m_dwNumOutstandingOutputPinUsers(0) -{ - HRESULT hr = Initialize(); - if( FAILED( hr ) ) { - *phr = hr; - return; - } -} - -#ifdef UNICODE -CDynamicOutputPin::CDynamicOutputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName) : - CBaseOutputPin(pObjectName, pFilter, pLock, phr, pName), - m_hStopEvent(NULL), - m_pGraphConfig(NULL), - m_bPinUsesReadOnlyAllocator(FALSE), - m_BlockState(NOT_BLOCKED), - m_hUnblockOutputPinEvent(NULL), - m_hNotifyCallerPinBlockedEvent(NULL), - m_dwBlockCallerThreadID(0), - m_dwNumOutstandingOutputPinUsers(0) -{ - HRESULT hr = Initialize(); - if( FAILED( hr ) ) { - *phr = hr; - return; - } -} -#endif - -CDynamicOutputPin::~CDynamicOutputPin() -{ - if(NULL != m_hUnblockOutputPinEvent) { - // This call should not fail because we have access to m_hUnblockOutputPinEvent - // and m_hUnblockOutputPinEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(m_hUnblockOutputPinEvent)); - } - - if(NULL != m_hNotifyCallerPinBlockedEvent) { - // This call should not fail because we have access to m_hNotifyCallerPinBlockedEvent - // and m_hNotifyCallerPinBlockedEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent)); - } -} - -HRESULT CDynamicOutputPin::Initialize(void) -{ - m_hUnblockOutputPinEvent = ::CreateEvent( NULL, // The event will have the default security descriptor. - TRUE, // This is a manual reset event. - TRUE, // The event is initially signaled. - NULL ); // The event is not named. - - // CreateEvent() returns NULL if an error occurs. - if(NULL == m_hUnblockOutputPinEvent) { - return AmGetLastErrorToHResult(); - } - - // Set flag to say we can reconnect while streaming. - SetReconnectWhenActive(true); - - return S_OK; -} - -STDMETHODIMP CDynamicOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - if(riid == IID_IPinFlowControl) { - return GetInterface(static_cast(this), ppv); - } else { - return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); - } -} - -STDMETHODIMP CDynamicOutputPin::Disconnect(void) -{ - CAutoLock cObjectLock(m_pLock); - return DisconnectInternal(); -} - -STDMETHODIMP CDynamicOutputPin::Block(DWORD dwBlockFlags, HANDLE hEvent) -{ - const DWORD VALID_FLAGS = AM_PIN_FLOW_CONTROL_BLOCK; - - // Check for illegal flags. - if(dwBlockFlags & ~VALID_FLAGS) { - return E_INVALIDARG; - } - - // Make sure the event is unsignaled. - if((dwBlockFlags & AM_PIN_FLOW_CONTROL_BLOCK) && (NULL != hEvent)) { - if( !::ResetEvent( hEvent ) ) { - return AmGetLastErrorToHResult(); - } - } - - // No flags are set if we are unblocking the output pin. - if(0 == dwBlockFlags) { - - // This parameter should be NULL because unblock operations are always synchronous. - // There is no need to notify the caller when the event is done. - if(NULL != hEvent) { - return E_INVALIDARG; - } - } - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - HRESULT hr; - - if(dwBlockFlags & AM_PIN_FLOW_CONTROL_BLOCK) { - // IPinFlowControl::Block()'s hEvent parameter is NULL if the block is synchronous. - // If hEvent is not NULL, the block is asynchronous. - if(NULL == hEvent) { - hr = SynchronousBlockOutputPin(); - } else { - hr = AsynchronousBlockOutputPin(hEvent); - } - } else { - hr = UnblockOutputPin(); - } - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - if(FAILED(hr)) { - return hr; - } - - return S_OK; -} - -HRESULT CDynamicOutputPin::SynchronousBlockOutputPin(void) -{ - HANDLE hNotifyCallerPinBlockedEvent = :: CreateEvent( NULL, // The event will have the default security attributes. - FALSE, // This is an automatic reset event. - FALSE, // The event is initially unsignaled. - NULL ); // The event is not named. - - // CreateEvent() returns NULL if an error occurs. - if(NULL == hNotifyCallerPinBlockedEvent) { - return AmGetLastErrorToHResult(); - } - - HRESULT hr = AsynchronousBlockOutputPin(hNotifyCallerPinBlockedEvent); - if(FAILED(hr)) { - // This call should not fail because we have access to hNotifyCallerPinBlockedEvent - // and hNotifyCallerPinBlockedEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(hNotifyCallerPinBlockedEvent)); - - return hr; - } - - hr = WaitEvent(hNotifyCallerPinBlockedEvent); - - // This call should not fail because we have access to hNotifyCallerPinBlockedEvent - // and hNotifyCallerPinBlockedEvent is a valid event. - EXECUTE_ASSERT(::CloseHandle(hNotifyCallerPinBlockedEvent)); - - if(FAILED(hr)) { - return hr; - } - - return S_OK; -} - -HRESULT CDynamicOutputPin::AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent) -{ - // This function holds the m_BlockStateLock because it uses - // m_dwBlockCallerThreadID, m_BlockState and - // m_hNotifyCallerPinBlockedEvent. - CAutoLock alBlockStateLock(&m_BlockStateLock); - - if(NOT_BLOCKED != m_BlockState) { - if(m_dwBlockCallerThreadID == ::GetCurrentThreadId()) { - return VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD; - } else { - return VFW_E_PIN_ALREADY_BLOCKED; - } - } - - BOOL fSuccess = ::DuplicateHandle( ::GetCurrentProcess(), - hNotifyCallerPinBlockedEvent, - ::GetCurrentProcess(), - &m_hNotifyCallerPinBlockedEvent, - EVENT_MODIFY_STATE, - FALSE, - 0 ); - if( !fSuccess ) { - return AmGetLastErrorToHResult(); - } - - m_BlockState = PENDING; - m_dwBlockCallerThreadID = ::GetCurrentThreadId(); - - // The output pin cannot be blocked if the streaming thread is - // calling IPin::NewSegment(), IPin::EndOfStream(), IMemInputPin::Receive() - // or IMemInputPin::ReceiveMultiple() on the connected input pin. Also, it - // cannot be blocked if the streaming thread is calling DynamicReconnect(), - // ChangeMediaType() or ChangeOutputFormat(). - if(!StreamingThreadUsingOutputPin()) { - - // The output pin can be immediately blocked. - BlockOutputPin(); - } - - return S_OK; -} - -void CDynamicOutputPin::BlockOutputPin(void) -{ - // The caller should always hold the m_BlockStateLock because this function - // uses m_BlockState and m_hNotifyCallerPinBlockedEvent. - ASSERT(CritCheckIn(&m_BlockStateLock)); - - // This function should not be called if the streaming thread is modifying - // the connection state or it's passing data downstream. - ASSERT(!StreamingThreadUsingOutputPin()); - - // This should not fail because we successfully created the event - // and we have the security permissions to change it's state. - EXECUTE_ASSERT(::ResetEvent(m_hUnblockOutputPinEvent)); - - // This event should not fail because AsynchronousBlockOutputPin() successfully - // duplicated this handle and we have the appropriate security permissions. - EXECUTE_ASSERT(::SetEvent(m_hNotifyCallerPinBlockedEvent)); - EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent)); - - m_BlockState = BLOCKED; - m_hNotifyCallerPinBlockedEvent = NULL; -} - -HRESULT CDynamicOutputPin::UnblockOutputPin(void) -{ - // UnblockOutputPin() holds the m_BlockStateLock because it - // uses m_BlockState, m_dwBlockCallerThreadID and - // m_hNotifyCallerPinBlockedEvent. - CAutoLock alBlockStateLock(&m_BlockStateLock); - - if(NOT_BLOCKED == m_BlockState) { - return S_FALSE; - } - - // This should not fail because we successfully created the event - // and we have the security permissions to change it's state. - EXECUTE_ASSERT(::SetEvent(m_hUnblockOutputPinEvent)); - - // Cancel the block operation if it's still pending. - if(NULL != m_hNotifyCallerPinBlockedEvent) { - // This event should not fail because AsynchronousBlockOutputPin() successfully - // duplicated this handle and we have the appropriate security permissions. - EXECUTE_ASSERT(::SetEvent(m_hNotifyCallerPinBlockedEvent)); - EXECUTE_ASSERT(::CloseHandle(m_hNotifyCallerPinBlockedEvent)); - } - - m_BlockState = NOT_BLOCKED; - m_dwBlockCallerThreadID = 0; - m_hNotifyCallerPinBlockedEvent = NULL; - - return S_OK; -} - -HRESULT CDynamicOutputPin::StartUsingOutputPin(void) -{ - // The caller should not hold m_BlockStateLock. If the caller does, - // a deadlock could occur. - ASSERT(CritCheckOut(&m_BlockStateLock)); - - CAutoLock alBlockStateLock(&m_BlockStateLock); - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - // Are we in the middle of a block operation? - while(BLOCKED == m_BlockState) { - m_BlockStateLock.Unlock(); - - // If this ASSERT fires, a deadlock could occur. The caller should make sure - // that this thread never acquires the Block State lock more than once. - ASSERT(CritCheckOut( &m_BlockStateLock )); - - // WaitForMultipleObjects() returns WAIT_OBJECT_0 if the unblock event - // is fired. It returns WAIT_OBJECT_0 + 1 if the stop event if fired. - // See the Windows SDK documentation for more information on - // WaitForMultipleObjects(). - const DWORD UNBLOCK = WAIT_OBJECT_0; - const DWORD STOP = WAIT_OBJECT_0 + 1; - - HANDLE ahWaitEvents[] = { m_hUnblockOutputPinEvent, m_hStopEvent }; - DWORD dwNumWaitEvents = sizeof(ahWaitEvents)/sizeof(HANDLE); - - DWORD dwReturnValue = ::WaitForMultipleObjects( dwNumWaitEvents, ahWaitEvents, FALSE, INFINITE ); - - m_BlockStateLock.Lock(); - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - switch( dwReturnValue ) { - case UNBLOCK: - break; - - case STOP: - return VFW_E_STATE_CHANGED; - - case WAIT_FAILED: - return AmGetLastErrorToHResult(); - - default: - DbgBreak( "An Unexpected case occured in CDynamicOutputPin::StartUsingOutputPin()." ); - return E_UNEXPECTED; - } - } - - m_dwNumOutstandingOutputPinUsers++; - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - return S_OK; -} - -void CDynamicOutputPin::StopUsingOutputPin(void) -{ - CAutoLock alBlockStateLock(&m_BlockStateLock); - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG - - m_dwNumOutstandingOutputPinUsers--; - - if((m_dwNumOutstandingOutputPinUsers == 0) && (NOT_BLOCKED != m_BlockState)) { - BlockOutputPin(); - } - - #ifdef DEBUG - AssertValid(); - #endif // DEBUG -} - -bool CDynamicOutputPin::StreamingThreadUsingOutputPin(void) -{ - CAutoLock alBlockStateLock(&m_BlockStateLock); - - return (m_dwNumOutstandingOutputPinUsers > 0); -} - -void CDynamicOutputPin::SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent) -{ - // This pointer is not addrefed because filters are not allowed to - // hold references to the filter graph manager. See the documentation for - // IBaseFilter::JoinFilterGraph() in the Direct Show SDK for more information. - m_pGraphConfig = pGraphConfig; - - m_hStopEvent = hStopEvent; -} - -HRESULT CDynamicOutputPin::Active(void) -{ - // Make sure the user initialized the object by calling SetConfigInfo(). - if((NULL == m_hStopEvent) || (NULL == m_pGraphConfig)) { - DbgBreak( ERROR: CDynamicOutputPin::Active() failed because m_pGraphConfig and m_hStopEvent were not initialized. Call SetConfigInfo() to initialize them. ); - return E_FAIL; - } - - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then Active() is called. An event - // handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(ResetEvent(m_hStopEvent)); - - return CBaseOutputPin::Active(); -} - -HRESULT CDynamicOutputPin::Inactive(void) -{ - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then Active() is called. An event - // handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(SetEvent(m_hStopEvent)); - - return CBaseOutputPin::Inactive(); -} - -HRESULT CDynamicOutputPin::DeliverBeginFlush(void) -{ - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then DeliverBeginFlush() is called. - // An event handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(SetEvent(m_hStopEvent)); - - return CBaseOutputPin::DeliverBeginFlush(); -} - -HRESULT CDynamicOutputPin::DeliverEndFlush(void) -{ - // If this ASSERT fires, the user may have passed an invalid event handle to SetConfigInfo(). - // The ASSERT can also fire if the event if destroyed and then DeliverBeginFlush() is called. - // An event handle is invalid if 1) the event does not exist or the user does not have the security - // permissions to use the event. - EXECUTE_ASSERT(ResetEvent(m_hStopEvent)); - - return CBaseOutputPin::DeliverEndFlush(); -} - - -// ChangeOutputFormat() either dynamicly changes the connection's format type or it dynamicly -// reconnects the output pin. -HRESULT CDynamicOutputPin::ChangeOutputFormat - ( - const AM_MEDIA_TYPE *pmt, - REFERENCE_TIME tSegmentStart, - REFERENCE_TIME tSegmentStop, - double dSegmentRate - ) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - // Callers should always pass a valid media type to ChangeOutputFormat() . - ASSERT(NULL != pmt); - - CMediaType cmt(*pmt); - HRESULT hr = ChangeMediaType(&cmt); - if (FAILED(hr)) { - return hr; - } - - hr = DeliverNewSegment(tSegmentStart, tSegmentStop, dSegmentRate); - if( FAILED( hr ) ) { - return hr; - } - - return S_OK; -} - -HRESULT CDynamicOutputPin::ChangeMediaType(const CMediaType *pmt) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - // This function assumes the filter graph is running. - ASSERT(!IsStopped()); - - if(!IsConnected()) { - return VFW_E_NOT_CONNECTED; - } - - /* First check if the downstream pin will accept a dynamic - format change - */ - QzCComPtr pConnection; - - m_Connected->QueryInterface(IID_IPinConnection, (void **)&pConnection); - if(pConnection != NULL) { - - if(S_OK == pConnection->DynamicQueryAccept(pmt)) { - - HRESULT hr = ChangeMediaTypeHelper(pmt); - if(FAILED(hr)) { - return hr; - } - - return S_OK; - } - } - - /* Can't do the dynamic connection */ - return DynamicReconnect(pmt); -} - -HRESULT CDynamicOutputPin::ChangeMediaTypeHelper(const CMediaType *pmt) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - HRESULT hr = m_Connected->ReceiveConnection(this, pmt); - if(FAILED(hr)) { - return hr; - } - - hr = SetMediaType(pmt); - if(FAILED(hr)) { - return hr; - } - - // Does this pin use the local memory transport? - if(NULL != m_pInputPin) { - // This function assumes that m_pInputPin and m_Connected are - // two different interfaces to the same object. - ASSERT(::IsEqualObject(m_Connected, m_pInputPin)); - - ALLOCATOR_PROPERTIES apInputPinRequirements; - apInputPinRequirements.cbAlign = 0; - apInputPinRequirements.cbBuffer = 0; - apInputPinRequirements.cbPrefix = 0; - apInputPinRequirements.cBuffers = 0; - - m_pInputPin->GetAllocatorRequirements(&apInputPinRequirements); - - // A zero allignment does not make any sense. - if(0 == apInputPinRequirements.cbAlign) { - apInputPinRequirements.cbAlign = 1; - } - - hr = m_pAllocator->Decommit(); - if(FAILED(hr)) { - return hr; - } - - hr = DecideBufferSize(m_pAllocator, &apInputPinRequirements); - if(FAILED(hr)) { - return hr; - } - - hr = m_pAllocator->Commit(); - if(FAILED(hr)) { - return hr; - } - - hr = m_pInputPin->NotifyAllocator(m_pAllocator, m_bPinUsesReadOnlyAllocator); - if(FAILED(hr)) { - return hr; - } - } - - return S_OK; -} - -// this method has to be called from the thread that is pushing data, -// and it's the caller's responsibility to make sure that the thread -// has no outstand samples because they cannot be delivered after a -// reconnect -// -HRESULT CDynamicOutputPin::DynamicReconnect( const CMediaType* pmt ) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - if((m_pGraphConfig == NULL) || (NULL == m_hStopEvent)) { - return E_FAIL; - } - - HRESULT hr = m_pGraphConfig->Reconnect( - this, - NULL, - pmt, - NULL, - m_hStopEvent, - AM_GRAPH_CONFIG_RECONNECT_CACHE_REMOVED_FILTERS ); - - return hr; -} - -HRESULT CDynamicOutputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin); - if(SUCCEEDED(hr)) { - if(!IsStopped() && m_pAllocator) { - hr = m_pAllocator->Commit(); - ASSERT(hr != VFW_E_ALREADY_COMMITTED); - } - } - - return hr; -} - -#ifdef DEBUG -void CDynamicOutputPin::AssertValid(void) -{ - // Make sure the object was correctly initialized. - - // This ASSERT only fires if the object failed to initialize - // and the user ignored the constructor's return code (phr). - ASSERT(NULL != m_hUnblockOutputPinEvent); - - // If either of these ASSERTs fire, the user did not correctly call - // SetConfigInfo(). - ASSERT(NULL != m_hStopEvent); - ASSERT(NULL != m_pGraphConfig); - - // Make sure the block state is consistent. - - CAutoLock alBlockStateLock(&m_BlockStateLock); - - // BLOCK_STATE variables only have three legal values: PENDING, BLOCKED and NOT_BLOCKED. - ASSERT((NOT_BLOCKED == m_BlockState) || (PENDING == m_BlockState) || (BLOCKED == m_BlockState)); - - // m_hNotifyCallerPinBlockedEvent is only needed when a block operation cannot complete - // immediately. - ASSERT(((NULL == m_hNotifyCallerPinBlockedEvent) && (PENDING != m_BlockState)) || - ((NULL != m_hNotifyCallerPinBlockedEvent) && (PENDING == m_BlockState)) ); - - // m_dwBlockCallerThreadID should always be 0 if the pin is not blocked and - // the user is not trying to block the pin. - ASSERT((0 == m_dwBlockCallerThreadID) || (NOT_BLOCKED != m_BlockState)); - - // If this ASSERT fires, the streaming thread is using the output pin and the - // output pin is blocked. - ASSERT(((0 != m_dwNumOutstandingOutputPinUsers) && (BLOCKED != m_BlockState)) || - ((0 == m_dwNumOutstandingOutputPinUsers) && (NOT_BLOCKED != m_BlockState)) || - ((0 == m_dwNumOutstandingOutputPinUsers) && (NOT_BLOCKED == m_BlockState)) ); -} -#endif // DEBUG - -HRESULT CDynamicOutputPin::WaitEvent(HANDLE hEvent) -{ - const DWORD EVENT_SIGNALED = WAIT_OBJECT_0; - - DWORD dwReturnValue = ::WaitForSingleObject(hEvent, INFINITE); - - switch( dwReturnValue ) { - case EVENT_SIGNALED: - return S_OK; - - case WAIT_FAILED: - return AmGetLastErrorToHResult(); - - default: - DbgBreak( "An Unexpected case occured in CDynamicOutputPin::WaitEvent()." ); - return E_UNEXPECTED; - } -} - -//===================================================================== -//===================================================================== -// Implements CBaseAllocator -//===================================================================== -//===================================================================== - - -/* Constructor overrides the default settings for the free list to request - that it be alertable (ie the list can be cast to a handle which can be - passed to WaitForSingleObject). Both of the allocator lists also ask for - object locking, the all list matches the object default settings but I - have included them here just so it is obvious what kind of list it is */ - -CBaseAllocator::CBaseAllocator(TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - BOOL bEvent, - BOOL fEnableReleaseCallback - ) : - CUnknown(pName, pUnk), - m_lAllocated(0), - m_bChanged(FALSE), - m_bCommitted(FALSE), - m_bDecommitInProgress(FALSE), - m_lSize(0), - m_lCount(0), - m_lAlignment(0), - m_lPrefix(0), - m_hSem(NULL), - m_lWaiting(0), - m_fEnableReleaseCallback(fEnableReleaseCallback), - m_pNotify(NULL) -{ - - if (bEvent) { - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if (m_hSem == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - } -} - -#ifdef UNICODE -CBaseAllocator::CBaseAllocator(CHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - BOOL bEvent, - BOOL fEnableReleaseCallback) : - CUnknown(pName, pUnk), - m_lAllocated(0), - m_bChanged(FALSE), - m_bCommitted(FALSE), - m_bDecommitInProgress(FALSE), - m_lSize(0), - m_lCount(0), - m_lAlignment(0), - m_lPrefix(0), - m_hSem(NULL), - m_lWaiting(0), - m_fEnableReleaseCallback(fEnableReleaseCallback), - m_pNotify(NULL) -{ - - if (bEvent) { - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if (m_hSem == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - } -} -#endif - -/* Destructor */ - -CBaseAllocator::~CBaseAllocator() -{ - // we can't call Decommit here since that would mean a call to a - // pure virtual in destructor. - // We must assume that the derived class has gone into decommit state in - // its destructor. - - ASSERT(!m_bCommitted); - if (m_hSem != NULL) { - EXECUTE_ASSERT(CloseHandle(m_hSem)); - } - if (m_pNotify) { - m_pNotify->Release(); - } -} - - -/* Override this to publicise our interfaces */ - -STDMETHODIMP -CBaseAllocator::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - /* Do we know about this interface */ - - if (riid == IID_IMemAllocator || - riid == IID_IMemAllocatorCallbackTemp && m_fEnableReleaseCallback) { - return GetInterface((IMemAllocatorCallbackTemp *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -/* This sets the size and count of the required samples. The memory isn't - actually allocated until Commit() is called, if memory has already been - allocated then assuming no samples are outstanding the user may call us - to change the buffering, the memory will be released in Commit() */ - -STDMETHODIMP -CBaseAllocator::SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual) -{ - CheckPointer(pRequest, E_POINTER); - CheckPointer(pActual, E_POINTER); - ValidateReadWritePtr(pActual, sizeof(ALLOCATOR_PROPERTIES)); - CAutoLock cObjectLock(this); - - ZeroMemory(pActual, sizeof(ALLOCATOR_PROPERTIES)); - - ASSERT(pRequest->cbBuffer > 0); - - /* Check the alignment requested */ - if (pRequest->cbAlign != 1) { - DbgLog((LOG_ERROR, 2, TEXT("Alignment requested was 0x%x, not 1"), - pRequest->cbAlign)); - return VFW_E_BADALIGN; - } - - /* Can't do this if already committed, there is an argument that says we - should not reject the SetProperties call if there are buffers still - active. However this is called by the source filter, which is the same - person who is holding the samples. Therefore it is not unreasonable - for them to free all their samples before changing the requirements */ - - if (m_bCommitted) { - return VFW_E_ALREADY_COMMITTED; - } - - /* Must be no outstanding buffers */ - - if (m_lAllocated != m_lFree.GetCount()) { - return VFW_E_BUFFERS_OUTSTANDING; - } - - /* There isn't any real need to check the parameters as they - will just be rejected when the user finally calls Commit */ - - pActual->cbBuffer = m_lSize = pRequest->cbBuffer; - pActual->cBuffers = m_lCount = pRequest->cBuffers; - pActual->cbAlign = m_lAlignment = pRequest->cbAlign; - pActual->cbPrefix = m_lPrefix = pRequest->cbPrefix; - - m_bChanged = TRUE; - return NOERROR; -} - -STDMETHODIMP -CBaseAllocator::GetProperties( - ALLOCATOR_PROPERTIES * pActual) -{ - CheckPointer(pActual,E_POINTER); - ValidateReadWritePtr(pActual,sizeof(ALLOCATOR_PROPERTIES)); - - CAutoLock cObjectLock(this); - pActual->cbBuffer = m_lSize; - pActual->cBuffers = m_lCount; - pActual->cbAlign = m_lAlignment; - pActual->cbPrefix = m_lPrefix; - return NOERROR; -} - -// get container for a sample. Blocking, synchronous call to get the -// next free buffer (as represented by an IMediaSample interface). -// on return, the time etc properties will be invalid, but the buffer -// pointer and size will be correct. - -HRESULT CBaseAllocator::GetBuffer(IMediaSample **ppBuffer, - REFERENCE_TIME *pStartTime, - REFERENCE_TIME *pEndTime, - DWORD dwFlags - ) -{ - UNREFERENCED_PARAMETER(pStartTime); - UNREFERENCED_PARAMETER(pEndTime); - UNREFERENCED_PARAMETER(dwFlags); - CMediaSample *pSample; - - *ppBuffer = NULL; - for (;;) - { - { // scope for lock - CAutoLock cObjectLock(this); - - /* Check we are committed */ - if (!m_bCommitted) { - return VFW_E_NOT_COMMITTED; - } - pSample = (CMediaSample *) m_lFree.RemoveHead(); - if (pSample == NULL) { - SetWaiting(); - } - } - - /* If we didn't get a sample then wait for the list to signal */ - - if (pSample) { - break; - } - if (dwFlags & AM_GBF_NOWAIT) { - return VFW_E_TIMEOUT; - } - ASSERT(m_hSem != NULL); - WaitForSingleObject(m_hSem, INFINITE); - } - - /* Addref the buffer up to one. On release - back to zero instead of being deleted, it will requeue itself by - calling the ReleaseBuffer member function. NOTE the owner of a - media sample must always be derived from CBaseAllocator */ - - - ASSERT(pSample->m_cRef == 0); - pSample->m_cRef = 1; - *ppBuffer = pSample; - - - return NOERROR; -} - - -/* Final release of a CMediaSample will call this */ - -STDMETHODIMP -CBaseAllocator::ReleaseBuffer(IMediaSample * pSample) -{ - CheckPointer(pSample,E_POINTER); - ValidateReadPtr(pSample,sizeof(IMediaSample)); - - - - BOOL bRelease = FALSE; - { - CAutoLock cal(this); - - /* Put back on the free list */ - - m_lFree.Add((CMediaSample *)pSample); - if (m_lWaiting != 0) { - NotifySample(); - } - - // if there is a pending Decommit, then we need to complete it by - // calling Free() when the last buffer is placed on the free list - - LONG l1 = m_lFree.GetCount(); - if (m_bDecommitInProgress && (l1 == m_lAllocated)) { - Free(); - m_bDecommitInProgress = FALSE; - bRelease = TRUE; - } - } - - if (m_pNotify) { - - ASSERT(m_fEnableReleaseCallback); - - // - // Note that this is not synchronized with setting up a notification - // method. - // - m_pNotify->NotifyRelease(); - } - - /* For each buffer there is one AddRef, made in GetBuffer and released - here. This may cause the allocator and all samples to be deleted */ - - if (bRelease) { - Release(); - } - return NOERROR; -} - -STDMETHODIMP -CBaseAllocator::SetNotify( - IMemAllocatorNotifyCallbackTemp* pNotify - ) -{ - ASSERT(m_fEnableReleaseCallback); - CAutoLock lck(this); - if (pNotify) { - pNotify->AddRef(); - } - if (m_pNotify) { - m_pNotify->Release(); - } - m_pNotify = pNotify; - return S_OK; -} - -STDMETHODIMP -CBaseAllocator::GetFreeCount( - LONG* plBuffersFree - ) -{ - ASSERT(m_fEnableReleaseCallback); - CAutoLock cObjectLock(this); - *plBuffersFree = m_lCount - m_lAllocated + m_lFree.GetCount(); - return NOERROR; -} - -void -CBaseAllocator::NotifySample() -{ - if (m_lWaiting != 0) { - ASSERT(m_hSem != NULL); - ReleaseSemaphore(m_hSem, m_lWaiting, 0); - m_lWaiting = 0; - } -} - -STDMETHODIMP -CBaseAllocator::Commit() -{ - /* Check we are not decommitted */ - CAutoLock cObjectLock(this); - - // cannot need to alloc or re-alloc if we are committed - if (m_bCommitted) { - return NOERROR; - } - - /* Allow GetBuffer calls */ - - m_bCommitted = TRUE; - - // is there a pending decommit ? if so, just cancel it - if (m_bDecommitInProgress) { - m_bDecommitInProgress = FALSE; - - // don't call Alloc at this point. He cannot allow SetProperties - // between Decommit and the last free, so the buffer size cannot have - // changed. And because some of the buffers are not free yet, he - // cannot re-alloc anyway. - return NOERROR; - } - - DbgLog((LOG_MEMORY, 1, TEXT("Allocating: %ldx%ld"), m_lCount, m_lSize)); - - // actually need to allocate the samples - HRESULT hr = Alloc(); - if (FAILED(hr)) { - m_bCommitted = FALSE; - return hr; - } - AddRef(); - return NOERROR; -} - - -STDMETHODIMP -CBaseAllocator::Decommit() -{ - BOOL bRelease = FALSE; - { - /* Check we are not already decommitted */ - CAutoLock cObjectLock(this); - if (m_bCommitted == FALSE) { - if (m_bDecommitInProgress == FALSE) { - return NOERROR; - } - } - - /* No more GetBuffer calls will succeed */ - m_bCommitted = FALSE; - - // are any buffers outstanding? - if (m_lFree.GetCount() < m_lAllocated) { - // please complete the decommit when last buffer is freed - m_bDecommitInProgress = TRUE; - } else { - m_bDecommitInProgress = FALSE; - - // need to complete the decommit here as there are no - // outstanding buffers - - Free(); - bRelease = TRUE; - } - - // Tell anyone waiting that they can go now so we can - // reject their call - NotifySample(); - } - - if (bRelease) { - Release(); - } - return NOERROR; -} - - -/* Base definition of allocation which checks we are ok to go ahead and do - the full allocation. We return S_FALSE if the requirements are the same */ - -HRESULT -CBaseAllocator::Alloc(void) -{ - /* Error if he hasn't set the size yet */ - if (m_lCount <= 0 || m_lSize <= 0 || m_lAlignment <= 0) { - return VFW_E_SIZENOTSET; - } - - /* should never get here while buffers outstanding */ - ASSERT(m_lFree.GetCount() == m_lAllocated); - - /* If the requirements haven't changed then don't reallocate */ - if (m_bChanged == FALSE) { - return S_FALSE; - } - - return NOERROR; -} - -/* Implement CBaseAllocator::CSampleList::Remove(pSample) - Removes pSample from the list -*/ -void -CBaseAllocator::CSampleList::Remove(CMediaSample * pSample) -{ - CMediaSample **pSearch; - for (pSearch = &m_List; - *pSearch != NULL; - pSearch = &(CBaseAllocator::NextSample(*pSearch))) { - if (*pSearch == pSample) { - *pSearch = CBaseAllocator::NextSample(pSample); - CBaseAllocator::NextSample(pSample) = NULL; - m_nOnList--; - return; - } - } - DbgBreak("Couldn't find sample in list"); -} - -//===================================================================== -//===================================================================== -// Implements CMemAllocator -//===================================================================== -//===================================================================== - - -/* This goes in the factory template table to create new instances */ -CUnknown *CMemAllocator::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) -{ - CUnknown *pUnkRet = new CMemAllocator(NAME("CMemAllocator"), pUnk, phr); - return pUnkRet; -} - -CMemAllocator::CMemAllocator( - TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr) - : CBaseAllocator(pName, pUnk, phr, TRUE, TRUE), - m_pBuffer(NULL) -{ -} - -#ifdef UNICODE -CMemAllocator::CMemAllocator( - CHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr) - : CBaseAllocator(pName, pUnk, phr, TRUE, TRUE), - m_pBuffer(NULL) -{ -} -#endif - -/* This sets the size and count of the required samples. The memory isn't - actually allocated until Commit() is called, if memory has already been - allocated then assuming no samples are outstanding the user may call us - to change the buffering, the memory will be released in Commit() */ -STDMETHODIMP -CMemAllocator::SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual) -{ - CheckPointer(pActual,E_POINTER); - ValidateReadWritePtr(pActual,sizeof(ALLOCATOR_PROPERTIES)); - CAutoLock cObjectLock(this); - - ZeroMemory(pActual, sizeof(ALLOCATOR_PROPERTIES)); - - ASSERT(pRequest->cbBuffer > 0); - - SYSTEM_INFO SysInfo; - GetSystemInfo(&SysInfo); - - /* Check the alignment request is a power of 2 */ - if ((-pRequest->cbAlign & pRequest->cbAlign) != pRequest->cbAlign) { - DbgLog((LOG_ERROR, 1, TEXT("Alignment requested 0x%x not a power of 2!"), - pRequest->cbAlign)); - } - /* Check the alignment requested */ - if (pRequest->cbAlign == 0 || - (SysInfo.dwAllocationGranularity & (pRequest->cbAlign - 1)) != 0) { - DbgLog((LOG_ERROR, 1, TEXT("Invalid alignment 0x%x requested - granularity = 0x%x"), - pRequest->cbAlign, SysInfo.dwAllocationGranularity)); - return VFW_E_BADALIGN; - } - - /* Can't do this if already committed, there is an argument that says we - should not reject the SetProperties call if there are buffers still - active. However this is called by the source filter, which is the same - person who is holding the samples. Therefore it is not unreasonable - for them to free all their samples before changing the requirements */ - - if (m_bCommitted == TRUE) { - return VFW_E_ALREADY_COMMITTED; - } - - /* Must be no outstanding buffers */ - - if (m_lFree.GetCount() < m_lAllocated) { - return VFW_E_BUFFERS_OUTSTANDING; - } - - /* There isn't any real need to check the parameters as they - will just be rejected when the user finally calls Commit */ - - // round length up to alignment - remember that prefix is included in - // the alignment - LONG lSize = pRequest->cbBuffer + pRequest->cbPrefix; - LONG lRemainder = lSize % pRequest->cbAlign; - if (lRemainder != 0) { - lSize = lSize - lRemainder + pRequest->cbAlign; - } - pActual->cbBuffer = m_lSize = (lSize - pRequest->cbPrefix); - - pActual->cBuffers = m_lCount = pRequest->cBuffers; - pActual->cbAlign = m_lAlignment = pRequest->cbAlign; - pActual->cbPrefix = m_lPrefix = pRequest->cbPrefix; - - m_bChanged = TRUE; - return NOERROR; -} - -// override this to allocate our resources when Commit is called. -// -// note that our resources may be already allocated when this is called, -// since we don't free them on Decommit. We will only be called when in -// decommit state with all buffers free. -// -// object locked by caller -HRESULT -CMemAllocator::Alloc(void) -{ - CAutoLock lck(this); - - /* Check he has called SetProperties */ - HRESULT hr = CBaseAllocator::Alloc(); - if (FAILED(hr)) { - return hr; - } - - /* If the requirements haven't changed then don't reallocate */ - if (hr == S_FALSE) { - ASSERT(m_pBuffer); - return NOERROR; - } - ASSERT(hr == S_OK); // we use this fact in the loop below - - /* Free the old resources */ - if (m_pBuffer) { - ReallyFree(); - } - - /* Compute the aligned size */ - LONG lAlignedSize = m_lSize + m_lPrefix; - if (m_lAlignment > 1) { - LONG lRemainder = lAlignedSize % m_lAlignment; - if (lRemainder != 0) { - lAlignedSize += (m_lAlignment - lRemainder); - } - } - - /* Create the contiguous memory block for the samples - making sure it's properly aligned (64K should be enough!) - */ - ASSERT(lAlignedSize % m_lAlignment == 0); - - m_pBuffer = (PBYTE)VirtualAlloc(NULL, - m_lCount * lAlignedSize, - MEM_COMMIT, - PAGE_READWRITE); - - if (m_pBuffer == NULL) { - return E_OUTOFMEMORY; - } - - LPBYTE pNext = m_pBuffer; - CMediaSample *pSample; - - ASSERT(m_lAllocated == 0); - - // Create the new samples - we have allocated m_lSize bytes for each sample - // plus m_lPrefix bytes per sample as a prefix. We set the pointer to - // the memory after the prefix - so that GetPointer() will return a pointer - // to m_lSize bytes. - for (; m_lAllocated < m_lCount; m_lAllocated++, pNext += lAlignedSize) { - - - pSample = new CMediaSample( - NAME("Default memory media sample"), - this, - &hr, - pNext + m_lPrefix, // GetPointer() value - m_lSize); // not including prefix - - ASSERT(SUCCEEDED(hr)); - if (pSample == NULL) { - return E_OUTOFMEMORY; - } - - // This CANNOT fail - m_lFree.Add(pSample); - } - - m_bChanged = FALSE; - return NOERROR; -} - - -// override this to free up any resources we have allocated. -// called from the base class on Decommit when all buffers have been -// returned to the free list. -// -// caller has already locked the object. - -// in our case, we keep the memory until we are deleted, so -// we do nothing here. The memory is deleted in the destructor by -// calling ReallyFree() -void -CMemAllocator::Free(void) -{ - return; -} - - -// called from the destructor (and from Alloc if changing size/count) to -// actually free up the memory -void -CMemAllocator::ReallyFree(void) -{ - /* Should never be deleting this unless all buffers are freed */ - - ASSERT(m_lAllocated == m_lFree.GetCount()); - - /* Free up all the CMediaSamples */ - - CMediaSample *pSample; - for (;;) { - pSample = m_lFree.RemoveHead(); - if (pSample != NULL) { - delete pSample; - } else { - break; - } - } - - m_lAllocated = 0; - - // free the block of buffer memory - if (m_pBuffer) { - EXECUTE_ASSERT(VirtualFree(m_pBuffer, 0, MEM_RELEASE)); - m_pBuffer = NULL; - } -} - - -/* Destructor frees our memory resources */ - -CMemAllocator::~CMemAllocator() -{ - Decommit(); - ReallyFree(); -} - -// ------------------------------------------------------------------------ -// filter registration through IFilterMapper. used if IFilterMapper is -// not found (Quartz 1.0 install) - -STDAPI -AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper * pIFM - , BOOL bRegister ) -{ - DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter"))); - - // check we've got data - // - if( NULL == psetupdata ) return S_FALSE; - - - // unregister filter - // (as pins are subkeys of filter's CLSID key - // they do not need to be removed separately). - // - DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter"))); - HRESULT hr = pIFM->UnregisterFilter( *(psetupdata->clsID) ); - - - if( bRegister ) - { - // register filter - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter"))); - hr = pIFM->RegisterFilter( *(psetupdata->clsID) - , psetupdata->strName - , psetupdata->dwMerit ); - if( SUCCEEDED(hr) ) - { - // all its pins - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter pins"))); - for( UINT m1=0; m1 < psetupdata->nPins; m1++ ) - { - hr = pIFM->RegisterPin( *(psetupdata->clsID) - , psetupdata->lpPin[m1].strName - , psetupdata->lpPin[m1].bRendered - , psetupdata->lpPin[m1].bOutput - , psetupdata->lpPin[m1].bZero - , psetupdata->lpPin[m1].bMany - , *(psetupdata->lpPin[m1].clsConnectsToFilter) - , psetupdata->lpPin[m1].strConnectsToPin ); - - if( SUCCEEDED(hr) ) - { - // and each pin's media types - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter pin types"))); - for( UINT m2=0; m2 < psetupdata->lpPin[m1].nMediaTypes; m2++ ) - { - hr = pIFM->RegisterPinType( *(psetupdata->clsID) - , psetupdata->lpPin[m1].strName - , *(psetupdata->lpPin[m1].lpMediaType[m2].clsMajorType) - , *(psetupdata->lpPin[m1].lpMediaType[m2].clsMinorType) ); - if( FAILED(hr) ) break; - } - if( FAILED(hr) ) break; - } - if( FAILED(hr) ) break; - } - } - } - - // handle one acceptable "error" - that - // of filter not being registered! - // (couldn't find a suitable #define'd - // name for the error!) - // - if( 0x80070002 == hr) - return NOERROR; - else - return hr; -} - -// Remove warnings about unreferenced inline functions -#pragma warning(disable:4514) - diff --git a/plugins/gs/gsdx9/baseclasses/amfilter.h b/plugins/gs/gsdx9/baseclasses/amfilter.h deleted file mode 100644 index 47ffc0a5f0..0000000000 --- a/plugins/gs/gsdx9/baseclasses/amfilter.h +++ /dev/null @@ -1,1587 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMFilter.h -// -// Desc: DirectShow base classes - efines class hierarchy for streams -// architecture. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __FILTER__ -#define __FILTER__ - -/* The following classes are declared in this header: */ - -class CBaseMediaFilter; // IMediaFilter support -class CBaseFilter; // IBaseFilter,IMediaFilter support -class CBasePin; // Abstract base class for IPin interface -class CEnumPins; // Enumerate input and output pins -class CEnumMediaTypes; // Enumerate the pin's preferred formats -class CBaseOutputPin; // Adds data provider member functions -class CBaseInputPin; // Implements IMemInputPin interface -class CMediaSample; // Basic transport unit for IMemInputPin -class CBaseAllocator; // General list guff for most allocators -class CMemAllocator; // Implements memory buffer allocation - - -//===================================================================== -//===================================================================== -// -// QueryFilterInfo and QueryPinInfo AddRef the interface pointers -// they return. You can use the macro below to release the interface. -// -//===================================================================== -//===================================================================== - -#define QueryFilterInfoReleaseGraph(fi) if ((fi).pGraph) (fi).pGraph->Release(); - -#define QueryPinInfoReleaseFilter(pi) if ((pi).pFilter) (pi).pFilter->Release(); - -//===================================================================== -//===================================================================== -// Defines CBaseMediaFilter -// -// Abstract base class implementing IMediaFilter. -// -// Typically you will derive your filter from CBaseFilter rather than -// this, unless you are implementing an object such as a plug-in -// distributor that needs to support IMediaFilter but not IBaseFilter. -// -// Note that IMediaFilter is derived from IPersist to allow query of -// class id. -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseMediaFilter : public CUnknown, - public IMediaFilter -{ - -protected: - - FILTER_STATE m_State; // current state: running, paused - IReferenceClock *m_pClock; // this filter's reference clock - // note: all filters in a filter graph use the same clock - - // offset from stream time to reference time - CRefTime m_tStart; - - CLSID m_clsid; // This filters clsid - // used for serialization - CCritSec *m_pLock; // Object we use for locking - -public: - - CBaseMediaFilter( - const TCHAR *pName, - LPUNKNOWN pUnk, - CCritSec *pLock, - REFCLSID clsid); - - virtual ~CBaseMediaFilter(); - - DECLARE_IUNKNOWN - - // override this to say what interfaces we support where - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); - - // - // --- IPersist method --- - // - - STDMETHODIMP GetClassID(CLSID *pClsID); - - // --- IMediaFilter methods --- - - STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State); - - STDMETHODIMP SetSyncSource(IReferenceClock *pClock); - - STDMETHODIMP GetSyncSource(IReferenceClock **pClock); - - // default implementation of Stop and Pause just record the - // state. Override to activate or de-activate your filter. - // Note that Run when called from Stopped state will call Pause - // to ensure activation, so if you are a source or transform - // you will probably not need to override Run. - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - - - // the start parameter is the difference to be added to the - // sample's stream time to get the reference time for - // its presentation - STDMETHODIMP Run(REFERENCE_TIME tStart); - - // --- helper methods --- - - // return the current stream time - ie find out what - // stream time should be appearing now - virtual HRESULT StreamTime(CRefTime& rtStream); - - // Is the filter currently active? (running or paused) - BOOL IsActive() { - CAutoLock cObjectLock(m_pLock); - return ((m_State == State_Paused) || (m_State == State_Running)); - }; -}; - -//===================================================================== -//===================================================================== -// Defines CBaseFilter -// -// An abstract class providing basic IBaseFilter support for pin -// enumeration and filter information reading. -// -// We cannot derive from CBaseMediaFilter since methods in IMediaFilter -// are also in IBaseFilter and would be ambiguous. Since much of the code -// assumes that they derive from a class that has m_State and other state -// directly available, we duplicate code from CBaseMediaFilter rather than -// having a member variable. -// -// Derive your filter from this, or from a derived object such as -// CTransformFilter. -//===================================================================== -//===================================================================== - - -class AM_NOVTABLE CBaseFilter : public CUnknown, // Handles an IUnknown - public IBaseFilter, // The Filter Interface - public IAMovieSetup // For un/registration -{ - -friend class CBasePin; - -protected: - FILTER_STATE m_State; // current state: running, paused - IReferenceClock *m_pClock; // this graph's ref clock - CRefTime m_tStart; // offset from stream time to reference time - CLSID m_clsid; // This filters clsid - // used for serialization - CCritSec *m_pLock; // Object we use for locking - - WCHAR *m_pName; // Full filter name - IFilterGraph *m_pGraph; // Graph we belong to - IMediaEventSink *m_pSink; // Called with notify events - LONG m_PinVersion; // Current pin version - -public: - - CBaseFilter( - const TCHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid); // The clsid to be used to serialize this filter - - CBaseFilter( - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid, // The clsid to be used to serialize this filter - HRESULT *phr); // General OLE return code -#ifdef UNICODE - CBaseFilter( - const CHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid); // The clsid to be used to serialize this filter - - CBaseFilter( - CHAR *pName, // Object description - LPUNKNOWN pUnk, // IUnknown of delegating object - CCritSec *pLock, // Object who maintains lock - REFCLSID clsid, // The clsid to be used to serialize this filter - HRESULT *phr); // General OLE return code -#endif - ~CBaseFilter(); - - DECLARE_IUNKNOWN - - // override this to say what interfaces we support where - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); -#ifdef DEBUG - STDMETHODIMP_(ULONG) NonDelegatingRelease(); -#endif - - // - // --- IPersist method --- - // - - STDMETHODIMP GetClassID(CLSID *pClsID); - - // --- IMediaFilter methods --- - - STDMETHODIMP GetState(DWORD dwMSecs, FILTER_STATE *State); - - STDMETHODIMP SetSyncSource(IReferenceClock *pClock); - - STDMETHODIMP GetSyncSource(IReferenceClock **pClock); - - - // override Stop and Pause so we can activate the pins. - // Note that Run will call Pause first if activation needed. - // Override these if you want to activate your filter rather than - // your pins. - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - - // the start parameter is the difference to be added to the - // sample's stream time to get the reference time for - // its presentation - STDMETHODIMP Run(REFERENCE_TIME tStart); - - // --- helper methods --- - - // return the current stream time - ie find out what - // stream time should be appearing now - virtual HRESULT StreamTime(CRefTime& rtStream); - - // Is the filter currently active? - BOOL IsActive() { - CAutoLock cObjectLock(m_pLock); - return ((m_State == State_Paused) || (m_State == State_Running)); - }; - - // Is this filter stopped (without locking) - BOOL IsStopped() { - return (m_State == State_Stopped); - }; - - // - // --- IBaseFilter methods --- - // - - // pin enumerator - STDMETHODIMP EnumPins( - IEnumPins ** ppEnum); - - - // default behaviour of FindPin assumes pin ids are their names - STDMETHODIMP FindPin( - LPCWSTR Id, - IPin ** ppPin - ); - - STDMETHODIMP QueryFilterInfo( - FILTER_INFO * pInfo); - - STDMETHODIMP JoinFilterGraph( - IFilterGraph * pGraph, - LPCWSTR pName); - - // return a Vendor information string. Optional - may return E_NOTIMPL. - // memory returned should be freed using CoTaskMemFree - // default implementation returns E_NOTIMPL - STDMETHODIMP QueryVendorInfo( - LPWSTR* pVendorInfo - ); - - // --- helper methods --- - - // send an event notification to the filter graph if we know about it. - // returns S_OK if delivered, S_FALSE if the filter graph does not sink - // events, or an error otherwise. - HRESULT NotifyEvent( - long EventCode, - LONG_PTR EventParam1, - LONG_PTR EventParam2); - - // return the filter graph we belong to - IFilterGraph *GetFilterGraph() { - return m_pGraph; - } - - // Request reconnect - // pPin is the pin to reconnect - // pmt is the type to reconnect with - can be NULL - // Calls ReconnectEx on the filter graph - HRESULT ReconnectPin(IPin *pPin, AM_MEDIA_TYPE const *pmt); - - // find out the current pin version (used by enumerators) - virtual LONG GetPinVersion(); - void IncrementPinVersion(); - - // you need to supply these to access the pins from the enumerator - // and for default Stop and Pause/Run activation. - virtual int GetPinCount() PURE; - virtual CBasePin *GetPin(int n) PURE; - - // --- IAMovieSetup methods --- - - STDMETHODIMP Register(); // ask filter to register itself - STDMETHODIMP Unregister(); // and unregister itself - - // --- setup helper methods --- - // (override to return filters setup data) - - virtual LPAMOVIESETUP_FILTER GetSetupData(){ return NULL; } - -}; - - -//===================================================================== -//===================================================================== -// Defines CBasePin -// -// Abstract class that supports the basics of IPin -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBasePin : public CUnknown, public IPin, public IQualityControl -{ - -protected: - - WCHAR * m_pName; // This pin's name - IPin *m_Connected; // Pin we have connected to - PIN_DIRECTION m_dir; // Direction of this pin - CCritSec *m_pLock; // Object we use for locking - bool m_bRunTimeError; // Run time error generated - bool m_bCanReconnectWhenActive; // OK to reconnect when active - bool m_bTryMyTypesFirst; // When connecting enumerate - // this pin's types first - CBaseFilter *m_pFilter; // Filter we were created by - IQualityControl *m_pQSink; // Target for Quality messages - LONG m_TypeVersion; // Holds current type version - CMediaType m_mt; // Media type of connection - - CRefTime m_tStart; // time from NewSegment call - CRefTime m_tStop; // time from NewSegment - double m_dRate; // rate from NewSegment - -#ifdef DEBUG - LONG m_cRef; // Ref count tracing -#endif - - // displays pin connection information - -#ifdef DEBUG - void DisplayPinInfo(IPin *pReceivePin); - void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt); -#else - void DisplayPinInfo(IPin *pReceivePin) {}; - void DisplayTypeInfo(IPin *pPin, const CMediaType *pmt) {}; -#endif - - // used to agree a media type for a pin connection - - // given a specific media type, attempt a connection (includes - // checking that the type is acceptable to this pin) - HRESULT - AttemptConnection( - IPin* pReceivePin, // connect to this pin - const CMediaType* pmt // using this type - ); - - // try all the media types in this enumerator - for each that - // we accept, try to connect using ReceiveConnection. - HRESULT TryMediaTypes( - IPin *pReceivePin, // connect to this pin - const CMediaType *pmt, // proposed type from Connect - IEnumMediaTypes *pEnum); // try this enumerator - - // establish a connection with a suitable mediatype. Needs to - // propose a media type if the pmt pointer is null or partially - // specified - use TryMediaTypes on both our and then the other pin's - // enumerator until we find one that works. - HRESULT AgreeMediaType( - IPin *pReceivePin, // connect to this pin - const CMediaType *pmt); // proposed type from Connect - -public: - - CBasePin( - TCHAR *pObjectName, // Object description - CBaseFilter *pFilter, // Owning filter who knows about pins - CCritSec *pLock, // Object who implements the lock - HRESULT *phr, // General OLE return code - LPCWSTR pName, // Pin name for us - PIN_DIRECTION dir); // Either PINDIR_INPUT or PINDIR_OUTPUT -#ifdef UNICODE - CBasePin( - CHAR *pObjectName, // Object description - CBaseFilter *pFilter, // Owning filter who knows about pins - CCritSec *pLock, // Object who implements the lock - HRESULT *phr, // General OLE return code - LPCWSTR pName, // Pin name for us - PIN_DIRECTION dir); // Either PINDIR_INPUT or PINDIR_OUTPUT -#endif - virtual ~CBasePin(); - - DECLARE_IUNKNOWN - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - - // --- IPin methods --- - - // take lead role in establishing a connection. Media type pointer - // may be null, or may point to partially-specified mediatype - // (subtype or format type may be GUID_NULL). - STDMETHODIMP Connect( - IPin * pReceivePin, - const AM_MEDIA_TYPE *pmt // optional media type - ); - - // (passive) accept a connection from another pin - STDMETHODIMP ReceiveConnection( - IPin * pConnector, // this is the initiating connecting pin - const AM_MEDIA_TYPE *pmt // this is the media type we will exchange - ); - - STDMETHODIMP Disconnect(); - - STDMETHODIMP ConnectedTo(IPin **pPin); - - STDMETHODIMP ConnectionMediaType(AM_MEDIA_TYPE *pmt); - - STDMETHODIMP QueryPinInfo( - PIN_INFO * pInfo - ); - - STDMETHODIMP QueryDirection( - PIN_DIRECTION * pPinDir - ); - - STDMETHODIMP QueryId( - LPWSTR * Id - ); - - // does the pin support this media type - STDMETHODIMP QueryAccept( - const AM_MEDIA_TYPE *pmt - ); - - // return an enumerator for this pins preferred media types - STDMETHODIMP EnumMediaTypes( - IEnumMediaTypes **ppEnum - ); - - // return an array of IPin* - the pins that this pin internally connects to - // All pins put in the array must be AddReffed (but no others) - // Errors: "Can't say" - FAIL, not enough slots - return S_FALSE - // Default: return E_NOTIMPL - // The filter graph will interpret NOT_IMPL as any input pin connects to - // all visible output pins and vice versa. - // apPin can be NULL if nPin==0 (not otherwise). - STDMETHODIMP QueryInternalConnections( - IPin* *apPin, // array of IPin* - ULONG *nPin // on input, the number of slots - // on output the number of pins - ) { return E_NOTIMPL; } - - // Called when no more data will be sent - STDMETHODIMP EndOfStream(void); - - // Begin/EndFlush still PURE - - // NewSegment notifies of the start/stop/rate applying to the data - // about to be received. Default implementation records data and - // returns S_OK. - // Override this to pass downstream. - STDMETHODIMP NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - //================================================================================ - // IQualityControl methods - //================================================================================ - - STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - - STDMETHODIMP SetSink(IQualityControl * piqc); - - // --- helper methods --- - - // Returns true if the pin is connected. false otherwise. - BOOL IsConnected(void) {return (m_Connected != NULL); }; - // Return the pin this is connected to (if any) - IPin * GetConnected() { return m_Connected; }; - - // Check if our filter is currently stopped - BOOL IsStopped() { - return (m_pFilter->m_State == State_Stopped); - }; - - // find out the current type version (used by enumerators) - virtual LONG GetMediaTypeVersion(); - void IncrementTypeVersion(); - - // switch the pin to active (paused or running) mode - // not an error to call this if already active - virtual HRESULT Active(void); - - // switch the pin to inactive state - may already be inactive - virtual HRESULT Inactive(void); - - // Notify of Run() from filter - virtual HRESULT Run(REFERENCE_TIME tStart); - - // check if the pin can support this specific proposed type and format - virtual HRESULT CheckMediaType(const CMediaType *) PURE; - - // set the connection to use this format (previously agreed) - virtual HRESULT SetMediaType(const CMediaType *); - - // check that the connection is ok before verifying it - // can be overridden eg to check what interfaces will be supported. - virtual HRESULT CheckConnect(IPin *); - - // Set and release resources required for a connection - virtual HRESULT BreakConnect(); - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - // returns the preferred formats for a pin - virtual HRESULT GetMediaType(int iPosition,CMediaType *pMediaType); - - // access to NewSegment values - REFERENCE_TIME CurrentStopTime() { - return m_tStop; - } - REFERENCE_TIME CurrentStartTime() { - return m_tStart; - } - double CurrentRate() { - return m_dRate; - } - - // Access name - LPWSTR Name() { return m_pName; }; - - // Can reconnectwhen active? - void SetReconnectWhenActive(bool bCanReconnect) - { - m_bCanReconnectWhenActive = bCanReconnect; - } - - bool CanReconnectWhenActive() - { - return m_bCanReconnectWhenActive; - } - -protected: - STDMETHODIMP DisconnectInternal(); -}; - - -//===================================================================== -//===================================================================== -// Defines CEnumPins -// -// Pin enumerator class that works by calling CBaseFilter. This interface -// is provided by CBaseFilter::EnumPins and calls GetPinCount() and -// GetPin() to enumerate existing pins. Needs to be a separate object so -// that it can be cloned (creating an existing object at the same -// position in the enumeration) -// -//===================================================================== -//===================================================================== - -class CEnumPins : public IEnumPins // The interface we support -{ - int m_Position; // Current ordinal position - int m_PinCount; // Number of pins available - CBaseFilter *m_pFilter; // The filter who owns us - LONG m_Version; // Pin version information - LONG m_cRef; - - typedef CGenericList CPinList; - - CPinList m_PinCache; // These pointers have not been AddRef'ed and - // so they should not be dereferenced. They are - // merely kept to ID which pins have been enumerated. - -#ifdef DEBUG - DWORD m_dwCookie; -#endif - - /* If while we are retrieving a pin for example from the filter an error - occurs we assume that our internal state is stale with respect to the - filter (someone may have deleted all the pins). We can check before - starting whether or not the operation is likely to fail by asking the - filter what it's current version number is. If the filter has not - overriden the GetPinVersion method then this will always match */ - - BOOL AreWeOutOfSync() { - return (m_pFilter->GetPinVersion() == m_Version ? FALSE : TRUE); - }; - - /* This method performs the same operations as Reset, except is does not clear - the cache of pins already enumerated. */ - - STDMETHODIMP Refresh(); - -public: - - CEnumPins( - CBaseFilter *pFilter, - CEnumPins *pEnumPins); - - virtual ~CEnumPins(); - - // IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void **ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // IEnumPins - STDMETHODIMP Next( - ULONG cPins, // place this many pins... - IPin ** ppPins, // ...in this array of IPin* - ULONG * pcFetched // actual count passed returned here - ); - - STDMETHODIMP Skip(ULONG cPins); - STDMETHODIMP Reset(); - STDMETHODIMP Clone(IEnumPins **ppEnum); - - -}; - - -//===================================================================== -//===================================================================== -// Defines CEnumMediaTypes -// -// Enumerates the preferred formats for input and output pins -//===================================================================== -//===================================================================== - -class CEnumMediaTypes : public IEnumMediaTypes // The interface we support -{ - int m_Position; // Current ordinal position - CBasePin *m_pPin; // The pin who owns us - LONG m_Version; // Media type version value - LONG m_cRef; -#ifdef DEBUG - DWORD m_dwCookie; -#endif - - /* The media types a filter supports can be quite dynamic so we add to - the general IEnumXXXX interface the ability to be signaled when they - change via an event handle the connected filter supplies. Until the - Reset method is called after the state changes all further calls to - the enumerator (except Reset) will return E_UNEXPECTED error code */ - - BOOL AreWeOutOfSync() { - return (m_pPin->GetMediaTypeVersion() == m_Version ? FALSE : TRUE); - }; - -public: - - CEnumMediaTypes( - CBasePin *pPin, - CEnumMediaTypes *pEnumMediaTypes); - - virtual ~CEnumMediaTypes(); - - // IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void **ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // IEnumMediaTypes - STDMETHODIMP Next( - ULONG cMediaTypes, // place this many pins... - AM_MEDIA_TYPE ** ppMediaTypes, // ...in this array - ULONG * pcFetched // actual count passed - ); - - STDMETHODIMP Skip(ULONG cMediaTypes); - STDMETHODIMP Reset(); - STDMETHODIMP Clone(IEnumMediaTypes **ppEnum); -}; - - - - -//===================================================================== -//===================================================================== -// Defines CBaseOutputPin -// -// class derived from CBasePin that can pass buffers to a connected pin -// that supports IMemInputPin. Supports IPin. -// -// Derive your output pin from this. -// -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseOutputPin : public CBasePin -{ - -protected: - - IMemAllocator *m_pAllocator; - IMemInputPin *m_pInputPin; // interface on the downstreaminput pin - // set up in CheckConnect when we connect. - -public: - - CBaseOutputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#ifdef UNICODE - CBaseOutputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - // override CompleteConnect() so we can negotiate an allocator - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - // negotiate the allocator and its buffer size/count and other properties - // Calls DecideBufferSize to set properties - virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc); - - // override this to set the buffer size and count. Return an error - // if the size/count is not to your liking. - // The allocator properties passed in are those requested by the - // input pin - use eg the alignment and prefix members if you have - // no preference on these. - virtual HRESULT DecideBufferSize( - IMemAllocator * pAlloc, - ALLOCATOR_PROPERTIES * ppropInputRequest - ) PURE; - - // returns an empty sample buffer from the allocator - virtual HRESULT GetDeliveryBuffer(IMediaSample ** ppSample, - REFERENCE_TIME * pStartTime, - REFERENCE_TIME * pEndTime, - DWORD dwFlags); - - // deliver a filled-in sample to the connected input pin - // note - you need to release it after calling this. The receiving - // pin will addref the sample if it needs to hold it beyond the - // call. - virtual HRESULT Deliver(IMediaSample *); - - // override this to control the connection - virtual HRESULT InitAllocator(IMemAllocator **ppAlloc); - HRESULT CheckConnect(IPin *pPin); - HRESULT BreakConnect(); - - // override to call Commit and Decommit - HRESULT Active(void); - HRESULT Inactive(void); - - // we have a default handling of EndOfStream which is to return - // an error, since this should be called on input pins only - STDMETHODIMP EndOfStream(void); - - // called from elsewhere in our filter to pass EOS downstream to - // our connected input pin - virtual HRESULT DeliverEndOfStream(void); - - // same for Begin/EndFlush - we handle Begin/EndFlush since it - // is an error on an output pin, and we have Deliver methods to - // call the methods on the connected pin - STDMETHODIMP BeginFlush(void); - STDMETHODIMP EndFlush(void); - virtual HRESULT DeliverBeginFlush(void); - virtual HRESULT DeliverEndFlush(void); - - // deliver NewSegment to connected pin - you will need to - // override this if you queue any data in your output pin. - virtual HRESULT DeliverNewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - //================================================================================ - // IQualityControl methods - //================================================================================ - - // All inherited from CBasePin and not overridden here. - // STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - // STDMETHODIMP SetSink(IQualityControl * piqc); -}; - - -//===================================================================== -//===================================================================== -// Defines CBaseInputPin -// -// derive your standard input pin from this. -// you need to supply GetMediaType and CheckConnect etc (see CBasePin), -// and you need to supply Receive to do something more useful. -// -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseInputPin : public CBasePin, - public IMemInputPin -{ - -protected: - - IMemAllocator *m_pAllocator; // Default memory allocator - - // allocator is read-only, so received samples - // cannot be modified (probably only relevant to in-place - // transforms - BYTE m_bReadOnly; - - // in flushing state (between BeginFlush and EndFlush) - // if TRUE, all Receives are returned with S_FALSE - BYTE m_bFlushing; - - // Sample properties - initalized in Receive - AM_SAMPLE2_PROPERTIES m_SampleProps; - -public: - - CBaseInputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#ifdef UNICODE - CBaseInputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - virtual ~CBaseInputPin(); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // return the allocator interface that this input pin - // would like the output pin to use - STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator); - - // tell the input pin which allocator the output pin is actually - // going to use. - STDMETHODIMP NotifyAllocator( - IMemAllocator * pAllocator, - BOOL bReadOnly); - - // do something with this media sample - STDMETHODIMP Receive(IMediaSample *pSample); - - // do something with these media samples - STDMETHODIMP ReceiveMultiple ( - IMediaSample **pSamples, - long nSamples, - long *nSamplesProcessed); - - // See if Receive() blocks - STDMETHODIMP ReceiveCanBlock(); - - // Default handling for BeginFlush - call at the beginning - // of your implementation (makes sure that all Receive calls - // fail). After calling this, you need to free any queued data - // and then call downstream. - STDMETHODIMP BeginFlush(void); - - // default handling for EndFlush - call at end of your implementation - // - before calling this, ensure that there is no queued data and no thread - // pushing any more without a further receive, then call downstream, - // then call this method to clear the m_bFlushing flag and re-enable - // receives - STDMETHODIMP EndFlush(void); - - // this method is optional (can return E_NOTIMPL). - // default implementation returns E_NOTIMPL. Override if you have - // specific alignment or prefix needs, but could use an upstream - // allocator - STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES*pProps); - - // Release the pin's allocator. - HRESULT BreakConnect(); - - // helper method to check the read-only flag - BOOL IsReadOnly() { - return m_bReadOnly; - }; - - // helper method to see if we are flushing - BOOL IsFlushing() { - return m_bFlushing; - }; - - // Override this for checking whether it's OK to process samples - // Also call this from EndOfStream. - virtual HRESULT CheckStreaming(); - - // Pass a Quality notification on to the appropriate sink - HRESULT PassNotify(Quality& q); - - - //================================================================================ - // IQualityControl methods (from CBasePin) - //================================================================================ - - STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - - // no need to override: - // STDMETHODIMP SetSink(IQualityControl * piqc); - - - // switch the pin to inactive state - may already be inactive - virtual HRESULT Inactive(void); - - // Return sample properties pointer - AM_SAMPLE2_PROPERTIES * SampleProps() { - ASSERT(m_SampleProps.cbData != 0); - return &m_SampleProps; - } - -}; - -/////////////////////////////////////////////////////////////////////////// -// CDynamicOutputPin -// - -class CDynamicOutputPin : public CBaseOutputPin, - public IPinFlowControl -{ -public: -#ifdef UNICODE - CDynamicOutputPin( - CHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); -#endif - - CDynamicOutputPin( - TCHAR *pObjectName, - CBaseFilter *pFilter, - CCritSec *pLock, - HRESULT *phr, - LPCWSTR pName); - - ~CDynamicOutputPin(); - - // IUnknown Methods - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // IPin Methods - STDMETHODIMP Disconnect(void); - - // IPinFlowControl Methods - STDMETHODIMP Block(DWORD dwBlockFlags, HANDLE hEvent); - - // Set graph config info - void SetConfigInfo(IGraphConfig *pGraphConfig, HANDLE hStopEvent); - - #ifdef DEBUG - virtual HRESULT Deliver(IMediaSample *pSample); - virtual HRESULT DeliverEndOfStream(void); - virtual HRESULT DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate); - #endif // DEBUG - - HRESULT DeliverBeginFlush(void); - HRESULT DeliverEndFlush(void); - - HRESULT Inactive(void); - HRESULT Active(void); - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - virtual HRESULT StartUsingOutputPin(void); - virtual void StopUsingOutputPin(void); - virtual bool StreamingThreadUsingOutputPin(void); - - HRESULT ChangeOutputFormat - ( - const AM_MEDIA_TYPE *pmt, - REFERENCE_TIME tSegmentStart, - REFERENCE_TIME tSegmentStop, - double dSegmentRate - ); - HRESULT ChangeMediaType(const CMediaType *pmt); - HRESULT DynamicReconnect(const CMediaType *pmt); - -protected: - HRESULT SynchronousBlockOutputPin(void); - HRESULT AsynchronousBlockOutputPin(HANDLE hNotifyCallerPinBlockedEvent); - HRESULT UnblockOutputPin(void); - - void BlockOutputPin(void); - void ResetBlockState(void); - - static HRESULT WaitEvent(HANDLE hEvent); - - enum BLOCK_STATE - { - NOT_BLOCKED, - PENDING, - BLOCKED - }; - - // This lock should be held when the following class members are - // being used: m_hNotifyCallerPinBlockedEvent, m_BlockState, - // m_dwBlockCallerThreadID and m_dwNumOutstandingOutputPinUsers. - CCritSec m_BlockStateLock; - - // This event should be signaled when the output pin is - // not blocked. This is a manual reset event. For more - // information on events, see the documentation for - // CreateEvent() in the Windows SDK. - HANDLE m_hUnblockOutputPinEvent; - - // This event will be signaled when block operation succeedes or - // when the user cancels the block operation. The block operation - // can be canceled by calling IPinFlowControl2::Block( 0, NULL ) - // while the block operation is pending. - HANDLE m_hNotifyCallerPinBlockedEvent; - - // The state of the current block operation. - BLOCK_STATE m_BlockState; - - // The ID of the thread which last called IPinFlowControl::Block(). - // For more information on thread IDs, see the documentation for - // GetCurrentThreadID() in the Windows SDK. - DWORD m_dwBlockCallerThreadID; - - // The number of times StartUsingOutputPin() has been sucessfully - // called and a corresponding call to StopUsingOutputPin() has not - // been made. When this variable is greater than 0, the streaming - // thread is calling IPin::NewSegment(), IPin::EndOfStream(), - // IMemInputPin::Receive() or IMemInputPin::ReceiveMultiple(). The - // streaming thread could also be calling: DynamicReconnect(), - // ChangeMediaType() or ChangeOutputFormat(). The output pin cannot - // be blocked while the output pin is being used. - DWORD m_dwNumOutstandingOutputPinUsers; - - // This event should be set when the IMediaFilter::Stop() is called. - // This is a manual reset event. It is also set when the output pin - // delivers a flush to the connected input pin. - HANDLE m_hStopEvent; - IGraphConfig* m_pGraphConfig; - - // TRUE if the output pin's allocator's samples are read only. - // Otherwise FALSE. For more information, see the documentation - // for IMemInputPin::NotifyAllocator(). - BOOL m_bPinUsesReadOnlyAllocator; - -private: - HRESULT Initialize(void); - HRESULT ChangeMediaTypeHelper(const CMediaType *pmt); - - #ifdef DEBUG - void AssertValid(void); - #endif // DEBUG -}; - -class CAutoUsingOutputPin -{ -public: - CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr ); - ~CAutoUsingOutputPin(); - -private: - CDynamicOutputPin* m_pOutputPin; -}; - -inline CAutoUsingOutputPin::CAutoUsingOutputPin( CDynamicOutputPin* pOutputPin, HRESULT* phr ) : - m_pOutputPin(NULL) -{ - // The caller should always pass in valid pointers. - ASSERT( NULL != pOutputPin ); - ASSERT( NULL != phr ); - - // Make sure the user initialized phr. - ASSERT( S_OK == *phr ); - - HRESULT hr = pOutputPin->StartUsingOutputPin(); - if( FAILED( hr ) ) - { - *phr = hr; - return; - } - - m_pOutputPin = pOutputPin; -} - -inline CAutoUsingOutputPin::~CAutoUsingOutputPin() -{ - if( NULL != m_pOutputPin ) - { - m_pOutputPin->StopUsingOutputPin(); - } -} - -#ifdef DEBUG - -inline HRESULT CDynamicOutputPin::Deliver(IMediaSample *pSample) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - return CBaseOutputPin::Deliver(pSample); -} - -inline HRESULT CDynamicOutputPin::DeliverEndOfStream(void) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT( StreamingThreadUsingOutputPin() ); - - return CBaseOutputPin::DeliverEndOfStream(); -} - -inline HRESULT CDynamicOutputPin::DeliverNewSegment(REFERENCE_TIME tStart, REFERENCE_TIME tStop, double dRate) -{ - // The caller should call StartUsingOutputPin() before calling this - // method. - ASSERT(StreamingThreadUsingOutputPin()); - - return CBaseOutputPin::DeliverNewSegment(tStart, tStop, dRate); -} - -#endif // DEBUG - -//===================================================================== -//===================================================================== -// Memory allocators -// -// the shared memory transport between pins requires the input pin -// to provide a memory allocator that can provide sample objects. A -// sample object supports the IMediaSample interface. -// -// CBaseAllocator handles the management of free and busy samples. It -// allocates CMediaSample objects. CBaseAllocator is an abstract class: -// in particular it has no method of initializing the list of free -// samples. CMemAllocator is derived from CBaseAllocator and initializes -// the list of samples using memory from the standard IMalloc interface. -// -// If you want your buffers to live in some special area of memory, -// derive your allocator object from CBaseAllocator. If you derive your -// IMemInputPin interface object from CBaseMemInputPin, you will get -// CMemAllocator-based allocation etc for free and will just need to -// supply the Receive handling, and media type / format negotiation. -//===================================================================== -//===================================================================== - - -//===================================================================== -//===================================================================== -// Defines CMediaSample -// -// an object of this class supports IMediaSample and represents a buffer -// for media data with some associated properties. Releasing it returns -// it to a freelist managed by a CBaseAllocator derived object. -//===================================================================== -//===================================================================== - -class CMediaSample : public IMediaSample2 // The interface we support -{ - -protected: - - friend class CBaseAllocator; - - /* Values for dwFlags - these are used for backward compatiblity - only now - use AM_SAMPLE_xxx - */ - enum { Sample_SyncPoint = 0x01, /* Is this a sync point */ - Sample_Preroll = 0x02, /* Is this a preroll sample */ - Sample_Discontinuity = 0x04, /* Set if start of new segment */ - Sample_TypeChanged = 0x08, /* Has the type changed */ - Sample_TimeValid = 0x10, /* Set if time is valid */ - Sample_MediaTimeValid = 0x20, /* Is the media time valid */ - Sample_TimeDiscontinuity = 0x40, /* Time discontinuity */ - Sample_StopValid = 0x100, /* Stop time valid */ - Sample_ValidFlags = 0x1FF - }; - - /* Properties, the media sample class can be a container for a format - change in which case we take a copy of a type through the SetMediaType - interface function and then return it when GetMediaType is called. As - we do no internal processing on it we leave it as a pointer */ - - DWORD m_dwFlags; /* Flags for this sample */ - /* Type specific flags are packed - into the top word - */ - DWORD m_dwTypeSpecificFlags; /* Media type specific flags */ - LPBYTE m_pBuffer; /* Pointer to the complete buffer */ - LONG m_lActual; /* Length of data in this sample */ - LONG m_cbBuffer; /* Size of the buffer */ - CBaseAllocator *m_pAllocator; /* The allocator who owns us */ - CMediaSample *m_pNext; /* Chaining in free list */ - REFERENCE_TIME m_Start; /* Start sample time */ - REFERENCE_TIME m_End; /* End sample time */ - LONGLONG m_MediaStart; /* Real media start position */ - LONG m_MediaEnd; /* A difference to get the end */ - AM_MEDIA_TYPE *m_pMediaType; /* Media type change data */ - DWORD m_dwStreamId; /* Stream id */ -public: - LONG m_cRef; /* Reference count */ - - -public: - - CMediaSample( - TCHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer = NULL, - LONG length = 0); -#ifdef UNICODE - CMediaSample( - CHAR *pName, - CBaseAllocator *pAllocator, - HRESULT *phr, - LPBYTE pBuffer = NULL, - LONG length = 0); -#endif - - virtual ~CMediaSample(); - - /* Note the media sample does not delegate to its owner */ - - STDMETHODIMP QueryInterface(REFIID riid, void **ppv); - STDMETHODIMP_(ULONG) AddRef(); - STDMETHODIMP_(ULONG) Release(); - - // set the buffer pointer and length. Used by allocators that - // want variable sized pointers or pointers into already-read data. - // This is only available through a CMediaSample* not an IMediaSample* - // and so cannot be changed by clients. - HRESULT SetPointer(BYTE * ptr, LONG cBytes); - - // Get me a read/write pointer to this buffer's memory. - STDMETHODIMP GetPointer(BYTE ** ppBuffer); - - STDMETHODIMP_(LONG) GetSize(void); - - // get the stream time at which this sample should start and finish. - STDMETHODIMP GetTime( - REFERENCE_TIME * pTimeStart, // put time here - REFERENCE_TIME * pTimeEnd - ); - - // Set the stream time at which this sample should start and finish. - STDMETHODIMP SetTime( - REFERENCE_TIME * pTimeStart, // put time here - REFERENCE_TIME * pTimeEnd - ); - STDMETHODIMP IsSyncPoint(void); - STDMETHODIMP SetSyncPoint(BOOL bIsSyncPoint); - STDMETHODIMP IsPreroll(void); - STDMETHODIMP SetPreroll(BOOL bIsPreroll); - - STDMETHODIMP_(LONG) GetActualDataLength(void); - STDMETHODIMP SetActualDataLength(LONG lActual); - - // these allow for limited format changes in band - - STDMETHODIMP GetMediaType(AM_MEDIA_TYPE **ppMediaType); - STDMETHODIMP SetMediaType(AM_MEDIA_TYPE *pMediaType); - - // returns S_OK if there is a discontinuity in the data (this same is - // not a continuation of the previous stream of data - // - there has been a seek). - STDMETHODIMP IsDiscontinuity(void); - // set the discontinuity property - TRUE if this sample is not a - // continuation, but a new sample after a seek. - STDMETHODIMP SetDiscontinuity(BOOL bDiscontinuity); - - // get the media times for this sample - STDMETHODIMP GetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd - ); - - // Set the media times for this sample - STDMETHODIMP SetMediaTime( - LONGLONG * pTimeStart, - LONGLONG * pTimeEnd - ); - - // Set and get properties (IMediaSample2) - STDMETHODIMP GetProperties( - DWORD cbProperties, - BYTE * pbProperties - ); - - STDMETHODIMP SetProperties( - DWORD cbProperties, - const BYTE * pbProperties - ); -}; - - -//===================================================================== -//===================================================================== -// Defines CBaseAllocator -// -// Abstract base class that manages a list of media samples -// -// This class provides support for getting buffers from the free list, -// including handling of commit and (asynchronous) decommit. -// -// Derive from this class and override the Alloc and Free functions to -// allocate your CMediaSample (or derived) objects and add them to the -// free list, preparing them as necessary. -//===================================================================== -//===================================================================== - -class AM_NOVTABLE CBaseAllocator : public CUnknown,// A non delegating IUnknown - public IMemAllocatorCallbackTemp, // The interface we support - public CCritSec // Provides object locking -{ - class CSampleList; - friend class CSampleList; - - /* Trick to get at protected member in CMediaSample */ - static CMediaSample * &NextSample(CMediaSample *pSample) - { - return pSample->m_pNext; - }; - - /* Mini list class for the free list */ - class CSampleList - { - public: - CSampleList() : m_List(NULL), m_nOnList(0) {}; -#ifdef DEBUG - ~CSampleList() - { - ASSERT(m_nOnList == 0); - }; -#endif - CMediaSample *Head() const { return m_List; }; - CMediaSample *Next(CMediaSample *pSample) const { return CBaseAllocator::NextSample(pSample); }; - int GetCount() const { return m_nOnList; }; - void Add(CMediaSample *pSample) - { - ASSERT(pSample != NULL); - CBaseAllocator::NextSample(pSample) = m_List; - m_List = pSample; - m_nOnList++; - }; - CMediaSample *RemoveHead() - { - CMediaSample *pSample = m_List; - if (pSample != NULL) { - m_List = CBaseAllocator::NextSample(m_List); - m_nOnList--; - } - return pSample; - }; - void Remove(CMediaSample *pSample); - - public: - CMediaSample *m_List; - int m_nOnList; - }; -protected: - - CSampleList m_lFree; // Free list - - /* Note to overriders of CBaseAllocator. - - We use a lazy signalling mechanism for waiting for samples. - This means we don't call the OS if no waits occur. - - In order to implement this: - - 1. When a new sample is added to m_lFree call NotifySample() which - calls ReleaseSemaphore on m_hSem with a count of m_lWaiting and - sets m_lWaiting to 0. - This must all be done holding the allocator's critical section. - - 2. When waiting for a sample call SetWaiting() which increments - m_lWaiting BEFORE leaving the allocator's critical section. - - 3. Actually wait by calling WaitForSingleObject(m_hSem, INFINITE) - having left the allocator's critical section. The effect of - this is to remove 1 from the semaphore's count. You MUST call - this once having incremented m_lWaiting. - - The following are then true when the critical section is not held : - (let nWaiting = number about to wait or waiting) - - (1) if (m_lFree.GetCount() != 0) then (m_lWaiting == 0) - (2) m_lWaiting + Semaphore count == nWaiting - - We would deadlock if - nWaiting != 0 && - m_lFree.GetCount() != 0 && - Semaphore count == 0 - - But from (1) if m_lFree.GetCount() != 0 then m_lWaiting == 0 so - from (2) Semaphore count == nWaiting (which is non-0) so the - deadlock can't happen. - */ - - HANDLE m_hSem; // For signalling - long m_lWaiting; // Waiting for a free element - long m_lCount; // how many buffers we have agreed to provide - long m_lAllocated; // how many buffers are currently allocated - long m_lSize; // agreed size of each buffer - long m_lAlignment; // agreed alignment - long m_lPrefix; // agreed prefix (preceeds GetPointer() value) - BOOL m_bChanged; // Have the buffer requirements changed - - // if true, we are decommitted and can't allocate memory - BOOL m_bCommitted; - // if true, the decommit has happened, but we haven't called Free yet - // as there are still outstanding buffers - BOOL m_bDecommitInProgress; - - // Notification interface - IMemAllocatorNotifyCallbackTemp *m_pNotify; - - BOOL m_fEnableReleaseCallback; - - // called to decommit the memory when the last buffer is freed - // pure virtual - need to override this - virtual void Free(void) PURE; - - // override to allocate the memory when commit called - virtual HRESULT Alloc(void); - -public: - - CBaseAllocator( - TCHAR *, LPUNKNOWN, HRESULT *, - BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE); -#ifdef UNICODE - CBaseAllocator( - CHAR *, LPUNKNOWN, HRESULT *, - BOOL bEvent = TRUE, BOOL fEnableReleaseCallback = FALSE); -#endif - virtual ~CBaseAllocator(); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - STDMETHODIMP SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual); - - // return the properties actually being used on this allocator - STDMETHODIMP GetProperties( - ALLOCATOR_PROPERTIES* pProps); - - // override Commit to allocate memory. We handle the GetBuffer - //state changes - STDMETHODIMP Commit(); - - // override this to handle the memory freeing. We handle any outstanding - // GetBuffer calls - STDMETHODIMP Decommit(); - - // get container for a sample. Blocking, synchronous call to get the - // next free buffer (as represented by an IMediaSample interface). - // on return, the time etc properties will be invalid, but the buffer - // pointer and size will be correct. The two time parameters are - // optional and either may be NULL, they may alternatively be set to - // the start and end times the sample will have attached to it - // bPrevFramesSkipped is not used (used only by the video renderer's - // allocator where it affects quality management in direct draw). - - STDMETHODIMP GetBuffer(IMediaSample **ppBuffer, - REFERENCE_TIME * pStartTime, - REFERENCE_TIME * pEndTime, - DWORD dwFlags); - - // final release of a CMediaSample will call this - STDMETHODIMP ReleaseBuffer(IMediaSample *pBuffer); - // obsolete:: virtual void PutOnFreeList(CMediaSample * pSample); - - STDMETHODIMP SetNotify(IMemAllocatorNotifyCallbackTemp *pNotify); - - STDMETHODIMP GetFreeCount(LONG *plBuffersFree); - - // Notify that a sample is available - void NotifySample(); - - // Notify that we're waiting for a sample - void SetWaiting() { m_lWaiting++; }; -}; - - -//===================================================================== -//===================================================================== -// Defines CMemAllocator -// -// this is an allocator based on CBaseAllocator that allocates sample -// buffers in main memory (from 'new'). You must call SetProperties -// before calling Commit. -// -// we don't free the memory when going into Decommit state. The simplest -// way to implement this without complicating CBaseAllocator is to -// have a Free() function, called to go into decommit state, that does -// nothing and a ReallyFree function called from our destructor that -// actually frees the memory. -//===================================================================== -//===================================================================== - -// Make me one from quartz.dll -STDAPI CreateMemoryAllocator(IMemAllocator **ppAllocator); - -class CMemAllocator : public CBaseAllocator -{ - -protected: - - LPBYTE m_pBuffer; // combined memory for all buffers - - // override to free the memory when decommit completes - // - we actually do nothing, and save the memory until deletion. - void Free(void); - - // called from the destructor (and from Alloc if changing size/count) to - // actually free up the memory - void ReallyFree(void); - - // overriden to allocate the memory when commit called - HRESULT Alloc(void); - -public: - /* This goes in the factory template table to create new instances */ - static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *); - - STDMETHODIMP SetProperties( - ALLOCATOR_PROPERTIES* pRequest, - ALLOCATOR_PROPERTIES* pActual); - - CMemAllocator(TCHAR *, LPUNKNOWN, HRESULT *); -#ifdef UNICODE - CMemAllocator(CHAR *, LPUNKNOWN, HRESULT *); -#endif - ~CMemAllocator(); -}; - -// helper used by IAMovieSetup implementation -STDAPI -AMovieSetupRegisterFilter( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper * pIFM - , BOOL bRegister ); - - -/////////////////////////////////////////////////////////////////////////// -// ------------------------------------------------------------------------ -// ------------------------------------------------------------------------ -// ------------------------------------------------------------------------ -// ------------------------------------------------------------------------ -/////////////////////////////////////////////////////////////////////////// - -#endif /* __FILTER__ */ - - - diff --git a/plugins/gs/gsdx9/baseclasses/amvideo.cpp b/plugins/gs/gsdx9/baseclasses/amvideo.cpp deleted file mode 100644 index 4b2494f21e..0000000000 --- a/plugins/gs/gsdx9/baseclasses/amvideo.cpp +++ /dev/null @@ -1,275 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AMVideo.cpp -// -// Desc: DirectShow base classes - implements helper functions for -// bitmap formats. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - -// These are bit field masks for true colour devices - -const DWORD bits555[] = {0x007C00,0x0003E0,0x00001F}; -const DWORD bits565[] = {0x00F800,0x0007E0,0x00001F}; -const DWORD bits888[] = {0xFF0000,0x00FF00,0x0000FF}; - -// This maps bitmap subtypes into a bits per pixel value and also a -// name. unicode and ansi versions are stored because we have to -// return a pointer to a static string. -const struct { - const GUID *pSubtype; - WORD BitCount; - CHAR *pName; - WCHAR *wszName; -} BitCountMap[] = { &MEDIASUBTYPE_RGB1, 1, "RGB Monochrome", L"RGB Monochrome", - &MEDIASUBTYPE_RGB4, 4, "RGB VGA", L"RGB VGA", - &MEDIASUBTYPE_RGB8, 8, "RGB 8", L"RGB 8", - &MEDIASUBTYPE_RGB565, 16, "RGB 565 (16 bit)", L"RGB 565 (16 bit)", - &MEDIASUBTYPE_RGB555, 16, "RGB 555 (16 bit)", L"RGB 555 (16 bit)", - &MEDIASUBTYPE_RGB24, 24, "RGB 24", L"RGB 24", - &MEDIASUBTYPE_RGB32, 32, "RGB 32", L"RGB 32", - &MEDIASUBTYPE_ARGB32, 32, "ARGB 32", L"ARGB 32", - &MEDIASUBTYPE_Overlay, 0, "Overlay", L"Overlay", - &GUID_NULL, 0, "UNKNOWN", L"UNKNOWN" -}; - -// Return the size of the bitmap as defined by this header - -STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader) -{ - return DIBSIZE(*pHeader); -} - - -// This is called if the header has a 16 bit colour depth and needs to work -// out the detailed type from the bit fields (either RGB 565 or RGB 555) - -STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader) -{ - BITMAPINFO *pbmInfo = (BITMAPINFO *) pbmiHeader; - ASSERT(pbmiHeader->biBitCount == 16); - - // If its BI_RGB then it's RGB 555 by default - - if (pbmiHeader->biCompression == BI_RGB) { - return MEDIASUBTYPE_RGB555; - } - - // Compare the bit fields with RGB 555 - - DWORD *pMask = (DWORD *) pbmInfo->bmiColors; - if (pMask[0] == bits555[0]) { - if (pMask[1] == bits555[1]) { - if (pMask[2] == bits555[2]) { - return MEDIASUBTYPE_RGB555; - } - } - } - - // Compare the bit fields with RGB 565 - - pMask = (DWORD *) pbmInfo->bmiColors; - if (pMask[0] == bits565[0]) { - if (pMask[1] == bits565[1]) { - if (pMask[2] == bits565[2]) { - return MEDIASUBTYPE_RGB565; - } - } - } - return GUID_NULL; -} - - -// Given a BITMAPINFOHEADER structure this returns the GUID sub type that is -// used to describe it in format negotiations. For example a video codec fills -// in the format block with a VIDEOINFO structure, it also fills in the major -// type with MEDIATYPE_VIDEO and the subtype with a GUID that matches the bit -// count, for example if it is an eight bit image then MEDIASUBTYPE_RGB8 - -STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader) -{ - ASSERT(pbmiHeader); - - // If it's not RGB then create a GUID from the compression type - - if (pbmiHeader->biCompression != BI_RGB) { - if (pbmiHeader->biCompression != BI_BITFIELDS) { - FOURCCMap FourCCMap(pbmiHeader->biCompression); - return (const GUID) FourCCMap; - } - } - - // Map the RGB DIB bit depth to a image GUID - - switch(pbmiHeader->biBitCount) { - case 1 : return MEDIASUBTYPE_RGB1; - case 4 : return MEDIASUBTYPE_RGB4; - case 8 : return MEDIASUBTYPE_RGB8; - case 16 : return GetTrueColorType(pbmiHeader); - case 24 : return MEDIASUBTYPE_RGB24; - case 32 : return MEDIASUBTYPE_RGB32; - } - return GUID_NULL; -} - - -// Given a video bitmap subtype we return the number of bits per pixel it uses -// We return a WORD bit count as thats what the BITMAPINFOHEADER uses. If the -// GUID subtype is not found in the table we return an invalid USHRT_MAX - -STDAPI_(WORD) GetBitCount(const GUID *pSubtype) -{ - ASSERT(pSubtype); - const GUID *pMediaSubtype; - INT iPosition = 0; - - // Scan the mapping list seeing if the source GUID matches any known - // bitmap subtypes, the list is terminated by a GUID_NULL entry - - while (TRUE) { - pMediaSubtype = BitCountMap[iPosition].pSubtype; - if (IsEqualGUID(*pMediaSubtype,GUID_NULL)) { - return USHRT_MAX; - } - if (IsEqualGUID(*pMediaSubtype,*pSubtype)) { - return BitCountMap[iPosition].BitCount; - } - iPosition++; - } -} - - -// Given a bitmap subtype we return a description name that can be used for -// debug purposes. In a retail build this function still returns the names -// If the subtype isn't found in the lookup table we return string UNKNOWN - -int LocateSubtype(const GUID *pSubtype) -{ - ASSERT(pSubtype); - const GUID *pMediaSubtype; - INT iPosition = 0; - - // Scan the mapping list seeing if the source GUID matches any known - // bitmap subtypes, the list is terminated by a GUID_NULL entry - - while (TRUE) { - pMediaSubtype = BitCountMap[iPosition].pSubtype; - if (IsEqualGUID(*pMediaSubtype,*pSubtype) || - IsEqualGUID(*pMediaSubtype,GUID_NULL) - ) - { - break; - } - - iPosition++; - } - - return iPosition; -} - - - -STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype) -{ - return BitCountMap[LocateSubtype(pSubtype)].wszName; -} - -STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype) -{ - return BitCountMap[LocateSubtype(pSubtype)].pName; -} - -#ifndef GetSubtypeName -#error wxutil.h should have defined GetSubtypeName -#endif -#undef GetSubtypeName - -// this is here for people that linked to it directly; most people -// would use the header file that picks the A or W version. -STDAPI_(CHAR *) GetSubtypeName(const GUID *pSubtype) -{ - return GetSubtypeNameA(pSubtype); -} - - -// The mechanism for describing a bitmap format is with the BITMAPINFOHEADER -// This is really messy to deal with because it invariably has fields that -// follow it holding bit fields, palettes and the rest. This function gives -// the number of bytes required to hold a VIDEOINFO that represents it. This -// count includes the prefix information (like the rcSource rectangle) the -// BITMAPINFOHEADER field, and any other colour information on the end. -// -// WARNING If you want to copy a BITMAPINFOHEADER into a VIDEOINFO always make -// sure that you use the HEADER macro because the BITMAPINFOHEADER field isn't -// right at the start of the VIDEOINFO (there are a number of other fields), -// -// CopyMemory(HEADER(pVideoInfo),pbmi,sizeof(BITMAPINFOHEADER)); -// - -STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader) -{ - // Everyone has this to start with this - LONG Size = SIZE_PREHEADER + pHeader->biSize; - - ASSERT(pHeader->biSize >= sizeof(BITMAPINFOHEADER)); - - // Does this format use a palette, if the number of colours actually used - // is zero then it is set to the maximum that are allowed for that colour - // depth (an example is 256 for eight bits). Truecolour formats may also - // pass a palette with them in which case the used count is non zero - - // This would scare me. - ASSERT(pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed == 0); - - if (pHeader->biBitCount <= iPALETTE || pHeader->biClrUsed) { - LONG Entries = (DWORD) 1 << pHeader->biBitCount; - if (pHeader->biClrUsed) { - Entries = pHeader->biClrUsed; - } - Size += Entries * sizeof(RGBQUAD); - } - - // Truecolour formats may have a BI_BITFIELDS specifier for compression - // type which means that room for three DWORDs should be allocated that - // specify where in each pixel the RGB colour components may be found - - if (pHeader->biCompression == BI_BITFIELDS) { - Size += SIZE_MASKS; - } - - // A BITMAPINFO for a palettised image may also contain a palette map that - // provides the information to map from a source palette to a destination - // palette during a BitBlt for example, because this information is only - // ever processed during drawing you don't normally store the palette map - // nor have any way of knowing if it is present in the data structure - - return Size; -} - - -// Returns TRUE if the VIDEOINFO contains a palette - -STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo) -{ - if (PALETTISED(pVideoInfo) == FALSE) { - if (pVideoInfo->bmiHeader.biClrUsed == 0) { - return FALSE; - } - } - return TRUE; -} - - -// Return a pointer to the first entry in a palette - -STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo) -{ - if (pVideoInfo->bmiHeader.biCompression == BI_BITFIELDS) { - return TRUECOLOR(pVideoInfo)->bmiColors; - } - return COLORS(pVideoInfo); -} diff --git a/plugins/gs/gsdx9/baseclasses/audevcod.h b/plugins/gs/gsdx9/baseclasses/audevcod.h deleted file mode 100644 index d97d4ff6a7..0000000000 --- a/plugins/gs/gsdx9/baseclasses/audevcod.h +++ /dev/null @@ -1,53 +0,0 @@ -//------------------------------------------------------------------------------ -// File: AudEvCod.h -// -// Desc: List of Audio device error event codes and the expected params. -// -// Copyright (c) 1999-2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - - -#ifndef __AUDEVCOD__ -#define __AUDEVCOD__ - - -#define EC_SND_DEVICE_ERROR_BASE 0x0200 - -typedef enum _tagSND_DEVICE_ERROR { - - SNDDEV_ERROR_Open=1, - SNDDEV_ERROR_Close=2, - SNDDEV_ERROR_GetCaps=3, - SNDDEV_ERROR_PrepareHeader=4, - SNDDEV_ERROR_UnprepareHeader=5, - SNDDEV_ERROR_Reset=6, - SNDDEV_ERROR_Restart=7, - SNDDEV_ERROR_GetPosition=8, - SNDDEV_ERROR_Write=9, - SNDDEV_ERROR_Pause=10, - SNDDEV_ERROR_Stop=11, - SNDDEV_ERROR_Start=12, - SNDDEV_ERROR_AddBuffer=13, - SNDDEV_ERROR_Query=14, - -} SNDDEV_ERR; - - -// Sound device error event codes -// ============================== -// -// All audio device error events are always passed on to the application, and are -// never processed by the filter graph - - -#define EC_SNDDEV_IN_ERROR (EC_SND_DEVICE_ERROR_BASE + 0x00) -#define EC_SNDDEV_OUT_ERROR (EC_SND_DEVICE_ERROR_BASE + 0x01) -// Parameters: ( DWORD, DWORD) -// lParam1 is an enum SND_DEVICE_ERROR which notifies the app how the device was -// being accessed when the failure occurred. -// -// lParam2 is the error returned from the sound device call. -// - -#endif // __AUDEVCOD__ diff --git a/plugins/gs/gsdx9/baseclasses/baseclasses.vcproj b/plugins/gs/gsdx9/baseclasses/baseclasses.vcproj deleted file mode 100644 index 77c3619736..0000000000 --- a/plugins/gs/gsdx9/baseclasses/baseclasses.vcproj +++ /dev/null @@ -1,444 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/plugins/gs/gsdx9/baseclasses/baseclasses.vcproj.REFRACTION.Administrator.user b/plugins/gs/gsdx9/baseclasses/baseclasses.vcproj.REFRACTION.Administrator.user deleted file mode 100644 index 6a3b1f8b6c..0000000000 --- a/plugins/gs/gsdx9/baseclasses/baseclasses.vcproj.REFRACTION.Administrator.user +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - diff --git a/plugins/gs/gsdx9/baseclasses/cache.h b/plugins/gs/gsdx9/baseclasses/cache.h deleted file mode 100644 index d98f262f9c..0000000000 --- a/plugins/gs/gsdx9/baseclasses/cache.h +++ /dev/null @@ -1,74 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Cache.h -// -// Desc: DirectShow base classes - efines a non-MFC generic cache class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* This class implements a simple cache. A cache object is instantiated - with the number of items it is to hold. An item is a pointer to an - object derived from CBaseObject (helps reduce memory leaks). The cache - can then have objects added to it and removed from it. The cache size - is fixed at construction time and may therefore run out or be flooded. - If it runs out it returns a NULL pointer, if it fills up it also returns - a NULL pointer instead of a pointer to the object just inserted */ - -/* Making these classes inherit from CBaseObject does nothing for their - functionality but it allows us to check there are no memory leaks */ - -/* WARNING Be very careful when using this class, what it lets you do is - store and retrieve objects so that you can minimise object creation - which in turns improves efficiency. However the object you store is - exactly the same as the object you get back which means that it short - circuits the constructor initialisation phase. This means any class - variables the object has (eg pointers) are highly likely to be invalid. - Therefore ensure you reinitialise the object before using it again */ - - -#ifndef __CACHE__ -#define __CACHE__ - - -class CCache : CBaseObject { - - /* Make copy constructor and assignment operator inaccessible */ - - CCache(const CCache &refCache); - CCache &operator=(const CCache &refCache); - -private: - - /* These are initialised in the constructor. The first variable points to - an array of pointers, each of which points to a CBaseObject derived - object. The m_iCacheSize is the static fixed size for the cache and the - m_iUsed defines the number of places filled with objects at any time. - We fill the array of pointers from the start (ie m_ppObjects[0] first) - and then only add and remove objects from the end position, so in this - respect the array of object pointers should be treated as a stack */ - - CBaseObject **m_ppObjects; - const INT m_iCacheSize; - INT m_iUsed; - -public: - - CCache(TCHAR *pName,INT iItems); - virtual ~CCache(); - - /* Add an item to the cache */ - CBaseObject *AddToCache(CBaseObject *pObject); - - /* Remove an item from the cache */ - CBaseObject *RemoveFromCache(); - - /* Delete all the objects held in the cache */ - void RemoveAll(void); - - /* Return the cache size which is set during construction */ - INT GetCacheSize(void) const {return m_iCacheSize;}; -}; - -#endif /* __CACHE__ */ - diff --git a/plugins/gs/gsdx9/baseclasses/combase.cpp b/plugins/gs/gsdx9/baseclasses/combase.cpp deleted file mode 100644 index 3e092af3ca..0000000000 --- a/plugins/gs/gsdx9/baseclasses/combase.cpp +++ /dev/null @@ -1,256 +0,0 @@ -//------------------------------------------------------------------------------ -// File: ComBase.cpp -// -// Desc: DirectShow base classes - implements class hierarchy for creating -// COM objects. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#pragma warning( disable : 4514 ) // Disable warnings re unused inline functions - - -/* Define the static member variable */ - -LONG CBaseObject::m_cObjects = 0; - - -/* Constructor */ - -CBaseObject::CBaseObject(const TCHAR *pName) -{ - /* Increment the number of active objects */ - InterlockedIncrement(&m_cObjects); - -#ifdef DEBUG - -#ifdef UNICODE - m_dwCookie = DbgRegisterObjectCreation(0, pName); -#else - m_dwCookie = DbgRegisterObjectCreation(pName, 0); -#endif - -#endif -} - -#ifdef UNICODE -CBaseObject::CBaseObject(const char *pName) -{ - /* Increment the number of active objects */ - InterlockedIncrement(&m_cObjects); - -#ifdef DEBUG - m_dwCookie = DbgRegisterObjectCreation(pName, 0); -#endif -} -#endif - -HINSTANCE hlibOLEAut32; - -/* Destructor */ - -CBaseObject::~CBaseObject() -{ - /* Decrement the number of objects active */ - if (InterlockedDecrement(&m_cObjects) == 0) { - if (hlibOLEAut32) { - FreeLibrary(hlibOLEAut32); - - hlibOLEAut32 = 0; - } - }; - - -#ifdef DEBUG - DbgRegisterObjectDestruction(m_dwCookie); -#endif -} - -static const TCHAR szOle32Aut[] = TEXT("OleAut32.dll"); - -HINSTANCE LoadOLEAut32() -{ - if (hlibOLEAut32 == 0) { - - hlibOLEAut32 = LoadLibrary(szOle32Aut); - } - - return hlibOLEAut32; -} - - -/* Constructor */ - -// We know we use "this" in the initialization list, we also know we don't modify *phr. -#pragma warning( disable : 4355 4100 ) -CUnknown::CUnknown(const TCHAR *pName, LPUNKNOWN pUnk) -: CBaseObject(pName) -/* Start the object with a reference count of zero - when the */ -/* object is queried for it's first interface this may be */ -/* incremented depending on whether or not this object is */ -/* currently being aggregated upon */ -, m_cRef(0) -/* Set our pointer to our IUnknown interface. */ -/* If we have an outer, use its, otherwise use ours. */ -/* This pointer effectivly points to the owner of */ -/* this object and can be accessed by the GetOwner() method. */ -, m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) - /* Why the double cast? Well, the inner cast is a type-safe cast */ - /* to pointer to a type from which we inherit. The second is */ - /* type-unsafe but works because INonDelegatingUnknown "behaves */ - /* like" IUnknown. (Only the names on the methods change.) */ -{ - // Everything we need to do has been done in the initializer list -} - -// This does the same as above except it has a useless HRESULT argument -// use the previous constructor, this is just left for compatibility... -CUnknown::CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) : - CBaseObject(pName), - m_cRef(0), - m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) -{ -} - -#ifdef UNICODE -CUnknown::CUnknown(const CHAR *pName, LPUNKNOWN pUnk) -: CBaseObject(pName), m_cRef(0), - m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) -{ } - -CUnknown::CUnknown(CHAR *pName, LPUNKNOWN pUnk,HRESULT *phr) : - CBaseObject(pName), m_cRef(0), - m_pUnknown( pUnk != 0 ? pUnk : reinterpret_cast( static_cast(this) ) ) -{ } - -#endif - -#pragma warning( default : 4355 4100 ) - - -/* QueryInterface */ - -STDMETHODIMP CUnknown::NonDelegatingQueryInterface(REFIID riid, void ** ppv) -{ - CheckPointer(ppv,E_POINTER); - ValidateReadWritePtr(ppv,sizeof(PVOID)); - - /* We know only about IUnknown */ - - if (riid == IID_IUnknown) { - GetInterface((LPUNKNOWN) (PNDUNKNOWN) this, ppv); - return NOERROR; - } else { - *ppv = NULL; - return E_NOINTERFACE; - } -} - -/* We have to ensure that we DON'T use a max macro, since these will typically */ -/* lead to one of the parameters being evaluated twice. Since we are worried */ -/* about concurrency, we can't afford to access the m_cRef twice since we can't */ -/* afford to run the risk that its value having changed between accesses. */ - -template inline static T ourmax( const T & a, const T & b ) -{ - return a > b ? a : b; -} - -/* AddRef */ - -STDMETHODIMP_(ULONG) CUnknown::NonDelegatingAddRef() -{ - LONG lRef = InterlockedIncrement( &m_cRef ); - ASSERT(lRef > 0); - DbgLog((LOG_MEMORY,3,TEXT(" Obj %d ref++ = %d"), - m_dwCookie, m_cRef)); - return ourmax(ULONG(m_cRef), 1ul); -} - - -/* Release */ - -STDMETHODIMP_(ULONG) CUnknown::NonDelegatingRelease() -{ - /* If the reference count drops to zero delete ourselves */ - - LONG lRef = InterlockedDecrement( &m_cRef ); - ASSERT(lRef >= 0); - - DbgLog((LOG_MEMORY,3,TEXT(" Object %d ref-- = %d"), - m_dwCookie, m_cRef)); - if (lRef == 0) { - - // COM rules say we must protect against re-entrancy. - // If we are an aggregator and we hold our own interfaces - // on the aggregatee, the QI for these interfaces will - // addref ourselves. So after doing the QI we must release - // a ref count on ourselves. Then, before releasing the - // private interface, we must addref ourselves. When we do - // this from the destructor here it will result in the ref - // count going to 1 and then back to 0 causing us to - // re-enter the destructor. Hence we add an extra refcount here - // once we know we will delete the object. - // for an example aggregator see filgraph\distrib.cpp. - - m_cRef++; - - delete this; - return ULONG(0); - } else { - return ourmax(ULONG(m_cRef), 1ul); - } -} - - -/* Return an interface pointer to a requesting client - performing a thread safe AddRef as necessary */ - -STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv) -{ - CheckPointer(ppv, E_POINTER); - *ppv = pUnk; - pUnk->AddRef(); - return NOERROR; -} - - -/* Compares two interfaces and returns TRUE if they are on the same object */ - -BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond) -{ - /* Different objects can't have the same interface pointer for - any interface - */ - if (pFirst == pSecond) { - return TRUE; - } - /* OK - do it the hard way - check if they have the same - IUnknown pointers - a single object can only have one of these - */ - LPUNKNOWN pUnknown1; // Retrieve the IUnknown interface - LPUNKNOWN pUnknown2; // Retrieve the other IUnknown interface - HRESULT hr; // General OLE return code - - ASSERT(pFirst); - ASSERT(pSecond); - - /* See if the IUnknown pointers match */ - - hr = pFirst->QueryInterface(IID_IUnknown,(void **) &pUnknown1); - ASSERT(SUCCEEDED(hr)); - ASSERT(pUnknown1); - - hr = pSecond->QueryInterface(IID_IUnknown,(void **) &pUnknown2); - ASSERT(SUCCEEDED(hr)); - ASSERT(pUnknown2); - - /* Release the extra interfaces we hold */ - - pUnknown1->Release(); - pUnknown2->Release(); - return (pUnknown1 == pUnknown2); -} - diff --git a/plugins/gs/gsdx9/baseclasses/combase.h b/plugins/gs/gsdx9/baseclasses/combase.h deleted file mode 100644 index 34d5ca65cd..0000000000 --- a/plugins/gs/gsdx9/baseclasses/combase.h +++ /dev/null @@ -1,319 +0,0 @@ -//------------------------------------------------------------------------------ -// File: ComBase.h -// -// Desc: DirectShow base classes - defines a class hierarchy for creating -// COM objects. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* - -a. Derive your COM object from CUnknown - -b. Make a static CreateInstance function that takes an LPUNKNOWN, an HRESULT * - and a TCHAR *. The LPUNKNOWN defines the object to delegate IUnknown calls - to. The HRESULT * allows error codes to be passed around constructors and - the TCHAR * is a descriptive name that can be printed on the debugger. - - It is important that constructors only change the HRESULT * if they have - to set an ERROR code, if it was successful then leave it alone or you may - overwrite an error code from an object previously created. - - When you call a constructor the descriptive name should be in static store - as we do not copy the string. To stop large amounts of memory being used - in retail builds by all these static strings use the NAME macro, - - CMyFilter = new CImplFilter(NAME("My filter"),pUnknown,phr); - if (FAILED(hr)) { - return hr; - } - - In retail builds NAME(_x_) compiles to NULL, the base CBaseObject class - knows not to do anything with objects that don't have a name. - -c. Have a constructor for your object that passes the LPUNKNOWN, HRESULT * and - TCHAR * to the CUnknown constructor. You can set the HRESULT if you have an - error, or just simply pass it through to the constructor. - - The object creation will fail in the class factory if the HRESULT indicates - an error (ie FAILED(HRESULT) == TRUE) - -d. Create a FactoryTemplate with your object's class id and CreateInstance - function. - -Then (for each interface) either - -Multiple inheritance - -1. Also derive it from ISomeInterface -2. Include DECLARE_IUNKNOWN in your class definition to declare - implementations of QueryInterface, AddRef and Release that - call the outer unknown -3. Override NonDelegatingQueryInterface to expose ISomeInterface by - code something like - - if (riid == IID_ISomeInterface) { - return GetInterface((ISomeInterface *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - -4. Declare and implement the member functions of ISomeInterface. - -or: Nested interfaces - -1. Declare a class derived from CUnknown -2. Include DECLARE_IUNKNOWN in your class definition -3. Override NonDelegatingQueryInterface to expose ISomeInterface by - code something like - - if (riid == IID_ISomeInterface) { - return GetInterface((ISomeInterface *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - -4. Implement the member functions of ISomeInterface. Use GetOwner() to - access the COM object class. - -And in your COM object class: - -5. Make the nested class a friend of the COM object class, and declare - an instance of the nested class as a member of the COM object class. - - NOTE that because you must always pass the outer unknown and an hResult - to the CUnknown constructor you cannot use a default constructor, in - other words you will have to make the member variable a pointer to the - class and make a NEW call in your constructor to actually create it. - -6. override the NonDelegatingQueryInterface with code like this: - - if (riid == IID_ISomeInterface) { - return m_pImplFilter-> - NonDelegatingQueryInterface(IID_ISomeInterface, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - -You can have mixed classes which support some interfaces via multiple -inheritance and some via nested classes - -*/ - -#ifndef __COMBASE__ -#define __COMBASE__ - -// Filter Setup data structures no defined in axextend.idl - -typedef REGPINTYPES -AMOVIESETUP_MEDIATYPE, * PAMOVIESETUP_MEDIATYPE, * FAR LPAMOVIESETUP_MEDIATYPE; - -typedef REGFILTERPINS -AMOVIESETUP_PIN, * PAMOVIESETUP_PIN, * FAR LPAMOVIESETUP_PIN; - -typedef struct _AMOVIESETUP_FILTER -{ - const CLSID * clsID; - const WCHAR * strName; - DWORD dwMerit; - UINT nPins; - const AMOVIESETUP_PIN * lpPin; -} -AMOVIESETUP_FILTER, * PAMOVIESETUP_FILTER, * FAR LPAMOVIESETUP_FILTER; - -/* The DLLENTRY module initialises the module handle on loading */ - -extern HINSTANCE g_hInst; - -/* On DLL load remember which platform we are running on */ - -extern DWORD g_amPlatform; -extern OSVERSIONINFO g_osInfo; // Filled in by GetVersionEx - -/* Version of IUnknown that is renamed to allow a class to support both - non delegating and delegating IUnknowns in the same COM object */ - -#ifndef INONDELEGATINGUNKNOWN_DEFINED -DECLARE_INTERFACE(INonDelegatingUnknown) -{ - STDMETHOD(NonDelegatingQueryInterface) (THIS_ REFIID, LPVOID *) PURE; - STDMETHOD_(ULONG, NonDelegatingAddRef)(THIS) PURE; - STDMETHOD_(ULONG, NonDelegatingRelease)(THIS) PURE; -}; -#define INONDELEGATINGUNKNOWN_DEFINED -#endif - -typedef INonDelegatingUnknown *PNDUNKNOWN; - - -/* This is the base object class that supports active object counting. As - part of the debug facilities we trace every time a C++ object is created - or destroyed. The name of the object has to be passed up through the class - derivation list during construction as you cannot call virtual functions - in the constructor. The downside of all this is that every single object - constructor has to take an object name parameter that describes it */ - -class CBaseObject -{ - -private: - - // Disable the copy constructor and assignment by default so you will get - // compiler errors instead of unexpected behaviour if you pass objects - // by value or assign objects. - CBaseObject(const CBaseObject& objectSrc); // no implementation - void operator=(const CBaseObject& objectSrc); // no implementation - -private: - static LONG m_cObjects; /* Total number of objects active */ - -protected: -#ifdef DEBUG - DWORD m_dwCookie; /* Cookie identifying this object */ -#endif - - -public: - - /* These increment and decrement the number of active objects */ - - CBaseObject(const TCHAR *pName); -#ifdef UNICODE - CBaseObject(const char *pName); -#endif - ~CBaseObject(); - - /* Call this to find if there are any CUnknown derived objects active */ - - static LONG ObjectsActive() { - return m_cObjects; - }; -}; - - -/* An object that supports one or more COM interfaces will be based on - this class. It supports counting of total objects for DLLCanUnloadNow - support, and an implementation of the core non delegating IUnknown */ - -class AM_NOVTABLE CUnknown : public INonDelegatingUnknown, - public CBaseObject -{ -private: - const LPUNKNOWN m_pUnknown; /* Owner of this object */ - -protected: /* So we can override NonDelegatingRelease() */ - volatile LONG m_cRef; /* Number of reference counts */ - -public: - - CUnknown(const TCHAR *pName, LPUNKNOWN pUnk); - virtual ~CUnknown() {}; - - // This is redundant, just use the other constructor - // as we never touch the HRESULT in this anyway - CUnknown(TCHAR *pName, LPUNKNOWN pUnk,HRESULT *phr); -#ifdef UNICODE - CUnknown(const char *pName, LPUNKNOWN pUnk); - CUnknown(char *pName, LPUNKNOWN pUnk,HRESULT *phr); -#endif - - /* Return the owner of this object */ - - LPUNKNOWN GetOwner() const { - return m_pUnknown; - }; - - /* Called from the class factory to create a new instance, it is - pure virtual so it must be overriden in your derived class */ - - /* static CUnknown *CreateInstance(LPUNKNOWN, HRESULT *) */ - - /* Non delegating unknown implementation */ - - STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **); - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); -}; - -#if (_MSC_VER <= 1200) -#pragma warning(disable:4211) - -/* The standard InterlockedXXX functions won't take volatiles */ -static inline LONG WINAPI InterlockedIncrement( volatile LONG * plong ) -{ return InterlockedIncrement( const_cast( plong ) ); } - -static inline LONG WINAPI InterlockedDecrement( volatile LONG * plong ) -{ return InterlockedDecrement( const_cast( plong ) ); } - -#pragma warning(default:4211) -#endif - - -/* Return an interface pointer to a requesting client - performing a thread safe AddRef as necessary */ - -STDAPI GetInterface(LPUNKNOWN pUnk, void **ppv); - -/* A function that can create a new COM object */ - -typedef CUnknown *(CALLBACK *LPFNNewCOMObject)(LPUNKNOWN pUnkOuter, HRESULT *phr); - -/* A function (can be NULL) which is called from the DLL entrypoint - routine for each factory template: - - bLoading - TRUE on DLL load, FALSE on DLL unload - rclsid - the m_ClsID of the entry -*/ -typedef void (CALLBACK *LPFNInitRoutine)(BOOL bLoading, const CLSID *rclsid); - -/* Create one of these per object class in an array so that - the default class factory code can create new instances */ - -class CFactoryTemplate { - -public: - - const WCHAR * m_Name; - const CLSID * m_ClsID; - LPFNNewCOMObject m_lpfnNew; - LPFNInitRoutine m_lpfnInit; - const AMOVIESETUP_FILTER * m_pAMovieSetup_Filter; - - BOOL IsClassID(REFCLSID rclsid) const { - return (IsEqualCLSID(*m_ClsID,rclsid)); - }; - - CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) const { - CheckPointer(phr,NULL); - return m_lpfnNew(pUnk, phr); - }; -}; - - -/* You must override the (pure virtual) NonDelegatingQueryInterface to return - interface pointers (using GetInterface) to the interfaces your derived - class supports (the default implementation only supports IUnknown) */ - -#define DECLARE_IUNKNOWN \ - STDMETHODIMP QueryInterface(REFIID riid, void **ppv) { \ - return GetOwner()->QueryInterface(riid,ppv); \ - }; \ - STDMETHODIMP_(ULONG) AddRef() { \ - return GetOwner()->AddRef(); \ - }; \ - STDMETHODIMP_(ULONG) Release() { \ - return GetOwner()->Release(); \ - }; - - - -HINSTANCE LoadOLEAut32(); - - -#endif /* __COMBASE__ */ - - - - diff --git a/plugins/gs/gsdx9/baseclasses/comlite.h b/plugins/gs/gsdx9/baseclasses/comlite.h deleted file mode 100644 index bfdf644e7f..0000000000 --- a/plugins/gs/gsdx9/baseclasses/comlite.h +++ /dev/null @@ -1,26 +0,0 @@ -//------------------------------------------------------------------------------ -// File: COMLite.h -// -// Desc: This header file is to provide a migration path for users of -// ActiveMovie betas 1 and 2. -// -// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef _INC_COMLITE_ -#define _INC_COMLITE_ - -#define QzInitialize CoInitialize -#define QzUninitialize CoUninitialize -#define QzFreeUnusedLibraries CoFreeUnusedLibraries - -#define QzGetMalloc CoGetMalloc -#define QzTaskMemAlloc CoTaskMemAlloc -#define QzTaskMemRealloc CoTaskMemRealloc -#define QzTaskMemFree CoTaskMemFree -#define QzCreateFilterObject CoCreateInstance -#define QzCLSIDFromString CLSIDFromString -#define QzStringFromGUID2 StringFromGUID2 - -#endif // _INC_COMLITE_ diff --git a/plugins/gs/gsdx9/baseclasses/cprop.cpp b/plugins/gs/gsdx9/baseclasses/cprop.cpp deleted file mode 100644 index fdb0749010..0000000000 --- a/plugins/gs/gsdx9/baseclasses/cprop.cpp +++ /dev/null @@ -1,380 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CProp.cpp -// -// Desc: DirectShow base classes - implements CBasePropertyPage class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -// Constructor for the base property page class. As described in the header -// file we must be initialised with dialog and title resource identifiers. -// The class supports IPropertyPage and overrides AddRef and Release calls -// to keep track of the reference counts. When the last count is released -// we call SetPageSite(NULL) and SetObjects(0,NULL) to release interfaces -// previously obtained by the property page when it had SetObjects called - -CBasePropertyPage::CBasePropertyPage(TCHAR *pName, // Debug only name - LPUNKNOWN pUnk, // COM Delegator - int DialogId, // Resource ID - int TitleId) : // To get tital - CUnknown(pName,pUnk), - m_DialogId(DialogId), - m_TitleId(TitleId), - m_hwnd(NULL), - m_Dlg(NULL), - m_pPageSite(NULL), - m_bObjectSet(FALSE), - m_bDirty(FALSE) -{ -} - -#ifdef UNICODE -CBasePropertyPage::CBasePropertyPage(CHAR *pName, // Debug only name - LPUNKNOWN pUnk, // COM Delegator - int DialogId, // Resource ID - int TitleId) : // To get tital - CUnknown(pName,pUnk), - m_DialogId(DialogId), - m_TitleId(TitleId), - m_hwnd(NULL), - m_Dlg(NULL), - m_pPageSite(NULL), - m_bObjectSet(FALSE), - m_bDirty(FALSE) -{ -} -#endif - -// Increment our reference count - -STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingAddRef() -{ - LONG lRef = InterlockedIncrement(&m_cRef); - ASSERT(lRef > 0); - return max(ULONG(m_cRef),1ul); -} - - -// Release a reference count and protect against reentrancy - -STDMETHODIMP_(ULONG) CBasePropertyPage::NonDelegatingRelease() -{ - // If the reference count drops to zero delete ourselves - - if (InterlockedDecrement(&m_cRef) == 0) { - m_cRef++; - SetPageSite(NULL); - SetObjects(0,NULL); - delete this; - return ULONG(0); - } else { - return max(ULONG(m_cRef),1ul); - } -} - - -// Expose our IPropertyPage interface - -STDMETHODIMP -CBasePropertyPage::NonDelegatingQueryInterface(REFIID riid,void **ppv) -{ - if (riid == IID_IPropertyPage) { - return GetInterface((IPropertyPage *)this,ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid,ppv); - } -} - - -// Get the page info so that the page site can size itself - -STDMETHODIMP CBasePropertyPage::GetPageInfo(LPPROPPAGEINFO pPageInfo) -{ - CheckPointer(pPageInfo,E_POINTER); - WCHAR wszTitle[STR_MAX_LENGTH]; - WideStringFromResource(wszTitle,m_TitleId); - - // Allocate dynamic memory for the property page title - - LPOLESTR pszTitle; - HRESULT hr = AMGetWideString(wszTitle, &pszTitle); - if (FAILED(hr)) { - NOTE("No caption memory"); - return hr; - } - - pPageInfo->cb = sizeof(PROPPAGEINFO); - pPageInfo->pszTitle = pszTitle; - pPageInfo->pszDocString = NULL; - pPageInfo->pszHelpFile = NULL; - pPageInfo->dwHelpContext = 0; - - // Set defaults in case GetDialogSize fails - pPageInfo->size.cx = 340; - pPageInfo->size.cy = 150; - - GetDialogSize(m_DialogId, DialogProc,0L,&pPageInfo->size); - return NOERROR; -} - - -// Handles the messages for our property window - -INT_PTR CALLBACK CBasePropertyPage::DialogProc(HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam) -{ - CBasePropertyPage *pPropertyPage; - - switch (uMsg) { - - case WM_INITDIALOG: - - SetWindowLongPtr(hwnd, DWLP_USER, lParam); - - // This pointer may be NULL when calculating size - - pPropertyPage = (CBasePropertyPage *) lParam; - if (pPropertyPage == NULL) { - return (LRESULT) 1; - } - pPropertyPage->m_Dlg = hwnd; - } - - // This pointer may be NULL when calculating size - - pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER); - if (pPropertyPage == NULL) { - return (LRESULT) 1; - } - return pPropertyPage->OnReceiveMessage(hwnd,uMsg,wParam,lParam); -} - - -// Tells us the object that should be informed of the property changes - -STDMETHODIMP CBasePropertyPage::SetObjects(ULONG cObjects,LPUNKNOWN *ppUnk) -{ - if (cObjects == 1) { - - if ((ppUnk == NULL) || (*ppUnk == NULL)) { - return E_POINTER; - } - - // Set a flag to say that we have set the Object - m_bObjectSet = TRUE ; - return OnConnect(*ppUnk); - - } else if (cObjects == 0) { - - // Set a flag to say that we have not set the Object for the page - m_bObjectSet = FALSE ; - return OnDisconnect(); - } - - DbgBreak("No support for more than one object"); - return E_UNEXPECTED; -} - - -// Create the window we will use to edit properties - -STDMETHODIMP CBasePropertyPage::Activate(HWND hwndParent, - LPCRECT pRect, - BOOL fModal) -{ - CheckPointer(pRect,E_POINTER); - - // Return failure if SetObject has not been called. - if (m_bObjectSet == FALSE) { - return E_UNEXPECTED; - } - - if (m_hwnd) { - return E_UNEXPECTED; - } - - m_hwnd = CreateDialogParam(g_hInst, - MAKEINTRESOURCE(m_DialogId), - hwndParent, - DialogProc, - (LPARAM) this); - if (m_hwnd == NULL) { - return E_OUTOFMEMORY; - } - - OnActivate(); - Move(pRect); - return Show(SW_SHOWNORMAL); -} - - -// Set the position of the property page - -STDMETHODIMP CBasePropertyPage::Move(LPCRECT pRect) -{ - CheckPointer(pRect,E_POINTER); - - if (m_hwnd == NULL) { - return E_UNEXPECTED; - } - - MoveWindow(m_hwnd, // Property page handle - pRect->left, // x coordinate - pRect->top, // y coordinate - WIDTH(pRect), // Overall window width - HEIGHT(pRect), // And likewise height - TRUE); // Should we repaint it - - return NOERROR; -} - - -// Display the property dialog - -STDMETHODIMP CBasePropertyPage::Show(UINT nCmdShow) -{ - // Have we been activated yet - - if (m_hwnd == NULL) { - return E_UNEXPECTED; - } - - // Ignore wrong show flags - - if ((nCmdShow != SW_SHOW) && (nCmdShow != SW_SHOWNORMAL) && (nCmdShow != SW_HIDE)) { - return E_INVALIDARG; - } - - ShowWindow(m_hwnd,nCmdShow); - InvalidateRect(m_hwnd,NULL,TRUE); - return NOERROR; -} - - -// Destroy the property page dialog - -STDMETHODIMP CBasePropertyPage::Deactivate(void) -{ - if (m_hwnd == NULL) { - return E_UNEXPECTED; - } - - // Remove WS_EX_CONTROLPARENT before DestroyWindow call - - DWORD dwStyle = GetWindowLong(m_hwnd, GWL_EXSTYLE); - dwStyle = dwStyle & (~WS_EX_CONTROLPARENT); - - // Set m_hwnd to be NULL temporarily so the message handler - // for WM_STYLECHANGING doesn't add the WS_EX_CONTROLPARENT - // style back in - HWND hwnd = m_hwnd; - m_hwnd = NULL; - SetWindowLong(hwnd, GWL_EXSTYLE, dwStyle); - m_hwnd = hwnd; - - OnDeactivate(); - - // Destroy the dialog window - - DestroyWindow(m_hwnd); - m_hwnd = NULL; - return NOERROR; -} - - -// Tells the application property page site - -STDMETHODIMP CBasePropertyPage::SetPageSite(LPPROPERTYPAGESITE pPageSite) -{ - if (pPageSite) { - - if (m_pPageSite) { - return E_UNEXPECTED; - } - - m_pPageSite = pPageSite; - m_pPageSite->AddRef(); - - } else { - - if (m_pPageSite == NULL) { - return E_UNEXPECTED; - } - - m_pPageSite->Release(); - m_pPageSite = NULL; - } - return NOERROR; -} - - -// Apply any changes so far made - -STDMETHODIMP CBasePropertyPage::Apply() -{ - // In ActiveMovie 1.0 we used to check whether we had been activated or - // not. This is too constrictive. Apply should be allowed as long as - // SetObject was called to set an object. So we will no longer check to - // see if we have been activated (ie., m_hWnd != NULL), but instead - // make sure that m_bObjectSet is TRUE (ie., SetObject has been called). - - if (m_bObjectSet == FALSE) { - return E_UNEXPECTED; - } - - // Must have had a site set - - if (m_pPageSite == NULL) { - return E_UNEXPECTED; - } - - // Has anything changed - - if (m_bDirty == FALSE) { - return NOERROR; - } - - // Commit derived class changes - - HRESULT hr = OnApplyChanges(); - if (SUCCEEDED(hr)) { - m_bDirty = FALSE; - } - return hr; -} - - -// Base class definition for message handling - -INT_PTR CBasePropertyPage::OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam) -{ - // we would like the TAB key to move around the tab stops in our property - // page, but for some reason OleCreatePropertyFrame clears the CONTROLPARENT - // style behind our back, so we need to switch it back on now behind its - // back. Otherwise the tab key will be useless in every page. - // - - CBasePropertyPage *pPropertyPage; - { - pPropertyPage = (CBasePropertyPage *) GetWindowLongPtr(hwnd, DWLP_USER); - if (pPropertyPage->m_hwnd == NULL) { - return 0; - } - switch (uMsg) { - case WM_STYLECHANGING: - if (wParam == GWL_EXSTYLE) { - LPSTYLESTRUCT lpss = (LPSTYLESTRUCT)lParam; - lpss->styleNew |= WS_EX_CONTROLPARENT; - return 0; - } - } - } - - return DefWindowProc(hwnd,uMsg,wParam,lParam); -} - diff --git a/plugins/gs/gsdx9/baseclasses/cprop.h b/plugins/gs/gsdx9/baseclasses/cprop.h deleted file mode 100644 index 4e50350aa0..0000000000 --- a/plugins/gs/gsdx9/baseclasses/cprop.h +++ /dev/null @@ -1,95 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CProp.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __CPROP__ -#define __CPROP__ - -// Base property page class. Filters typically expose custom properties by -// implementing special control interfaces, examples are IDirectDrawVideo -// and IQualProp on renderers. This allows property pages to be built that -// use the given interface. Applications such as the ActiveMovie OCX query -// filters for the property pages they support and expose them to the user -// -// This class provides all the framework for a property page. A property -// page is a COM object that supports IPropertyPage. We should be created -// with a resource ID for the dialog which we will load when required. We -// should also be given in the constructor a resource ID for a title string -// we will load from the DLLs STRINGTABLE. The property page titles must be -// stored in resource files so that they can be easily internationalised -// -// We have a number of virtual methods (not PURE) that may be overriden in -// derived classes to query for interfaces and so on. These functions have -// simple implementations here that just return NOERROR. Derived classes -// will almost definately have to override the message handler method called -// OnReceiveMessage. We have a static dialog procedure that calls the method -// so that derived classes don't have to fiddle around with the this pointer - -class AM_NOVTABLE CBasePropertyPage : public IPropertyPage, public CUnknown -{ -protected: - - LPPROPERTYPAGESITE m_pPageSite; // Details for our property site - HWND m_hwnd; // Window handle for the page - HWND m_Dlg; // Actual dialog window handle - BOOL m_bDirty; // Has anything been changed - int m_TitleId; // Resource identifier for title - int m_DialogId; // Dialog resource identifier - - static INT_PTR CALLBACK DialogProc(HWND hwnd, - UINT uMsg, - WPARAM wParam, - LPARAM lParam); - -private: - BOOL m_bObjectSet ; // SetObject has been called or not. -public: - - CBasePropertyPage(TCHAR *pName, // Debug only name - LPUNKNOWN pUnk, // COM Delegator - int DialogId, // Resource ID - int TitleId); // To get tital - -#ifdef UNICODE - CBasePropertyPage(CHAR *pName, - LPUNKNOWN pUnk, - int DialogId, - int TitleId); -#endif - virtual ~CBasePropertyPage() { }; - DECLARE_IUNKNOWN - - // Override these virtual methods - - virtual HRESULT OnConnect(IUnknown *pUnknown) { return NOERROR; }; - virtual HRESULT OnDisconnect() { return NOERROR; }; - virtual HRESULT OnActivate() { return NOERROR; }; - virtual HRESULT OnDeactivate() { return NOERROR; }; - virtual HRESULT OnApplyChanges() { return NOERROR; }; - virtual INT_PTR OnReceiveMessage(HWND hwnd,UINT uMsg,WPARAM wParam,LPARAM lParam); - - // These implement an IPropertyPage interface - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - STDMETHODIMP SetPageSite(LPPROPERTYPAGESITE pPageSite); - STDMETHODIMP Activate(HWND hwndParent,LPCRECT prect,BOOL fModal); - STDMETHODIMP Deactivate(void); - STDMETHODIMP GetPageInfo(LPPROPPAGEINFO pPageInfo); - STDMETHODIMP SetObjects(ULONG cObjects, LPUNKNOWN *ppUnk); - STDMETHODIMP Show(UINT nCmdShow); - STDMETHODIMP Move(LPCRECT prect); - STDMETHODIMP IsPageDirty(void) { return m_bDirty ? S_OK : S_FALSE; } - STDMETHODIMP Apply(void); - STDMETHODIMP Help(LPCWSTR lpszHelpDir) { return E_NOTIMPL; } - STDMETHODIMP TranslateAccelerator(LPMSG lpMsg) { return E_NOTIMPL; } -}; - -#endif // __CPROP__ - diff --git a/plugins/gs/gsdx9/baseclasses/ctlutil.cpp b/plugins/gs/gsdx9/baseclasses/ctlutil.cpp deleted file mode 100644 index 64073d4fc9..0000000000 --- a/plugins/gs/gsdx9/baseclasses/ctlutil.cpp +++ /dev/null @@ -1,2531 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CtlUtil.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Base classes implementing IDispatch parsing for the basic control dual -// interfaces. Derive from these and implement just the custom method and -// property methods. We also implement CPosPassThru that can be used by -// renderers and transforms to pass by IMediaPosition and IMediaSeeking - - -#include -#include -#include "seekpt.h" - -// 'bool' non standard reserved word -#pragma warning(disable:4237) - - -// --- CBaseDispatch implementation ---------- -CBaseDispatch::~CBaseDispatch() -{ - if (m_pti) { - m_pti->Release(); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CBaseDispatch::GetTypeInfoCount(UINT * pctinfo) -{ - CheckPointer(pctinfo,E_POINTER); - ValidateReadWritePtr(pctinfo,sizeof(UINT *)); - *pctinfo = 1; - return S_OK; -} - - -typedef HRESULT (STDAPICALLTYPE *LPLOADTYPELIB)( - const OLECHAR FAR *szFile, - ITypeLib FAR* FAR* pptlib); - -typedef HRESULT (STDAPICALLTYPE *LPLOADREGTYPELIB)(REFGUID rguid, - WORD wVerMajor, - WORD wVerMinor, - LCID lcid, - ITypeLib FAR* FAR* pptlib); - -// attempt to find our type library - -STDMETHODIMP -CBaseDispatch::GetTypeInfo( - REFIID riid, - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) -{ - CheckPointer(pptinfo,E_POINTER); - ValidateReadWritePtr(pptinfo,sizeof(ITypeInfo *)); - HRESULT hr; - - *pptinfo = NULL; - - // we only support one type element - if (0 != itinfo) { - return TYPE_E_ELEMENTNOTFOUND; - } - - if (NULL == pptinfo) { - return E_POINTER; - } - - // always look for neutral - if (NULL == m_pti) { - - LPLOADTYPELIB lpfnLoadTypeLib; - LPLOADREGTYPELIB lpfnLoadRegTypeLib; - ITypeLib *ptlib; - HINSTANCE hInst; - - static const char szTypeLib[] = "LoadTypeLib"; - static const char szRegTypeLib[] = "LoadRegTypeLib"; - static const WCHAR szControl[] = L"control.tlb"; - - // - // Try to get the Ole32Aut.dll module handle. - // - - hInst = LoadOLEAut32(); - if (hInst == NULL) { - DWORD dwError = GetLastError(); - return AmHresultFromWin32(dwError); - } - lpfnLoadRegTypeLib = (LPLOADREGTYPELIB)GetProcAddress(hInst, - szRegTypeLib); - if (lpfnLoadRegTypeLib == NULL) { - DWORD dwError = GetLastError(); - return AmHresultFromWin32(dwError); - } - - hr = (*lpfnLoadRegTypeLib)(LIBID_QuartzTypeLib, 1, 0, // version 1.0 - lcid, &ptlib); - - if (FAILED(hr)) { - - // attempt to load directly - this will fill the - // registry in if it finds it - - lpfnLoadTypeLib = (LPLOADTYPELIB)GetProcAddress(hInst, szTypeLib); - if (lpfnLoadTypeLib == NULL) { - DWORD dwError = GetLastError(); - return AmHresultFromWin32(dwError); - } - - hr = (*lpfnLoadTypeLib)(szControl, &ptlib); - if (FAILED(hr)) { - return hr; - } - } - - hr = ptlib->GetTypeInfoOfGuid( - riid, - &m_pti); - - ptlib->Release(); - - if (FAILED(hr)) { - return hr; - } - } - - *pptinfo = m_pti; - m_pti->AddRef(); - return S_OK; -} - - -STDMETHODIMP -CBaseDispatch::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) -{ - // although the IDispatch riid is dead, we use this to pass from - // the interface implementation class to us the iid we are talking about. - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(riid, 0, lcid, &pti); - - if (SUCCEEDED(hr)) { - hr = pti->GetIDsOfNames(rgszNames, cNames, rgdispid); - - pti->Release(); - } - return hr; -} - - -// --- CMediaControl implementation --------- - -CMediaControl::CMediaControl(const TCHAR * name,LPUNKNOWN pUnk) : - CUnknown(name, pUnk) -{ -} - -// expose our interfaces IMediaControl and IUnknown - -STDMETHODIMP -CMediaControl::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if (riid == IID_IMediaControl) { - return GetInterface( (IMediaControl *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CMediaControl::GetTypeInfoCount(UINT * pctinfo) -{ - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -// attempt to find our type library - -STDMETHODIMP -CMediaControl::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) -{ - return m_basedisp.GetTypeInfo( - IID_IMediaControl, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CMediaControl::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) -{ - return m_basedisp.GetIDsOfNames( - IID_IMediaControl, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CMediaControl::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) -{ - // this parameter is a dead leftover from an earlier interface - if (IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if (FAILED(hr)) { - return hr; - } - - hr = pti->Invoke( - (IMediaControl *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- CMediaEvent implementation ---------- - - -CMediaEvent::CMediaEvent(const TCHAR * name,LPUNKNOWN pUnk) : - CUnknown(name, pUnk) -{ -} - - -// expose our interfaces IMediaEvent and IUnknown - -STDMETHODIMP -CMediaEvent::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if (riid == IID_IMediaEvent || riid == IID_IMediaEventEx) { - return GetInterface( (IMediaEventEx *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CMediaEvent::GetTypeInfoCount(UINT * pctinfo) -{ - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -// attempt to find our type library - -STDMETHODIMP -CMediaEvent::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) -{ - return m_basedisp.GetTypeInfo( - IID_IMediaEvent, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CMediaEvent::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) -{ - return m_basedisp.GetIDsOfNames( - IID_IMediaEvent, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CMediaEvent::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) -{ - // this parameter is a dead leftover from an earlier interface - if (IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if (FAILED(hr)) { - return hr; - } - - hr = pti->Invoke( - (IMediaEvent *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- CMediaPosition implementation ---------- - - -CMediaPosition::CMediaPosition(const TCHAR * name,LPUNKNOWN pUnk) : - CUnknown(name, pUnk) -{ -} - -CMediaPosition::CMediaPosition(const TCHAR * name, - LPUNKNOWN pUnk, - HRESULT * phr) : - CUnknown(name, pUnk) -{ - UNREFERENCED_PARAMETER(phr); -} - - -// expose our interfaces IMediaPosition and IUnknown - -STDMETHODIMP -CMediaPosition::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if (riid == IID_IMediaPosition) { - return GetInterface( (IMediaPosition *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// return 1 if we support GetTypeInfo - -STDMETHODIMP -CMediaPosition::GetTypeInfoCount(UINT * pctinfo) -{ - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -// attempt to find our type library - -STDMETHODIMP -CMediaPosition::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) -{ - return m_basedisp.GetTypeInfo( - IID_IMediaPosition, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CMediaPosition::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) -{ - return m_basedisp.GetIDsOfNames( - IID_IMediaPosition, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CMediaPosition::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) -{ - // this parameter is a dead leftover from an earlier interface - if (IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if (FAILED(hr)) { - return hr; - } - - hr = pti->Invoke( - (IMediaPosition *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- IMediaPosition and IMediaSeeking pass through class ---------- - - -CPosPassThru::CPosPassThru(const TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - IPin *pPin) : - CMediaPosition(pName,pUnk), - m_pPin(pPin) -{ - if (pPin == NULL) { - *phr = E_POINTER; - return; - } -} - - -// Expose our IMediaSeeking and IMediaPosition interfaces - -STDMETHODIMP -CPosPassThru::NonDelegatingQueryInterface(REFIID riid,void **ppv) -{ - CheckPointer(ppv,E_POINTER); - *ppv = NULL; - - if (riid == IID_IMediaSeeking) { - return GetInterface( static_cast(this), ppv); - } - return CMediaPosition::NonDelegatingQueryInterface(riid,ppv); -} - - -// Return the IMediaPosition interface from our peer - -HRESULT -CPosPassThru::GetPeer(IMediaPosition ** ppMP) -{ - *ppMP = NULL; - - IPin *pConnected; - HRESULT hr = m_pPin->ConnectedTo(&pConnected); - if (FAILED(hr)) { - return E_NOTIMPL; - } - IMediaPosition * pMP; - hr = pConnected->QueryInterface(IID_IMediaPosition, (void **) &pMP); - pConnected->Release(); - if (FAILED(hr)) { - return E_NOTIMPL; - } - - *ppMP = pMP; - return S_OK; -} - - -// Return the IMediaSeeking interface from our peer - -HRESULT -CPosPassThru::GetPeerSeeking(IMediaSeeking ** ppMS) -{ - *ppMS = NULL; - - IPin *pConnected; - HRESULT hr = m_pPin->ConnectedTo(&pConnected); - if (FAILED(hr)) { - return E_NOTIMPL; - } - IMediaSeeking * pMS; - hr = pConnected->QueryInterface(IID_IMediaSeeking, (void **) &pMS); - pConnected->Release(); - if (FAILED(hr)) { - return E_NOTIMPL; - } - - *ppMS = pMS; - return S_OK; -} - - -// --- IMediaSeeking methods ---------- - - -STDMETHODIMP -CPosPassThru::GetCapabilities(DWORD * pCaps) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->GetCapabilities(pCaps); - pMS->Release(); - return hr; -} - -STDMETHODIMP -CPosPassThru::CheckCapabilities(DWORD * pCaps) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->CheckCapabilities(pCaps); - pMS->Release(); - return hr; -} - -STDMETHODIMP -CPosPassThru::IsFormatSupported(const GUID * pFormat) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->IsFormatSupported(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::QueryPreferredFormat(GUID *pFormat) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->QueryPreferredFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::SetTimeFormat(const GUID * pFormat) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->SetTimeFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::GetTimeFormat(GUID *pFormat) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->GetTimeFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::IsUsingTimeFormat(const GUID * pFormat) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->IsUsingTimeFormat(pFormat); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::ConvertTimeFormat(LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->ConvertTimeFormat(pTarget, pTargetFormat, Source, pSourceFormat ); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->SetPositions(pCurrent, CurrentFlags, pStop, StopFlags ); - pMS->Release(); - return hr; -} - -STDMETHODIMP -CPosPassThru::GetPositions(LONGLONG *pCurrent, LONGLONG * pStop) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->GetPositions(pCurrent,pStop); - pMS->Release(); - return hr; -} - -HRESULT -CPosPassThru::GetSeekingLongLong -( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * ) -, LONGLONG * pll -) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (SUCCEEDED(hr)) - { - hr = (pMS->*pMethod)(pll); - pMS->Release(); - } - return hr; -} - -// If we don't have a current position then ask upstream - -STDMETHODIMP -CPosPassThru::GetCurrentPosition(LONGLONG *pCurrent) -{ - // Can we report the current position - HRESULT hr = GetMediaTime(pCurrent,NULL); - if (SUCCEEDED(hr)) hr = NOERROR; - else hr = GetSeekingLongLong( &IMediaSeeking::GetCurrentPosition, pCurrent ); - return hr; -} - - -STDMETHODIMP -CPosPassThru::GetStopPosition(LONGLONG *pStop) -{ - return GetSeekingLongLong( &IMediaSeeking::GetStopPosition, pStop );; -} - -STDMETHODIMP -CPosPassThru::GetDuration(LONGLONG *pDuration) -{ - return GetSeekingLongLong( &IMediaSeeking::GetDuration, pDuration );; -} - - -STDMETHODIMP -CPosPassThru::GetPreroll(LONGLONG *pllPreroll) -{ - return GetSeekingLongLong( &IMediaSeeking::GetPreroll, pllPreroll );; -} - - -STDMETHODIMP -CPosPassThru::GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest ) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - - hr = pMS->GetAvailable( pEarliest, pLatest ); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::GetRate(double * pdRate) -{ - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - hr = pMS->GetRate(pdRate); - pMS->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::SetRate(double dRate) -{ - if (0.0 == dRate) { - return E_INVALIDARG; - } - - IMediaSeeking* pMS; - HRESULT hr = GetPeerSeeking(&pMS); - if (FAILED(hr)) { - return hr; - } - hr = pMS->SetRate(dRate); - pMS->Release(); - return hr; -} - - - - -// --- IMediaPosition methods ---------- - - -STDMETHODIMP -CPosPassThru::get_Duration(REFTIME * plength) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - - hr = pMP->get_Duration(plength); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_CurrentPosition(REFTIME * pllTime) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->get_CurrentPosition(pllTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_CurrentPosition(REFTIME llTime) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->put_CurrentPosition(llTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_StopTime(REFTIME * pllTime) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->get_StopTime(pllTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_StopTime(REFTIME llTime) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->put_StopTime(llTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_PrerollTime(REFTIME * pllTime) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->get_PrerollTime(pllTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_PrerollTime(REFTIME llTime) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->put_PrerollTime(llTime); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::get_Rate(double * pdRate) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->get_Rate(pdRate); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::put_Rate(double dRate) -{ - if (0.0 == dRate) { - return E_INVALIDARG; - } - - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->put_Rate(dRate); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::CanSeekForward(LONG *pCanSeekForward) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->CanSeekForward(pCanSeekForward); - pMP->Release(); - return hr; -} - - -STDMETHODIMP -CPosPassThru::CanSeekBackward(LONG *pCanSeekBackward) -{ - IMediaPosition* pMP; - HRESULT hr = GetPeer(&pMP); - if (FAILED(hr)) { - return hr; - } - hr = pMP->CanSeekBackward(pCanSeekBackward); - pMP->Release(); - return hr; -} - - -// --- Implements the CRendererPosPassThru class ---------- - - -// Media times (eg current frame, field, sample etc) are passed through the -// filtergraph in media samples. When a renderer gets a sample with media -// times in it, it will call one of the RegisterMediaTime methods we expose -// (one takes an IMediaSample, the other takes the media times direct). We -// store the media times internally and return them in GetCurrentPosition. - -CRendererPosPassThru::CRendererPosPassThru(const TCHAR *pName, - LPUNKNOWN pUnk, - HRESULT *phr, - IPin *pPin) : - CPosPassThru(pName,pUnk,phr,pPin), - m_StartMedia(0), - m_EndMedia(0), - m_bReset(TRUE) -{ -} - - -// Sets the media times the object should report - -HRESULT -CRendererPosPassThru::RegisterMediaTime(IMediaSample *pMediaSample) -{ - ASSERT(pMediaSample); - LONGLONG StartMedia; - LONGLONG EndMedia; - - CAutoLock cAutoLock(&m_PositionLock); - - // Get the media times from the sample - - HRESULT hr = pMediaSample->GetTime(&StartMedia,&EndMedia); - if (FAILED(hr)) - { - ASSERT(hr == VFW_E_SAMPLE_TIME_NOT_SET); - return hr; - } - - m_StartMedia = StartMedia; - m_EndMedia = EndMedia; - m_bReset = FALSE; - return NOERROR; -} - - -// Sets the media times the object should report - -HRESULT -CRendererPosPassThru::RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime) -{ - CAutoLock cAutoLock(&m_PositionLock); - m_StartMedia = StartTime; - m_EndMedia = EndTime; - m_bReset = FALSE; - return NOERROR; -} - - -// Return the current media times registered in the object - -HRESULT -CRendererPosPassThru::GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime) -{ - ASSERT(pStartTime); - - CAutoLock cAutoLock(&m_PositionLock); - if (m_bReset == TRUE) { - return E_FAIL; - } - - // We don't have to return the end time - - HRESULT hr = ConvertTimeFormat( pStartTime, 0, m_StartMedia, &TIME_FORMAT_MEDIA_TIME ); - if (pEndTime && SUCCEEDED(hr)) { - hr = ConvertTimeFormat( pEndTime, 0, m_EndMedia, &TIME_FORMAT_MEDIA_TIME ); - } - return hr; -} - - -// Resets the media times we hold - -HRESULT -CRendererPosPassThru::ResetMediaTime() -{ - CAutoLock cAutoLock(&m_PositionLock); - m_StartMedia = 0; - m_EndMedia = 0; - m_bReset = TRUE; - return NOERROR; -} - -// Intended to be called by the owing filter during EOS processing so -// that the media times can be adjusted to the stop time. This ensures -// that the GetCurrentPosition will actully get to the stop position. -HRESULT -CRendererPosPassThru::EOS() -{ - HRESULT hr; - - if ( m_bReset == TRUE ) hr = E_FAIL; - else - { - LONGLONG llStop; - if SUCCEEDED(hr=GetStopPosition(&llStop)) - { - CAutoLock cAutoLock(&m_PositionLock); - m_StartMedia = - m_EndMedia = llStop; - } - } - return hr; -} - -// -- CSourceSeeking implementation ------------ - -CSourceSeeking::CSourceSeeking( - const TCHAR * pName, - LPUNKNOWN pUnk, - HRESULT* phr, - CCritSec * pLock) : - CUnknown(pName, pUnk), - m_pLock(pLock), - m_rtStart((long)0) -{ - m_rtStop = _I64_MAX / 2; - m_rtDuration = m_rtStop; - m_dRateSeeking = 1.0; - - m_dwSeekingCaps = AM_SEEKING_CanSeekForwards - | AM_SEEKING_CanSeekBackwards - | AM_SEEKING_CanSeekAbsolute - | AM_SEEKING_CanGetStopPos - | AM_SEEKING_CanGetDuration; -} - -HRESULT CSourceSeeking::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - if(riid == IID_IMediaSeeking) { - CheckPointer(ppv, E_POINTER); - return GetInterface(static_cast(this), ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -HRESULT CSourceSeeking::IsFormatSupported(const GUID * pFormat) -{ - CheckPointer(pFormat, E_POINTER); - // only seeking in time (REFERENCE_TIME units) is supported - return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE; -} - -HRESULT CSourceSeeking::QueryPreferredFormat(GUID *pFormat) -{ - CheckPointer(pFormat, E_POINTER); - *pFormat = TIME_FORMAT_MEDIA_TIME; - return S_OK; -} - -HRESULT CSourceSeeking::SetTimeFormat(const GUID * pFormat) -{ - CheckPointer(pFormat, E_POINTER); - - // nothing to set; just check that it's TIME_FORMAT_TIME - return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : E_INVALIDARG; -} - -HRESULT CSourceSeeking::IsUsingTimeFormat(const GUID * pFormat) -{ - CheckPointer(pFormat, E_POINTER); - return *pFormat == TIME_FORMAT_MEDIA_TIME ? S_OK : S_FALSE; -} - -HRESULT CSourceSeeking::GetTimeFormat(GUID *pFormat) -{ - CheckPointer(pFormat, E_POINTER); - *pFormat = TIME_FORMAT_MEDIA_TIME; - return S_OK; -} - -HRESULT CSourceSeeking::GetDuration(LONGLONG *pDuration) -{ - CheckPointer(pDuration, E_POINTER); - CAutoLock lock(m_pLock); - *pDuration = m_rtDuration; - return S_OK; -} - -HRESULT CSourceSeeking::GetStopPosition(LONGLONG *pStop) -{ - CheckPointer(pStop, E_POINTER); - CAutoLock lock(m_pLock); - *pStop = m_rtStop; - return S_OK; -} - -HRESULT CSourceSeeking::GetCurrentPosition(LONGLONG *pCurrent) -{ - // GetCurrentPosition is typically supported only in renderers and - // not in source filters. - return E_NOTIMPL; -} - -HRESULT CSourceSeeking::GetCapabilities( DWORD * pCapabilities ) -{ - CheckPointer(pCapabilities, E_POINTER); - *pCapabilities = m_dwSeekingCaps; - return S_OK; -} - -HRESULT CSourceSeeking::CheckCapabilities( DWORD * pCapabilities ) -{ - CheckPointer(pCapabilities, E_POINTER); - - // make sure all requested capabilities are in our mask - return (~m_dwSeekingCaps & *pCapabilities) ? S_FALSE : S_OK; -} - -HRESULT CSourceSeeking::ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ) -{ - CheckPointer(pTarget, E_POINTER); - // format guids can be null to indicate current format - - // since we only support TIME_FORMAT_MEDIA_TIME, we don't really - // offer any conversions. - if(pTargetFormat == 0 || *pTargetFormat == TIME_FORMAT_MEDIA_TIME) - { - if(pSourceFormat == 0 || *pSourceFormat == TIME_FORMAT_MEDIA_TIME) - { - *pTarget = Source; - return S_OK; - } - } - - return E_INVALIDARG; -} - - -HRESULT CSourceSeeking::SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ) -{ - DWORD StopPosBits = StopFlags & AM_SEEKING_PositioningBitsMask; - DWORD StartPosBits = CurrentFlags & AM_SEEKING_PositioningBitsMask; - - if(StopFlags) { - CheckPointer(pStop, E_POINTER); - - // accept only relative, incremental, or absolute positioning - if(StopPosBits != StopFlags) { - return E_INVALIDARG; - } - } - - if(CurrentFlags) { - CheckPointer(pCurrent, E_POINTER); - if(StartPosBits != AM_SEEKING_AbsolutePositioning && - StartPosBits != AM_SEEKING_RelativePositioning) { - return E_INVALIDARG; - } - } - - - // scope for autolock - { - CAutoLock lock(m_pLock); - - // set start position - if(StartPosBits == AM_SEEKING_AbsolutePositioning) - { - m_rtStart = *pCurrent; - } - else if(StartPosBits == AM_SEEKING_RelativePositioning) - { - m_rtStart += *pCurrent; - } - - // set stop position - if(StopPosBits == AM_SEEKING_AbsolutePositioning) - { - m_rtStop = *pStop; - } - else if(StopPosBits == AM_SEEKING_IncrementalPositioning) - { - m_rtStop = m_rtStart + *pStop; - } - else if(StopPosBits == AM_SEEKING_RelativePositioning) - { - m_rtStop = m_rtStop + *pStop; - } - } - - - HRESULT hr = S_OK; - if(SUCCEEDED(hr) && StopPosBits) { - hr = ChangeStop(); - } - if(StartPosBits) { - hr = ChangeStart(); - } - - return hr; -} - - -HRESULT CSourceSeeking::GetPositions( LONGLONG * pCurrent, LONGLONG * pStop ) -{ - if(pCurrent) { - *pCurrent = m_rtStart; - } - if(pStop) { - *pStop = m_rtStop; - } - - return S_OK;; -} - - -HRESULT CSourceSeeking::GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest ) -{ - if(pEarliest) { - *pEarliest = 0; - } - if(pLatest) { - CAutoLock lock(m_pLock); - *pLatest = m_rtDuration; - } - return S_OK; -} - -HRESULT CSourceSeeking::SetRate( double dRate) -{ - { - CAutoLock lock(m_pLock); - m_dRateSeeking = dRate; - } - return ChangeRate(); -} - -HRESULT CSourceSeeking::GetRate( double * pdRate) -{ - CheckPointer(pdRate, E_POINTER); - CAutoLock lock(m_pLock); - *pdRate = m_dRateSeeking; - return S_OK; -} - -HRESULT CSourceSeeking::GetPreroll(LONGLONG *pPreroll) -{ - CheckPointer(pPreroll, E_POINTER); - *pPreroll = 0; - return S_OK; -} - - - - - -// --- CSourcePosition implementation ---------- - - -CSourcePosition::CSourcePosition(const TCHAR * pName, - LPUNKNOWN pUnk, - HRESULT* phr, - CCritSec * pLock) : - CMediaPosition(pName, pUnk), - m_pLock(pLock), - m_Start(CRefTime((LONGLONG)0)) -{ - m_Stop = _I64_MAX; - m_Rate = 1.0; -} - - -STDMETHODIMP -CSourcePosition::get_Duration(REFTIME * plength) -{ - CheckPointer(plength,E_POINTER); - ValidateReadWritePtr(plength,sizeof(REFTIME)); - CAutoLock lock(m_pLock); - - *plength = m_Duration; - return S_OK; -} - - -STDMETHODIMP -CSourcePosition::put_CurrentPosition(REFTIME llTime) -{ - m_pLock->Lock(); - m_Start = llTime; - m_pLock->Unlock(); - - return ChangeStart(); -} - - -STDMETHODIMP -CSourcePosition::get_StopTime(REFTIME * pllTime) -{ - CheckPointer(pllTime,E_POINTER); - ValidateReadWritePtr(pllTime,sizeof(REFTIME)); - CAutoLock lock(m_pLock); - - *pllTime = m_Stop; - return S_OK; -} - - -STDMETHODIMP -CSourcePosition::put_StopTime(REFTIME llTime) -{ - m_pLock->Lock(); - m_Stop = llTime; - m_pLock->Unlock(); - - return ChangeStop(); -} - - -STDMETHODIMP -CSourcePosition::get_PrerollTime(REFTIME * pllTime) -{ - CheckPointer(pllTime,E_POINTER); - ValidateReadWritePtr(pllTime,sizeof(REFTIME)); - return E_NOTIMPL; -} - - -STDMETHODIMP -CSourcePosition::put_PrerollTime(REFTIME llTime) -{ - return E_NOTIMPL; -} - - -STDMETHODIMP -CSourcePosition::get_Rate(double * pdRate) -{ - CheckPointer(pdRate,E_POINTER); - ValidateReadWritePtr(pdRate,sizeof(double)); - CAutoLock lock(m_pLock); - - *pdRate = m_Rate; - return S_OK; -} - - -STDMETHODIMP -CSourcePosition::put_Rate(double dRate) -{ - m_pLock->Lock(); - m_Rate = dRate; - m_pLock->Unlock(); - - return ChangeRate(); -} - - -// By default we can seek forwards - -STDMETHODIMP -CSourcePosition::CanSeekForward(LONG *pCanSeekForward) -{ - CheckPointer(pCanSeekForward,E_POINTER); - *pCanSeekForward = OATRUE; - return S_OK; -} - - -// By default we can seek backwards - -STDMETHODIMP -CSourcePosition::CanSeekBackward(LONG *pCanSeekBackward) -{ - CheckPointer(pCanSeekBackward,E_POINTER); - *pCanSeekBackward = OATRUE; - return S_OK; -} - - -// --- Implementation of CBasicAudio class ---------- - - -CBasicAudio::CBasicAudio(const TCHAR * pName,LPUNKNOWN punk) : - CUnknown(pName, punk) -{ -} - -// overriden to publicise our interfaces - -STDMETHODIMP -CBasicAudio::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if (riid == IID_IBasicAudio) { - return GetInterface( (IBasicAudio *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -STDMETHODIMP -CBasicAudio::GetTypeInfoCount(UINT * pctinfo) -{ - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -STDMETHODIMP -CBasicAudio::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) -{ - return m_basedisp.GetTypeInfo( - IID_IBasicAudio, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CBasicAudio::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) -{ - return m_basedisp.GetIDsOfNames( - IID_IBasicAudio, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CBasicAudio::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) -{ - // this parameter is a dead leftover from an earlier interface - if (IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if (FAILED(hr)) { - return hr; - } - - hr = pti->Invoke( - (IBasicAudio *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- IVideoWindow implementation ---------- - -CBaseVideoWindow::CBaseVideoWindow(const TCHAR * pName,LPUNKNOWN punk) : - CUnknown(pName, punk) -{ -} - - -// overriden to publicise our interfaces - -STDMETHODIMP -CBaseVideoWindow::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if (riid == IID_IVideoWindow) { - return GetInterface( (IVideoWindow *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -STDMETHODIMP -CBaseVideoWindow::GetTypeInfoCount(UINT * pctinfo) -{ - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -STDMETHODIMP -CBaseVideoWindow::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) -{ - return m_basedisp.GetTypeInfo( - IID_IVideoWindow, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CBaseVideoWindow::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) -{ - return m_basedisp.GetIDsOfNames( - IID_IVideoWindow, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CBaseVideoWindow::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) -{ - // this parameter is a dead leftover from an earlier interface - if (IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if (FAILED(hr)) { - return hr; - } - - hr = pti->Invoke( - (IVideoWindow *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- IBasicVideo implementation ---------- - - -CBaseBasicVideo::CBaseBasicVideo(const TCHAR * pName,LPUNKNOWN punk) : - CUnknown(pName, punk) -{ -} - - -// overriden to publicise our interfaces - -STDMETHODIMP -CBaseBasicVideo::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if (riid == IID_IBasicVideo || riid == IID_IBasicVideo2) { - return GetInterface( static_cast(this), ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -STDMETHODIMP -CBaseBasicVideo::GetTypeInfoCount(UINT * pctinfo) -{ - return m_basedisp.GetTypeInfoCount(pctinfo); -} - - -STDMETHODIMP -CBaseBasicVideo::GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo) -{ - return m_basedisp.GetTypeInfo( - IID_IBasicVideo, - itinfo, - lcid, - pptinfo); -} - - -STDMETHODIMP -CBaseBasicVideo::GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid) -{ - return m_basedisp.GetIDsOfNames( - IID_IBasicVideo, - rgszNames, - cNames, - lcid, - rgdispid); -} - - -STDMETHODIMP -CBaseBasicVideo::Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr) -{ - // this parameter is a dead leftover from an earlier interface - if (IID_NULL != riid) { - return DISP_E_UNKNOWNINTERFACE; - } - - ITypeInfo * pti; - HRESULT hr = GetTypeInfo(0, lcid, &pti); - - if (FAILED(hr)) { - return hr; - } - - hr = pti->Invoke( - (IBasicVideo *)this, - dispidMember, - wFlags, - pdispparams, - pvarResult, - pexcepinfo, - puArgErr); - - pti->Release(); - return hr; -} - - -// --- Implementation of Deferred Commands ---------- - - -CDispParams::CDispParams(UINT nArgs, VARIANT* pArgs, HRESULT *phr) -{ - cNamedArgs = 0; - rgdispidNamedArgs = NULL; - cArgs = nArgs; - - if (cArgs) { - rgvarg = new VARIANT[cArgs]; - if (NULL == rgvarg) { - cArgs = 0; - if (phr) { - *phr = E_OUTOFMEMORY; - } - return; - } - - for (UINT i = 0; i < cArgs; i++) { - - VARIANT * pDest = &rgvarg[i]; - VARIANT * pSrc = &pArgs[i]; - - pDest->vt = pSrc->vt; - switch(pDest->vt) { - - case VT_I4: - pDest->lVal = pSrc->lVal; - break; - - case VT_UI1: - pDest->bVal = pSrc->bVal; - break; - - case VT_I2: - pDest->iVal = pSrc->iVal; - break; - - case VT_R4: - pDest->fltVal = pSrc->fltVal; - break; - - case VT_R8: - pDest->dblVal = pSrc->dblVal; - break; - - case VT_BOOL: - pDest->boolVal = pSrc->boolVal; - break; - - case VT_ERROR: - pDest->scode = pSrc->scode; - break; - - case VT_CY: - pDest->cyVal = pSrc->cyVal; - break; - - case VT_DATE: - pDest->date = pSrc->date; - break; - - case VT_BSTR: - if (pSrc->bstrVal == NULL) { - pDest->bstrVal = NULL; - } else { - - // a BSTR is a WORD followed by a UNICODE string. - // the pointer points just after the WORD - - WORD len = * (WORD*) (pSrc->bstrVal - (sizeof(WORD) / sizeof(OLECHAR))); - OLECHAR* pch = new OLECHAR[len + (sizeof(WORD)/sizeof(OLECHAR))]; - if (pch) { - WORD *pui = (WORD*)pch; - *pui = len; - pDest->bstrVal = pch + (sizeof(WORD)/sizeof(OLECHAR)); - CopyMemory(pDest->bstrVal, pSrc->bstrVal, len*sizeof(OLECHAR)); - } else { - cArgs = i; - if (phr) { - *phr = E_OUTOFMEMORY; - } - } - } - pDest->bstrVal = pSrc->bstrVal; - break; - - case VT_UNKNOWN: - pDest->punkVal = pSrc->punkVal; - pDest->punkVal->AddRef(); - break; - - case VT_DISPATCH: - pDest->pdispVal = pSrc->pdispVal; - pDest->pdispVal->AddRef(); - break; - - default: - // a type we haven't got round to adding yet! - ASSERT(0); - break; - } - } - - } else { - rgvarg = NULL; - } - -} - - -CDispParams::~CDispParams() -{ - for (UINT i = 0; i < cArgs; i++) { - switch(rgvarg[i].vt) { - case VT_BSTR: - if (rgvarg[i].bstrVal != NULL) { - OLECHAR * pch = rgvarg[i].bstrVal - (sizeof(WORD)/sizeof(OLECHAR)); - delete pch; - } - break; - - case VT_UNKNOWN: - rgvarg[i].punkVal->Release(); - break; - - case VT_DISPATCH: - rgvarg[i].pdispVal->Release(); - break; - } - } - delete[] rgvarg; -} - - -// lifetime is controlled by refcounts (see defer.h) - -CDeferredCommand::CDeferredCommand( - CCmdQueue * pQ, - LPUNKNOWN pUnk, - HRESULT * phr, - LPUNKNOWN pUnkExecutor, - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long nArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream - ) : - CUnknown(NAME("DeferredCommand"), pUnk), - m_pQueue(pQ), - m_pUnk(pUnkExecutor), - m_iid(iid), - m_dispidMethod(dispidMethod), - m_wFlags(wFlags), - m_DispParams(nArgs, pDispParams, phr), - m_pvarResult(pvarResult), - m_bStream(bStream), - m_hrResult(E_ABORT) - -{ - // convert REFTIME to REFERENCE_TIME - COARefTime convertor(time); - m_time = convertor; - - // no check of time validity - it's ok to queue a command that's - // already late - - // check iid is supportable on pUnk by QueryInterface for it - IUnknown * pInterface; - HRESULT hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface); - if (FAILED(hr)) { - *phr = hr; - return; - } - pInterface->Release(); - - - // !!! check dispidMethod and param/return types using typelib - ITypeInfo *pti; - hr = m_Dispatch.GetTypeInfo(*iid, 0, 0, &pti); - if (FAILED(hr)) { - *phr = hr; - return; - } - // !!! some sort of ITypeInfo validity check here - pti->Release(); - - - // Fix up the dispid for put and get - if (wFlags == DISPATCH_PROPERTYPUT) { - m_DispParams.cNamedArgs = 1; - m_DispId = DISPID_PROPERTYPUT; - m_DispParams.rgdispidNamedArgs = &m_DispId; - } - - // all checks ok - add to queue - hr = pQ->Insert(this); - if (FAILED(hr)) { - *phr = hr; - } -} - - -// refcounts are held by caller of InvokeAt... and by list. So if -// we get here, we can't be on the list - -#if 0 -CDeferredCommand::~CDeferredCommand() -{ - // this assert is invalid since if the queue is deleted while we are - // still on the queue, we will have been removed by the queue and this - // m_pQueue will not have been modified. - // ASSERT(m_pQueue == NULL); - - // we don't hold a ref count on pUnk, which is the object that should - // execute the command. - // This is because there would otherwise be a circular refcount problem - // since pUnk probably owns the CmdQueue object that has a refcount - // on us. - // The lifetime of pUnk is guaranteed by it being part of, or lifetime - // controlled by, our parent object. As long as we are on the list, pUnk - // must be valid. Once we are off the list, we do not use pUnk. - -} -#endif - - -// overriden to publicise our interfaces - -STDMETHODIMP -CDeferredCommand::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ValidateReadWritePtr(ppv,sizeof(PVOID)); - if (riid == IID_IDeferredCommand) { - return GetInterface( (IDeferredCommand *) this, ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// remove from q. this will reduce the refcount by one (since the q -// holds a count) but can't make us go away since he must have a -// refcount in order to call this method. - -STDMETHODIMP -CDeferredCommand::Cancel() -{ - if (m_pQueue == NULL) { - return VFW_E_ALREADY_CANCELLED; - } - - HRESULT hr = m_pQueue->Remove(this); - if (FAILED(hr)) { - return hr; - } - - m_pQueue = NULL; - return S_OK; -} - - -STDMETHODIMP -CDeferredCommand::Confidence(LONG* pConfidence) -{ - return E_NOTIMPL; -} - - -STDMETHODIMP -CDeferredCommand::GetHResult(HRESULT * phrResult) -{ - CheckPointer(phrResult,E_POINTER); - ValidateReadWritePtr(phrResult,sizeof(HRESULT)); - - if (m_pQueue != NULL) { - return E_ABORT; - } - *phrResult = m_hrResult; - return S_OK; -} - - -// set the time to be a new time (checking that it is valid) and -// then requeue - -STDMETHODIMP -CDeferredCommand::Postpone(REFTIME newtime) -{ - - // check that this time is not past - // convert REFTIME to REFERENCE_TIME - COARefTime convertor(newtime); - - // check that the time has not passed - if (m_pQueue->CheckTime(convertor, IsStreamTime())) { - return VFW_E_TIME_ALREADY_PASSED; - } - - // extract from list - HRESULT hr = m_pQueue->Remove(this); - if (FAILED(hr)) { - return hr; - } - - // change time - m_time = convertor; - - // requeue - hr = m_pQueue->Insert(this); - - return hr; -} - - -HRESULT -CDeferredCommand::Invoke() -{ - // check that we are still outstanding - if (m_pQueue == NULL) { - return VFW_E_ALREADY_CANCELLED; - } - - // get the type info - ITypeInfo* pti; - HRESULT hr = m_Dispatch.GetTypeInfo(GetIID(), 0, 0, &pti); - if (FAILED(hr)) { - return hr; - } - - // qi for the expected interface and then invoke it. Note that we have to - // treat the returned interface as IUnknown since we don't know its type. - IUnknown* pInterface; - - hr = m_pUnk->QueryInterface(GetIID(), (void**) &pInterface); - if (FAILED(hr)) { - pti->Release(); - return hr; - } - - EXCEPINFO expinfo; - UINT uArgErr; - m_hrResult = pti->Invoke( - pInterface, - GetMethod(), - GetFlags(), - GetParams(), - GetResult(), - &expinfo, - &uArgErr); - - // release the interface we QI'd for - pInterface->Release(); - pti->Release(); - - - // remove from list whether or not successful - // or we loop indefinitely - hr = m_pQueue->Remove(this); - m_pQueue = NULL; - return hr; -} - - - -// --- CCmdQueue methods ---------- - - -CCmdQueue::CCmdQueue() : - m_listPresentation(NAME("Presentation time command list")), - m_listStream(NAME("Stream time command list")), - m_evDue(TRUE), // manual reset - m_dwAdvise(0), - m_pClock(NULL), - m_bRunning(FALSE) -{ -} - - -CCmdQueue::~CCmdQueue() -{ - // empty all our lists - - // we hold a refcount on each, so traverse and Release each - // entry then RemoveAll to empty the list - WXLIST_POSITION pos = m_listPresentation.GetHeadPosition(); - - while(pos) { - CDeferredCommand* pCmd = m_listPresentation.GetNext(pos); - pCmd->Release(); - } - m_listPresentation.RemoveAll(); - - pos = m_listStream.GetHeadPosition(); - - while(pos) { - CDeferredCommand* pCmd = m_listStream.GetNext(pos); - pCmd->Release(); - } - m_listStream.RemoveAll(); - - if (m_pClock) { - if (m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - m_dwAdvise = 0; - } - m_pClock->Release(); - } -} - - -// returns a new CDeferredCommand object that will be initialised with -// the parameters and will be added to the queue during construction. -// returns S_OK if successfully created otherwise an error and -// no object has been queued. - -HRESULT -CCmdQueue::New( - CDeferredCommand **ppCmd, - LPUNKNOWN pUnk, // this object will execute command - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long cArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream -) -{ - CAutoLock lock(&m_Lock); - - HRESULT hr = S_OK; - *ppCmd = NULL; - - CDeferredCommand* pCmd; - pCmd = new CDeferredCommand( - this, - NULL, // not aggregated - &hr, - pUnk, // this guy will execute - time, - iid, - dispidMethod, - wFlags, - cArgs, - pDispParams, - pvarResult, - puArgErr, - bStream); - - if (pCmd == NULL) { - hr = E_OUTOFMEMORY; - } else { - *ppCmd = pCmd; - } - return hr; -} - - -HRESULT -CCmdQueue::Insert(CDeferredCommand* pCmd) -{ - CAutoLock lock(&m_Lock); - - // addref the item - pCmd->AddRef(); - - CGenericList * pList; - if (pCmd->IsStreamTime()) { - pList = &m_listStream; - } else { - pList = &m_listPresentation; - } - WXLIST_POSITION pos = pList->GetHeadPosition(); - - // seek past all items that are before us - while (pos && - (pList->Get(pos)->GetTime() <= pCmd->GetTime())) { - - pList->GetNext(pos); - } - - // now at end of list or in front of items that come later - if (!pos) { - pList->AddTail(pCmd); - } else { - pList->AddBefore(pos, pCmd); - } - - SetTimeAdvise(); - return S_OK; -} - - -HRESULT -CCmdQueue::Remove(CDeferredCommand* pCmd) -{ - CAutoLock lock(&m_Lock); - HRESULT hr = S_OK; - - CGenericList * pList; - if (pCmd->IsStreamTime()) { - pList = &m_listStream; - } else { - pList = &m_listPresentation; - } - WXLIST_POSITION pos = pList->GetHeadPosition(); - - // traverse the list - while (pos && (pList->Get(pos) != pCmd)) { - pList->GetNext(pos); - } - - // did we drop off the end? - if (!pos) { - hr = VFW_E_NOT_FOUND; - } else { - - // found it - now take off list - pList->Remove(pos); - - // Insert did an AddRef, so release it - pCmd->Release(); - - // check that timer request is still for earliest time - SetTimeAdvise(); - } - return hr; -} - - -// set the clock used for timing - -HRESULT -CCmdQueue::SetSyncSource(IReferenceClock* pClock) -{ - CAutoLock lock(&m_Lock); - - // addref the new clock first in case they are the same - if (pClock) { - pClock->AddRef(); - } - - // kill any advise on the old clock - if (m_pClock) { - if (m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - m_dwAdvise = 0; - } - m_pClock->Release(); - } - m_pClock = pClock; - - // set up a new advise - SetTimeAdvise(); - return S_OK; -} - - -// set up a timer event with the reference clock - -void -CCmdQueue::SetTimeAdvise(void) -{ - // make sure we have a clock to use - if (!m_pClock) { - return; - } - - // reset the event whenever we are requesting a new signal - m_evDue.Reset(); - - // time 0 is earliest - CRefTime current; - - // find the earliest presentation time - if (m_listPresentation.GetCount() > 0) { - - WXLIST_POSITION pos = m_listPresentation.GetHeadPosition(); - current = m_listPresentation.Get(pos)->GetTime(); - } - - // if we're running, check the stream times too - if (m_bRunning) { - - CRefTime t; - - if (m_listStream.GetCount() > 0) { - - WXLIST_POSITION pos = m_listStream.GetHeadPosition(); - t = m_listStream.Get(pos)->GetTime(); - - // add on stream time offset to get presentation time - t += m_StreamTimeOffset; - - // is this earlier? - if ((current == TimeZero) || (t < current)) { - current = t; - } - } - } - - // need to change? - if ((current > TimeZero) && (current != m_tCurrentAdvise)) { - if (m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - // reset the event whenever we are requesting a new signal - m_evDue.Reset(); - } - - // ask for time advice - the first two params are either - // stream time offset and stream time or - // presentation time and 0. we always use the latter - HRESULT hr = m_pClock->AdviseTime( - (REFERENCE_TIME)current, - TimeZero, - (HEVENT) HANDLE(m_evDue), - &m_dwAdvise); - - ASSERT(SUCCEEDED(hr)); - m_tCurrentAdvise = current; - } -} - - -// switch to run mode. Streamtime to Presentation time mapping known. - -HRESULT -CCmdQueue::Run(REFERENCE_TIME tStreamTimeOffset) -{ - CAutoLock lock(&m_Lock); - - m_StreamTimeOffset = tStreamTimeOffset; - m_bRunning = TRUE; - - // ensure advise is accurate - SetTimeAdvise(); - return S_OK; -} - - -// switch to Stopped or Paused mode. Time mapping not known. - -HRESULT -CCmdQueue::EndRun() -{ - CAutoLock lock(&m_Lock); - - m_bRunning = FALSE; - - // check timer setting - stream times - SetTimeAdvise(); - return S_OK; -} - - -// return a pointer to the next due command. Blocks for msTimeout -// milliseconds until there is a due command. -// Stream-time commands will only become due between Run and Endrun calls. -// The command remains queued until invoked or cancelled. -// Returns E_ABORT if timeout occurs, otherwise S_OK (or other error). -// -// returns an AddRef'd object - -HRESULT -CCmdQueue::GetDueCommand(CDeferredCommand ** ppCmd, long msTimeout) -{ - // loop until we timeout or find a due command - for (;;) { - - { - CAutoLock lock(&m_Lock); - - - // find the earliest command - CDeferredCommand * pCmd = NULL; - - // check the presentation time and the - // stream time list to find the earliest - - if (m_listPresentation.GetCount() > 0) { - WXLIST_POSITION pos = m_listPresentation.GetHeadPosition(); - pCmd = m_listPresentation.Get(pos); - } - - if (m_bRunning && (m_listStream.GetCount() > 0)) { - WXLIST_POSITION pos = m_listStream.GetHeadPosition(); - CDeferredCommand* pStrm = m_listStream.Get(pos); - - CRefTime t = pStrm->GetTime() + m_StreamTimeOffset; - if (!pCmd || (t < pCmd->GetTime())) { - pCmd = pStrm; - } - } - - // if we have found one, is it due? - if (pCmd) { - if (CheckTime(pCmd->GetTime(), pCmd->IsStreamTime())) { - - // yes it's due - addref it - pCmd->AddRef(); - *ppCmd = pCmd; - return S_OK; - } - } - } - - // block until the advise is signalled - if (WaitForSingleObject(m_evDue, msTimeout) != WAIT_OBJECT_0) { - return E_ABORT; - } - } -} - - -// return a pointer to a command that will be due for a given time. -// Pass in a stream time here. The stream time offset will be passed -// in via the Run method. -// Commands remain queued until invoked or cancelled. -// This method will not block. It will report E_ABORT if there are no -// commands due yet. -// -// returns an AddRef'd object - -HRESULT -CCmdQueue::GetCommandDueFor(REFERENCE_TIME rtStream, CDeferredCommand**ppCmd) -{ - CAutoLock lock(&m_Lock); - - CRefTime tStream(rtStream); - - // find the earliest stream and presentation time commands - CDeferredCommand* pStream = NULL; - if (m_listStream.GetCount() > 0) { - WXLIST_POSITION pos = m_listStream.GetHeadPosition(); - pStream = m_listStream.Get(pos); - } - CDeferredCommand* pPresent = NULL; - if (m_listPresentation.GetCount() > 0) { - WXLIST_POSITION pos = m_listPresentation.GetHeadPosition(); - pPresent = m_listPresentation.Get(pos); - } - - // is there a presentation time that has passed already - if (pPresent && CheckTime(pPresent->GetTime(), FALSE)) { - pPresent->AddRef(); - *ppCmd = pPresent; - return S_OK; - } - - // is there a stream time command due before this stream time - if (pStream && (pStream->GetTime() <= tStream)) { - pPresent->AddRef(); - *ppCmd = pStream; - return S_OK; - } - - // if we are running, we can map presentation times to - // stream time. In this case, is there a presentation time command - // that will be due before this stream time is presented? - if (m_bRunning && pPresent) { - - // this stream time will appear at... - tStream += m_StreamTimeOffset; - - // due before that? - if (pPresent->GetTime() <= tStream) { - *ppCmd = pPresent; - return S_OK; - } - } - - // no commands due yet - return VFW_E_NOT_FOUND; -} - diff --git a/plugins/gs/gsdx9/baseclasses/ctlutil.h b/plugins/gs/gsdx9/baseclasses/ctlutil.h deleted file mode 100644 index 5df80c0d00..0000000000 --- a/plugins/gs/gsdx9/baseclasses/ctlutil.h +++ /dev/null @@ -1,919 +0,0 @@ -//------------------------------------------------------------------------------ -// File: CtlUtil.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Base classes implementing IDispatch parsing for the basic control dual -// interfaces. Derive from these and implement just the custom method and -// property methods. We also implement CPosPassThru that can be used by -// renderers and transforms to pass by IMediaPosition and IMediaSeeking - -#ifndef __CTLUTIL__ -#define __CTLUTIL__ - -// OLE Automation has different ideas of TRUE and FALSE - -#define OATRUE (-1) -#define OAFALSE (0) - - -// It's possible that we could replace this class with CreateStdDispatch - -class CBaseDispatch -{ - ITypeInfo * m_pti; - -public: - - CBaseDispatch() : m_pti(NULL) {} - ~CBaseDispatch(); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - REFIID riid, - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); -}; - - -class AM_NOVTABLE CMediaControl : - public IMediaControl, - public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CMediaControl(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -class AM_NOVTABLE CMediaEvent : - public IMediaEventEx, - public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CMediaEvent(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -class AM_NOVTABLE CMediaPosition : - public IMediaPosition, - public CUnknown -{ - CBaseDispatch m_basedisp; - - -public: - - CMediaPosition(const TCHAR *, LPUNKNOWN); - CMediaPosition(const TCHAR *, LPUNKNOWN, HRESULT *phr); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); - -}; - - -// OA-compatibility means that we must use double as the RefTime value, -// and REFERENCE_TIME (essentially a LONGLONG) within filters. -// this class converts between the two - -class COARefTime : public CRefTime { -public: - - COARefTime() { - }; - - COARefTime(CRefTime t) - : CRefTime(t) - { - }; - - COARefTime(REFERENCE_TIME t) - : CRefTime(t) - { - }; - - COARefTime(double d) { - m_time = (LONGLONG) (d * 10000000); - }; - - operator double() { - return double(m_time) / 10000000; - }; - - operator REFERENCE_TIME() { - return m_time; - }; - - COARefTime& operator=(const double& rd) { - m_time = (LONGLONG) (rd * 10000000); - return *this; - } - - COARefTime& operator=(const REFERENCE_TIME& rt) { - m_time = rt; - return *this; - } - - inline BOOL operator==(const COARefTime& rt) - { - return m_time == rt.m_time; - }; - - inline BOOL operator!=(const COARefTime& rt) - { - return m_time != rt.m_time; - }; - - inline BOOL operator < (const COARefTime& rt) - { - return m_time < rt.m_time; - }; - - inline BOOL operator > (const COARefTime& rt) - { - return m_time > rt.m_time; - }; - - inline BOOL operator >= (const COARefTime& rt) - { - return m_time >= rt.m_time; - }; - - inline BOOL operator <= (const COARefTime& rt) - { - return m_time <= rt.m_time; - }; - - inline COARefTime operator+(const COARefTime& rt) - { - return COARefTime(m_time + rt.m_time); - }; - - inline COARefTime operator-(const COARefTime& rt) - { - return COARefTime(m_time - rt.m_time); - }; - - inline COARefTime operator*(LONG l) - { - return COARefTime(m_time * l); - }; - - inline COARefTime operator/(LONG l) - { - return COARefTime(m_time / l); - }; - -private: - // Prevent bugs from constructing from LONG (which gets - // converted to double and then multiplied by 10000000 - COARefTime(LONG); - int operator=(LONG); -}; - - -// A utility class that handles IMediaPosition and IMediaSeeking on behalf -// of single-input pin renderers, or transform filters. -// -// Renderers will expose this from the filter; transform filters will -// expose it from the output pin and not the renderer. -// -// Create one of these, giving it your IPin* for your input pin, and delegate -// all IMediaPosition methods to it. It will query the input pin for -// IMediaPosition and respond appropriately. -// -// Call ForceRefresh if the pin connection changes. -// -// This class no longer caches the upstream IMediaPosition or IMediaSeeking -// it acquires it on each method call. This means ForceRefresh is not needed. -// The method is kept for source compatibility and to minimise the changes -// if we need to put it back later for performance reasons. - -class CPosPassThru : public IMediaSeeking, public CMediaPosition -{ - IPin *m_pPin; - - HRESULT GetPeer(IMediaPosition **ppMP); - HRESULT GetPeerSeeking(IMediaSeeking **ppMS); - -public: - - CPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *); - DECLARE_IUNKNOWN - - HRESULT ForceRefresh() { - return S_OK; - }; - - // override to return an accurate current position - virtual HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime) { - return E_FAIL; - } - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - - // IMediaSeeking methods - STDMETHODIMP GetCapabilities( DWORD * pCapabilities ); - STDMETHODIMP CheckCapabilities( DWORD * pCapabilities ); - STDMETHODIMP SetTimeFormat(const GUID * pFormat); - STDMETHODIMP GetTimeFormat(GUID *pFormat); - STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat); - STDMETHODIMP IsFormatSupported( const GUID * pFormat); - STDMETHODIMP QueryPreferredFormat( GUID *pFormat); - STDMETHODIMP ConvertTimeFormat(LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ); - STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ); - - STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop ); - STDMETHODIMP GetCurrentPosition( LONGLONG * pCurrent ); - STDMETHODIMP GetStopPosition( LONGLONG * pStop ); - STDMETHODIMP SetRate( double dRate); - STDMETHODIMP GetRate( double * pdRate); - STDMETHODIMP GetDuration( LONGLONG *pDuration); - STDMETHODIMP GetAvailable( LONGLONG *pEarliest, LONGLONG *pLatest ); - STDMETHODIMP GetPreroll( LONGLONG *pllPreroll ); - - // IMediaPosition properties - STDMETHODIMP get_Duration(REFTIME * plength); - STDMETHODIMP put_CurrentPosition(REFTIME llTime); - STDMETHODIMP get_StopTime(REFTIME * pllTime); - STDMETHODIMP put_StopTime(REFTIME llTime); - STDMETHODIMP get_PrerollTime(REFTIME * pllTime); - STDMETHODIMP put_PrerollTime(REFTIME llTime); - STDMETHODIMP get_Rate(double * pdRate); - STDMETHODIMP put_Rate(double dRate); - STDMETHODIMP get_CurrentPosition(REFTIME * pllTime); - STDMETHODIMP CanSeekForward(LONG *pCanSeekForward); - STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward); - -private: - HRESULT GetSeekingLongLong( HRESULT (__stdcall IMediaSeeking::*pMethod)( LONGLONG * ), - LONGLONG * pll ); -}; - - -// Adds the ability to return a current position - -class CRendererPosPassThru : public CPosPassThru -{ - CCritSec m_PositionLock; // Locks access to our position - LONGLONG m_StartMedia; // Start media time last seen - LONGLONG m_EndMedia; // And likewise the end media - BOOL m_bReset; // Have media times been set - -public: - - // Used to help with passing media times through graph - - CRendererPosPassThru(const TCHAR *, LPUNKNOWN, HRESULT*, IPin *); - HRESULT RegisterMediaTime(IMediaSample *pMediaSample); - HRESULT RegisterMediaTime(LONGLONG StartTime,LONGLONG EndTime); - HRESULT GetMediaTime(LONGLONG *pStartTime,LONGLONG *pEndTime); - HRESULT ResetMediaTime(); - HRESULT EOS(); -}; - -STDAPI CreatePosPassThru( - LPUNKNOWN pAgg, - BOOL bRenderer, - IPin *pPin, - IUnknown **ppPassThru -); - -// A class that handles the IDispatch part of IBasicAudio and leaves the -// properties and methods themselves pure virtual. - -class AM_NOVTABLE CBasicAudio : public IBasicAudio, public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CBasicAudio(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -// A class that handles the IDispatch part of IBasicVideo and leaves the -// properties and methods themselves pure virtual. - -class AM_NOVTABLE CBaseBasicVideo : public IBasicVideo2, public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CBaseBasicVideo(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); - - STDMETHODIMP GetPreferredAspectRatio( - long *plAspectX, - long *plAspectY) - { - return E_NOTIMPL; - } -}; - - -// A class that handles the IDispatch part of IVideoWindow and leaves the -// properties and methods themselves pure virtual. - -class AM_NOVTABLE CBaseVideoWindow : public IVideoWindow, public CUnknown -{ - CBaseDispatch m_basedisp; - -public: - - CBaseVideoWindow(const TCHAR *, LPUNKNOWN); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - /* IDispatch methods */ - STDMETHODIMP GetTypeInfoCount(UINT * pctinfo); - - STDMETHODIMP GetTypeInfo( - UINT itinfo, - LCID lcid, - ITypeInfo ** pptinfo); - - STDMETHODIMP GetIDsOfNames( - REFIID riid, - OLECHAR ** rgszNames, - UINT cNames, - LCID lcid, - DISPID * rgdispid); - - STDMETHODIMP Invoke( - DISPID dispidMember, - REFIID riid, - LCID lcid, - WORD wFlags, - DISPPARAMS * pdispparams, - VARIANT * pvarResult, - EXCEPINFO * pexcepinfo, - UINT * puArgErr); -}; - - -// abstract class to help source filters with their implementation -// of IMediaPosition. Derive from this and set the duration (and stop -// position). Also override NotifyChange to do something when the properties -// change. - -class AM_NOVTABLE CSourcePosition : public CMediaPosition -{ - -public: - CSourcePosition(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *); - - // IMediaPosition methods - STDMETHODIMP get_Duration(REFTIME * plength); - STDMETHODIMP put_CurrentPosition(REFTIME llTime); - STDMETHODIMP get_StopTime(REFTIME * pllTime); - STDMETHODIMP put_StopTime(REFTIME llTime); - STDMETHODIMP get_PrerollTime(REFTIME * pllTime); - STDMETHODIMP put_PrerollTime(REFTIME llTime); - STDMETHODIMP get_Rate(double * pdRate); - STDMETHODIMP put_Rate(double dRate); - STDMETHODIMP CanSeekForward(LONG *pCanSeekForward); - STDMETHODIMP CanSeekBackward(LONG *pCanSeekBackward); - - // override if you can return the data you are actually working on - STDMETHODIMP get_CurrentPosition(REFTIME * pllTime) { - return E_NOTIMPL; - }; - -protected: - - // we call this to notify changes. Override to handle them - virtual HRESULT ChangeStart() PURE; - virtual HRESULT ChangeStop() PURE; - virtual HRESULT ChangeRate() PURE; - - COARefTime m_Duration; - COARefTime m_Start; - COARefTime m_Stop; - double m_Rate; - - CCritSec * m_pLock; -}; - -class AM_NOVTABLE CSourceSeeking : - public IMediaSeeking, - public CUnknown -{ - -public: - - DECLARE_IUNKNOWN; - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // IMediaSeeking methods - - STDMETHODIMP IsFormatSupported(const GUID * pFormat); - STDMETHODIMP QueryPreferredFormat(GUID *pFormat); - STDMETHODIMP SetTimeFormat(const GUID * pFormat); - STDMETHODIMP IsUsingTimeFormat(const GUID * pFormat); - STDMETHODIMP GetTimeFormat(GUID *pFormat); - STDMETHODIMP GetDuration(LONGLONG *pDuration); - STDMETHODIMP GetStopPosition(LONGLONG *pStop); - STDMETHODIMP GetCurrentPosition(LONGLONG *pCurrent); - STDMETHODIMP GetCapabilities( DWORD * pCapabilities ); - STDMETHODIMP CheckCapabilities( DWORD * pCapabilities ); - STDMETHODIMP ConvertTimeFormat( LONGLONG * pTarget, const GUID * pTargetFormat, - LONGLONG Source, const GUID * pSourceFormat ); - - STDMETHODIMP SetPositions( LONGLONG * pCurrent, DWORD CurrentFlags - , LONGLONG * pStop, DWORD StopFlags ); - - STDMETHODIMP GetPositions( LONGLONG * pCurrent, LONGLONG * pStop ); - - STDMETHODIMP GetAvailable( LONGLONG * pEarliest, LONGLONG * pLatest ); - STDMETHODIMP SetRate( double dRate); - STDMETHODIMP GetRate( double * pdRate); - STDMETHODIMP GetPreroll(LONGLONG *pPreroll); - - -protected: - - // ctor - CSourceSeeking(const TCHAR *, LPUNKNOWN, HRESULT*, CCritSec *); - - // we call this to notify changes. Override to handle them - virtual HRESULT ChangeStart() PURE; - virtual HRESULT ChangeStop() PURE; - virtual HRESULT ChangeRate() PURE; - - CRefTime m_rtDuration; // length of stream - CRefTime m_rtStart; // source will start here - CRefTime m_rtStop; // source will stop here - double m_dRateSeeking; - - // seeking capabilities - DWORD m_dwSeekingCaps; - - CCritSec * m_pLock; -}; - - -// Base classes supporting Deferred commands. - -// Deferred commands are queued by calls to methods on the IQueueCommand -// interface, exposed by the filtergraph and by some filters. A successful -// call to one of these methods will return an IDeferredCommand interface -// representing the queued command. -// -// A CDeferredCommand object represents a single deferred command, and exposes -// the IDeferredCommand interface as well as other methods permitting time -// checks and actual execution. It contains a reference to the CCommandQueue -// object on which it is queued. -// -// CCommandQueue is a base class providing a queue of CDeferredCommand -// objects, and methods to add, remove, check status and invoke the queued -// commands. A CCommandQueue object would be part of an object that -// implemented IQueueCommand. - -class CCmdQueue; - -// take a copy of the params and store them. Release any allocated -// memory in destructor - -class CDispParams : public DISPPARAMS -{ -public: - CDispParams(UINT nArgs, VARIANT* pArgs, HRESULT *phr = NULL); - ~CDispParams(); -}; - - -// CDeferredCommand lifetime is controlled by refcounts. Caller of -// InvokeAt.. gets a refcounted interface pointer, and the CCmdQueue -// object also holds a refcount on us. Calling Cancel or Invoke takes -// us off the CCmdQueue and thus reduces the refcount by 1. Once taken -// off the queue we cannot be put back on the queue. - -class CDeferredCommand - : public CUnknown, - public IDeferredCommand -{ -public: - - CDeferredCommand( - CCmdQueue * pQ, - LPUNKNOWN pUnk, // aggregation outer unk - HRESULT * phr, - LPUNKNOWN pUnkExecutor, // object that will execute this cmd - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long cArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream - ); - - DECLARE_IUNKNOWN - - // override this to publicise our interfaces - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // IDeferredCommand methods - STDMETHODIMP Cancel(); - STDMETHODIMP Confidence( - LONG* pConfidence); - STDMETHODIMP Postpone( - REFTIME newtime); - STDMETHODIMP GetHResult( - HRESULT* phrResult); - - // other public methods - - HRESULT Invoke(); - - // access methods - - // returns TRUE if streamtime, FALSE if presentation time - BOOL IsStreamTime() { - return m_bStream; - }; - - CRefTime GetTime() { - return m_time; - }; - - REFIID GetIID() { - return *m_iid; - }; - - long GetMethod() { - return m_dispidMethod; - }; - - short GetFlags() { - return m_wFlags; - }; - - DISPPARAMS* GetParams() { - return &m_DispParams; - }; - - VARIANT* GetResult() { - return m_pvarResult; - }; - -protected: - - CCmdQueue* m_pQueue; - - // pUnk for the interface that we will execute the command on - LPUNKNOWN m_pUnk; - - // stored command data - REFERENCE_TIME m_time; - GUID* m_iid; - long m_dispidMethod; - short m_wFlags; - VARIANT* m_pvarResult; - BOOL m_bStream; - CDispParams m_DispParams; - DISPID m_DispId; // For get and put - - // we use this for ITypeInfo access - CBaseDispatch m_Dispatch; - - // save retval here - HRESULT m_hrResult; -}; - - -// a list of CDeferredCommand objects. this is a base class providing -// the basics of access to the list. If you want to use CDeferredCommand -// objects then your queue needs to be derived from this class. - -class AM_NOVTABLE CCmdQueue -{ -public: - CCmdQueue(); - virtual ~CCmdQueue(); - - // returns a new CDeferredCommand object that will be initialised with - // the parameters and will be added to the queue during construction. - // returns S_OK if successfully created otherwise an error and - // no object has been queued. - virtual HRESULT New( - CDeferredCommand **ppCmd, - LPUNKNOWN pUnk, - REFTIME time, - GUID* iid, - long dispidMethod, - short wFlags, - long cArgs, - VARIANT* pDispParams, - VARIANT* pvarResult, - short* puArgErr, - BOOL bStream - ); - - // called by the CDeferredCommand object to add and remove itself - // from the queue - virtual HRESULT Insert(CDeferredCommand* pCmd); - virtual HRESULT Remove(CDeferredCommand* pCmd); - - // Command-Due Checking - // - // There are two schemes of synchronisation: coarse and accurate. In - // coarse mode, you wait till the time arrives and then execute the cmd. - // In accurate mode, you wait until you are processing the sample that - // will appear at the time, and then execute the command. It's up to the - // filter which one it will implement. The filtergraph will always - // implement coarse mode for commands queued at the filtergraph. - // - // If you want coarse sync, you probably want to wait until there is a - // command due, and then execute it. You can do this by calling - // GetDueCommand. If you have several things to wait for, get the - // event handle from GetDueHandle() and when this is signalled then call - // GetDueCommand. Stream time will only advance between calls to Run and - // EndRun. Note that to avoid an extra thread there is no guarantee that - // if the handle is set there will be a command ready. Each time the - // event is signalled, call GetDueCommand (probably with a 0 timeout); - // This may return E_ABORT. - // - // If you want accurate sync, you must call GetCommandDueFor, passing - // as a parameter the stream time of the samples you are about to process. - // This will return: - // -- a stream-time command due at or before that stream time - // -- a presentation-time command due at or before the - // time that stream time will be presented (only between Run - // and EndRun calls, since outside of this, the mapping from - // stream time to presentation time is not known. - // -- any presentation-time command due now. - // This means that if you want accurate synchronisation on samples that - // might be processed during Paused mode, you need to use - // stream-time commands. - // - // In all cases, commands remain queued until Invoked or Cancelled. The - // setting and resetting of the event handle is managed entirely by this - // queue object. - - // set the clock used for timing - virtual HRESULT SetSyncSource(IReferenceClock*); - - // switch to run mode. Streamtime to Presentation time mapping known. - virtual HRESULT Run(REFERENCE_TIME tStreamTimeOffset); - - // switch to Stopped or Paused mode. Time mapping not known. - virtual HRESULT EndRun(); - - // return a pointer to the next due command. Blocks for msTimeout - // milliseconds until there is a due command. - // Stream-time commands will only become due between Run and Endrun calls. - // The command remains queued until invoked or cancelled. - // Returns E_ABORT if timeout occurs, otherwise S_OK (or other error). - // Returns an AddRef-ed object - virtual HRESULT GetDueCommand(CDeferredCommand ** ppCmd, long msTimeout); - - // return the event handle that will be signalled whenever - // there are deferred commands due for execution (when GetDueCommand - // will not block). - HANDLE GetDueHandle() { - return HANDLE(m_evDue); - }; - - // return a pointer to a command that will be due for a given time. - // Pass in a stream time here. The stream time offset will be passed - // in via the Run method. - // Commands remain queued until invoked or cancelled. - // This method will not block. It will report VFW_E_NOT_FOUND if there - // are no commands due yet. - // Returns an AddRef-ed object - virtual HRESULT GetCommandDueFor(REFERENCE_TIME tStream, CDeferredCommand**ppCmd); - - // check if a given time is due (TRUE if it is due yet) - BOOL CheckTime(CRefTime time, BOOL bStream) { - - // if no clock, nothing is due! - if (!m_pClock) { - return FALSE; - } - - // stream time - if (bStream) { - - // not valid if not running - if (!m_bRunning) { - return FALSE; - } - // add on known stream time offset to get presentation time - time += m_StreamTimeOffset; - } - - CRefTime Now; - m_pClock->GetTime((REFERENCE_TIME*)&Now); - return (time <= Now); - }; - -protected: - - // protect access to lists etc - CCritSec m_Lock; - - // commands queued in presentation time are stored here - CGenericList m_listPresentation; - - // commands queued in stream time are stored here - CGenericList m_listStream; - - // set when any commands are due - CAMEvent m_evDue; - - // creates an advise for the earliest time required, if any - void SetTimeAdvise(void); - - // advise id from reference clock (0 if no outstanding advise) - DWORD_PTR m_dwAdvise; - - // advise time is for this presentation time - CRefTime m_tCurrentAdvise; - - // the reference clock we are using (addrefed) - IReferenceClock* m_pClock; - - // true when running - BOOL m_bRunning; - - // contains stream time offset when m_bRunning is true - CRefTime m_StreamTimeOffset; -}; - -#endif // __CTLUTIL__ diff --git a/plugins/gs/gsdx9/baseclasses/ddmm.cpp b/plugins/gs/gsdx9/baseclasses/ddmm.cpp deleted file mode 100644 index 834ce990bb..0000000000 --- a/plugins/gs/gsdx9/baseclasses/ddmm.cpp +++ /dev/null @@ -1,129 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DDMM.cpp -// -// Desc: DirectShow base classes - implements routines for using DirectDraw -// on a multimonitor system. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include -#include "ddmm.h" - -/* - * FindDeviceCallback - */ -typedef struct { - LPSTR szDevice; - GUID* lpGUID; - GUID GUID; - BOOL fFound; -} FindDeviceData; - -BOOL CALLBACK FindDeviceCallback(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam) -{ - FindDeviceData *p = (FindDeviceData*)lParam; - - if (lstrcmpiA(p->szDevice, szDevice) == 0) { - if (lpGUID) { - p->GUID = *lpGUID; - p->lpGUID = &p->GUID; - } else { - p->lpGUID = NULL; - } - p->fFound = TRUE; - return FALSE; - } - return TRUE; -} - - -BOOL CALLBACK FindDeviceCallbackEx(GUID* lpGUID, LPSTR szName, LPSTR szDevice, LPVOID lParam, HMONITOR hMonitor) -{ - FindDeviceData *p = (FindDeviceData*)lParam; - - if (lstrcmpiA(p->szDevice, szDevice) == 0) { - if (lpGUID) { - p->GUID = *lpGUID; - p->lpGUID = &p->GUID; - } else { - p->lpGUID = NULL; - } - p->fFound = TRUE; - return FALSE; - } - return TRUE; -} - - -/* - * DirectDrawCreateFromDevice - * - * create a DirectDraw object for a particular device - */ -IDirectDraw * DirectDrawCreateFromDevice(LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, PDRAWENUM DirectDrawEnumerateP) -{ - IDirectDraw* pdd = NULL; - FindDeviceData find; - - if (szDevice == NULL) { - DirectDrawCreateP(NULL, &pdd, NULL); - return pdd; - } - - find.szDevice = szDevice; - find.fFound = FALSE; - DirectDrawEnumerateP(FindDeviceCallback, (LPVOID)&find); - - if (find.fFound) - { - // - // In 4bpp mode the following DDraw call causes a message box to be popped - // up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we - // make sure it doesn't happen. - // - UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); - DirectDrawCreateP(find.lpGUID, &pdd, NULL); - SetErrorMode(ErrorMode); - } - - return pdd; -} - - -/* - * DirectDrawCreateFromDeviceEx - * - * create a DirectDraw object for a particular device - */ -IDirectDraw * DirectDrawCreateFromDeviceEx(LPSTR szDevice, PDRAWCREATE DirectDrawCreateP, LPDIRECTDRAWENUMERATEEXA DirectDrawEnumerateExP) -{ - IDirectDraw* pdd = NULL; - FindDeviceData find; - - if (szDevice == NULL) { - DirectDrawCreateP(NULL, &pdd, NULL); - return pdd; - } - - find.szDevice = szDevice; - find.fFound = FALSE; - DirectDrawEnumerateExP(FindDeviceCallbackEx, (LPVOID)&find, - DDENUM_ATTACHEDSECONDARYDEVICES); - - if (find.fFound) - { - // - // In 4bpp mode the following DDraw call causes a message box to be popped - // up by DDraw (!?!). It's DDraw's fault, but we don't like it. So we - // make sure it doesn't happen. - // - UINT ErrorMode = SetErrorMode(SEM_FAILCRITICALERRORS); - DirectDrawCreateP(find.lpGUID, &pdd, NULL); - SetErrorMode(ErrorMode); - } - - return pdd; -} diff --git a/plugins/gs/gsdx9/baseclasses/ddmm.h b/plugins/gs/gsdx9/baseclasses/ddmm.h deleted file mode 100644 index 678bec3f66..0000000000 --- a/plugins/gs/gsdx9/baseclasses/ddmm.h +++ /dev/null @@ -1,28 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DDMM.h -// -// Desc: DirectShow base classes - efines routines for using DirectDraw -// on a multimonitor system. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifdef __cplusplus -extern "C" { /* Assume C declarations for C++ */ -#endif /* __cplusplus */ - -// DDRAW.H might not include these -#ifndef DDENUM_ATTACHEDSECONDARYDEVICES -#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001L -#endif - -typedef HRESULT (*PDRAWCREATE)(IID *,LPDIRECTDRAW *,LPUNKNOWN); -typedef HRESULT (*PDRAWENUM)(LPDDENUMCALLBACKA, LPVOID); - -IDirectDraw * DirectDrawCreateFromDevice(LPSTR, PDRAWCREATE, PDRAWENUM); -IDirectDraw * DirectDrawCreateFromDeviceEx(LPSTR, PDRAWCREATE, LPDIRECTDRAWENUMERATEEXA); - -#ifdef __cplusplus -} -#endif /* __cplusplus */ diff --git a/plugins/gs/gsdx9/baseclasses/dllentry.cpp b/plugins/gs/gsdx9/baseclasses/dllentry.cpp deleted file mode 100644 index be9fd1c32a..0000000000 --- a/plugins/gs/gsdx9/baseclasses/dllentry.cpp +++ /dev/null @@ -1,333 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DllEntry.cpp -// -// Desc: DirectShow base classes - implements classes used to support dll -// entry points for COM objects. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - -#include -#include - -#ifdef DEBUG -#ifdef UNICODE -#ifndef _UNICODE -#define _UNICODE -#endif // _UNICODE -#endif // UNICODE - -#endif // DEBUG - -extern CFactoryTemplate g_Templates[]; -extern int g_cTemplates; - -HINSTANCE g_hInst; -DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx) -OSVERSIONINFO g_osInfo; - -// -// an instance of this is created by the DLLGetClassObject entrypoint -// it uses the CFactoryTemplate object it is given to support the -// IClassFactory interface - -class CClassFactory : public IClassFactory, public CBaseObject -{ - -private: - const CFactoryTemplate *const m_pTemplate; - - ULONG m_cRef; - - static int m_cLocked; -public: - CClassFactory(const CFactoryTemplate *); - - // IUnknown - STDMETHODIMP QueryInterface(REFIID riid, void ** ppv); - STDMETHODIMP_(ULONG)AddRef(); - STDMETHODIMP_(ULONG)Release(); - - // IClassFactory - STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, void **pv); - STDMETHODIMP LockServer(BOOL fLock); - - // allow DLLGetClassObject to know about global server lock status - static BOOL IsLocked() { - return (m_cLocked > 0); - }; -}; - -// process-wide dll locked state -int CClassFactory::m_cLocked = 0; - -CClassFactory::CClassFactory(const CFactoryTemplate *pTemplate) -: CBaseObject(NAME("Class Factory")) -, m_cRef(0) -, m_pTemplate(pTemplate) -{ -} - - -STDMETHODIMP -CClassFactory::QueryInterface(REFIID riid,void **ppv) -{ - CheckPointer(ppv,E_POINTER) - ValidateReadWritePtr(ppv,sizeof(PVOID)); - *ppv = NULL; - - // any interface on this object is the object pointer. - if ((riid == IID_IUnknown) || (riid == IID_IClassFactory)) { - *ppv = (LPVOID) this; - // AddRef returned interface pointer - ((LPUNKNOWN) *ppv)->AddRef(); - return NOERROR; - } - - return ResultFromScode(E_NOINTERFACE); -} - - -STDMETHODIMP_(ULONG) -CClassFactory::AddRef() -{ - return ++m_cRef; -} - -STDMETHODIMP_(ULONG) -CClassFactory::Release() -{ - if (--m_cRef == 0) { - delete this; - return 0; - } else { - return m_cRef; - } -} - -STDMETHODIMP -CClassFactory::CreateInstance( - LPUNKNOWN pUnkOuter, - REFIID riid, - void **pv) -{ - CheckPointer(pv,E_POINTER) - ValidateReadWritePtr(pv,sizeof(void *)); - - /* Enforce the normal OLE rules regarding interfaces and delegation */ - - if (pUnkOuter != NULL) { - if (IsEqualIID(riid,IID_IUnknown) == FALSE) { - return ResultFromScode(E_NOINTERFACE); - } - } - - /* Create the new object through the derived class's create function */ - - HRESULT hr = NOERROR; - CUnknown *pObj = m_pTemplate->CreateInstance(pUnkOuter, &hr); - - if (pObj == NULL) { - if (SUCCEEDED(hr)) { - hr = E_OUTOFMEMORY; - } - return hr; - } - - /* Delete the object if we got a construction error */ - - if (FAILED(hr)) { - delete pObj; - return hr; - } - - /* Get a reference counted interface on the object */ - - /* We wrap the non-delegating QI with NDAddRef & NDRelease. */ - /* This protects any outer object from being prematurely */ - /* released by an inner object that may have to be created */ - /* in order to supply the requested interface. */ - pObj->NonDelegatingAddRef(); - hr = pObj->NonDelegatingQueryInterface(riid, pv); - pObj->NonDelegatingRelease(); - /* Note that if NonDelegatingQueryInterface fails, it will */ - /* not increment the ref count, so the NonDelegatingRelease */ - /* will drop the ref back to zero and the object will "self-*/ - /* destruct". Hence we don't need additional tidy-up code */ - /* to cope with NonDelegatingQueryInterface failing. */ - - if (SUCCEEDED(hr)) { - ASSERT(*pv); - } - - return hr; -} - -STDMETHODIMP -CClassFactory::LockServer(BOOL fLock) -{ - if (fLock) { - m_cLocked++; - } else { - m_cLocked--; - } - return NOERROR; -} - - -// --- COM entrypoints ----------------------------------------- - -//called by COM to get the class factory object for a given class -STDAPI -DllGetClassObject( - REFCLSID rClsID, - REFIID riid, - void **pv) -{ - if (!(riid == IID_IUnknown) && !(riid == IID_IClassFactory)) { - return E_NOINTERFACE; - } - - // traverse the array of templates looking for one with this - // class id - for (int i = 0; i < g_cTemplates; i++) { - const CFactoryTemplate * pT = &g_Templates[i]; - if (pT->IsClassID(rClsID)) { - - // found a template - make a class factory based on this - // template - - *pv = (LPVOID) (LPUNKNOWN) new CClassFactory(pT); - if (*pv == NULL) { - return E_OUTOFMEMORY; - } - ((LPUNKNOWN)*pv)->AddRef(); - return NOERROR; - } - } - return CLASS_E_CLASSNOTAVAILABLE; -} - -// -// Call any initialization routines -// -void -DllInitClasses(BOOL bLoading) -{ - int i; - - // traverse the array of templates calling the init routine - // if they have one - for (i = 0; i < g_cTemplates; i++) { - const CFactoryTemplate * pT = &g_Templates[i]; - if (pT->m_lpfnInit != NULL) { - (*pT->m_lpfnInit)(bLoading, pT->m_ClsID); - } - } - -} - -// called by COM to determine if this dll can be unloaded -// return ok unless there are outstanding objects or a lock requested -// by IClassFactory::LockServer -// -// CClassFactory has a static function that can tell us about the locks, -// and CCOMObject has a static function that can tell us about the active -// object count -STDAPI -DllCanUnloadNow() -{ - DbgLog((LOG_MEMORY,2,TEXT("DLLCanUnloadNow called - IsLocked = %d, Active objects = %d"), - CClassFactory::IsLocked(), - CBaseObject::ObjectsActive())); - - if (CClassFactory::IsLocked() || CBaseObject::ObjectsActive()) { - return S_FALSE; - } else { - return S_OK; - } -} - - -// --- standard WIN32 entrypoints -------------------------------------- - - -extern "C" BOOL WINAPI DllEntryPoint(HINSTANCE, ULONG, LPVOID); - -BOOL WINAPI -DllEntryPoint(HINSTANCE hInstance, ULONG ulReason, LPVOID pv) -{ -#ifdef DEBUG - extern bool g_fDbgInDllEntryPoint; - g_fDbgInDllEntryPoint = true; -#endif - - switch (ulReason) - { - - case DLL_PROCESS_ATTACH: - DisableThreadLibraryCalls(hInstance); - DbgInitialise(hInstance); - - { - // The platform identifier is used to work out whether - // full unicode support is available or not. Hence the - // default will be the lowest common denominator - i.e. N/A - g_amPlatform = VER_PLATFORM_WIN32_WINDOWS; // win95 assumed in case GetVersionEx fails - - g_osInfo.dwOSVersionInfoSize = sizeof(g_osInfo); - if (GetVersionEx(&g_osInfo)) { - g_amPlatform = g_osInfo.dwPlatformId; - } else { - DbgLog((LOG_ERROR, 1, TEXT("Failed to get the OS platform, assuming Win95"))); - } - } - - g_hInst = hInstance; - DllInitClasses(TRUE); - break; - - case DLL_PROCESS_DETACH: - DllInitClasses(FALSE); - -#ifdef DEBUG - if (CBaseObject::ObjectsActive()) { - DbgSetModuleLevel(LOG_MEMORY, 2); - TCHAR szInfo[512]; - extern TCHAR m_ModuleName[]; // Cut down module name - - TCHAR FullName[_MAX_PATH]; // Load the full path and module name - TCHAR *pName; // Searches from the end for a backslash - - GetModuleFileName(NULL,FullName,_MAX_PATH); - pName = _tcsrchr(FullName,'\\'); - if (pName == NULL) { - pName = FullName; - } else { - pName++; - } - - (void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("Executable: %s Pid %x Tid %x. "), - pName, GetCurrentProcessId(), GetCurrentThreadId()); - DWORD cch = lstrlen(szInfo); - - (void)StringCchPrintf(szInfo+cch, NUMELMS(szInfo) - cch, TEXT("Module %s, %d objects left active!"), - m_ModuleName, CBaseObject::ObjectsActive()); - DbgAssert(szInfo, TEXT(__FILE__),__LINE__); - - // If running remotely wait for the Assert to be acknowledged - // before dumping out the object register - DbgDumpObjectRegister(); - } - DbgTerminate(); -#endif - break; - } - -#ifdef DEBUG - g_fDbgInDllEntryPoint = false; -#endif - return TRUE; -} - - diff --git a/plugins/gs/gsdx9/baseclasses/dllsetup.cpp b/plugins/gs/gsdx9/baseclasses/dllsetup.cpp deleted file mode 100644 index a6551b89d4..0000000000 --- a/plugins/gs/gsdx9/baseclasses/dllsetup.cpp +++ /dev/null @@ -1,727 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DllSetup.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -//--------------------------------------------------------------------------- -// defines and constants - -#define MAX_KEY_LEN 260 - -#ifdef UNICODE -static LPCTSTR CLSID_KEY_FORMAT_STRING = TEXT("CLSID\\%s"); -#else -static LPCTSTR CLSID_KEY_FORMAT_STRING = TEXT("CLSID\\%S"); -#endif - -//--------------------------------------------------------------------------- -// externally defined functions/variable - -extern int g_cTemplates; -extern CFactoryTemplate g_Templates[]; - - -//--------------------------------------------------------------------------- -// internally defined functions - -static HRESULT -ConvertUnicodeStringToTCHARString( LPTSTR szDest, size_t cchDest, LPCWSTR szSource ); - -//--------------------------------------------------------------------------- -// -// EliminateSubKey -// -// Try to enumerate all keys under this one. -// if we find anything, delete it completely. -// Otherwise just delete it. -// -// note - this was pinched/duplicated from -// Filgraph\Mapper.cpp - so should it be in -// a lib somewhere? -// -//--------------------------------------------------------------------------- - -STDAPI -EliminateSubKey( HKEY hkey, LPTSTR strSubKey ) -{ - HKEY hk; - if (0 == lstrlen(strSubKey) ) { - // defensive approach - return E_FAIL; - } - - LONG lreturn = RegOpenKeyEx( hkey - , strSubKey - , 0 - , MAXIMUM_ALLOWED - , &hk ); - - ASSERT( lreturn == ERROR_SUCCESS - || lreturn == ERROR_FILE_NOT_FOUND - || lreturn == ERROR_INVALID_HANDLE ); - - if( ERROR_SUCCESS == lreturn ) - { - // Keep on enumerating the first (zero-th) - // key and deleting that - - for( ; ; ) - { - TCHAR Buffer[MAX_KEY_LEN]; - DWORD dw = MAX_KEY_LEN; - FILETIME ft; - - lreturn = RegEnumKeyEx( hk - , 0 - , Buffer - , &dw - , NULL - , NULL - , NULL - , &ft); - - ASSERT( lreturn == ERROR_SUCCESS - || lreturn == ERROR_NO_MORE_ITEMS ); - - if( ERROR_SUCCESS == lreturn ) - { - EliminateSubKey(hk, Buffer); - } - else - { - break; - } - } - - RegCloseKey(hk); - RegDeleteKey(hkey, strSubKey); - } - - return NOERROR; -} - - -//--------------------------------------------------------------------------- -// -// AMovieSetupRegisterServer() -// -// registers specfied file "szFileName" as server for -// CLSID "clsServer". A description is also required. -// The ThreadingModel and ServerType are optional, as -// they default to InprocServer32 (i.e. dll) and Both. -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieSetupRegisterServer( CLSID clsServer - , LPCWSTR szDescription - , LPCWSTR szFileName - , LPCWSTR szThreadingModel = L"Both" - , LPCWSTR szServerType = L"InprocServer32" ) -{ - // temp buffer - // - TCHAR achTemp[MAX_PATH]; - - // convert CLSID uuid to string and write - // out subkey as string - CLSID\{} - // - OLECHAR szCLSID[CHARS_IN_GUID]; - HRESULT hr = StringFromGUID2( clsServer - , szCLSID - , CHARS_IN_GUID ); - ASSERT( SUCCEEDED(hr) ); - - // create key - // - HKEY hkey; - - (void)StringCchPrintf( achTemp, NUMELMS(achTemp), CLSID_KEY_FORMAT_STRING, szCLSID ); - - LONG lreturn = RegCreateKey( HKEY_CLASSES_ROOT - , (LPCTSTR)achTemp - , &hkey ); - if( ERROR_SUCCESS != lreturn ) - { - return AmHresultFromWin32(lreturn); - } - - // set description string - // - - (void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szDescription ); - lreturn = RegSetValue( hkey - , (LPCTSTR)NULL - , REG_SZ - , achTemp - , sizeof(achTemp) ); - if( ERROR_SUCCESS != lreturn ) - { - RegCloseKey( hkey ); - return AmHresultFromWin32(lreturn); - } - - // create CLSID\\{"CLSID"}\\"ServerType" key, - // using key to CLSID\\{"CLSID"} passed back by - // last call to RegCreateKey(). - // - HKEY hsubkey; - - (void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szServerType ); - lreturn = RegCreateKey( hkey - , achTemp - , &hsubkey ); - if( ERROR_SUCCESS != lreturn ) - { - RegCloseKey( hkey ); - return AmHresultFromWin32(lreturn); - } - - // set Server string - // - (void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szFileName ); - lreturn = RegSetValue( hsubkey - , (LPCTSTR)NULL - , REG_SZ - , (LPCTSTR)achTemp - , sizeof(TCHAR) * (lstrlen(achTemp)+1) ); - if( ERROR_SUCCESS != lreturn ) - { - RegCloseKey( hkey ); - RegCloseKey( hsubkey ); - return AmHresultFromWin32(lreturn); - } - - (void)ConvertUnicodeStringToTCHARString( achTemp, NUMELMS(achTemp), szThreadingModel ); - lreturn = RegSetValueEx( hsubkey - , TEXT("ThreadingModel") - , 0L - , REG_SZ - , (CONST BYTE *)achTemp - , sizeof(TCHAR) * (lstrlen(achTemp)+1) ); - - // close hkeys - // - RegCloseKey( hkey ); - RegCloseKey( hsubkey ); - - // and return - // - return HRESULT_FROM_WIN32(lreturn); - -} - - -//--------------------------------------------------------------------------- -// -// AMovieSetupUnregisterServer() -// -// default ActiveMovie dll setup function -// - to use must be called from an exported -// function named DllRegisterServer() -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieSetupUnregisterServer( CLSID clsServer ) -{ - // convert CLSID uuid to string and write - // out subkey CLSID\{} - // - OLECHAR szCLSID[CHARS_IN_GUID]; - HRESULT hr = StringFromGUID2( clsServer - , szCLSID - , CHARS_IN_GUID ); - ASSERT( SUCCEEDED(hr) ); - - TCHAR achBuffer[MAX_KEY_LEN]; - (void)StringCchPrintf( achBuffer, NUMELMS(achBuffer), CLSID_KEY_FORMAT_STRING, szCLSID ); - - // delete subkey - // - - hr = EliminateSubKey( HKEY_CLASSES_ROOT, achBuffer ); - ASSERT( SUCCEEDED(hr) ); - - // return - // - return NOERROR; -} - - -//--------------------------------------------------------------------------- -// -// AMovieSetupRegisterFilter through IFilterMapper2 -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper2 * pIFM2 - , BOOL bRegister ) -{ - DbgLog((LOG_TRACE, 3, TEXT("= AMovieSetupRegisterFilter"))); - - // check we've got data - // - if( NULL == psetupdata ) return S_FALSE; - - - // unregister filter - // (as pins are subkeys of filter's CLSID key - // they do not need to be removed separately). - // - DbgLog((LOG_TRACE, 3, TEXT("= = unregister filter"))); - HRESULT hr = pIFM2->UnregisterFilter( - 0, // default category - 0, // default instance name - *psetupdata->clsID ); - - - if( bRegister ) - { - REGFILTER2 rf2; - rf2.dwVersion = 1; - rf2.dwMerit = psetupdata->dwMerit; - rf2.cPins = psetupdata->nPins; - rf2.rgPins = psetupdata->lpPin; - - // register filter - // - DbgLog((LOG_TRACE, 3, TEXT("= = register filter"))); - hr = pIFM2->RegisterFilter(*psetupdata->clsID - , psetupdata->strName - , 0 // moniker - , 0 // category - , NULL // instance - , &rf2); - } - - // handle one acceptable "error" - that - // of filter not being registered! - // (couldn't find a suitable #define'd - // name for the error!) - // - if( 0x80070002 == hr) - return NOERROR; - else - return hr; -} - - -//--------------------------------------------------------------------------- -// -// RegisterAllServers() -// -//--------------------------------------------------------------------------- - -STDAPI -RegisterAllServers( LPCWSTR szFileName, BOOL bRegister ) -{ - HRESULT hr = NOERROR; - - for( int i = 0; i < g_cTemplates; i++ ) - { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), - (LPCWSTR)pT->m_Name )); - - // register CLSID and InprocServer32 - // - if( bRegister ) - { - hr = AMovieSetupRegisterServer( *(pT->m_ClsID) - , (LPCWSTR)pT->m_Name - , szFileName ); - } - else - { - hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) ); - } - - // check final error for this pass - // and break loop if we failed - // - if( FAILED(hr) ) - break; - } - - return hr; -} - - -//--------------------------------------------------------------------------- -// -// AMovieDllRegisterServer2() -// -// default ActiveMovie dll setup function -// - to use must be called from an exported -// function named DllRegisterServer() -// -// this function is table driven using the -// static members of the CFactoryTemplate -// class defined in the dll. -// -// it registers the Dll as the InprocServer32 -// and then calls the IAMovieSetup.Register -// method. -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieDllRegisterServer2( BOOL bRegister ) -{ - HRESULT hr = NOERROR; - - DbgLog((LOG_TRACE, 2, TEXT("AMovieDllRegisterServer2()"))); - - // get file name (where g_hInst is the - // instance handle of the filter dll) - // - WCHAR achFileName[MAX_PATH]; - - // WIN95 doesn't support GetModuleFileNameW - // - { - char achTemp[MAX_PATH]; - - DbgLog((LOG_TRACE, 2, TEXT("- get module file name"))); - - // g_hInst handle is set in our dll entry point. Make sure - // DllEntryPoint in dllentry.cpp is called - ASSERT(g_hInst != 0); - - if( 0 == GetModuleFileNameA( g_hInst - , achTemp - , sizeof(achTemp) ) ) - { - // we've failed! - DWORD dwerr = GetLastError(); - return AmHresultFromWin32(dwerr); - } - - MultiByteToWideChar( CP_ACP - , 0L - , achTemp - , lstrlenA(achTemp) + 1 - , achFileName - , NUMELMS(achFileName) ); - } - - // - // first registering, register all OLE servers - // - if( bRegister ) - { - DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers"))); - hr = RegisterAllServers( achFileName, TRUE ); - } - - // - // next, register/unregister all filters - // - - if( SUCCEEDED(hr) ) - { - // init is ref counted so call just in case - // we're being called cold. - // - DbgLog((LOG_TRACE, 2, TEXT("- CoInitialize"))); - hr = CoInitialize( (LPVOID)NULL ); - ASSERT( SUCCEEDED(hr) ); - - // get hold of IFilterMapper2 - // - DbgLog((LOG_TRACE, 2, TEXT("- obtain IFilterMapper2"))); - IFilterMapper2 *pIFM2 = 0; - IFilterMapper *pIFM = 0; - hr = CoCreateInstance( CLSID_FilterMapper2 - , NULL - , CLSCTX_INPROC_SERVER - , IID_IFilterMapper2 - , (void **)&pIFM2 ); - if(FAILED(hr)) - { - DbgLog((LOG_TRACE, 2, TEXT("- trying IFilterMapper instead"))); - - hr = CoCreateInstance( - CLSID_FilterMapper, - NULL, - CLSCTX_INPROC_SERVER, - IID_IFilterMapper, - (void **)&pIFM); - } - if( SUCCEEDED(hr) ) - { - // scan through array of CFactoryTemplates - // registering servers and filters. - // - DbgLog((LOG_TRACE, 2, TEXT("- register Filters"))); - for( int i = 0; i < g_cTemplates; i++ ) - { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - if( NULL != pT->m_pAMovieSetup_Filter ) - { - DbgLog((LOG_TRACE, 2, TEXT("- - register %ls"), (LPCWSTR)pT->m_Name )); - - if(pIFM2) - { - hr = AMovieSetupRegisterFilter2( pT->m_pAMovieSetup_Filter, pIFM2, bRegister ); - } - else - { - hr = AMovieSetupRegisterFilter( pT->m_pAMovieSetup_Filter, pIFM, bRegister ); - } - } - - // check final error for this pass - // and break loop if we failed - // - if( FAILED(hr) ) - break; - } - - // release interface - // - if(pIFM2) - pIFM2->Release(); - else - pIFM->Release(); - - } - - // and clear up - // - CoFreeUnusedLibraries(); - CoUninitialize(); - } - - // - // if unregistering, unregister all OLE servers - // - if( SUCCEEDED(hr) && !bRegister ) - { - DbgLog((LOG_TRACE, 2, TEXT("- register OLE Servers"))); - hr = RegisterAllServers( achFileName, FALSE ); - } - - DbgLog((LOG_TRACE, 2, TEXT("- return %0x"), hr)); - return hr; -} - - -//--------------------------------------------------------------------------- -// -// AMovieDllRegisterServer() -// -// default ActiveMovie dll setup function -// - to use must be called from an exported -// function named DllRegisterServer() -// -// this function is table driven using the -// static members of the CFactoryTemplate -// class defined in the dll. -// -// it registers the Dll as the InprocServer32 -// and then calls the IAMovieSetup.Register -// method. -// -//--------------------------------------------------------------------------- - - -STDAPI -AMovieDllRegisterServer( void ) -{ - HRESULT hr = NOERROR; - - // get file name (where g_hInst is the - // instance handle of the filter dll) - // - WCHAR achFileName[MAX_PATH]; - - { - // WIN95 doesn't support GetModuleFileNameW - // - char achTemp[MAX_PATH]; - - if( 0 == GetModuleFileNameA( g_hInst - , achTemp - , sizeof(achTemp) ) ) - { - // we've failed! - DWORD dwerr = GetLastError(); - return AmHresultFromWin32(dwerr); - } - - MultiByteToWideChar( CP_ACP - , 0L - , achTemp - , lstrlenA(achTemp) + 1 - , achFileName - , NUMELMS(achFileName) ); - } - - // scan through array of CFactoryTemplates - // registering servers and filters. - // - for( int i = 0; i < g_cTemplates; i++ ) - { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - // register CLSID and InprocServer32 - // - hr = AMovieSetupRegisterServer( *(pT->m_ClsID) - , (LPCWSTR)pT->m_Name - , achFileName ); - - // instantiate all servers and get hold of - // IAMovieSetup, if implemented, and call - // IAMovieSetup.Register() method - // - if( SUCCEEDED(hr) && (NULL != pT->m_lpfnNew) ) - { - // instantiate object - // - PAMOVIESETUP psetup; - hr = CoCreateInstance( *(pT->m_ClsID) - , 0 - , CLSCTX_INPROC_SERVER - , IID_IAMovieSetup - , reinterpret_cast(&psetup) ); - if( SUCCEEDED(hr) ) - { - hr = psetup->Unregister(); - if( SUCCEEDED(hr) ) - hr = psetup->Register(); - psetup->Release(); - } - else - { - if( (E_NOINTERFACE == hr ) - || (VFW_E_NEED_OWNER == hr ) ) - hr = NOERROR; - } - } - - // check final error for this pass - // and break loop if we failed - // - if( FAILED(hr) ) - break; - - } // end-for - - return hr; -} - - -//--------------------------------------------------------------------------- -// -// AMovieDllUnregisterServer() -// -// default ActiveMovie dll uninstall function -// - to use must be called from an exported -// function named DllRegisterServer() -// -// this function is table driven using the -// static members of the CFactoryTemplate -// class defined in the dll. -// -// it calls the IAMovieSetup.Unregister -// method and then unregisters the Dll -// as the InprocServer32 -// -//--------------------------------------------------------------------------- - -STDAPI -AMovieDllUnregisterServer() -{ - // initialize return code - // - HRESULT hr = NOERROR; - - // scan through CFactory template and unregister - // all OLE servers and filters. - // - for( int i = g_cTemplates; i--; ) - { - // get i'th template - // - const CFactoryTemplate *pT = &g_Templates[i]; - - // check method exists - // - if( NULL != pT->m_lpfnNew ) - { - // instantiate object - // - PAMOVIESETUP psetup; - hr = CoCreateInstance( *(pT->m_ClsID) - , 0 - , CLSCTX_INPROC_SERVER - , IID_IAMovieSetup - , reinterpret_cast(&psetup) ); - if( SUCCEEDED(hr) ) - { - hr = psetup->Unregister(); - psetup->Release(); - } - else - { - if( (E_NOINTERFACE == hr ) - || (VFW_E_NEED_OWNER == hr ) ) - hr = NOERROR; - } - } - - // unregister CLSID and InprocServer32 - // - if( SUCCEEDED(hr) ) - { - hr = AMovieSetupUnregisterServer( *(pT->m_ClsID) ); - } - - // check final error for this pass - // and break loop if we failed - // - if( FAILED(hr) ) - break; - } - - return hr; -} - -static HRESULT -ConvertUnicodeStringToTCHARString( LPTSTR szDest, size_t cchDest, LPCWSTR szSource ) -{ - HRESULT hr = NOERROR; - - #ifdef UNICODE - LPCTSTR FORMAT_STRING = TEXT("%s"); - #else - LPCTSTR FORMAT_STRING = TEXT("%S"); - #endif - - hr = StringCchPrintf( szDest, cchDest, FORMAT_STRING, szSource ); - if( FAILED( hr ) ) - { - return hr; - } - - return S_OK; -} - diff --git a/plugins/gs/gsdx9/baseclasses/dllsetup.h b/plugins/gs/gsdx9/baseclasses/dllsetup.h deleted file mode 100644 index a43d2fda5c..0000000000 --- a/plugins/gs/gsdx9/baseclasses/dllsetup.h +++ /dev/null @@ -1,46 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DllSetup.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// To be self registering, OLE servers must -// export functions named DllRegisterServer -// and DllUnregisterServer. To allow use of -// custom and default implementations the -// defaults are named AMovieDllRegisterServer -// and AMovieDllUnregisterServer. -// -// To the use the default implementation you -// must provide stub functions. -// -// i.e. STDAPI DllRegisterServer() -// { -// return AMovieDllRegisterServer(); -// } -// -// STDAPI DllUnregisterServer() -// { -// return AMovieDllUnregisterServer(); -// } -// -// -// AMovieDllRegisterServer calls IAMovieSetup.Register(), and -// AMovieDllUnregisterServer calls IAMovieSetup.Unregister(). - -STDAPI AMovieDllRegisterServer2( BOOL ); -STDAPI AMovieDllRegisterServer(); -STDAPI AMovieDllUnregisterServer(); - -// helper functions -STDAPI EliminateSubKey( HKEY, LPTSTR ); - - -STDAPI -AMovieSetupRegisterFilter2( const AMOVIESETUP_FILTER * const psetupdata - , IFilterMapper2 * pIFM2 - , BOOL bRegister ); - diff --git a/plugins/gs/gsdx9/baseclasses/dshow.h b/plugins/gs/gsdx9/baseclasses/dshow.h deleted file mode 100644 index 19115a82f2..0000000000 --- a/plugins/gs/gsdx9/baseclasses/dshow.h +++ /dev/null @@ -1,83 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DShow.h -// -// Desc: DirectShow top-level include file -// -// Copyright (c) 2000-2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - -#ifndef __DSHOW_INCLUDED__ -#define __DSHOW_INCLUDED__ - -/////////////////////////////////////////////////////////////////////////// -// Set up constants & pragmas for the compiler -/////////////////////////////////////////////////////////////////////////// -#ifdef _MSC_VER -// disable some level-4 warnings, use #pragma warning(default:###) to re-enable -#pragma warning(disable:4100) // warning C4100: unreferenced formal parameter -#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union -#pragma warning(disable:4511) // warning C4511: copy constructor could not be generated -#pragma warning(disable:4512) // warning C4512: assignment operator could not be generated -#pragma warning(disable:4514) // warning C4514: "unreferenced inline function has been removed" - -#if _MSC_VER>=1100 -#define AM_NOVTABLE __declspec(novtable) -#else -#define AM_NOVTABLE -#endif -#endif // MSC_VER - -/////////////////////////////////////////////////////////////////////////// -// Include standard Windows files -/////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include -#include - -#ifndef NO_DSHOW_STRSAFE -#define NO_SHLWAPI_STRFCNS -#include -#endif - -#ifndef NUMELMS - #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0])) -#endif - -/////////////////////////////////////////////////////////////////////////// -// Include DirectShow include files -/////////////////////////////////////////////////////////////////////////// -#include // Generated IDL header file for streams interfaces -#include // ActiveMovie video interfaces and definitions -#include // ActiveMovie audio interfaces and definitions -#include // generated from control.odl -#include // event code definitions -#include // declaration of type GUIDs and well-known clsids -#include // HRESULT status and error definitions -#include // External device control interface defines -#include // audio filter device error event codes -#include // DVD error event codes - -/////////////////////////////////////////////////////////////////////////// -// Define OLE Automation constants -/////////////////////////////////////////////////////////////////////////// -#ifndef OATRUE -#define OATRUE (-1) -#endif // OATRUE -#ifndef OAFALSE -#define OAFALSE (0) -#endif // OAFALSE - -/////////////////////////////////////////////////////////////////////////// -// Define Win64 interfaces if not already defined -/////////////////////////////////////////////////////////////////////////// - -// InterlockedExchangePointer -#ifndef InterlockedExchangePointer -#define InterlockedExchangePointer(Target, Value) \ - (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value)) -#endif - - -#endif // __DSHOW_INCLUDED__ diff --git a/plugins/gs/gsdx9/baseclasses/dsschedule.h b/plugins/gs/gsdx9/baseclasses/dsschedule.h deleted file mode 100644 index cc21b1c3ce..0000000000 --- a/plugins/gs/gsdx9/baseclasses/dsschedule.h +++ /dev/null @@ -1,128 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DSSchedule.h (replaces DirectX 8's schedule.h) -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __CAMSchedule__ -#define __CAMSchedule__ - -class CAMSchedule : private CBaseObject -{ -public: - virtual ~CAMSchedule(); - // ev is the event we should fire if the advise time needs re-evaluating - CAMSchedule( HANDLE ev ); - - DWORD GetAdviseCount(); - REFERENCE_TIME GetNextAdviseTime(); - - // We need a method for derived classes to add advise packets, we return the cookie - DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic ); - // And a way to cancel - HRESULT Unadvise(DWORD_PTR dwAdviseCookie); - - // Tell us the time please, and we'll dispatch the expired events. We return the time of the next event. - // NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of - // whoever is using this helper class (typically a clock). - REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime ); - - // Get the event handle which will be set if advise time requires re-evaluation. - HANDLE GetEvent() const { return m_ev; } - -private: - // We define the nodes that will be used in our singly linked list - // of advise packets. The list is ordered by time, with the - // elements that will expire first at the front. - class CAdvisePacket - { - public: - CAdvisePacket() - {} - - CAdvisePacket * m_next; - DWORD_PTR m_dwAdviseCookie; - REFERENCE_TIME m_rtEventTime; // Time at which event should be set - REFERENCE_TIME m_rtPeriod; // Periodic time - HANDLE m_hNotify; // Handle to event or semephore - BOOL m_bPeriodic; // TRUE => Periodic event - - CAdvisePacket( CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time) - {} - - void InsertAfter( CAdvisePacket * p ) - { - p->m_next = m_next; - m_next = p; - } - - int IsZ() const // That is, is it the node that represents the end of the list - { return m_next == 0; } - - CAdvisePacket * RemoveNext() - { - CAdvisePacket *const next = m_next; - CAdvisePacket *const new_next = next->m_next; - m_next = new_next; - return next; - } - - void DeleteNext() - { - delete RemoveNext(); - } - - CAdvisePacket * Next() const - { - CAdvisePacket * result = m_next; - if (result->IsZ()) result = 0; - return result; - } - - DWORD_PTR Cookie() const - { return m_dwAdviseCookie; } - }; - - // Structure is: - // head -> elmt1 -> elmt2 -> z -> null - // So an empty list is: head -> z -> null - // Having head & z as links makes insertaion, - // deletion and shunting much easier. - CAdvisePacket head, z; // z is both a tail and a sentry - - volatile DWORD_PTR m_dwNextCookie; // Strictly increasing - volatile DWORD m_dwAdviseCount; // Number of elements on list - - CCritSec m_Serialize; - - // AddAdvisePacket: adds the packet, returns the cookie (0 if failed) - DWORD_PTR AddAdvisePacket( CAdvisePacket * pPacket ); - // Event that we should set if the packed added above will be the next to fire. - const HANDLE m_ev; - - // A Shunt is where we have changed the first element in the - // list and want it re-evaluating (i.e. repositioned) in - // the list. - void ShuntHead(); - - // Rather than delete advise packets, we cache them for future use - CAdvisePacket * m_pAdviseCache; - DWORD m_dwCacheCount; - enum { dwCacheMax = 5 }; // Don't bother caching more than five - - void Delete( CAdvisePacket * pLink );// This "Delete" will cache the Link - -// Attributes and methods for debugging -public: -#ifdef DEBUG - void DumpLinkedList(); -#else - void DumpLinkedList() {} -#endif - -}; - -#endif // __CAMSchedule__ diff --git a/plugins/gs/gsdx9/baseclasses/dvdevcod.h b/plugins/gs/gsdx9/baseclasses/dvdevcod.h deleted file mode 100644 index 82f43d0615..0000000000 --- a/plugins/gs/gsdx9/baseclasses/dvdevcod.h +++ /dev/null @@ -1,363 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DVDevCod.h -// -// Desc: List of standard DVD-Video event codes and the expected params. -// -// Copyright (c) 1992 - 2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - -#ifndef __DVDEVCOD__ -#define __DVDEVCOD__ - - -#define EC_DVDBASE 0x0100 - -#ifndef EXCLUDE_DVDEVCODE_ENUMS - -typedef enum _tagDVD_ERROR { - DVD_ERROR_Unexpected=1, // Something unexpected happened, perhaps content - // is incorrectly authored. Playback is stopped. - DVD_ERROR_CopyProtectFail=2, // Key exchange for DVD copy protection failed. - // Playback is stopped. - DVD_ERROR_InvalidDVD1_0Disc=3, // DVD-Video disc is incorrectly authored for v1.0 - // of spec. Playback is stopped. - DVD_ERROR_InvalidDiscRegion=4, // The Disc cannot be played because the disc is not - // authored to play in system region. - // The region mismatch may be fixable by - // changing the system region with dvdrgn.exe - DVD_ERROR_LowParentalLevel=5, // Player parental level is lower than the lowest parental - // level available in the DVD content. Playback is stopped. - DVD_ERROR_MacrovisionFail=6, // Macrovision Distribution Failed. - // Playback is stopped. - DVD_ERROR_IncompatibleSystemAndDecoderRegions=7, - // No discs can be played because the system region - // does not match the decoder region. - DVD_ERROR_IncompatibleDiscAndDecoderRegions=8 - // The disc cannot be played because the disc is - // not authored to be played in the decoder's region -} DVD_ERROR; - -typedef enum _tagDVD_WARNING { - DVD_WARNING_InvalidDVD1_0Disc=1,// DVD-Video disc is incorrectly authored. Playback - // can continue, but unexpected behavior may occur. - DVD_WARNING_FormatNotSupported=2,// A decoder would not support the current format. Playback - // of a stream (audio, video of SP) may not function. - // lParam2 contains the stream type (see AM_DVD_STREAM_FLAGS) - DVD_WARNING_IllegalNavCommand=3,// The internal DVD navigation command processor attempted to - // process an illegal command. - DVD_WARNING_Open = 4, // File Open Failed - DVD_WARNING_Seek = 5, // File Seek Failed - DVD_WARNING_Read = 6 // File Read Failed -} DVD_WARNING; - -typedef enum _tagDVD_PB_STOPPED { - DVD_PB_STOPPED_Other=0, // The navigator stopped the playback (no reason available). - DVD_PB_STOPPED_NoBranch=1, // The nav completed the current pgc and there was no more video and - // did not find any other branching instruction for subsequent playback. - DVD_PB_STOPPED_NoFirstPlayDomain =2, // The disc does not contain an initial startup program. - DVD_PB_STOPPED_StopCommand = 3, // The app issued a stop() command or a stop command was authored on the disc. - DVD_PB_STOPPED_Reset=4, // The navigator was reset to the start of the disc (using ResetOnStop). - DVD_PB_STOPPED_DiscEjected=5, // The disc was ejected. - DVD_PB_STOPPED_IllegalNavCommand = 6, // An illegal nav command prevented playback from continuing. - DVD_PB_STOPPED_PlayPeriodAutoStop = 7, // PlayPeriod completed - DVD_PB_STOPPED_PlayChapterAutoStop = 8, // PlayChapter completed - DVD_PB_STOPPED_ParentalFailure = 9, // A parental level failure prevented playback - DVD_PB_STOPPED_RegionFailure = 10, // A region failure prevented playback - DVD_PB_STOPPED_MacrovisionFailure = 11, // A Macrovision failure prevented playback. - DVD_PB_STOPPED_DiscReadError = 12, // A read error prevented playback. - DVD_PB_STOPPED_CopyProtectFailure = 13 // Copy protection failure. -} DVD_PB_STOPPED; - - -#endif - -// DVD-Video event codes -// ====================== -// -// All DVD-Video event are always passed on to the application, and are -// never processed by the filter graph - - -#define EC_DVD_DOMAIN_CHANGE (EC_DVDBASE + 0x01) -// Parameters: ( DWORD, void ) -// lParam1 is enum DVD_DOMAIN, and indicates the player's new domain -// -// Raised from following domains: all -// -// Signaled when ever the DVD player changes domains. - - -#define EC_DVD_TITLE_CHANGE (EC_DVDBASE + 0x02) -// Parameters: ( DWORD, void ) -// lParam1 is the new title number. -// -// Raised from following domains: DVD_DOMAIN_Title -// -// Indicates when the current title number changes. Title numbers -// range 1 to 99. This indicates the TTN, which is the title number -// with respect to the whole disc, not the VTS_TTN which is the title -// number with respect to just a current VTS. - - -#define EC_DVD_CHAPTER_START (EC_DVDBASE + 0x03) -// Parameters: ( DWORD, void ) -// lParam1 is the new chapter number (which is the program number for -// One_Sequential_PGC_Titles). -// -// Raised from following domains: DVD_DOMAIN_Title -// -// Signales that DVD player started playback of a new program in the Title -// domain. This is only signaled for One_Sequential_PGC_Titles. - - -#define EC_DVD_AUDIO_STREAM_CHANGE (EC_DVDBASE + 0x04) -// Parameters: ( DWORD, void ) -// lParam1 is the new user audio stream number. -// -// Raised from following domains: all -// -// Signaled when ever the current user audio stream number changes for the main -// title. This can be changed automatically with a navigation command on disc -// as well as through IDVDAnnexJ. -// Audio stream numbers range from 0 to 7. Stream 0xffffffff -// indicates that no stream is selected. - -#define EC_DVD_SUBPICTURE_STREAM_CHANGE (EC_DVDBASE + 0x05) -// Parameters: ( DWORD, BOOL ) -// lParam1 is the new user subpicture stream number. -// lParam2 is the subpicture's on/off state (TRUE if on) -// -// Raised from following domains: all -// -// Signaled when ever the current user subpicture stream number changes for the main -// title. This can be changed automatically with a navigation command on disc -// as well as through IDVDAnnexJ. -// Subpicture stream numbers range from 0 to 31. Stream 0xffffffff -// indicates that no stream is selected. - -#define EC_DVD_ANGLE_CHANGE (EC_DVDBASE + 0x06) -// Parameters: ( DWORD, DWORD ) -// lParam1 is the number of available angles. -// lParam2 is the current user angle number. -// -// Raised from following domains: all -// -// Signaled when ever either -// a) the number of available angles changes, or -// b) the current user angle number changes. -// Current angle number can be changed automatically with navigation command -// on disc as well as through IDVDAnnexJ. -// When the number of available angles is 1, the current video is not multiangle. -// Angle numbers range from 1 to 9. - - -#define EC_DVD_BUTTON_CHANGE (EC_DVDBASE + 0x07) -// Parameters: ( DWORD, DWORD ) -// lParam1 is the number of available buttons. -// lParam2 is the current selected button number. -// -// Raised from following domains: all -// -// Signaled when ever either -// a) the number of available buttons changes, or -// b) the current selected button number changes. -// The current selected button can be changed automatically with navigation -// commands on disc as well as through IDVDAnnexJ. -// Button numbers range from 1 to 36. Selected button number 0 implies that -// no button is selected. Note that these button numbers enumerate all -// available button numbers, and do not always correspond to button numbers -// used for IDVDAnnexJ::ButtonSelectAndActivate since only a subset of buttons -// may be activated with ButtonSelectAndActivate. - - -#define EC_DVD_VALID_UOPS_CHANGE (EC_DVDBASE + 0x08) -// Parameters: ( DWORD, void ) -// lParam1 is a VALID_UOP_SOMTHING_OR_OTHER bit-field stuct which indicates -// which IDVDAnnexJ commands are explicitly disable by the DVD disc. -// -// Raised from following domains: all -// -// Signaled when ever the available set of IDVDAnnexJ methods changes. This -// only indicates which operations are explicited disabled by the content on -// the DVD disc, and does not guarentee that it is valid to call methods -// which are not disabled. For example, if no buttons are currently present, -// IDVDAnnexJ::ButtonActivate() won't work, even though the buttons are not -// explicitly disabled. - - -#define EC_DVD_STILL_ON (EC_DVDBASE + 0x09) -// Parameters: ( BOOL, DWORD ) -// lParam1 == 0 --> buttons are available, so StillOff won't work -// lParam1 == 1 --> no buttons available, so StillOff will work -// lParam2 indicates the number of seconds the still will last, with 0xffffffff -// indicating an infinite still (wait till button or StillOff selected). -// -// Raised from following domains: all -// -// Signaled at the beginning of any still: PGC still, Cell Still, or VOBU Still. -// Note that all combinations of buttons and still are possible (buttons on with -// still on, buttons on with still off, button off with still on, button off -// with still off). - -#define EC_DVD_STILL_OFF (EC_DVDBASE + 0x0a) -// Parameters: ( void, void ) -// -// Indicating that any still that is currently active -// has been released. -// -// Raised from following domains: all -// -// Signaled at the end of any still: PGC still, Cell Still, or VOBU Still. -// - -#define EC_DVD_CURRENT_TIME (EC_DVDBASE + 0x0b) -// Parameters: ( DWORD, BOOL ) -// lParam1 is a DVD_TIMECODE which indicates the current -// playback time code in a BCD HH:MM:SS:FF format. -// lParam2 == 0 --> time code is 25 frames/sec -// lParam2 == 1 --> time code is 30 frames/sec (non-drop). -// lParam2 == 2 --> time code is invalid (current playback time -// cannot be determined for current title) -// -// Raised from following domains: DVD_DOMAIN_Title -// -// Signaled at the beginning of every VOBU, which occurs every .4 to 1.0 sec. -// This is only signaled for One_Sequential_PGC_Titles. - - -#define EC_DVD_ERROR (EC_DVDBASE + 0x0c) -// Parameters: ( DWORD, void) -// lParam1 is an enum DVD_ERROR which notifies the app of some error condition. -// -// Raised from following domains: all -// - -#define EC_DVD_WARNING (EC_DVDBASE + 0x0d) -// Parameters: ( DWORD, DWORD) -// lParam1 is an enum DVD_WARNING which notifies the app of some warning condition. -// lParam2 contains more specific information about the warning (warning dependent) -// -// Raised from following domains: all -// - -#define EC_DVD_CHAPTER_AUTOSTOP (EC_DVDBASE + 0x0e) -// Parameters: (BOOL, void) -// lParam1 is a BOOL which indicates the reason for the cancellation of ChapterPlayAutoStop -// lParam1 == 0 indicates successful completion of ChapterPlayAutoStop -// lParam1 == 1 indicates that ChapterPlayAutoStop is being cancelled as a result of another -// IDVDControl call or the end of content has been reached & no more chapters -// can be played. -// Indicating that playback is stopped as a result of a call -// to IDVDControl::ChapterPlayAutoStop() -// -// Raised from following domains : DVD_DOMAIN_TITLE -// - -#define EC_DVD_NO_FP_PGC (EC_DVDBASE + 0x0f) -// Parameters : (void, void) -// -// Raised from the following domains : FP_DOM -// -// Indicates that the DVD disc does not have a FP_PGC (First Play Program Chain) -// and the DVD Navigator will not automatically load any PGC and start playback. -// - -#define EC_DVD_PLAYBACK_RATE_CHANGE (EC_DVDBASE + 0x10) -// Parameters : (LONG, void) -// lParam1 is a LONG indicating the new playback rate. -// lParam1 < 0 indicates reverse playback mode. -// lParam1 > 0 indicates forward playback mode -// Value of lParam1 is the actual playback rate multiplied by 10000. -// i.e. lParam1 = rate * 10000 -// -// Raised from the following domains : TT_DOM -// -// Indicates that a rate change in playback has been initiated and the parameter -// lParam1 indicates the new playback rate that is being used. -// - -#define EC_DVD_PARENTAL_LEVEL_CHANGE (EC_DVDBASE + 0x11) -// Parameters : (LONG, void) -// lParam1 is a LONG indicating the new parental level. -// -// Raised from the following domains : VMGM_DOM -// -// Indicates that an authored Nav command has changed the parental level -// setting in the player. -// - -#define EC_DVD_PLAYBACK_STOPPED (EC_DVDBASE + 0x12) -// Parameters : (DWORD, void) -// -// Raised from the following domains : All Domains -// -// Indicates that playback has been stopped as the Navigator has completed -// playback of the pgc and did not find any other branching instruction for -// subsequent playback. -// -// The DWORD returns the reason for the completion of the playback. See -// The DVD_PB_STOPPED enumeration for details. -// - -#define EC_DVD_ANGLES_AVAILABLE (EC_DVDBASE + 0x13) -// Parameters : (BOOL, void) -// lParam1 == 0 indicates that playback is not in an angle block and angles are -// not available -// lParam1 == 1 indicates that an angle block is being played back and angle changes -// can be performed. -// -// Indicates whether an angle block is being played and if angle changes can be -// performed. However, angle changes are not restricted to angle blocks and the -// manifestation of the angle change can be seen only in an angle block. - -#define EC_DVD_PLAYPERIOD_AUTOSTOP (EC_DVDBASE + 0x14) -// Parameters: (void, void) -// Sent when the PlayPeriodInTitle completes or is cancelled -// -// Raised from following domains : DVD_DOMAIN_TITLE -// - -#define EC_DVD_BUTTON_AUTO_ACTIVATED (EC_DVDBASE + 0x15) -// Parameters: (DWORD button, void) -// Sent when a button is automatically activated -// -// Raised from following domains : DVD_DOMAIN_MENU -// - -#define EC_DVD_CMD_START (EC_DVDBASE + 0x16) -// Parameters: (CmdID, HRESULT) -// Sent when a command begins -// - -#define EC_DVD_CMD_END (EC_DVDBASE + 0x17) -// Parameters: (CmdID, HRESULT) -// Sent when a command completes -// - -#define EC_DVD_DISC_EJECTED (EC_DVDBASE + 0x18) -// Parameters: none -// Sent when the nav detects that a disc was ejected and stops the playback -// The app does not need to take any action to stop the playback. -// - -#define EC_DVD_DISC_INSERTED (EC_DVDBASE + 0x19) -// Parameters: none -// Sent when the nav detects that a disc was inserted and the nav begins playback -// The app does not need to take any action to start the playback. -// - -#define EC_DVD_CURRENT_HMSF_TIME (EC_DVDBASE + 0x1a) -// Parameters: ( ULONG, ULONG ) -// lParam2 contains a union of the DVD_TIMECODE_FLAGS -// lParam1 contains a DVD_HMSF_TIMECODE. Assign lParam1 to a ULONG then cast the -// ULONG as a DVD_HMSF_TIMECODE to use its values. -// -// Raised from following domains: DVD_DOMAIN_Title -// -// Signaled at the beginning of every VOBU, which occurs every .4 to 1.0 sec. - -#define EC_DVD_KARAOKE_MODE (EC_DVDBASE + 0x1b) -// Parameters: ( BOOL, reserved ) -// lParam1 is either TRUE (a karaoke track is being played) or FALSE (no karaoke data is being played). -// -#endif // __DVDEVCOD__ diff --git a/plugins/gs/gsdx9/baseclasses/dvdmedia.h b/plugins/gs/gsdx9/baseclasses/dvdmedia.h deleted file mode 100644 index 6be8de0582..0000000000 --- a/plugins/gs/gsdx9/baseclasses/dvdmedia.h +++ /dev/null @@ -1,427 +0,0 @@ -//------------------------------------------------------------------------------ -// File: DVDMedia.h -// -// Desc: Contains typedefs and defines necessary for user mode (ring 3) DVD -// filters and applications. -// -// This should be included in the DirectShow SDK for user mode filters. -// The types defined here should be kept in synch with ksmedia.h WDM -// DDK for kernel mode filters. -// -// Copyright (c) 1997 - 2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __DVDMEDIA_H__ -#define __DVDMEDIA_H__ - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -// ----------------------------------------------------------------------- -// AC-3 definition for the AM_KSPROPSETID_AC3 property set -// ----------------------------------------------------------------------- - -typedef enum { - AM_PROPERTY_AC3_ERROR_CONCEALMENT = 1, - AM_PROPERTY_AC3_ALTERNATE_AUDIO = 2, - AM_PROPERTY_AC3_DOWNMIX = 3, - AM_PROPERTY_AC3_BIT_STREAM_MODE = 4, - AM_PROPERTY_AC3_DIALOGUE_LEVEL = 5, - AM_PROPERTY_AC3_LANGUAGE_CODE = 6, - AM_PROPERTY_AC3_ROOM_TYPE = 7 -} AM_PROPERTY_AC3; - -typedef struct { - BOOL fRepeatPreviousBlock; - BOOL fErrorInCurrentBlock; -} AM_AC3_ERROR_CONCEALMENT, *PAM_AC3_ERROR_CONCEALMENT; - -typedef struct { - BOOL fStereo; - ULONG DualMode; -} AM_AC3_ALTERNATE_AUDIO, *PAM_AC3_ALTERNATE_AUDIO; - -#define AM_AC3_ALTERNATE_AUDIO_1 1 -#define AM_AC3_ALTERNATE_AUDIO_2 2 -#define AM_AC3_ALTERNATE_AUDIO_BOTH 3 - -typedef struct { - BOOL fDownMix; - BOOL fDolbySurround; -} AM_AC3_DOWNMIX, *PAM_AC3_DOWNMIX; - -typedef struct { - LONG BitStreamMode; -} AM_AC3_BIT_STREAM_MODE, *PAM_AC3_BIT_STREAM_MODE; - -#define AM_AC3_SERVICE_MAIN_AUDIO 0 -#define AM_AC3_SERVICE_NO_DIALOG 1 -#define AM_AC3_SERVICE_VISUALLY_IMPAIRED 2 -#define AM_AC3_SERVICE_HEARING_IMPAIRED 3 -#define AM_AC3_SERVICE_DIALOG_ONLY 4 -#define AM_AC3_SERVICE_COMMENTARY 5 -#define AM_AC3_SERVICE_EMERGENCY_FLASH 6 -#define AM_AC3_SERVICE_VOICE_OVER 7 - -typedef struct { - ULONG DialogueLevel; -} AM_AC3_DIALOGUE_LEVEL, *PAM_AC3_DIALOGUE_LEVEL; - -typedef struct { - BOOL fLargeRoom; -} AM_AC3_ROOM_TYPE, *PAM_AC3_ROOM_TYPE; - - -// ----------------------------------------------------------------------- -// subpicture definition for the AM_KSPROPSETID_DvdSubPic property set -// ----------------------------------------------------------------------- - -typedef enum { - AM_PROPERTY_DVDSUBPIC_PALETTE = 0, - AM_PROPERTY_DVDSUBPIC_HLI = 1, - AM_PROPERTY_DVDSUBPIC_COMPOSIT_ON = 2 // TRUE for subpicture is displayed -} AM_PROPERTY_DVDSUBPIC; - -typedef struct _AM_DVD_YUV { - UCHAR Reserved; - UCHAR Y; - UCHAR U; - UCHAR V; -} AM_DVD_YUV, *PAM_DVD_YUV; - -typedef struct _AM_PROPERTY_SPPAL { - AM_DVD_YUV sppal[16]; -} AM_PROPERTY_SPPAL, *PAM_PROPERTY_SPPAL; - -typedef struct _AM_COLCON { - UCHAR emph1col:4; - UCHAR emph2col:4; - UCHAR backcol:4; - UCHAR patcol:4; - UCHAR emph1con:4; - UCHAR emph2con:4; - UCHAR backcon:4; - UCHAR patcon:4; - -} AM_COLCON, *PAM_COLCON; - -typedef struct _AM_PROPERTY_SPHLI { - USHORT HLISS; // - USHORT Reserved; - ULONG StartPTM; // start presentation time in x/90000 - ULONG EndPTM; // end PTM in x/90000 - USHORT StartX; - USHORT StartY; - USHORT StopX; - USHORT StopY; - AM_COLCON ColCon; // color contrast description (4 bytes as given in HLI) -} AM_PROPERTY_SPHLI, *PAM_PROPERTY_SPHLI; - -typedef BOOL AM_PROPERTY_COMPOSIT_ON, *PAM_PROPERTY_COMPOSIT_ON; - - - -// ----------------------------------------------------------------------- -// copy protection definitions -// ----------------------------------------------------------------------- - -// AM_UseNewCSSKey for the dwTypeSpecificFlags in IMediaSample2 to indicate -// the exact point in a stream after which to start applying a new CSS key. -// This is typically sent on an empty media sample just before attempting -// to renegotiate a CSS key. -#define AM_UseNewCSSKey 0x1 - -// -// AM_KSPROPSETID_CopyProt property set definitions -// -typedef enum { - AM_PROPERTY_DVDCOPY_CHLG_KEY = 0x01, - AM_PROPERTY_DVDCOPY_DVD_KEY1 = 0x02, - AM_PROPERTY_DVDCOPY_DEC_KEY2 = 0x03, - AM_PROPERTY_DVDCOPY_TITLE_KEY = 0x04, - AM_PROPERTY_COPY_MACROVISION = 0x05, - AM_PROPERTY_DVDCOPY_REGION = 0x06, - AM_PROPERTY_DVDCOPY_SET_COPY_STATE = 0x07, - AM_PROPERTY_DVDCOPY_DISC_KEY = 0x80 -} AM_PROPERTY_DVDCOPYPROT; - -typedef struct _AM_DVDCOPY_CHLGKEY { - BYTE ChlgKey[10]; - BYTE Reserved[2]; -} AM_DVDCOPY_CHLGKEY, *PAM_DVDCOPY_CHLGKEY; - -typedef struct _AM_DVDCOPY_BUSKEY { - BYTE BusKey[5]; - BYTE Reserved[1]; -} AM_DVDCOPY_BUSKEY, *PAM_DVDCOPY_BUSKEY; - -typedef struct _AM_DVDCOPY_DISCKEY { - BYTE DiscKey[2048]; -} AM_DVDCOPY_DISCKEY, *PAM_DVDCOPY_DISCKEY; - -typedef struct AM_DVDCOPY_TITLEKEY { - ULONG KeyFlags; - ULONG Reserved1[2]; - UCHAR TitleKey[6]; - UCHAR Reserved2[2]; -} AM_DVDCOPY_TITLEKEY, *PAM_DVDCOPY_TITLEKEY; - -typedef struct _AM_COPY_MACROVISION { - ULONG MACROVISIONLevel; -} AM_COPY_MACROVISION, *PAM_COPY_MACROVISION; - -typedef struct AM_DVDCOPY_SET_COPY_STATE { - ULONG DVDCopyState; -} AM_DVDCOPY_SET_COPY_STATE, *PAM_DVDCOPY_SET_COPY_STATE; - -typedef enum { - AM_DVDCOPYSTATE_INITIALIZE = 0, - AM_DVDCOPYSTATE_INITIALIZE_TITLE = 1, // indicates we are starting a title - // key copy protection sequence - AM_DVDCOPYSTATE_AUTHENTICATION_NOT_REQUIRED = 2, - AM_DVDCOPYSTATE_AUTHENTICATION_REQUIRED = 3, - AM_DVDCOPYSTATE_DONE = 4 -} AM_DVDCOPYSTATE; - -typedef enum { - AM_MACROVISION_DISABLED = 0, - AM_MACROVISION_LEVEL1 = 1, - AM_MACROVISION_LEVEL2 = 2, - AM_MACROVISION_LEVEL3 = 3 -} AM_COPY_MACROVISION_LEVEL, *PAM_COPY_MACROVISION_LEVEL; - - -// CSS region stucture -typedef struct _DVD_REGION { - UCHAR CopySystem; - UCHAR RegionData; - UCHAR SystemRegion; - UCHAR Reserved; -} DVD_REGION, *PDVD_REGION; - -// -// CGMS Copy Protection Flags -// - -#define AM_DVD_CGMS_RESERVED_MASK 0x00000078 - -#define AM_DVD_CGMS_COPY_PROTECT_MASK 0x00000018 -#define AM_DVD_CGMS_COPY_PERMITTED 0x00000000 -#define AM_DVD_CGMS_COPY_ONCE 0x00000010 -#define AM_DVD_CGMS_NO_COPY 0x00000018 - -#define AM_DVD_COPYRIGHT_MASK 0x00000040 -#define AM_DVD_NOT_COPYRIGHTED 0x00000000 -#define AM_DVD_COPYRIGHTED 0x00000040 - -#define AM_DVD_SECTOR_PROTECT_MASK 0x00000020 -#define AM_DVD_SECTOR_NOT_PROTECTED 0x00000000 -#define AM_DVD_SECTOR_PROTECTED 0x00000020 - - -// ----------------------------------------------------------------------- -// video format blocks -// ----------------------------------------------------------------------- - -enum AM_MPEG2Level { - AM_MPEG2Level_Low = 1, - AM_MPEG2Level_Main = 2, - AM_MPEG2Level_High1440 = 3, - AM_MPEG2Level_High = 4 -}; - -enum AM_MPEG2Profile { - AM_MPEG2Profile_Simple = 1, - AM_MPEG2Profile_Main = 2, - AM_MPEG2Profile_SNRScalable = 3, - AM_MPEG2Profile_SpatiallyScalable = 4, - AM_MPEG2Profile_High = 5 -}; - -#define AMINTERLACE_IsInterlaced 0x00000001 // if 0, other interlace bits are irrelevent -#define AMINTERLACE_1FieldPerSample 0x00000002 // else 2 fields per media sample -#define AMINTERLACE_Field1First 0x00000004 // else Field 2 is first; top field in PAL is field 1, top field in NTSC is field 2? -#define AMINTERLACE_UNUSED 0x00000008 // -#define AMINTERLACE_FieldPatternMask 0x00000030 // use this mask with AMINTERLACE_FieldPat* -#define AMINTERLACE_FieldPatField1Only 0x00000000 // stream never contains a Field2 -#define AMINTERLACE_FieldPatField2Only 0x00000010 // stream never contains a Field1 -#define AMINTERLACE_FieldPatBothRegular 0x00000020 // There will be a Field2 for every Field1 (required for Weave?) -#define AMINTERLACE_FieldPatBothIrregular 0x00000030 // Random pattern of Field1s and Field2s -#define AMINTERLACE_DisplayModeMask 0x000000c0 -#define AMINTERLACE_DisplayModeBobOnly 0x00000000 -#define AMINTERLACE_DisplayModeWeaveOnly 0x00000040 -#define AMINTERLACE_DisplayModeBobOrWeave 0x00000080 - -#define AMCOPYPROTECT_RestrictDuplication 0x00000001 // duplication of this stream should be restricted - -#define AMMPEG2_DoPanScan 0x00000001 //if set, the MPEG-2 video decoder should crop output image - // based on pan-scan vectors in picture_display_extension - // and change the picture aspect ratio accordingly. -#define AMMPEG2_DVDLine21Field1 0x00000002 //if set, the MPEG-2 decoder must be able to produce an output - // pin for DVD style closed caption data found in GOP layer of field 1 -#define AMMPEG2_DVDLine21Field2 0x00000004 //if set, the MPEG-2 decoder must be able to produce an output - // pin for DVD style closed caption data found in GOP layer of field 2 -#define AMMPEG2_SourceIsLetterboxed 0x00000008 //if set, indicates that black bars have been encoded in the top - // and bottom of the video. -#define AMMPEG2_FilmCameraMode 0x00000010 //if set, indicates "film mode" used for 625/50 content. If cleared, - // indicates that "camera mode" was used. -#define AMMPEG2_LetterboxAnalogOut 0x00000020 //if set and this stream is sent to an analog output, it should - // be letterboxed. Streams sent to VGA should be letterboxed only by renderers. -#define AMMPEG2_DSS_UserData 0x00000040 //if set, the MPEG-2 decoder must process DSS style user data -#define AMMPEG2_DVB_UserData 0x00000080 //if set, the MPEG-2 decoder must process DVB style user data -#define AMMPEG2_27MhzTimebase 0x00000100 //if set, the PTS,DTS timestamps advance at 27MHz rather than 90KHz - -#define AMMPEG2_WidescreenAnalogOut 0x00000200 //if set and this stream is sent to an analog output, it should - // be in widescreen format (4x3 content should be centered on a 16x9 output). - // Streams sent to VGA should be widescreened only by renderers. - -// PRESENT in dwReserved1 field in VIDEOINFOHEADER2 -#define AMCONTROL_USED 0x00000001 // Used to test if these flags are supported. Set and test for AcceptMediaType. - // If rejected, then you cannot use the AMCONTROL flags (send 0 for dwReserved1) -#define AMCONTROL_PAD_TO_4x3 0x00000002 // if set means display the image in a 4x3 area -#define AMCONTROL_PAD_TO_16x9 0x00000004 // if set means display the image in a 16x9 area - -typedef struct tagVIDEOINFOHEADER2 { - RECT rcSource; - RECT rcTarget; - DWORD dwBitRate; - DWORD dwBitErrorRate; - REFERENCE_TIME AvgTimePerFrame; - DWORD dwInterlaceFlags; // use AMINTERLACE_* defines. Reject connection if undefined bits are not 0 - DWORD dwCopyProtectFlags; // use AMCOPYPROTECT_* defines. Reject connection if undefined bits are not 0 - DWORD dwPictAspectRatioX; // X dimension of picture aspect ratio, e.g. 16 for 16x9 display - DWORD dwPictAspectRatioY; // Y dimension of picture aspect ratio, e.g. 9 for 16x9 display - union { - DWORD dwControlFlags; // use AMCONTROL_* defines, use this from now on - DWORD dwReserved1; // for backward compatiblity (was "must be 0"; connection rejected otherwise) - }; - DWORD dwReserved2; // must be 0; reject connection otherwise - BITMAPINFOHEADER bmiHeader; -} VIDEOINFOHEADER2; - -typedef struct tagMPEG2VIDEOINFO { - VIDEOINFOHEADER2 hdr; - DWORD dwStartTimeCode; // ?? not used for DVD ?? - DWORD cbSequenceHeader; // is 0 for DVD (no sequence header) - DWORD dwProfile; // use enum MPEG2Profile - DWORD dwLevel; // use enum MPEG2Level - DWORD dwFlags; // use AMMPEG2_* defines. Reject connection if undefined bits are not 0 - DWORD dwSequenceHeader[1]; // DWORD instead of Byte for alignment purposes - // For MPEG-2, if a sequence_header is included, the sequence_extension - // should also be included -} MPEG2VIDEOINFO; - -#define SIZE_MPEG2VIDEOINFO(pv) (FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader[0]) + (pv)->cbSequenceHeader) - -// do not use -#define MPEG1_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->bSequenceHeader) - -// use this macro instead, the previous only works for MPEG1VIDEOINFO structures -#define MPEG2_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->dwSequenceHeader) - - -//=================================================================================== -// flags for dwTypeSpecificFlags in AM_SAMPLE2_PROPERTIES which define type specific -// data in IMediaSample2 -//=================================================================================== - -#define AM_VIDEO_FLAG_FIELD_MASK 0x0003L // use this mask to check whether the sample is field1 or field2 or frame -#define AM_VIDEO_FLAG_INTERLEAVED_FRAME 0x0000L // the sample is a frame (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this) -#define AM_VIDEO_FLAG_FIELD1 0x0001L // the sample is field1 (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this) -#define AM_VIDEO_FLAG_FIELD2 0x0002L // the sample is the field2 (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this) -#define AM_VIDEO_FLAG_FIELD1FIRST 0x0004L // if set means display field1 first, else display field2 first. - // this bit is irrelavant for 1FieldPerSample mode -#define AM_VIDEO_FLAG_WEAVE 0x0008L // if set use bob display mode else weave -#define AM_VIDEO_FLAG_IPB_MASK 0x0030L // use this mask to check whether the sample is I, P or B -#define AM_VIDEO_FLAG_I_SAMPLE 0x0000L // I Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this) -#define AM_VIDEO_FLAG_P_SAMPLE 0x0010L // P Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this) -#define AM_VIDEO_FLAG_B_SAMPLE 0x0020L // B Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this) -#define AM_VIDEO_FLAG_REPEAT_FIELD 0x0040L // if set means display the field which has been displayed first again after displaying - // both fields first. This bit is irrelavant for 1FieldPerSample mode - -// ----------------------------------------------------------------------- -// AM_KSPROPSETID_DvdKaraoke property set definitions -// ----------------------------------------------------------------------- - -typedef struct tagAM_DvdKaraokeData -{ - DWORD dwDownmix; // bitwise OR of AM_DvdKaraoke_Downmix flags - DWORD dwSpeakerAssignment; // AM_DvdKaraoke_SpeakerAssignment -} AM_DvdKaraokeData; - -typedef enum { - AM_PROPERTY_DVDKARAOKE_ENABLE = 0, // BOOL - AM_PROPERTY_DVDKARAOKE_DATA = 1, -} AM_PROPERTY_DVDKARAOKE; - -// ----------------------------------------------------------------------- -// AM_KSPROPSETID_TSRateChange property set definitions for time stamp -// rate changes. -// ----------------------------------------------------------------------- - -typedef enum { - AM_RATE_SimpleRateChange = 1, // rw, use AM_SimpleRateChange - AM_RATE_ExactRateChange = 2, // rw, use AM_ExactRateChange - AM_RATE_MaxFullDataRate = 3, // r, use AM_MaxFullDataRate - AM_RATE_Step = 4, // w, use AM_Step - AM_RATE_UseRateVersion = 5, // w, use WORD - AM_RATE_QueryFullFrameRate =6, // r, use AM_QueryRate - AM_RATE_QueryLastRateSegPTS =7, // r, use REFERENCE_TIME - AM_RATE_CorrectTS = 8 // w, use LONG -} AM_PROPERTY_TS_RATE_CHANGE; - -// ------------------------------------------------------------------- -// AM_KSPROPSETID_DVD_RateChange property set definitions for new DVD -// rate change scheme. -// ------------------------------------------------------------------- - -typedef enum { - AM_RATE_ChangeRate = 1, // w, use AM_DVD_ChangeRate - AM_RATE_FullDataRateMax = 2, // r, use AM_MaxFullDataRate - AM_RATE_ReverseDecode = 3, // r, use LONG - AM_RATE_DecoderPosition = 4, // r, use AM_DVD_DecoderPosition - AM_RATE_DecoderVersion = 5 // r, use LONG -} AM_PROPERTY_DVD_RATE_CHANGE; - -typedef struct { - // this is the simplest mechanism to set a time stamp rate change on - // a filter (simplest for the person setting the rate change, harder - // for the filter doing the rate change). - REFERENCE_TIME StartTime; //stream time at which to start this rate - LONG Rate; //new rate * 10000 (decimal) -} AM_SimpleRateChange; - -typedef struct { - LONG lMaxForwardFullFrame ; // rate * 10000 - LONG lMaxReverseFullFrame ; // rate * 10000 -} AM_QueryRate ; - -typedef struct { - REFERENCE_TIME OutputZeroTime; //input TS that maps to zero output TS - LONG Rate; //new rate * 10000 (decimal) -} AM_ExactRateChange; - -typedef LONG AM_MaxFullDataRate; //rate * 10000 (decimal) - -typedef DWORD AM_Step; // number of frame to step - -// New rate change property set, structs. enums etc. -typedef struct { - REFERENCE_TIME StartInTime; // stream time (input) at which to start decoding at this rate - REFERENCE_TIME StartOutTime; // reference time (output) at which to start showing at this rate - LONG Rate; // new rate * 10000 (decimal) -} AM_DVD_ChangeRate ; - -typedef LONGLONG AM_DVD_DecoderPosition ; - -typedef enum { - DVD_DIR_FORWARD = 0, - DVD_DIR_BACKWARD = 1 -} DVD_PLAY_DIRECTION ; - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // __DVDMEDIA_H__ diff --git a/plugins/gs/gsdx9/baseclasses/edevdefs.h b/plugins/gs/gsdx9/baseclasses/edevdefs.h deleted file mode 100644 index e066bbf16c..0000000000 --- a/plugins/gs/gsdx9/baseclasses/edevdefs.h +++ /dev/null @@ -1,531 +0,0 @@ -//------------------------------------------------------------------------------ -// File: EDevDefs.h -// -// Desc: External Device (such as a VCR) control interface parameter and -// value definitions. -// -// Note: new constants added: ED_BASE+800L -> ED_BASE+811L -// -// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __EDEVDEFS__ -#define __EDEVDEFS__ - - -#define ED_BASE 0x1000L - -// this is used to tell the device communications object which -// physical communications port to use. -#define DEV_PORT_SIM 1 -#define DEV_PORT_COM1 2 // standard serial ports -#define DEV_PORT_COM2 3 -#define DEV_PORT_COM3 4 -#define DEV_PORT_COM4 5 -#define DEV_PORT_DIAQ 6 // Diaquest driver -#define DEV_PORT_ARTI 7 // ARTI driver -#define DEV_PORT_1394 8 // IEEE 1394 Bus -#define DEV_PORT_USB 9 // Universal Serial Bus -#define DEV_PORT_MIN DEV_PORT_SIM -#define DEV_PORT_MAX DEV_PORT_USB - - -// IAMExtDevice Capability Items: unless otherwise specified, these items return -// OATRUE or OAFALSE. All return values are in pdwValue unless otherwise specified: - -#define ED_DEVCAP_CAN_RECORD ED_BASE+1L -#define ED_DEVCAP_CAN_RECORD_STROBE ED_BASE+2L // for multitrack devices: - // switches currently recording tracks off - // and selected non-recording tracks into record -#define ED_DEVCAP_HAS_AUDIO ED_BASE+3L -#define ED_DEVCAP_HAS_VIDEO ED_BASE+4L -#define ED_DEVCAP_USES_FILES ED_BASE+5L -#define ED_DEVCAP_CAN_SAVE ED_BASE+6L - -#define ED_DEVCAP_DEVICE_TYPE ED_BASE+7L // returns one of the following: -#define ED_DEVTYPE_VCR ED_BASE+8L -#define ED_DEVTYPE_LASERDISK ED_BASE+9L -#define ED_DEVTYPE_ATR ED_BASE+10L -#define ED_DEVTYPE_DDR ED_BASE+11L -#define ED_DEVTYPE_ROUTER ED_BASE+12L -#define ED_DEVTYPE_KEYER ED_BASE+13L -#define ED_DEVTYPE_MIXER_VIDEO ED_BASE+14L -#define ED_DEVTYPE_DVE ED_BASE+15L -#define ED_DEVTYPE_WIPEGEN ED_BASE+16L -#define ED_DEVTYPE_MIXER_AUDIO ED_BASE+17L -#define ED_DEVTYPE_CG ED_BASE+18L -#define ED_DEVTYPE_TBC ED_BASE+19L -#define ED_DEVTYPE_TCG ED_BASE+20L -#define ED_DEVTYPE_GPI ED_BASE+21L -#define ED_DEVTYPE_JOYSTICK ED_BASE+22L -#define ED_DEVTYPE_KEYBOARD ED_BASE+23L - -// returns mfr-specific ID from external device. -#define ED_DEVCAP_EXTERNAL_DEVICE_ID ED_BASE+24L - -#define ED_DEVCAP_TIMECODE_READ ED_BASE+25L -#define ED_DEVCAP_TIMECODE_WRITE ED_BASE+26L -// used for seekable non-timecode enabled devices -#define ED_DEVCAP_CTLTRK_READ ED_BASE+27L -// used for seekable non-timecode enabled devices -#define ED_DEVCAP_INDEX_READ ED_BASE+28L - -// returns device preroll time in current time format -#define ED_DEVCAP_PREROLL ED_BASE+29L -// returns device postroll time in current time format -#define ED_DEVCAP_POSTROLL ED_BASE+30L - -// returns indication of device’s synchronization accuracy. -#define ED_DEVCAP_SYNC_ACCURACY ED_BASE+31L // returns one of the following: -#define ED_SYNCACC_PRECISE ED_BASE+32L -#define ED_SYNCACC_FRAME ED_BASE+33L -#define ED_SYNCACC_ROUGH ED_BASE+34L - -// returns device’s normal framerate. -#define ED_DEVCAP_NORMAL_RATE ED_BASE+35L // returns one of the following: -#define ED_RATE_24 ED_BASE+36L -#define ED_RATE_25 ED_BASE+37L -#define ED_RATE_2997 ED_BASE+38L -#define ED_RATE_30 ED_BASE+39L - -#define ED_DEVCAP_CAN_PREVIEW ED_BASE+40L -#define ED_DEVCAP_CAN_MONITOR_SOURCES ED_BASE+41L - -// indicates implementation allows testing of methods/parameters by -// setting the hi bit of a parm that makes sense - see individual methods -// for details. -#define ED_DEVCAP_CAN_TEST ED_BASE+42L - -// indicates device accepts video as an input. -#define ED_DEVCAP_VIDEO_INPUTS ED_BASE+43L - -// indicates device accepts audio as an input. -#define ED_DEVCAP_AUDIO_INPUTS ED_BASE+44L - -#define ED_DEVCAP_NEEDS_CALIBRATING ED_BASE+45L - -#define ED_DEVCAP_SEEK_TYPE ED_BASE+46L // returns one of the following: -#define ED_SEEK_PERFECT ED_BASE+47L // indicates device can execute seek - // within 1 video frames without signal - // break (like a DDR) -#define ED_SEEK_FAST ED_BASE+48L // indicates device can move pretty quick - // with short break in signal -#define ED_SEEK_SLOW ED_BASE+49L // seeks like a tape transport - -#define ED_POWER_ON ED_BASE+50L -#define ED_POWER_OFF ED_BASE+51L -#define ED_POWER_STANDBY ED_BASE+52L - -#define ED_ACTIVE ED_BASE+53L -#define ED_INACTIVE ED_BASE+54L -#define ED_ALL ED_BASE+55L -#define ED_TEST ED_BASE+56L - -// IAMExtTransport Capability Items: unless otherwise specified, these items return -// OATRUE or OAFALSE. All return values are in pdwValue unless otherwise specified: - -#define ED_TRANSCAP_CAN_EJECT ED_BASE+100L -#define ED_TRANSCAP_CAN_BUMP_PLAY ED_BASE+101L // variable speed for synchronizing -#define ED_TRANSCAP_CAN_PLAY_BACKWARDS ED_BASE+102L // servo locked for use during an edit -#define ED_TRANSCAP_CAN_SET_EE ED_BASE+103L // show device’s input on its output -#define ED_TRANSCAP_CAN_SET_PB ED_BASE+104L // show media playback on device’s output -#define ED_TRANSCAP_CAN_DELAY_VIDEO_IN ED_BASE+105L // transport can do delayed-in video edits -#define ED_TRANSCAP_CAN_DELAY_VIDEO_OUT ED_BASE+106L // transport can do delayed-out video edits -#define ED_TRANSCAP_CAN_DELAY_AUDIO_IN ED_BASE+107L // transport can do delayed-in audio edits -#define ED_TRANSCAP_CAN_DELAY_AUDIO_OUT ED_BASE+108L // transport can do delayed-out audio edits -#define ED_TRANSCAP_FWD_VARIABLE_MAX ED_BASE+109L // max forward speed (multiple of play speed) - // in pdblValue -#define ED_TRANSCAP_FWD_VARIABLE_MIN ED_BASE+800L // min forward speed (multiple of play speed) - // in pdblValue -#define ED_TRANSCAP_REV_VARIABLE_MAX ED_BASE+110L // max reverse speed (multiple of play speed) in - // pdblValue -#define ED_TRANSCAP_REV_VARIABLE_MIN ED_BASE+801L // min reverse speed (multiple of play speed) - // in pdblValue -#define ED_TRANSCAP_FWD_SHUTTLE_MAX ED_BASE+802L // max forward speed in Shuttle mode (multiple - // of play speed) in pdblValue -#define ED_TRANSCAP_FWD_SHUTTLE_MIN ED_BASE+803L // min forward speed in Shuttle mode (multiple - // of play speed) in pdblValue -#define ED_TRANSCAP_REV_SHUTTLE_MAX ED_BASE+804L // max reverse speed in Shuttle mode (multiple - // of play speed) in pdblValue -#define ED_TRANSCAP_REV_SHUTTLE_MIN ED_BASE+805L // min reverse speed in Shuttle mode (multiple - // of play speed) in pdblValue -#define ED_TRANSCAP_NUM_AUDIO_TRACKS ED_BASE+111L // returns number of audio tracks -#define ED_TRANSCAP_LTC_TRACK ED_BASE+112L // returns track number of LTC timecode track. - // ED_ALL means no dedicated timecode track -#define ED_TRANSCAP_NEEDS_TBC ED_BASE+113L // device’s output not stable -#define ED_TRANSCAP_NEEDS_CUEING ED_BASE+114L // device must be cued prior to performing edit -#define ED_TRANSCAP_CAN_INSERT ED_BASE+115L -#define ED_TRANSCAP_CAN_ASSEMBLE ED_BASE+116L -#define ED_TRANSCAP_FIELD_STEP ED_BASE+117L // device responds to Frame Advance command by - // advancing one field -#define ED_TRANSCAP_CLOCK_INC_RATE ED_BASE+118L // VISCA command - keep for compatibility -#define ED_TRANSCAP_CAN_DETECT_LENGTH ED_BASE+119L -#define ED_TRANSCAP_CAN_FREEZE ED_BASE+120L -#define ED_TRANSCAP_HAS_TUNER ED_BASE+121L -#define ED_TRANSCAP_HAS_TIMER ED_BASE+122L -#define ED_TRANSCAP_HAS_CLOCK ED_BASE+123L -#define ED_TRANSCAP_MULTIPLE_EDITS ED_BASE+806L // OATRUE means device/filter can support - // multiple edit events -#define ED_TRANSCAP_IS_MASTER ED_BASE+807L // OATRUE means device is the master clock - // for synchronizing (this sets timecode-to- - // reference clock offset for editing) -#define ED_TRANSCAP_HAS_DT ED_BASE+814L // OATRUE means device has Dynamic Tracking - -// IAMExtTransport Media States -#define ED_MEDIA_SPIN_UP ED_BASE+130L -#define ED_MEDIA_SPIN_DOWN ED_BASE+131L -#define ED_MEDIA_UNLOAD ED_BASE+132L - -// IAMExtTransport Modes -#define ED_MODE_PLAY ED_BASE+200L -#define ED_MODE_STOP ED_BASE+201L -#define ED_MODE_FREEZE ED_BASE+202L // really "pause" -#define ED_MODE_THAW ED_BASE+203L -#define ED_MODE_FF ED_BASE+204L -#define ED_MODE_REW ED_BASE+205L -#define ED_MODE_RECORD ED_BASE+206L -#define ED_MODE_RECORD_STROBE ED_BASE+207L -#define ED_MODE_RECORD_FREEZE ED_BASE+808L // never "put", only "get" -#define ED_MODE_STEP ED_BASE+208L // same as "jog" -#define ED_MODE_STEP_FWD ED_BASE+208L // same as ED_MODE_STEP -#define ED_MODE_STEP_REV ED_BASE+809L -#define ED_MODE_SHUTTLE ED_BASE+209L -#define ED_MODE_EDIT_CUE ED_BASE+210L -#define ED_MODE_VAR_SPEED ED_BASE+211L -#define ED_MODE_PERFORM ED_BASE+212L // returned status only -#define ED_MODE_LINK_ON ED_BASE+280L -#define ED_MODE_LINK_OFF ED_BASE+281L -#define ED_MODE_NOTIFY_ENABLE ED_BASE+810L -#define ED_MODE_NOTIFY_DISABLE ED_BASE+811L -#define ED_MODE_SHOT_SEARCH ED_BASE+812L - -// IAMTimecodeReader/Generator/Display defines -// -// Timecode Generator Mode params and values: -// -#define ED_TCG_TIMECODE_TYPE ED_BASE+400L // can be one of the following: -#define ED_TCG_SMPTE_LTC ED_BASE+401L -#define ED_TCG_SMPTE_VITC ED_BASE+402L -#define ED_TCG_MIDI_QF ED_BASE+403L -#define ED_TCG_MIDI_FULL ED_BASE+404L - -#define ED_TCG_FRAMERATE ED_BASE+405L // can be one of the following: -#define ED_FORMAT_SMPTE_30 ED_BASE+406L -#define ED_FORMAT_SMPTE_30DROP ED_BASE+407L -#define ED_FORMAT_SMPTE_25 ED_BASE+408L -#define ED_FORMAT_SMPTE_24 ED_BASE+409L - -#define ED_TCG_SYNC_SOURCE ED_BASE+410L // can be one of the following: -#define ED_TCG_VIDEO ED_BASE+411L -#define ED_TCG_READER ED_BASE+412L -#define ED_TCG_FREE ED_BASE+413L - -#define ED_TCG_REFERENCE_SOURCE ED_BASE+414L // can have one these values: - // ED_TCG_FREE || ED_TCG_READER - // (for regen/jamsync) - -// TimeCodeReader Mode params and values: -#define ED_TCR_SOURCE ED_BASE+416L // can be one of the following: -// ED_TCG (already defined) -#define ED_TCR_LTC ED_BASE+417L -#define ED_TCR_VITC ED_BASE+418L -#define ED_TCR_CT ED_BASE+419L // Control Track -#define ED_TCR_FTC ED_BASE+420L // File TimeCode - for file-based devices - // that wish they were transports -// ED_MODE_NOTIFY_ENABLE can be OATRUE or OAFALSE (defined in transport mode -// section of this file). -#define ED_TCR_LAST_VALUE ED_BASE+421L // for notification mode - - // successive calls to GetTimecode - // return the last read value -// TimeCode Display Mode params and values: -// -#define ED_TCD_SOURCE ED_BASE+422L // can be one of the following: -#define ED_TCR ED_BASE+423L -#define ED_TCG ED_BASE+424L - -#define ED_TCD_SIZE ED_BASE+425L // can be one of the following: -#define ED_SMALL ED_BASE+426L -#define ED_MED ED_BASE+427L -#define ED_LARGE ED_BASE+428L - -#define ED_TCD_POSITION ED_BASE+429L // can be one of the following: -#define ED_TOP 0x0001 -#define ED_MIDDLE 0x0002 -#define ED_BOTTOM 0x0004 // OR'd with -#define ED_LEFT 0x0100 -#define ED_CENTER 0x0200 -#define ED_RIGHT 0x0400 - -#define ED_TCD_INTENSITY ED_BASE+436L // can be one of the following: -#define ED_HIGH ED_BASE+437L -#define ED_LOW ED_BASE+438L - -#define ED_TCD_TRANSPARENCY ED_BASE+439L // 0-4, 0 is opaque - -#define ED_TCD_INVERT ED_BASE+440L // OATRUE=black on white - // OAFALSE=white on black -// IAMExtTransport defines -// -// Transport status, params and values -// - -// IAMExtTransport Status items and and values: -#define ED_MODE ED_BASE+500L // see ED_MODE_xxx values above -#define ED_ERROR ED_BASE+501L -#define ED_LOCAL ED_BASE+502L -#define ED_RECORD_INHIBIT ED_BASE+503L -#define ED_SERVO_LOCK ED_BASE+504L -#define ED_MEDIA_PRESENT ED_BASE+505L -#define ED_MEDIA_LENGTH ED_BASE+506L -#define ED_MEDIA_SIZE ED_BASE+507L -#define ED_MEDIA_TRACK_COUNT ED_BASE+508L -#define ED_MEDIA_TRACK_LENGTH ED_BASE+509L -#define ED_MEDIA_SIDE ED_BASE+510L - -#define ED_MEDIA_TYPE ED_BASE+511L // can be one of the following: -#define ED_MEDIA_VHS ED_BASE+512L -#define ED_MEDIA_SVHS ED_BASE+513L -#define ED_MEDIA_HI8 ED_BASE+514L -#define ED_MEDIA_UMATIC ED_BASE+515L -#define ED_MEDIA_DVC ED_BASE+516L -#define ED_MEDIA_1_INCH ED_BASE+517L -#define ED_MEDIA_D1 ED_BASE+518L -#define ED_MEDIA_D2 ED_BASE+519L -#define ED_MEDIA_D3 ED_BASE+520L -#define ED_MEDIA_D5 ED_BASE+521L -#define ED_MEDIA_DBETA ED_BASE+522L -#define ED_MEDIA_BETA ED_BASE+523L -#define ED_MEDIA_8MM ED_BASE+524L -#define ED_MEDIA_DDR ED_BASE+525L -#define ED_MEDIA_SX ED_BASE+813L -#define ED_MEDIA_OTHER ED_BASE+526L -#define ED_MEDIA_CLV ED_BASE+527L -#define ED_MEDIA_CAV ED_BASE+528L -#define ED_MEDIA_POSITION ED_BASE+529L - -#define ED_LINK_MODE ED_BASE+530L // OATRUE if transport controls - // are linked to graph's RUN, - // STOP, and PAUSE methods - -// IAMExtTransport Basic Parms -#define ED_TRANSBASIC_TIME_FORMAT ED_BASE+540L // can be one of the following: -#define ED_FORMAT_MILLISECONDS ED_BASE+541L -#define ED_FORMAT_FRAMES ED_BASE+542L -#define ED_FORMAT_REFERENCE_TIME ED_BASE+543L - -#define ED_FORMAT_HMSF ED_BASE+547L -#define ED_FORMAT_TMSF ED_BASE+548L - -#define ED_TRANSBASIC_TIME_REFERENCE ED_BASE+549L // can be one of the following: -#define ED_TIMEREF_TIMECODE ED_BASE+550L -#define ED_TIMEREF_CONTROL_TRACK ED_BASE+551L -#define ED_TIMEREF_INDEX ED_BASE+552L - -#define ED_TRANSBASIC_SUPERIMPOSE ED_BASE+553L // enable/disable onscreen display -#define ED_TRANSBASIC_END_STOP_ACTION ED_BASE+554L // can be one of: ED_MODE_STOP | - // ED_MODE_REWIND | ED_MODE_FREEZE -#define ED_TRANSBASIC_RECORD_FORMAT ED_BASE+555L // can be one of the following: -#define ED_RECORD_FORMAT_SP ED_BASE+556L -#define ED_RECORD_FORMAT_LP ED_BASE+557L -#define ED_RECORD_FORMAT_EP ED_BASE+558L - -#define ED_TRANSBASIC_STEP_COUNT ED_BASE+559L -#define ED_TRANSBASIC_STEP_UNIT ED_BASE+560L // can be one of the following: -#define ED_STEP_FIELD ED_BASE+561L -#define ED_STEP_FRAME ED_BASE+562L -#define ED_STEP_3_2 ED_BASE+563L - -#define ED_TRANSBASIC_PREROLL ED_BASE+564L -#define ED_TRANSBASIC_RECPREROLL ED_BASE+565L -#define ED_TRANSBASIC_POSTROLL ED_BASE+566L -#define ED_TRANSBASIC_EDIT_DELAY ED_BASE+567L -#define ED_TRANSBASIC_PLAYTC_DELAY ED_BASE+568L -#define ED_TRANSBASIC_RECTC_DELAY ED_BASE+569L -#define ED_TRANSBASIC_EDIT_FIELD ED_BASE+570L -#define ED_TRANSBASIC_FRAME_SERVO ED_BASE+571L -#define ED_TRANSBASIC_CF_SERVO ED_BASE+572L -#define ED_TRANSBASIC_SERVO_REF ED_BASE+573L // can be one of the following: -#define ED_REF_EXTERNAL ED_BASE+574L -#define ED_REF_INPUT ED_BASE+575L -#define ED_REF_INTERNAL ED_BASE+576L -#define ED_REF_AUTO ED_BASE+577L - -#define ED_TRANSBASIC_WARN_GL ED_BASE+578L -#define ED_TRANSBASIC_SET_TRACKING ED_BASE+579L // can be one of the following: -#define ED_TRACKING_PLUS ED_BASE+580L -#define ED_TRACKING_MINUS ED_BASE+581L -#define ED_TRACKING_RESET ED_BASE+582L - -#define ED_TRANSBASIC_SET_FREEZE_TIMEOUT ED_BASE+583L -#define ED_TRANSBASIC_VOLUME_NAME ED_BASE+584L -#define ED_TRANSBASIC_BALLISTIC_1 ED_BASE+585L // space for proprietary data -#define ED_TRANSBASIC_BALLISTIC_2 ED_BASE+586L -#define ED_TRANSBASIC_BALLISTIC_3 ED_BASE+587L -#define ED_TRANSBASIC_BALLISTIC_4 ED_BASE+588L -#define ED_TRANSBASIC_BALLISTIC_5 ED_BASE+589L -#define ED_TRANSBASIC_BALLISTIC_6 ED_BASE+590L -#define ED_TRANSBASIC_BALLISTIC_7 ED_BASE+591L -#define ED_TRANSBASIC_BALLISTIC_8 ED_BASE+592L -#define ED_TRANSBASIC_BALLISTIC_9 ED_BASE+593L -#define ED_TRANSBASIC_BALLISTIC_10 ED_BASE+594L -#define ED_TRANSBASIC_BALLISTIC_11 ED_BASE+595L -#define ED_TRANSBASIC_BALLISTIC_12 ED_BASE+596L -#define ED_TRANSBASIC_BALLISTIC_13 ED_BASE+597L -#define ED_TRANSBASIC_BALLISTIC_14 ED_BASE+598L -#define ED_TRANSBASIC_BALLISTIC_15 ED_BASE+599L -#define ED_TRANSBASIC_BALLISTIC_16 ED_BASE+600L -#define ED_TRANSBASIC_BALLISTIC_17 ED_BASE+601L -#define ED_TRANSBASIC_BALLISTIC_18 ED_BASE+602L -#define ED_TRANSBASIC_BALLISTIC_19 ED_BASE+603L -#define ED_TRANSBASIC_BALLISTIC_20 ED_BASE+604L - -// consumer VCR items -#define ED_TRANSBASIC_SETCLOCK ED_BASE+605L -#define ED_TRANSBASIC_SET_COUNTER_FORMAT ED_BASE+606L // uses time format flags -#define ED_TRANSBASIC_SET_COUNTER_VALUE ED_BASE+607L - -#define ED_TRANSBASIC_SETTUNER_CH_UP ED_BASE+608L -#define ED_TRANSBASIC_SETTUNER_CH_DN ED_BASE+609L -#define ED_TRANSBASIC_SETTUNER_SK_UP ED_BASE+610L -#define ED_TRANSBASIC_SETTUNER_SK_DN ED_BASE+611L -#define ED_TRANSBASIC_SETTUNER_CH ED_BASE+612L -#define ED_TRANSBASIC_SETTUNER_NUM ED_BASE+613L - -#define ED_TRANSBASIC_SETTIMER_EVENT ED_BASE+614L -#define ED_TRANSBASIC_SETTIMER_STARTDAY ED_BASE+615L -#define ED_TRANSBASIC_SETTIMER_STARTTIME ED_BASE+616L -#define ED_TRANSBASIC_SETTIMER_STOPDAY ED_BASE+617L -#define ED_TRANSBASIC_SETTIMER_STOPTIME ED_BASE+618L - -// IAMExtTransport video parameters -#define ED_TRANSVIDEO_SET_OUTPUT ED_BASE+630L // can be one of the following: -#define ED_E2E ED_BASE+631L -#define ED_PLAYBACK ED_BASE+632L -#define ED_OFF ED_BASE+633L - -#define ED_TRANSVIDEO_SET_SOURCE ED_BASE+634L - -// IAMExtTransport audio parameters -#define ED_TRANSAUDIO_ENABLE_OUTPUT ED_BASE+640L // can be the following: -#define ED_AUDIO_ALL 0x10000000 // or any of the following OR'd together -#define ED_AUDIO_1 0x0000001L -#define ED_AUDIO_2 0x0000002L -#define ED_AUDIO_3 0x0000004L -#define ED_AUDIO_4 0x0000008L -#define ED_AUDIO_5 0x0000010L -#define ED_AUDIO_6 0x0000020L -#define ED_AUDIO_7 0x0000040L -#define ED_AUDIO_8 0x0000080L -#define ED_AUDIO_9 0x0000100L -#define ED_AUDIO_10 0x0000200L -#define ED_AUDIO_11 0x0000400L -#define ED_AUDIO_12 0x0000800L -#define ED_AUDIO_13 0x0001000L -#define ED_AUDIO_14 0x0002000L -#define ED_AUDIO_15 0x0004000L -#define ED_AUDIO_16 0x0008000L -#define ED_AUDIO_17 0x0010000L -#define ED_AUDIO_18 0x0020000L -#define ED_AUDIO_19 0x0040000L -#define ED_AUDIO_20 0x0080000L -#define ED_AUDIO_21 0x0100000L -#define ED_AUDIO_22 0x0200000L -#define ED_AUDIO_23 0x0400000L -#define ED_AUDIO_24 0x0800000L -#define ED_VIDEO 0x2000000L // for Edit props below - -#define ED_TRANSAUDIO_ENABLE_RECORD ED_BASE+642L -#define ED_TRANSAUDIO_ENABLE_SELSYNC ED_BASE+643L -#define ED_TRANSAUDIO_SET_SOURCE ED_BASE+644L -#define ED_TRANSAUDIO_SET_MONITOR ED_BASE+645L - - -// Edit Property Set-related defs - -// The following values reflect (and control) the state of an -// edit property set -#define ED_INVALID ED_BASE+652L -#define ED_EXECUTING ED_BASE+653L -#define ED_REGISTER ED_BASE+654L -#define ED_DELETE ED_BASE+655L - -// Edit property set parameters and values -#define ED_EDIT_HEVENT ED_BASE+656L // event handle to signal event - // completion -#define ED_EDIT_TEST ED_BASE+657L // returns OAFALSE if filter thinks - // edit can be done, OATRUE if not -#define ED_EDIT_IMMEDIATE ED_BASE+658L // OATRUE means start put the - // device into edit mode (editing - // "on the fly") immediately upon - // execution of Mode(ED_MODE_EDIT_CUE) -#define ED_EDIT_MODE ED_BASE+659L -// can be one of the following values: -#define ED_EDIT_MODE_ASSEMBLE ED_BASE+660L -#define ED_EDIT_MODE_INSERT ED_BASE+661L -#define ED_EDIT_MODE_CRASH_RECORD ED_BASE+662L -#define ED_EDIT_MODE_BOOKMARK_TIME ED_BASE+663L // these two are for -#define ED_EDIT_MODE_BOOKMARK_CHAPTER ED_BASE+664L // laserdisks - -#define ED_EDIT_MASTER ED_BASE+666L // OATRUE causes device - // not to synchronize - -#define ED_EDIT_TRACK ED_BASE+667L -// can be one of the following possible OR'd values: -// ED_VIDEO, ED_AUDIO_1 thru ED_AUDIO_24 (or ED_AUDIO_ALL) - -#define ED_EDIT_SRC_INPOINT ED_BASE+668L // in current time format -#define ED_EDIT_SRC_OUTPOINT ED_BASE+669L // in current time format -#define ED_EDIT_REC_INPOINT ED_BASE+670L // in current time format -#define ED_EDIT_REC_OUTPOINT ED_BASE+671L // in current time format - -#define ED_EDIT_REHEARSE_MODE ED_BASE+672L -// can be one of the following possible values: -#define ED_EDIT_BVB ED_BASE+673L // means rehearse the edit with - // "black-video-black" -#define ED_EDIT_VBV ED_BASE+674L -#define ED_EDIT_VVV ED_BASE+675L -#define ED_EDIT_PERFORM ED_BASE+676L // means perform the edit with no - // rehearsal. - -// Set this property to OATRUE to kill the edit if in progress -#define ED_EDIT_ABORT ED_BASE+677L -// how long to wait for edit to complete -#define ED_EDIT_TIMEOUT ED_BASE+678L // in current time format - -// This property causes the device to seek to a point specified by -// ED_EDIT_SEEK_MODE (see below). NOTE: Only one event at a time can seek. -#define ED_EDIT_SEEK ED_BASE+679L // OATRUE means do it now. -#define ED_EDIT_SEEK_MODE ED_BASE+680L -//possible values: -#define ED_EDIT_SEEK_EDIT_IN ED_BASE+681L // seek to edit's inpoint -#define ED_EDIT_SEEK_EDIT_OUT ED_BASE+682L // seek to edit's outpoint -#define ED_EDIT_SEEK_PREROLL ED_BASE+683L // seek to edit's - // inpoint-preroll -#define ED_EDIT_SEEK_PREROLL_CT ED_BASE+684L // seek to preroll point - // using control track (used for tapes with - // discontinuoustimecode before edit point: seek - // to inpoint using timecode, then backup to - // preroll point using control track) -#define ED_EDIT_SEEK_BOOKMARK ED_BASE+685L // seek to bookmark (just like - // timecode search) -// This property is used for multiple-VCR systems where each machine must -// cue to a different location relative to the graph's reference clock. The -// basic idea is that an edit event is setup with an ED_EDIT_OFFSET property -// that tells the VCR what offset to maintain between it's timecode (converted -// to reference clock units) and the reference clock. -#define ED_EDIT_OFFSET ED_BASE+686L // in current time format - -#define ED_EDIT_PREREAD ED_BASE+815L // OATRUE means device supports - // pre-read (recorder can also be - // player - -// -// Some error codes: -// -// device could be in local mode -#define ED_ERR_DEVICE_NOT_READY ED_BASE+700L - -#endif // __EDEVDEFS__ - -// eof edevdefs.h diff --git a/plugins/gs/gsdx9/baseclasses/errors.h b/plugins/gs/gsdx9/baseclasses/errors.h deleted file mode 100644 index c3432278e7..0000000000 --- a/plugins/gs/gsdx9/baseclasses/errors.h +++ /dev/null @@ -1,47 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Errors.h -// -// Desc: ActiveMovie error defines. -// -// Copyright (c) 1992-2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __ERRORS__ -#define __ERRORS__ - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -#ifndef _AMOVIE_ -#define AMOVIEAPI DECLSPEC_IMPORT -#else -#define AMOVIEAPI -#endif - -// codes 0-01ff are reserved for OLE -#define VFW_FIRST_CODE 0x200 -#define MAX_ERROR_TEXT_LEN 160 - -#include // includes all message definitions - -typedef BOOL (WINAPI* AMGETERRORTEXTPROCA)(HRESULT, char *, DWORD); -typedef BOOL (WINAPI* AMGETERRORTEXTPROCW)(HRESULT, WCHAR *, DWORD); - -AMOVIEAPI DWORD WINAPI AMGetErrorTextA( HRESULT hr , char *pbuffer , DWORD MaxLen); -AMOVIEAPI DWORD WINAPI AMGetErrorTextW( HRESULT hr , WCHAR *pbuffer , DWORD MaxLen); - - -#ifdef UNICODE -#define AMGetErrorText AMGetErrorTextW -typedef AMGETERRORTEXTPROCW AMGETERRORTEXTPROC; -#else -#define AMGetErrorText AMGetErrorTextA -typedef AMGETERRORTEXTPROCA AMGETERRORTEXTPROC; -#endif - -#ifdef __cplusplus -} -#endif // __cplusplus -#endif // __ERRORS__ diff --git a/plugins/gs/gsdx9/baseclasses/evcode.h b/plugins/gs/gsdx9/baseclasses/evcode.h deleted file mode 100644 index 62a26b2de7..0000000000 --- a/plugins/gs/gsdx9/baseclasses/evcode.h +++ /dev/null @@ -1,428 +0,0 @@ -//------------------------------------------------------------------------------ -// File: EvCode.h -// -// Desc: List of standard Quartz event codes and the expected params. -// -// Copyright (c) 1992 - 2001, Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Event codes are broken into two groups -// -- system event codes -// -- extension event codes -// All system event codes are below EC_USER - -#define EC_SYSTEMBASE 0x00 -#define EC_USER 0x8000 - -// System-defined event codes -// ========================== -// -// There are three types of system-defined event codes: -// -// 1. Those which are always passed through to the application -// (To be collected by calls to GetEvent or within WaitForCompletion.) -// (e.g. EC_ERRORABORT, EC_USERABORT.) -// -// 2. Those which are pure internal and will never be passed to -// the application. (e.g. EC_SHUTDOWN) -// -// 3. Those which have default handling. Default handing implies that -// the event is not passed to the application. However, default -// handling may be canceled by calling -// IMediaEvent::CancelDefaultHandling. If the default handling is -// cancelled in this way, then the message will be delivered to the -// application and the application must action it appropriately. -// Default handling can be restored by calling RestoreDefaultHandling. -// -// We will refer to these events as application, internal and defaulted -// events respectively. -// -// System-defined events may have interface pointers, BSTR's, etc passed -// as parameters. It is therefore essential that, for any message -// retrieved using GetEvent, a matching call to FreeEventParams is made -// to ensure that relevant interfaces are released and storage freed. -// Failure to call FreeEventParams will result in memory leaks, if not -// worse. -// -// Filters sending these messages to the filter graph should not AddRef() -// any interfaces that they may pass as parameters. The filter graph -// manager will AddRef them if required. E.g. if the event is to be queued -// for the application or queued to a worker thread. - -// Each event listed below is immediately followed by a parameter list -// detailing the types of the parameters associated with the message, -// and an indication of whether the message is an application, internal -// or defaulted message. This is then followed by a short description. -// The use of "void" in the parameter list implies that the parameter is not -// used. Such parameters should be zero. - -// Other defined EC_ regions: -// DVD event codes 0x0100 - 0x0150 (dvdevcod.h) -// audio device event codes 0x0200 - 0x0250 (audevcod.h) -// WindowsMedia SDK-originated events 0x0251 - 0x0300 (see below) -// MSVIDCTL 0x0301 - 0x0325 (msvidctl.idl) -// stream buffer engine (PVR) 0x0326 - 0x0350 (sbe.idl) - -#define EC_COMPLETE 0x01 -// ( HRESULT, void ) : defaulted (special) -// Signals the completed playback of a stream within the graph. This message -// is sent by renderers when they receive end-of-stream. The default handling -// of this message results in a _SINGLE_ EC_COMPLETE being sent to the -// application when ALL of the individual renderers have signaled EC_COMPLETE -// to the filter graph. If the default handing is canceled, the application -// will see all of the individual EC_COMPLETEs. - - -#define EC_USERABORT 0x02 -// ( void, void ) : application -// In some sense, the user has requested that playback be terminated. -// This message is typically sent by renderers that render into a -// window if the user closes the window into which it was rendering. -// It is up to the application to decide if playback should actually -// be stopped. - - -#define EC_ERRORABORT 0x03 -// ( HRESULT, void ) : application -// Operation aborted because of error - - -#define EC_TIME 0x04 -// ( DWORD, DWORD ) : application -// The requested reference time occurred. (This event is currently not used). -// lParam1 is low dword of ref time, lParam2 is high dword of reftime. - - -#define EC_REPAINT 0x05 -// ( IPin * (could be NULL), void ) : defaulted -// A repaint is required - lParam1 contains the (IPin *) that needs the data -// to be sent again. Default handling is: if the output pin which the IPin is -// attached to supports the IMediaEventSink interface then it will be called -// with the EC_REPAINT first. If that fails then normal repaint processing is -// done by the filter graph. - - -// Stream error notifications -#define EC_STREAM_ERROR_STOPPED 0x06 -#define EC_STREAM_ERROR_STILLPLAYING 0x07 -// ( HRESULT, DWORD ) : application -// lParam 1 is major code, lParam2 is minor code, either may be zero. - - -#define EC_ERROR_STILLPLAYING 0x08 -// ( HRESULT, void ) : application -// The filter graph manager may issue Run's to the graph asynchronously. -// If such a Run fails, EC_ERROR_STILLPLAYING is issued to notify the -// application of the failure. The state of the underlying filters -// at such a time will be indeterminate - they will all have been asked -// to run, but some are almost certainly not. - - -#define EC_PALETTE_CHANGED 0x09 -// ( void, void ) : application -// notify application that the video palette has changed - - -#define EC_VIDEO_SIZE_CHANGED 0x0A -// ( DWORD, void ) : application -// Sent by video renderers. -// Notifies the application that the native video size has changed. -// LOWORD of the DWORD is the new width, HIWORD is the new height. - - -#define EC_QUALITY_CHANGE 0x0B -// ( void, void ) : application -// Notify application that playback degradation has occurred - - -#define EC_SHUTTING_DOWN 0x0C -// ( void, void ) : internal -// This message is sent by the filter graph manager to any plug-in -// distributors which support IMediaEventSink to notify them that -// the filter graph is starting to shutdown. - - -#define EC_CLOCK_CHANGED 0x0D -// ( void, void ) : application -// Notify application that the clock has changed. -// (i.e. SetSyncSource has been called on the filter graph and has been -// distributed successfully to the filters in the graph.) - - -#define EC_PAUSED 0x0E -// ( HRESULT, void ) : application -// Notify application the previous pause request has completed - - -#define EC_OPENING_FILE 0x10 -#define EC_BUFFERING_DATA 0x11 -// ( BOOL, void ) : application -// lParam1 == 1 --> starting to open file or buffer data -// lParam1 == 0 --> not opening or buffering any more -// (This event does not appear to be used by ActiveMovie.) - - -#define EC_FULLSCREEN_LOST 0x12 -// ( void, IBaseFilter * ) : application -// Sent by full screen renderers when switched away from full screen. -// IBaseFilter may be NULL. - - -#define EC_ACTIVATE 0x13 -// ( BOOL, IBaseFilter * ) : internal -// Sent by video renderers when they lose or gain activation. -// lParam1 is set to 1 if gained or 0 if lost -// lParam2 is the IBaseFilter* for the filter that is sending the message -// Used for sound follows focus and full-screen switching - - -#define EC_NEED_RESTART 0x14 -// ( void, void ) : defaulted -// Sent by renderers when they regain a resource (e.g. audio renderer). -// Causes a restart by Pause/put_Current/Run (if running). - - -#define EC_WINDOW_DESTROYED 0x15 -// ( IBaseFilter *, void ) : internal -// Sent by video renderers when the window has been destroyed. Handled -// by the filter graph / distributor telling the resource manager. -// lParam1 is the IBaseFilter* of the filter whose window is being destroyed - - -#define EC_DISPLAY_CHANGED 0x16 -// ( IPin *, void ) : internal -// Sent by renderers when they detect a display change. the filter graph -// will arrange for the graph to be stopped and the pin send in lParam1 -// to be reconnected. by being reconnected it allows a renderer to reset -// and connect with a more appropriate format for the new display mode -// lParam1 contains an (IPin *) that should be reconnected by the graph - - -#define EC_STARVATION 0x17 -// ( void, void ) : defaulted -// Sent by a filter when it detects starvation. Default handling (only when -// running) is for the graph to be paused until all filters enter the -// paused state and then run. Normally this would be sent by a parser or source -// filter when too little data is arriving. - - -#define EC_OLE_EVENT 0x18 -// ( BSTR, BSTR ) : application -// Sent by a filter to pass a text string to the application. -// Conventionally, the first string is a type, and the second a parameter. - - -#define EC_NOTIFY_WINDOW 0x19 -// ( HWND, void ) : internal -// Pass the window handle around during pin connection. - -#define EC_STREAM_CONTROL_STOPPED 0x1A -// ( IPin * pSender, DWORD dwCookie ) -// Notification that an earlier call to IAMStreamControl::StopAt -// has now take effect. Calls to the method can be marked -// with a cookie which is passed back in the second parameter, -// allowing applications to easily tie together request -// and completion notifications. -// -// NB: IPin will point to the pin that actioned the Stop. This -// may not be the pin that the StopAt was sent to. - -#define EC_STREAM_CONTROL_STARTED 0x1B -// ( IPin * pSender, DWORD dwCookie ) -// Notification that an earlier call to IAMStreamControl::StartAt -// has now take effect. Calls to the method can be marked -// with a cookie which is passed back in the second parameter, -// allowing applications to easily tie together request -// and completion notifications. -// -// NB: IPin will point to the pin that actioned the Start. This -// may not be the pin that the StartAt was sent to. - -#define EC_END_OF_SEGMENT 0x1C -// -// ( const REFERENCE_TIME *pStreamTimeAtEndOfSegment, DWORD dwSegmentNumber ) -// -// pStreamTimeAtEndOfSegment -// pointer to the accumulated stream clock -// time since the start of the segment - this is directly computable -// as the sum of the previous and current segment durations (Stop - Start) -// and the rate applied to each segment -// The source add this time to the time within each segment to get -// a total elapsed time -// -// dwSegmentNumber -// Segment number - starts at 0 -// -// Notifies that a segment end has been reached when the -// AM_SEEKING_Segment flags was set for IMediaSeeking::SetPositions -// Passes in an IMediaSeeking interface to allow the next segment -// to be defined by the application - -#define EC_SEGMENT_STARTED 0x1D -// -// ( const REFERENCE_TIME *pStreamTimeAtStartOfSegment, DWORD dwSegmentNumber) -// -// pStreamTimeAtStartOfSegment -// pointer to the accumulated stream clock -// time since the start of the segment - this is directly computable -// as the sum of the previous segment durations (Stop - Start) -// and the rate applied to each segment -// -// dwSegmentNumber -// Segment number - starts at 0 -// -// Notifies that a new segment has been started. -// This is sent synchronously by any entity that will issue -// EC_END_OF_SEGMENT when a new segment is started -// (See IMediaSeeking::SetPositions - AM_SEEKING_Segment flag) -// It is used to compute how many EC_END_OF_SEGMENT notifications -// to expect at the end of a segment and as a consitency check - - -#define EC_LENGTH_CHANGED 0x1E -// (void, void) -// sent to indicate that the length of the "file" has changed - -#define EC_DEVICE_LOST 0x1f -// (IUnknown, 0) -// -// request window notification when the device is available again -// (through WM_DEVICECHANGED messages registered with -// RegisterDeviceNotification; see IAMDeviceRemoval interface) - -#define EC_STEP_COMPLETE 0x24 -// (BOOL bCacelled, void) -// Step request complete -// if bCancelled is TRUE the step was cancelled. This can happen -// if the application issued some control request or because there -// was a mode change etc etc - -// Event code 25 is reserved for future use. - -#define EC_TIMECODE_AVAILABLE 0x30 -// Sent by filter supporting timecode -// Param1 has a pointer to the sending object -// Param2 has the device ID of the sending object - -#define EC_EXTDEVICE_MODE_CHANGE 0x31 -// Sent by filter supporting IAMExtDevice -// Param1 has the new mode -// Param2 has the device ID of the sending object - -#define EC_STATE_CHANGE 0x32 -// ( FILTER_STATE, BOOL bInternal) -// Used to notify the application of any state changes in the filter graph. -// lParam1 is of type enum FILTER_STATE (defined in strmif.h) and indicates -// the state of the filter graph. -// -// lParam2 == 0 indicates that the previous state change request has completed -// & a change in application state. -// lParam2 == 1 reserved for future use to indicate internal state changes. - - -#define EC_GRAPH_CHANGED 0x50 -// Sent by filter to notify interesting graph changes - -#define EC_CLOCK_UNSET 0x51 -// ( void, void ) : application -// Used to notify the filter graph to unset the current graph clock. -// Has the affect of forcing the filter graph to reestablish the graph clock -// on the next Pause/Run (note that this is only used by ksproxy, when the pin -// of a clock providing filter is disconnected) - -#define EC_VMR_RENDERDEVICE_SET 0x53 -// (Render_Device type, void) -// Identifies the type of rendering mechanism the VMR -// is using to display video. Types used include: -#define VMR_RENDER_DEVICE_OVERLAY 0x01 -#define VMR_RENDER_DEVICE_VIDMEM 0x02 -#define VMR_RENDER_DEVICE_SYSMEM 0x04 - - -#define EC_VMR_SURFACE_FLIPPED 0x54 -// (hr - Flip return code, void) -// Identifies the VMR's allocator-presenter has called the DDraw flip api on -// the surface being presented. This allows the VMR to keep its DX-VA table -// of DDraw surfaces in sync with DDraws flipping chain. - -#define EC_VMR_RECONNECTION_FAILED 0x55 -// (hr - ReceiveConnection return code, void) -// Identifies that an upstream decoder tried to perform a dynamic format -// change and the VMR was unable to accept the new format. - - -#define EC_PREPROCESS_COMPLETE 0x56 -// Sent by the WM ASF writer filter (WMSDK V9 version) to signal the completion -// of a pre-process run when running in multipass encode mode. -// Param1 = 0, Param2 = IBaseFilter ptr of sending filter - -#define EC_CODECAPI_EVENT 0x57 -// Sent by the Codec API when an event is encountered. Both the Data -// must be freed by the recipient using CoTaskMemFree -// Param1 = UserDataPointer, Param2 = VOID* Data - -//------------------------------------------ -// -// BDA events: -// -// Event code 0x80 through 0x8f are reserved for BDA -// - - -//------------------------------------------ -// -// WindowsMedia SDK filter-specific events: -// -// -// Note that for EC_WMT_EVENT events the wmsdk-based filters use the following structure for -// passing event parameters to the app: -#ifndef AM_WMT_EVENT_DATA_DEFINED -#define AM_WMT_EVENT_DATA_DEFINED -typedef struct { - HRESULT hrStatus; // status code - void * pData; // event data -} AM_WMT_EVENT_DATA; -#endif -// -#define EC_WMT_EVENT_BASE 0x0251 -// -#define EC_WMT_INDEX_EVENT EC_WMT_EVENT_BASE -// WindowsMedia SDK-originated file indexing status, sent by WMSDK-based filters -// -// lParam1 is one of the enum WMT_STATUS messages listed below, sent by the WindowsMedia SDK -// lParam2 is specific to the lParam event -// -// the following WMT_STATUS messages are sent for this event: -// WMT_STARTED - lParam2 is 0 -// WMT_CLOSED - lParam2 is 0 -// WMT_INDEX_PROGRESS - lParam2 is a DWORD containing the progress percent complete -// -#define EC_WMT_EVENT EC_WMT_EVENT_BASE+1 -// WindowsMedia SDK-originated event, sent by WMSDK-based filters -// -// lParam1 is one of the enum WMT_STATUS messages listed below, sent by the WindowsMedia SDK -// lParam2 is a pointer an AM_WMT_EVENT_DATA structure where, -// hrStatus is the status code sent by the wmsdk -// pData is specific to the lParam1 event -// -// the following WMT_STATUS messages are sent by the WMSDK Reader filter for this event: -// WMT_NO_RIGHTS - pData is a pointer to a WCHAR string containing a challenge URL -// WMT_ACQUIRE_LICENSE - lParam2 is a pointer to a WM_GET_LICENSE_DATA struct -// WMT_NO_RIGHTS_EX - lParam2 is a pointer to a WM_GET_LICENSE_DATA struct -// WMT_NEEDS_INDIVIDUALIZATION - lParam2 is NULL -// WMT_INDIVIDUALIZE - lParam2 is a pointer to a WM_INDIVIDUALIZE_STATUS struct -// the WMSDK (V9) ASF Writer filter will send this event in response to a wmsdk-signaled error during file -// writing, along with the wmsdk WMT_STATUS error as the lParam1 and hrStatus embedded in the -// AM_WMT_EVENT_DATA struct pointed to by the lParam2 pointer. -// -// end WMSDK-originated events -//----------------------------------------- - - -#define EC_BUILT 0x300 -// Sent to notify transition from unbuilt to built state - - -#define EC_UNBUILT 0x301 -// Sent to notify transtion from built to unbuilt state diff --git a/plugins/gs/gsdx9/baseclasses/fourcc.h b/plugins/gs/gsdx9/baseclasses/fourcc.h deleted file mode 100644 index dea8171a6b..0000000000 --- a/plugins/gs/gsdx9/baseclasses/fourcc.h +++ /dev/null @@ -1,101 +0,0 @@ -//------------------------------------------------------------------------------ -// File: FourCC.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// FOURCCMap -// -// provides a mapping between old-style multimedia format DWORDs -// and new-style GUIDs. -// -// A range of 4 billion GUIDs has been allocated to ensure that this -// mapping can be done straightforwardly one-to-one in both directions. -// -// January 95 - - -#ifndef __FOURCC__ -#define __FOURCC__ - - -// Multimedia format types are marked with DWORDs built from four 8-bit -// chars and known as FOURCCs. New multimedia AM_MEDIA_TYPE definitions include -// a subtype GUID. In order to simplify the mapping, GUIDs in the range: -// XXXXXXXX-0000-0010-8000-00AA00389B71 -// are reserved for FOURCCs. - -class FOURCCMap : public GUID -{ - -public: - FOURCCMap(); - FOURCCMap(DWORD Fourcc); - FOURCCMap(const GUID *); - - - DWORD GetFOURCC(void); - void SetFOURCC(DWORD fourcc); - void SetFOURCC(const GUID *); - -private: - void InitGUID(); -}; - -#define GUID_Data2 0 -#define GUID_Data3 0x10 -#define GUID_Data4_1 0xaa000080 -#define GUID_Data4_2 0x719b3800 - -inline void -FOURCCMap::InitGUID() { - Data2 = GUID_Data2; - Data3 = GUID_Data3; - ((DWORD *)Data4)[0] = GUID_Data4_1; - ((DWORD *)Data4)[1] = GUID_Data4_2; -} - -inline -FOURCCMap::FOURCCMap() { - InitGUID(); - SetFOURCC( DWORD(0)); -} - -inline -FOURCCMap::FOURCCMap(DWORD fourcc) -{ - InitGUID(); - SetFOURCC(fourcc); -} - -inline -FOURCCMap::FOURCCMap(const GUID * pGuid) -{ - InitGUID(); - SetFOURCC(pGuid); -} - -inline void -FOURCCMap::SetFOURCC(const GUID * pGuid) -{ - FOURCCMap * p = (FOURCCMap*) pGuid; - SetFOURCC(p->GetFOURCC()); -} - -inline void -FOURCCMap::SetFOURCC(DWORD fourcc) -{ - Data1 = fourcc; -} - -inline DWORD -FOURCCMap::GetFOURCC(void) -{ - return Data1; -} - -#endif /* __FOURCC__ */ - diff --git a/plugins/gs/gsdx9/baseclasses/measure.h b/plugins/gs/gsdx9/baseclasses/measure.h deleted file mode 100644 index 75365e3a66..0000000000 --- a/plugins/gs/gsdx9/baseclasses/measure.h +++ /dev/null @@ -1,222 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Measure.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* - The idea is to pepper the source code with interesting measurements and - have the last few thousand of these recorded in a circular buffer that - can be post-processed to give interesting numbers. - - WHAT THE LOG LOOKS LIKE: - - Time (sec) Type Delta Incident_Name - 0.055,41 NOTE -. Incident Nine - Another note - 0.055,42 NOTE 0.000,01 Incident Nine - Another note - 0.055,44 NOTE 0.000,02 Incident Nine - Another note - 0.055,45 STOP -. Incident Eight - Also random - 0.055,47 START -. Incident Seven - Random - 0.055,49 NOTE 0.000,05 Incident Nine - Another note - ------- ---------------- - 0.125,60 STOP 0.000,03 Msr_Stop - 0.125,62 START -. Msr_Start - 0.125,63 START -. Incident Two - Start/Stop - 0.125,65 STOP 0.000,03 Msr_Start - 0.125,66 START -. Msr_Stop - 0.125,68 STOP 0.000,05 Incident Two - Start/Stop - 0.125,70 STOP 0.000,04 Msr_Stop - 0.125,72 START -. Msr_Start - 0.125,73 START -. Incident Two - Start/Stop - 0.125,75 STOP 0.000,03 Msr_Start - 0.125,77 START -. Msr_Stop - 0.125,78 STOP 0.000,05 Incident Two - Start/Stop - 0.125,80 STOP 0.000,03 Msr_Stop - 0.125,81 NOTE -. Incident Three - single Note - 0.125,83 START -. Incident Four - Start, no stop - 0.125,85 START -. Incident Five - Single Start/Stop - 0.125,87 STOP 0.000,02 Incident Five - Single Start/Stop - -Number Average StdDev Smallest Largest Incident_Name - 10 0.000,58 0.000,10 0.000,55 0.000,85 Incident One - Note - 50 0.000,05 0.000,00 0.000,05 0.000,05 Incident Two - Start/Stop - 1 -. -. -. -. Incident Three - single Note - 0 -. -. -. -. Incident Four - Start, no stop - 1 0.000,02 -. 0.000,02 0.000,02 Incident Five - Single Start/Stop - 0 -. -. -. -. Incident Six - zero occurrences - 100 0.000,25 0.000,12 0.000,02 0.000,62 Incident Seven - Random - 100 0.000,79 0.000,48 0.000,02 0.001,92 Incident Eight - Also random - 5895 0.000,01 0.000,01 0.000,01 0.000,56 Incident Nine - Another note - 10 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Note - 50 0.000,03 0.000,00 0.000,03 0.000,04 Msr_Start - 50 0.000,04 0.000,03 0.000,03 0.000,31 Msr_Stop - - WHAT IT MEANS: - The log shows what happened and when. Each line shows the time at which - something happened (see WHAT YOU CODE below) what it was that happened - and (if approporate) the time since the corresponding previous event - (that's the delta column). - - The statistics show how many times each event occurred, what the average - delta time was, also the standard deviation, largest and smalles delta. - - WHAT YOU CODE: - - Before anything else executes: - register your ids - - int id1 = Msr_Register("Incident One - Note"); - int id2 = Msr_Register("Incident Two - Start/Stop"); - int id3 = Msr_Register("Incident Three - single Note"); - etc. - - At interesting moments: - - // To measure a repetitive event - e.g. end of bitblt to screen - Msr_Note(Id9); // e.g. "video frame hiting the screen NOW!" - - or - - // To measure an elapsed time e.g. time taken to decode an MPEG B-frame - Msr_Start(Id2); // e.g. "Starting to decode MPEG B-frame" - . . . - MsrStop(Id2); // "Finished MPEG decode" - - At the end: - - HANDLE hFile; - hFile = CreateFile("Perf.log", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, NULL); - Msr_Dump(hFile); // This writes the log out to the file - CloseHandle(hFile); - - or - - Msr_Dump(NULL); // This writes it to DbgLog((LOG_TRACE,0, ... )); - // but if you are writing it out to the debugger - // then the times are probably all garbage because - // the debugger can make things run awfully slow. - - A given id should be used either for start / stop or Note calls. If Notes - are mixed in with Starts and Stops their statistics will be gibberish. - - If you code the calls in upper case i.e. MSR_START(idMunge); then you get - macros which will turn into nothing unless PERF is defined. - - You can reset the statistical counts for a given id by calling Reset(Id). - They are reset by default at the start. - It logs Reset as a special incident, so you can see it in the log. - - The log is a circular buffer in storage (to try to minimise disk I/O). - It overwrites the oldest entries once full. The statistics include ALL - incidents since the last Reset, whether still visible in the log or not. -*/ - -#ifndef __MEASURE__ -#define __MEASURE__ - -#ifdef PERF -#define MSR_INIT() Msr_Init() -#define MSR_TERMINATE() Msr_Terminate() -#define MSR_REGISTER(a) Msr_Register(a) -#define MSR_RESET(a) Msr_Reset(a) -#define MSR_CONTROL(a) Msr_Control(a) -#define MSR_START(a) Msr_Start(a) -#define MSR_STOP(a) Msr_Stop(a) -#define MSR_NOTE(a) Msr_Note(a) -#define MSR_INTEGER(a,b) Msr_Integer(a,b) -#define MSR_DUMP(a) Msr_Dump(a) -#define MSR_DUMPSTATS(a) Msr_DumpStats(a) -#else -#define MSR_INIT() ((void)0) -#define MSR_TERMINATE() ((void)0) -#define MSR_REGISTER(a) 0 -#define MSR_RESET(a) ((void)0) -#define MSR_CONTROL(a) ((void)0) -#define MSR_START(a) ((void)0) -#define MSR_STOP(a) ((void)0) -#define MSR_NOTE(a) ((void)0) -#define MSR_INTEGER(a,b) ((void)0) -#define MSR_DUMP(a) ((void)0) -#define MSR_DUMPSTATS(a) ((void)0) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// This must be called first - (called by the DllEntry) - -void WINAPI Msr_Init(void); - - -// Call this last to clean up (or just let it fall off the end - who cares?) - -void WINAPI Msr_Terminate(void); - - -// Call this to get an Id for an "incident" that you can pass to Start, Stop or Note -// everything that's logged is called an "incident". - -int WINAPI Msr_Register(LPTSTR Incident); - - -// Reset the statistical counts for an incident - -void WINAPI Msr_Reset(int Id); - - -// Reset all the counts for all incidents -#define MSR_RESET_ALL 0 -#define MSR_PAUSE 1 -#define MSR_RUN 2 - -void WINAPI Msr_Control(int iAction); - - -// log the start of an operation - -void WINAPI Msr_Start(int Id); - - -// log the end of an operation - -void WINAPI Msr_Stop(int Id); - - -// log a one-off or repetitive operation - -void WINAPI Msr_Note(int Id); - - -// log an integer (on which we can see statistics later) -void WINAPI Msr_Integer(int Id, int n); - - -// print out all the vaialable log (it may have wrapped) and then the statistics. -// When the log wraps you lose log but the statistics are still complete. -// hFIle==NULL => use DbgLog -// otherwise hFile must have come from CreateFile or OpenFile. - -void WINAPI Msr_Dump(HANDLE hFile); - - -// just dump the statistics - never mind the log - -void WINAPI Msr_DumpStats(HANDLE hFile); - -// Type definitions in case you want to declare a pointer to the dump functions -// (makes it a trifle easier to do dynamic linking -// i.e. LoadModule, GetProcAddress and call that) - -// Typedefs so can declare MSR_DUMPPROC *MsrDumpStats; or whatever -typedef void WINAPI MSR_DUMPPROC(HANDLE hFile); -typedef void WINAPI MSR_CONTROLPROC(int iAction); - - -#ifdef __cplusplus -} -#endif - -#endif // __MEASURE__ diff --git a/plugins/gs/gsdx9/baseclasses/msgthrd.h b/plugins/gs/gsdx9/baseclasses/msgthrd.h deleted file mode 100644 index f07d5162ad..0000000000 --- a/plugins/gs/gsdx9/baseclasses/msgthrd.h +++ /dev/null @@ -1,120 +0,0 @@ -//------------------------------------------------------------------------------ -// File: MsgThrd.h -// -// Desc: DirectShow base classes - provides support for a worker thread -// class to which one can asynchronously post messages. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Message class - really just a structure. -// -class CMsg { -public: - UINT uMsg; - DWORD dwFlags; - LPVOID lpParam; - CAMEvent *pEvent; - - CMsg(UINT u, DWORD dw, LPVOID lp, CAMEvent *pEvnt) - : uMsg(u), dwFlags(dw), lpParam(lp), pEvent(pEvnt) {} - - CMsg() - : uMsg(0), dwFlags(0L), lpParam(NULL), pEvent(NULL) {} -}; - -// This is the actual thread class. It exports all the usual thread control -// functions. The created thread is different from a normal WIN32 thread in -// that it is prompted to perform particaular tasks by responding to messages -// posted to its message queue. -// -class AM_NOVTABLE CMsgThread { -private: - static DWORD WINAPI DefaultThreadProc(LPVOID lpParam); - DWORD m_ThreadId; - HANDLE m_hThread; - -protected: - - // if you want to override GetThreadMsg to block on other things - // as well as this queue, you need access to this - CGenericList m_ThreadQueue; - CCritSec m_Lock; - HANDLE m_hSem; - LONG m_lWaiting; - -public: - CMsgThread() - : m_ThreadId(0), - m_hThread(NULL), - m_lWaiting(0), - m_hSem(NULL), - // make a list with a cache of 5 items - m_ThreadQueue(NAME("MsgThread list"), 5) - { - } - - ~CMsgThread(); - // override this if you want to block on other things as well - // as the message loop - void virtual GetThreadMsg(CMsg *msg); - - // override this if you want to do something on thread startup - virtual void OnThreadInit() { - }; - - BOOL CreateThread(); - - BOOL WaitForThreadExit(LPDWORD lpdwExitCode) { - if (m_hThread != NULL) { - WaitForSingleObject(m_hThread, INFINITE); - return GetExitCodeThread(m_hThread, lpdwExitCode); - } - return FALSE; - } - - DWORD ResumeThread() { - return ::ResumeThread(m_hThread); - } - - DWORD SuspendThread() { - return ::SuspendThread(m_hThread); - } - - int GetThreadPriority() { - return ::GetThreadPriority(m_hThread); - } - - BOOL SetThreadPriority(int nPriority) { - return ::SetThreadPriority(m_hThread, nPriority); - } - - HANDLE GetThreadHandle() { - return m_hThread; - } - - DWORD GetThreadId() { - return m_ThreadId; - } - - - void PutThreadMsg(UINT uMsg, DWORD dwMsgFlags, - LPVOID lpMsgParam, CAMEvent *pEvent = NULL) { - CAutoLock lck(&m_Lock); - CMsg* pMsg = new CMsg(uMsg, dwMsgFlags, lpMsgParam, pEvent); - m_ThreadQueue.AddTail(pMsg); - if (m_lWaiting != 0) { - ReleaseSemaphore(m_hSem, m_lWaiting, 0); - m_lWaiting = 0; - } - } - - // This is the function prototype of the function that the client - // supplies. It is always called on the created thread, never on - // the creator thread. - // - virtual LRESULT ThreadMessageProc( - UINT uMsg, DWORD dwFlags, LPVOID lpParam, CAMEvent *pEvent) = 0; -}; - diff --git a/plugins/gs/gsdx9/baseclasses/mtype.cpp b/plugins/gs/gsdx9/baseclasses/mtype.cpp deleted file mode 100644 index a383f423b2..0000000000 --- a/plugins/gs/gsdx9/baseclasses/mtype.cpp +++ /dev/null @@ -1,477 +0,0 @@ -//------------------------------------------------------------------------------ -// File: MType.cpp -// -// Desc: DirectShow base classes - implements a class that holds and -// manages media type information. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// helper class that derived pin objects can use to compare media -// types etc. Has same data members as the struct AM_MEDIA_TYPE defined -// in the streams IDL file, but also has (non-virtual) functions - -#include -#include - -CMediaType::~CMediaType(){ - FreeMediaType(*this); -} - - -CMediaType::CMediaType() -{ - InitMediaType(); -} - - -CMediaType::CMediaType(const GUID * type) -{ - InitMediaType(); - majortype = *type; -} - - -// copy constructor does a deep copy of the format block - -CMediaType::CMediaType(const AM_MEDIA_TYPE& rt, HRESULT* phr) -{ - HRESULT hr = CopyMediaType(this, &rt); - if (FAILED(hr) && (NULL != phr)) { - *phr = hr; - } -} - - -CMediaType::CMediaType(const CMediaType& rt, HRESULT* phr) -{ - HRESULT hr = CopyMediaType(this, &rt); - if (FAILED(hr) && (NULL != phr)) { - *phr = hr; - } -} - - -// this class inherits publicly from AM_MEDIA_TYPE so the compiler could generate -// the following assignment operator itself, however it could introduce some -// memory conflicts and leaks in the process because the structure contains -// a dynamically allocated block (pbFormat) which it will not copy correctly - -CMediaType& -CMediaType::operator=(const AM_MEDIA_TYPE& rt) -{ - Set(rt); - return *this; -} - -CMediaType& -CMediaType::operator=(const CMediaType& rt) -{ - *this = (AM_MEDIA_TYPE &) rt; - return *this; -} - -BOOL -CMediaType::operator == (const CMediaType& rt) const -{ - // I don't believe we need to check sample size or - // temporal compression flags, since I think these must - // be represented in the type, subtype and format somehow. They - // are pulled out as separate flags so that people who don't understand - // the particular format representation can still see them, but - // they should duplicate information in the format block. - - return ((IsEqualGUID(majortype,rt.majortype) == TRUE) && - (IsEqualGUID(subtype,rt.subtype) == TRUE) && - (IsEqualGUID(formattype,rt.formattype) == TRUE) && - (cbFormat == rt.cbFormat) && - ( (cbFormat == 0) || - (memcmp(pbFormat, rt.pbFormat, cbFormat) == 0))); -} - - -BOOL -CMediaType::operator != (const CMediaType& rt) const -{ - /* Check to see if they are equal */ - - if (*this == rt) { - return FALSE; - } - return TRUE; -} - - -HRESULT -CMediaType::Set(const CMediaType& rt) -{ - return Set((AM_MEDIA_TYPE &) rt); -} - - -HRESULT -CMediaType::Set(const AM_MEDIA_TYPE& rt) -{ - if (&rt != this) { - FreeMediaType(*this); - HRESULT hr = CopyMediaType(this, &rt); - if (FAILED(hr)) { - return E_OUTOFMEMORY; - } - } - - return S_OK; -} - - -BOOL -CMediaType::IsValid() const -{ - return (!IsEqualGUID(majortype,GUID_NULL)); -} - - -void -CMediaType::SetType(const GUID* ptype) -{ - majortype = *ptype; -} - - -void -CMediaType::SetSubtype(const GUID* ptype) -{ - subtype = *ptype; -} - - -ULONG -CMediaType::GetSampleSize() const { - if (IsFixedSize()) { - return lSampleSize; - } else { - return 0; - } -} - - -void -CMediaType::SetSampleSize(ULONG sz) { - if (sz == 0) { - SetVariableSize(); - } else { - bFixedSizeSamples = TRUE; - lSampleSize = sz; - } -} - - -void -CMediaType::SetVariableSize() { - bFixedSizeSamples = FALSE; -} - - -void -CMediaType::SetTemporalCompression(BOOL bCompressed) { - bTemporalCompression = bCompressed; -} - -BOOL -CMediaType::SetFormat(BYTE * pformat, ULONG cb) -{ - if (NULL == AllocFormatBuffer(cb)) - return(FALSE); - - ASSERT(pbFormat); - memcpy(pbFormat, pformat, cb); - return(TRUE); -} - - -// set the type of the media type format block, this type defines what you -// will actually find in the format pointer. For example FORMAT_VideoInfo or -// FORMAT_WaveFormatEx. In the future this may be an interface pointer to a -// property set. Before sending out media types this should be filled in. - -void -CMediaType::SetFormatType(const GUID *pformattype) -{ - formattype = *pformattype; -} - - -// reset the format buffer - -void CMediaType::ResetFormatBuffer() -{ - if (cbFormat) { - CoTaskMemFree((PVOID)pbFormat); - } - cbFormat = 0; - pbFormat = NULL; -} - - -// allocate length bytes for the format and return a read/write pointer -// If we cannot allocate the new block of memory we return NULL leaving -// the original block of memory untouched (as does ReallocFormatBuffer) - -BYTE* -CMediaType::AllocFormatBuffer(ULONG length) -{ - ASSERT(length); - - // do the types have the same buffer size - - if (cbFormat == length) { - return pbFormat; - } - - // allocate the new format buffer - - BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length); - if (pNewFormat == NULL) { - if (length <= cbFormat) return pbFormat; //reuse the old block anyway. - return NULL; - } - - // delete the old format - - if (cbFormat != 0) { - ASSERT(pbFormat); - CoTaskMemFree((PVOID)pbFormat); - } - - cbFormat = length; - pbFormat = pNewFormat; - return pbFormat; -} - - -// reallocate length bytes for the format and return a read/write pointer -// to it. We keep as much information as we can given the new buffer size -// if this fails the original format buffer is left untouched. The caller -// is responsible for ensuring the size of memory required is non zero - -BYTE* -CMediaType::ReallocFormatBuffer(ULONG length) -{ - ASSERT(length); - - // do the types have the same buffer size - - if (cbFormat == length) { - return pbFormat; - } - - // allocate the new format buffer - - BYTE *pNewFormat = (PBYTE)CoTaskMemAlloc(length); - if (pNewFormat == NULL) { - if (length <= cbFormat) return pbFormat; //reuse the old block anyway. - return NULL; - } - - // copy any previous format (or part of if new is smaller) - // delete the old format and replace with the new one - - if (cbFormat != 0) { - ASSERT(pbFormat); - memcpy(pNewFormat,pbFormat,min(length,cbFormat)); - CoTaskMemFree((PVOID)pbFormat); - } - - cbFormat = length; - pbFormat = pNewFormat; - return pNewFormat; -} - -// initialise a media type structure - -void CMediaType::InitMediaType() -{ - ZeroMemory((PVOID)this, sizeof(*this)); - lSampleSize = 1; - bFixedSizeSamples = TRUE; -} - - -// a partially specified media type can be passed to IPin::Connect -// as a constraint on the media type used in the connection. -// the type, subtype or format type can be null. -BOOL -CMediaType::IsPartiallySpecified(void) const -{ - if ((majortype == GUID_NULL) || - (formattype == GUID_NULL)) { - return TRUE; - } else { - return FALSE; - } -} - -BOOL -CMediaType::MatchesPartial(const CMediaType* ppartial) const -{ - if ((ppartial->majortype != GUID_NULL) && - (majortype != ppartial->majortype)) { - return FALSE; - } - if ((ppartial->subtype != GUID_NULL) && - (subtype != ppartial->subtype)) { - return FALSE; - } - - if (ppartial->formattype != GUID_NULL) { - // if the format block is specified then it must match exactly - if (formattype != ppartial->formattype) { - return FALSE; - } - if (cbFormat != ppartial->cbFormat) { - return FALSE; - } - if ((cbFormat != 0) && - (memcmp(pbFormat, ppartial->pbFormat, cbFormat) != 0)) { - return FALSE; - } - } - - return TRUE; - -} - - - -// general purpose function to delete a heap allocated AM_MEDIA_TYPE structure -// which is useful when calling IEnumMediaTypes::Next as the interface -// implementation allocates the structures which you must later delete -// the format block may also be a pointer to an interface to release - -void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt) -{ - // allow NULL pointers for coding simplicity - - if (pmt == NULL) { - return; - } - - FreeMediaType(*pmt); - CoTaskMemFree((PVOID)pmt); -} - - -// this also comes in useful when using the IEnumMediaTypes interface so -// that you can copy a media type, you can do nearly the same by creating -// a CMediaType object but as soon as it goes out of scope the destructor -// will delete the memory it allocated (this takes a copy of the memory) - -AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc) -{ - ASSERT(pSrc); - - // Allocate a block of memory for the media type - - AM_MEDIA_TYPE *pMediaType = - (AM_MEDIA_TYPE *)CoTaskMemAlloc(sizeof(AM_MEDIA_TYPE)); - - if (pMediaType == NULL) { - return NULL; - } - // Copy the variable length format block - - HRESULT hr = CopyMediaType(pMediaType,pSrc); - if (FAILED(hr)) { - CoTaskMemFree((PVOID)pMediaType); - return NULL; - } - - return pMediaType; -} - - -// Copy 1 media type to another - -HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource) -{ - // We'll leak if we copy onto one that already exists - there's one - // case we can check like that - copying to itself. - ASSERT(pmtSource != pmtTarget); - *pmtTarget = *pmtSource; - if (pmtSource->cbFormat != 0) { - ASSERT(pmtSource->pbFormat != NULL); - pmtTarget->pbFormat = (PBYTE)CoTaskMemAlloc(pmtSource->cbFormat); - if (pmtTarget->pbFormat == NULL) { - pmtTarget->cbFormat = 0; - return E_OUTOFMEMORY; - } else { - CopyMemory((PVOID)pmtTarget->pbFormat, (PVOID)pmtSource->pbFormat, - pmtTarget->cbFormat); - } - } - if (pmtTarget->pUnk != NULL) { - pmtTarget->pUnk->AddRef(); - } - - return S_OK; -} - -// Free an existing media type (ie free resources it holds) - -void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt) -{ - if (mt.cbFormat != 0) { - CoTaskMemFree((PVOID)mt.pbFormat); - - // Strictly unnecessary but tidier - mt.cbFormat = 0; - mt.pbFormat = NULL; - } - if (mt.pUnk != NULL) { - mt.pUnk->Release(); - mt.pUnk = NULL; - } -} - -// Initialize a media type from a WAVEFORMATEX - -STDAPI CreateAudioMediaType( - const WAVEFORMATEX *pwfx, - AM_MEDIA_TYPE *pmt, - BOOL bSetFormat -) -{ - pmt->majortype = MEDIATYPE_Audio; - if (pwfx->wFormatTag == WAVE_FORMAT_EXTENSIBLE) { - pmt->subtype = ((PWAVEFORMATEXTENSIBLE)pwfx)->SubFormat; - } else { - pmt->subtype = FOURCCMap(pwfx->wFormatTag); - } - pmt->formattype = FORMAT_WaveFormatEx; - pmt->bFixedSizeSamples = TRUE; - pmt->bTemporalCompression = FALSE; - pmt->lSampleSize = pwfx->nBlockAlign; - pmt->pUnk = NULL; - if (bSetFormat) { - if (pwfx->wFormatTag == WAVE_FORMAT_PCM) { - pmt->cbFormat = sizeof(WAVEFORMATEX); - } else { - pmt->cbFormat = sizeof(WAVEFORMATEX) + pwfx->cbSize; - } - pmt->pbFormat = (PBYTE)CoTaskMemAlloc(pmt->cbFormat); - if (pmt->pbFormat == NULL) { - return E_OUTOFMEMORY; - } - if (pwfx->wFormatTag == WAVE_FORMAT_PCM) { - CopyMemory(pmt->pbFormat, pwfx, sizeof(PCMWAVEFORMAT)); - ((WAVEFORMATEX *)pmt->pbFormat)->cbSize = 0; - } else { - CopyMemory(pmt->pbFormat, pwfx, pmt->cbFormat); - } - } - return S_OK; -} - -// eliminate very many spurious warnings from MS compiler -#pragma warning(disable:4514) diff --git a/plugins/gs/gsdx9/baseclasses/mtype.h b/plugins/gs/gsdx9/baseclasses/mtype.h deleted file mode 100644 index 7a8a2395b3..0000000000 --- a/plugins/gs/gsdx9/baseclasses/mtype.h +++ /dev/null @@ -1,89 +0,0 @@ -//------------------------------------------------------------------------------ -// File: MtType.h -// -// Desc: DirectShow base classes - defines a class that holds and manages -// media type information. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __MTYPE__ -#define __MTYPE__ - -/* Helper class that derived pin objects can use to compare media - types etc. Has same data members as the struct AM_MEDIA_TYPE defined - in the streams IDL file, but also has (non-virtual) functions */ - -class CMediaType : public _AMMediaType { - -public: - - ~CMediaType(); - CMediaType(); - CMediaType(const GUID * majortype); - CMediaType(const AM_MEDIA_TYPE&, HRESULT* phr = NULL); - CMediaType(const CMediaType&, HRESULT* phr = NULL); - - CMediaType& operator=(const CMediaType&); - CMediaType& operator=(const AM_MEDIA_TYPE&); - - BOOL operator == (const CMediaType&) const; - BOOL operator != (const CMediaType&) const; - - HRESULT Set(const CMediaType& rt); - HRESULT Set(const AM_MEDIA_TYPE& rt); - - BOOL IsValid() const; - - const GUID *Type() const { return &majortype;} ; - void SetType(const GUID *); - const GUID *Subtype() const { return &subtype;} ; - void SetSubtype(const GUID *); - - BOOL IsFixedSize() const {return bFixedSizeSamples; }; - BOOL IsTemporalCompressed() const {return bTemporalCompression; }; - ULONG GetSampleSize() const; - - void SetSampleSize(ULONG sz); - void SetVariableSize(); - void SetTemporalCompression(BOOL bCompressed); - - // read/write pointer to format - can't change length without - // calling SetFormat, AllocFormatBuffer or ReallocFormatBuffer - - BYTE* Format() const {return pbFormat; }; - ULONG FormatLength() const { return cbFormat; }; - - void SetFormatType(const GUID *); - const GUID *FormatType() const {return &formattype; }; - BOOL SetFormat(BYTE *pFormat, ULONG length); - void ResetFormatBuffer(); - BYTE* AllocFormatBuffer(ULONG length); - BYTE* ReallocFormatBuffer(ULONG length); - - void InitMediaType(); - - BOOL MatchesPartial(const CMediaType* ppartial) const; - BOOL IsPartiallySpecified(void) const; -}; - - -/* General purpose functions to copy and delete a task allocated AM_MEDIA_TYPE - structure which is useful when using the IEnumMediaFormats interface as - the implementation allocates the structures which you must later delete */ - -void WINAPI DeleteMediaType(AM_MEDIA_TYPE *pmt); -AM_MEDIA_TYPE * WINAPI CreateMediaType(AM_MEDIA_TYPE const *pSrc); -HRESULT WINAPI CopyMediaType(AM_MEDIA_TYPE *pmtTarget, const AM_MEDIA_TYPE *pmtSource); -void WINAPI FreeMediaType(AM_MEDIA_TYPE& mt); - -// Initialize a media type from a WAVEFORMATEX - -STDAPI CreateAudioMediaType( - const WAVEFORMATEX *pwfx, - AM_MEDIA_TYPE *pmt, - BOOL bSetFormat); - -#endif /* __MTYPE__ */ - diff --git a/plugins/gs/gsdx9/baseclasses/outputq.cpp b/plugins/gs/gsdx9/baseclasses/outputq.cpp deleted file mode 100644 index 0522a94d37..0000000000 --- a/plugins/gs/gsdx9/baseclasses/outputq.cpp +++ /dev/null @@ -1,794 +0,0 @@ -//------------------------------------------------------------------------------ -// File: OutputQ.cpp -// -// Desc: DirectShow base classes - implements COutputQueue class used by an -// output pin which may sometimes want to queue output samples on a -// separate thread and sometimes call Receive() directly on the input -// pin. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - - -// -// COutputQueue Constructor : -// -// Determines if a thread is to be created and creates resources -// -// pInputPin - the downstream input pin we're queueing samples to -// -// phr - changed to a failure code if this function fails -// (otherwise unchanges) -// -// bAuto - Ask pInputPin if it can block in Receive by calling -// its ReceiveCanBlock method and create a thread if -// it can block, otherwise not. -// -// bQueue - if bAuto == FALSE then we create a thread if and only -// if bQueue == TRUE -// -// lBatchSize - work in batches of lBatchSize -// -// bBatchEact - Use exact batch sizes so don't send until the -// batch is full or SendAnyway() is called -// -// lListSize - If we create a thread make the list of samples queued -// to the thread have this size cache -// -// dwPriority - If we create a thread set its priority to this -// -COutputQueue::COutputQueue( - IPin *pInputPin, // Pin to send stuff to - HRESULT *phr, // 'Return code' - BOOL bAuto, // Ask pin if queue or not - BOOL bQueue, // Send through queue - LONG lBatchSize, // Batch - BOOL bBatchExact, // Batch exactly to BatchSize - LONG lListSize, - DWORD dwPriority, - bool bFlushingOpt // flushing optimization - ) : m_lBatchSize(lBatchSize), - m_bBatchExact(bBatchExact && (lBatchSize > 1)), - m_hThread(NULL), - m_hSem(NULL), - m_List(NULL), - m_pPin(pInputPin), - m_ppSamples(NULL), - m_lWaiting(0), - m_pInputPin(NULL), - m_bSendAnyway(FALSE), - m_nBatched(0), - m_bFlushing(FALSE), - m_bFlushed(TRUE), - m_bFlushingOpt(bFlushingOpt), - m_bTerminate(FALSE), - m_hEventPop(NULL), - m_hr(S_OK) -{ - ASSERT(m_lBatchSize > 0); - - - if (FAILED(*phr)) { - return; - } - - // Check the input pin is OK and cache its IMemInputPin interface - - *phr = pInputPin->QueryInterface(IID_IMemInputPin, (void **)&m_pInputPin); - if (FAILED(*phr)) { - return; - } - - // See if we should ask the downstream pin - - if (bAuto) { - HRESULT hr = m_pInputPin->ReceiveCanBlock(); - if (SUCCEEDED(hr)) { - bQueue = hr == S_OK; - } - } - - // Create our sample batch - - m_ppSamples = new PMEDIASAMPLE[m_lBatchSize]; - if (m_ppSamples == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - - // If we're queueing allocate resources - - if (bQueue) { - DbgLog((LOG_TRACE, 2, TEXT("Creating thread for output pin"))); - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if (m_hSem == NULL) { - DWORD dwError = GetLastError(); - *phr = AmHresultFromWin32(dwError); - return; - } - m_List = new CSampleList(NAME("Sample Queue List"), - lListSize, - FALSE // No lock - ); - if (m_List == NULL) { - *phr = E_OUTOFMEMORY; - return; - } - - - DWORD dwThreadId; - m_hThread = CreateThread(NULL, - 0, - InitialThreadProc, - (LPVOID)this, - 0, - &dwThreadId); - if (m_hThread == NULL) { - DWORD dwError = GetLastError(); - *phr = AmHresultFromWin32(dwError); - return; - } - SetThreadPriority(m_hThread, dwPriority); - } else { - DbgLog((LOG_TRACE, 2, TEXT("Calling input pin directly - no thread"))); - } -} - -// -// COutputQueuee Destructor : -// -// Free all resources - -// -// Thread, -// Batched samples -// -COutputQueue::~COutputQueue() -{ - DbgLog((LOG_TRACE, 3, TEXT("COutputQueue::~COutputQueue"))); - /* Free our pointer */ - if (m_pInputPin != NULL) { - m_pInputPin->Release(); - } - if (m_hThread != NULL) { - { - CAutoLock lck(this); - m_bTerminate = TRUE; - m_hr = S_FALSE; - NotifyThread(); - } - DbgWaitForSingleObject(m_hThread); - EXECUTE_ASSERT(CloseHandle(m_hThread)); - - // The thread frees the samples when asked to terminate - - ASSERT(m_List->GetCount() == 0); - delete m_List; - } else { - FreeSamples(); - } - if (m_hSem != NULL) { - EXECUTE_ASSERT(CloseHandle(m_hSem)); - } - delete [] m_ppSamples; -} - -// -// Call the real thread proc as a member function -// -DWORD WINAPI COutputQueue::InitialThreadProc(LPVOID pv) -{ - HRESULT hrCoInit = CAMThread::CoInitializeHelper(); - - COutputQueue *pSampleQueue = (COutputQueue *)pv; - DWORD dwReturn = pSampleQueue->ThreadProc(); - - if(hrCoInit == S_OK) { - CoUninitialize(); - } - - return dwReturn; -} - -// -// Thread sending the samples downstream : -// -// When there is nothing to do the thread sets m_lWaiting (while -// holding the critical section) and then waits for m_hSem to be -// set (not holding the critical section) -// -DWORD COutputQueue::ThreadProc() -{ - while (TRUE) { - BOOL bWait = FALSE; - IMediaSample *pSample; - LONG lNumberToSend; // Local copy - NewSegmentPacket* ppacket; - - // - // Get a batch of samples and send it if possible - // In any case exit the loop if there is a control action - // requested - // - { - CAutoLock lck(this); - while (TRUE) { - - if (m_bTerminate) { - FreeSamples(); - return 0; - } - if (m_bFlushing) { - FreeSamples(); - SetEvent(m_evFlushComplete); - } - - // Get a sample off the list - - pSample = m_List->RemoveHead(); - // inform derived class we took something off the queue - if (m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - if (pSample != NULL && - !IsSpecialSample(pSample)) { - - // If its just a regular sample just add it to the batch - // and exit the loop if the batch is full - - m_ppSamples[m_nBatched++] = pSample; - if (m_nBatched == m_lBatchSize) { - break; - } - } else { - - // If there was nothing in the queue and there's nothing - // to send (either because there's nothing or the batch - // isn't full) then prepare to wait - - if (pSample == NULL && - (m_bBatchExact || m_nBatched == 0)) { - - // Tell other thread to set the event when there's - // something do to - - ASSERT(m_lWaiting == 0); - m_lWaiting++; - bWait = TRUE; - } else { - - // We break out of the loop on SEND_PACKET unless - // there's nothing to send - - if (pSample == SEND_PACKET && m_nBatched == 0) { - continue; - } - - if (pSample == NEW_SEGMENT) { - // now we need the parameters - we are - // guaranteed that the next packet contains them - ppacket = (NewSegmentPacket *) m_List->RemoveHead(); - // we took something off the queue - if (m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - ASSERT(ppacket); - } - // EOS_PACKET falls through here and we exit the loop - // In this way it acts like SEND_PACKET - } - break; - } - } - if (!bWait) { - // We look at m_nBatched from the client side so keep - // it up to date inside the critical section - lNumberToSend = m_nBatched; // Local copy - m_nBatched = 0; - } - } - - // Wait for some more data - - if (bWait) { - DbgWaitForSingleObject(m_hSem); - continue; - } - - - - // OK - send it if there's anything to send - // We DON'T check m_bBatchExact here because either we've got - // a full batch or we dropped through because we got - // SEND_PACKET or EOS_PACKET - both of which imply we should - // flush our batch - - if (lNumberToSend != 0) { - long nProcessed; - if (m_hr == S_OK) { - ASSERT(!m_bFlushed); - HRESULT hr = m_pInputPin->ReceiveMultiple(m_ppSamples, - lNumberToSend, - &nProcessed); - /* Don't overwrite a flushing state HRESULT */ - CAutoLock lck(this); - if (m_hr == S_OK) { - m_hr = hr; - } - ASSERT(!m_bFlushed); - } - while (lNumberToSend != 0) { - m_ppSamples[--lNumberToSend]->Release(); - } - if (m_hr != S_OK) { - - // In any case wait for more data - S_OK just - // means there wasn't an error - - DbgLog((LOG_ERROR, 2, TEXT("ReceiveMultiple returned %8.8X"), - m_hr)); - } - } - - // Check for end of stream - - if (pSample == EOS_PACKET) { - - // We don't send even end of stream on if we've previously - // returned something other than S_OK - // This is because in that case the pin which returned - // something other than S_OK should have either sent - // EndOfStream() or notified the filter graph - - if (m_hr == S_OK) { - DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()"))); - HRESULT hr = m_pPin->EndOfStream(); - if (FAILED(hr)) { - DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()"))); - } - } - } - - // Data from a new source - - if (pSample == RESET_PACKET) { - m_hr = S_OK; - SetEvent(m_evFlushComplete); - } - - if (pSample == NEW_SEGMENT) { - m_pPin->NewSegment(ppacket->tStart, ppacket->tStop, ppacket->dRate); - delete ppacket; - } - } -} - -// Send batched stuff anyway -void COutputQueue::SendAnyway() -{ - if (!IsQueued()) { - - // m_bSendAnyway is a private parameter checked in ReceiveMultiple - - m_bSendAnyway = TRUE; - LONG nProcessed; - ReceiveMultiple(NULL, 0, &nProcessed); - m_bSendAnyway = FALSE; - - } else { - CAutoLock lck(this); - QueueSample(SEND_PACKET); - NotifyThread(); - } -} - -void -COutputQueue::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) -{ - if (!IsQueued()) { - if (S_OK == m_hr) { - if (m_bBatchExact) { - SendAnyway(); - } - m_pPin->NewSegment(tStart, tStop, dRate); - } - } else { - if (m_hr == S_OK) { - // - // we need to queue the new segment to appear in order in the - // data, but we need to pass parameters to it. Rather than - // take the hit of wrapping every single sample so we can tell - // special ones apart, we queue special pointers to indicate - // special packets, and we guarantee (by holding the - // critical section) that the packet immediately following a - // NEW_SEGMENT value is a NewSegmentPacket containing the - // parameters. - NewSegmentPacket * ppack = new NewSegmentPacket; - if (ppack == NULL) { - return; - } - ppack->tStart = tStart; - ppack->tStop = tStop; - ppack->dRate = dRate; - - CAutoLock lck(this); - QueueSample(NEW_SEGMENT); - QueueSample( (IMediaSample*) ppack); - NotifyThread(); - } - } -} - - -// -// End of Stream is queued to output device -// -void COutputQueue::EOS() -{ - CAutoLock lck(this); - if (!IsQueued()) { - if (m_bBatchExact) { - SendAnyway(); - } - if (m_hr == S_OK) { - DbgLog((LOG_TRACE, 2, TEXT("COutputQueue sending EndOfStream()"))); - m_bFlushed = FALSE; - HRESULT hr = m_pPin->EndOfStream(); - if (FAILED(hr)) { - DbgLog((LOG_ERROR, 2, TEXT("COutputQueue got code 0x%8.8X from EndOfStream()"))); - } - } - } else { - if (m_hr == S_OK) { - m_bFlushed = FALSE; - QueueSample(EOS_PACKET); - NotifyThread(); - } - } -} - -// -// Flush all the samples in the queue -// -void COutputQueue::BeginFlush() -{ - if (IsQueued()) { - { - CAutoLock lck(this); - - // block receives -- we assume this is done by the - // filter in which we are a component - - // discard all queued data - - m_bFlushing = TRUE; - - // Make sure we discard all samples from now on - - if (m_hr == S_OK) { - m_hr = S_FALSE; - } - - // Optimize so we don't keep calling downstream all the time - - if (m_bFlushed && m_bFlushingOpt) { - return; - } - - // Make sure we really wait for the flush to complete - m_evFlushComplete.Reset(); - - NotifyThread(); - } - - // pass this downstream - - m_pPin->BeginFlush(); - } else { - // pass downstream first to avoid deadlocks - m_pPin->BeginFlush(); - CAutoLock lck(this); - // discard all queued data - - m_bFlushing = TRUE; - - // Make sure we discard all samples from now on - - if (m_hr == S_OK) { - m_hr = S_FALSE; - } - } - -} - -// -// leave flush mode - pass this downstream -void COutputQueue::EndFlush() -{ - { - CAutoLock lck(this); - ASSERT(m_bFlushing); - if (m_bFlushingOpt && m_bFlushed && IsQueued()) { - m_bFlushing = FALSE; - m_hr = S_OK; - return; - } - } - - // sync with pushing thread -- done in BeginFlush - // ensure no more data to go downstream -- done in BeginFlush - // - // Because we are synching here there is no need to hold the critical - // section (in fact we'd deadlock if we did!) - - if (IsQueued()) { - m_evFlushComplete.Wait(); - } else { - FreeSamples(); - } - - // Be daring - the caller has guaranteed no samples will arrive - // before EndFlush() returns - - m_bFlushing = FALSE; - m_bFlushed = TRUE; - - // call EndFlush on downstream pins - - m_pPin->EndFlush(); - - m_hr = S_OK; -} - -// COutputQueue::QueueSample -// -// private method to Send a sample to the output queue -// The critical section MUST be held when this is called - -void COutputQueue::QueueSample(IMediaSample *pSample) -{ - if (NULL == m_List->AddTail(pSample)) { - if (!IsSpecialSample(pSample)) { - pSample->Release(); - } - } -} - -// -// COutputQueue::Receive() -// -// Send a single sample by the multiple sample route -// (NOTE - this could be optimized if necessary) -// -// On return the sample will have been Release()'d -// - -HRESULT COutputQueue::Receive(IMediaSample *pSample) -{ - LONG nProcessed; - return ReceiveMultiple(&pSample, 1, &nProcessed); -} - -// -// COutputQueue::ReceiveMultiple() -// -// Send a set of samples to the downstream pin -// -// ppSamples - array of samples -// nSamples - how many -// nSamplesProcessed - How many were processed -// -// On return all samples will have been Release()'d -// - -HRESULT COutputQueue::ReceiveMultiple ( - IMediaSample **ppSamples, - long nSamples, - long *nSamplesProcessed) -{ - CAutoLock lck(this); - // Either call directly or queue up the samples - - if (!IsQueued()) { - - // If we already had a bad return code then just return - - if (S_OK != m_hr) { - - // If we've never received anything since the last Flush() - // and the sticky return code is not S_OK we must be - // flushing - // ((!A || B) is equivalent to A implies B) - ASSERT(!m_bFlushed || m_bFlushing); - - // We're supposed to Release() them anyway! - *nSamplesProcessed = 0; - for (int i = 0; i < nSamples; i++) { - DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (direct) : Discarding %d samples code 0x%8.8X"), - nSamples, m_hr)); - ppSamples[i]->Release(); - } - - return m_hr; - } - // - // If we're flushing the sticky return code should be S_FALSE - // - ASSERT(!m_bFlushing); - m_bFlushed = FALSE; - - ASSERT(m_nBatched < m_lBatchSize); - ASSERT(m_nBatched == 0 || m_bBatchExact); - - // Loop processing the samples in batches - - LONG iLost = 0; - long iDone; - for (iDone = 0; - iDone < nSamples || (m_nBatched != 0 && m_bSendAnyway); - ) { - -//pragma message (REMIND("Implement threshold scheme")) - ASSERT(m_nBatched < m_lBatchSize); - if (iDone < nSamples) { - m_ppSamples[m_nBatched++] = ppSamples[iDone++]; - } - if (m_nBatched == m_lBatchSize || - nSamples == 0 && (m_bSendAnyway || !m_bBatchExact)) { - LONG nDone; - DbgLog((LOG_TRACE, 4, TEXT("Batching %d samples"), - m_nBatched)); - - if (m_hr == S_OK) { - m_hr = m_pInputPin->ReceiveMultiple(m_ppSamples, - m_nBatched, - &nDone); - } else { - nDone = 0; - } - iLost += m_nBatched - nDone; - for (LONG i = 0; i < m_nBatched; i++) { - m_ppSamples[i]->Release(); - } - m_nBatched = 0; - } - } - *nSamplesProcessed = iDone - iLost; - if (*nSamplesProcessed < 0) { - *nSamplesProcessed = 0; - } - return m_hr; - } else { - /* We're sending to our thread */ - - if (m_hr != S_OK) { - *nSamplesProcessed = 0; - DbgLog((LOG_TRACE, 3, TEXT("COutputQueue (queued) : Discarding %d samples code 0x%8.8X"), - nSamples, m_hr)); - for (int i = 0; i < nSamples; i++) { - ppSamples[i]->Release(); - } - return m_hr; - } - m_bFlushed = FALSE; - for (long i = 0; i < nSamples; i++) { - QueueSample(ppSamples[i]); - } - *nSamplesProcessed = nSamples; - if (!m_bBatchExact || - m_nBatched + m_List->GetCount() >= m_lBatchSize) { - NotifyThread(); - } - return S_OK; - } -} - -// Get ready for new data - cancels sticky m_hr -void COutputQueue::Reset() -{ - if (!IsQueued()) { - m_hr = S_OK; - } else { - CAutoLock lck(this); - QueueSample(RESET_PACKET); - NotifyThread(); - m_evFlushComplete.Wait(); - } -} - -// Remove and Release() all queued and Batched samples -void COutputQueue::FreeSamples() -{ - CAutoLock lck(this); - if (IsQueued()) { - while (TRUE) { - IMediaSample *pSample = m_List->RemoveHead(); - // inform derived class we took something off the queue - if (m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - if (pSample == NULL) { - break; - } - if (!IsSpecialSample(pSample)) { - pSample->Release(); - } else { - if (pSample == NEW_SEGMENT) { - // Free NEW_SEGMENT packet - NewSegmentPacket *ppacket = - (NewSegmentPacket *) m_List->RemoveHead(); - // inform derived class we took something off the queue - if (m_hEventPop) { - //DbgLog((LOG_TRACE,3,TEXT("Queue: Delivered SET EVENT"))); - SetEvent(m_hEventPop); - } - - ASSERT(ppacket != NULL); - delete ppacket; - } - } - } - } - for (int i = 0; i < m_nBatched; i++) { - m_ppSamples[i]->Release(); - } - m_nBatched = 0; -} - -// Notify the thread if there is something to do -// -// The critical section MUST be held when this is called -void COutputQueue::NotifyThread() -{ - // Optimize - no need to signal if it's not waiting - ASSERT(IsQueued()); - if (m_lWaiting) { - ReleaseSemaphore(m_hSem, m_lWaiting, NULL); - m_lWaiting = 0; - } -} - -// See if there's any work to do -// Returns -// TRUE if there is nothing on the queue and nothing in the batch -// and all data has been sent -// FALSE otherwise -// -BOOL COutputQueue::IsIdle() -{ - CAutoLock lck(this); - - // We're idle if - // there is no thread (!IsQueued()) OR - // the thread is waiting for more work (m_lWaiting != 0) - // AND - // there's nothing in the current batch (m_nBatched == 0) - - if (IsQueued() && m_lWaiting == 0 || m_nBatched != 0) { - return FALSE; - } else { - - // If we're idle it shouldn't be possible for there - // to be anything on the work queue - - ASSERT(!IsQueued() || m_List->GetCount() == 0); - return TRUE; - } -} - - -void COutputQueue::SetPopEvent(HANDLE hEvent) -{ - m_hEventPop = hEvent; -} diff --git a/plugins/gs/gsdx9/baseclasses/outputq.h b/plugins/gs/gsdx9/baseclasses/outputq.h deleted file mode 100644 index d021922a53..0000000000 --- a/plugins/gs/gsdx9/baseclasses/outputq.h +++ /dev/null @@ -1,137 +0,0 @@ -//------------------------------------------------------------------------------ -// File: OutputQ.h -// -// Desc: DirectShow base classes - defines the COutputQueue class, which -// makes a queue of samples and sends them to an output pin. The -// class will optionally send the samples to the pin directly. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -typedef CGenericList CSampleList; - -class COutputQueue : public CCritSec -{ -public: - // Constructor - COutputQueue(IPin *pInputPin, // Pin to send stuff to - HRESULT *phr, // 'Return code' - BOOL bAuto = TRUE, // Ask pin if blocks - BOOL bQueue = TRUE, // Send through queue (ignored if - // bAuto set) - LONG lBatchSize = 1, // Batch - BOOL bBatchExact = FALSE,// Batch exactly to BatchSize - LONG lListSize = // Likely number in the list - DEFAULTCACHE, - DWORD dwPriority = // Priority of thread to create - THREAD_PRIORITY_NORMAL, - bool bFlushingOpt = false // flushing optimization - ); - ~COutputQueue(); - - // enter flush state - discard all data - void BeginFlush(); // Begin flushing samples - - // re-enable receives (pass this downstream) - void EndFlush(); // Complete flush of samples - downstream - // pin guaranteed not to block at this stage - - void EOS(); // Call this on End of stream - - void SendAnyway(); // Send batched samples anyway (if bBatchExact set) - - void NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - HRESULT Receive(IMediaSample *pSample); - - // do something with these media samples - HRESULT ReceiveMultiple ( - IMediaSample **pSamples, - long nSamples, - long *nSamplesProcessed); - - void Reset(); // Reset m_hr ready for more data - - // See if its idle or not - BOOL IsIdle(); - - // give the class an event to fire after everything removed from the queue - void SetPopEvent(HANDLE hEvent); - -protected: - static DWORD WINAPI InitialThreadProc(LPVOID pv); - DWORD ThreadProc(); - BOOL IsQueued() - { - return m_List != NULL; - } - - // The critical section MUST be held when this is called - void QueueSample(IMediaSample *pSample); - - BOOL IsSpecialSample(IMediaSample *pSample) - { - return (DWORD_PTR)pSample > (DWORD_PTR)(LONG_PTR)(-16); - } - - // Remove and Release() batched and queued samples - void FreeSamples(); - - // Notify the thread there is something to do - void NotifyThread(); - - -protected: - // Queue 'messages' - #define SEND_PACKET ((IMediaSample *)(LONG_PTR)(-2)) // Send batch - #define EOS_PACKET ((IMediaSample *)(LONG_PTR)(-3)) // End of stream - #define RESET_PACKET ((IMediaSample *)(LONG_PTR)(-4)) // Reset m_hr - #define NEW_SEGMENT ((IMediaSample *)(LONG_PTR)(-5)) // send NewSegment - - // new segment packet is always followed by one of these - struct NewSegmentPacket { - REFERENCE_TIME tStart; - REFERENCE_TIME tStop; - double dRate; - }; - - // Remember input stuff - IPin * const m_pPin; - IMemInputPin * m_pInputPin; - BOOL const m_bBatchExact; - LONG const m_lBatchSize; - - CSampleList * m_List; - HANDLE m_hSem; - CAMEvent m_evFlushComplete; - HANDLE m_hThread; - IMediaSample ** m_ppSamples; - LONG m_nBatched; - - // Wait optimization - LONG m_lWaiting; - // Flush synchronization - BOOL m_bFlushing; - - // flushing optimization. some downstream filters have trouble - // with the queue's flushing optimization. other rely on it - BOOL m_bFlushed; - bool m_bFlushingOpt; - - // Terminate now - BOOL m_bTerminate; - - // Send anyway flag for batching - BOOL m_bSendAnyway; - - // Deferred 'return code' - BOOL volatile m_hr; - - // an event that can be fired after every deliver - HANDLE m_hEventPop; -}; - diff --git a/plugins/gs/gsdx9/baseclasses/pstream.cpp b/plugins/gs/gsdx9/baseclasses/pstream.cpp deleted file mode 100644 index 147c76e394..0000000000 --- a/plugins/gs/gsdx9/baseclasses/pstream.cpp +++ /dev/null @@ -1,196 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PStream.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -#ifdef PERF -#include -#endif - - -// -// Constructor -// -CPersistStream::CPersistStream(IUnknown *punk, HRESULT *phr) - : mPS_fDirty(FALSE) -{ - mPS_dwFileVersion = GetSoftwareVersion(); -} - - -// -// Destructor -// -CPersistStream::~CPersistStream() { - // Nothing to do -} - -#if 0 -SAMPLE CODE TO COPY - not active at the moment - -// -// NonDelegatingQueryInterface -// -// This object supports IPersist & IPersistStream -STDMETHODIMP CPersistStream::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - if (riid == IID_IPersist) { - return GetInterface((IPersist *) this, ppv); - } - else if (riid == IID_IPersistStream) { - return GetInterface((IPersistStream *) this, ppv); - } - else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } -} -#endif - - -// -// WriteToStream -// -// Writes to the stream (default action is to write nothing) -HRESULT CPersistStream::WriteToStream(IStream *pStream) -{ - // You can override this to do things like - // hr = pStream->Write(MyStructure, sizeof(MyStructure), NULL); - - return NOERROR; -} - - - -HRESULT CPersistStream::ReadFromStream(IStream * pStream) -{ - // You can override this to do things like - // hr = pStream->Read(MyStructure, sizeof(MyStructure), NULL); - - return NOERROR; -} - - -// -// Load -// -// Load all the data from the given stream -STDMETHODIMP CPersistStream::Load(LPSTREAM pStm) -{ - HRESULT hr; - // Load the version number then the data - mPS_dwFileVersion = ReadInt(pStm, hr); - if (FAILED(hr)) { - return hr; - } - - return ReadFromStream(pStm); -} // Load - - - -// -// Save -// -// Save the contents of this Stream. -STDMETHODIMP CPersistStream::Save(LPSTREAM pStm, BOOL fClearDirty) -{ - - HRESULT hr = WriteInt(pStm, GetSoftwareVersion()); - if (FAILED(hr)) { - return hr; - } - - hr = WriteToStream(pStm); - if (FAILED(hr)) { - return hr; - } - - mPS_fDirty = !fClearDirty; - - return hr; -} // Save - - -// WriteInt -// -// Writes an integer to an IStream as 11 UNICODE characters followed by one space. -// You could use this for shorts or unsigneds or anything (up to 32 bits) -// where the value isn't actually truncated by squeezing it into 32 bits. -// Values such as (unsigned) 0x80000000 would come out as -2147483648 -// but would then load as 0x80000000 through ReadInt. Cast as you please. - -STDAPI WriteInt(IStream *pIStream, int n) -{ - WCHAR Buff[13]; // Allows for trailing null that we don't write - (void)StringCchPrintfW(Buff, NUMELMS(Buff), L"%011d ",n); - return pIStream->Write(&(Buff[0]), 12*sizeof(WCHAR), NULL); -} // WriteInt - - -// ReadInt -// -// Reads an integer from an IStream. -// Read as 4 bytes. You could use this for shorts or unsigneds or anything -// where the value isn't actually truncated by squeezing it into 32 bits -// Striped down subset of what sscanf can do (without dragging in the C runtime) - -STDAPI_(int) ReadInt(IStream *pIStream, HRESULT &hr) -{ - - int Sign = 1; - unsigned int n = 0; // result wil be n*Sign - WCHAR wch; - - hr = pIStream->Read( &wch, sizeof(wch), NULL); - if (FAILED(hr)) { - return 0; - } - - if (wch==L'-'){ - Sign = -1; - hr = pIStream->Read( &wch, sizeof(wch), NULL); - if (FAILED(hr)) { - return 0; - } - } - - for( ; ; ) { - if (wch>=L'0' && wch<=L'9') { - n = 10*n+(int)(wch-L'0'); - } else if ( wch == L' ' - || wch == L'\t' - || wch == L'\r' - || wch == L'\n' - || wch == L'\0' - ) { - break; - } else { - hr = VFW_E_INVALID_FILE_FORMAT; - return 0; - } - - hr = pIStream->Read( &wch, sizeof(wch), NULL); - if (FAILED(hr)) { - return 0; - } - } - - if (n==0x80000000 && Sign==-1) { - // This is the negative number that has no positive version! - return (int)n; - } - else return (int)n * Sign; -} // ReadInt - - -// The microsoft C/C++ compile generates level 4 warnings to the effect that -// a particular inline function (from some base class) was not needed. -// This line gets rid of hundreds of such unwanted messages and makes -// -W4 compilation feasible: -#pragma warning(disable: 4514) diff --git a/plugins/gs/gsdx9/baseclasses/pstream.h b/plugins/gs/gsdx9/baseclasses/pstream.h deleted file mode 100644 index 95ec88cdd5..0000000000 --- a/plugins/gs/gsdx9/baseclasses/pstream.h +++ /dev/null @@ -1,114 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PStream.h -// -// Desc: DirectShow base classes - defines a class for persistent properties -// of filters. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __PSTREAM__ -#define __PSTREAM__ - -// Base class for persistent properties of filters -// (i.e. filter properties in saved graphs) - -// The simplest way to use this is: -// 1. Arrange for your filter to inherit this class -// 2. Implement in your class WriteToStream and ReadFromStream -// These will override the "do nothing" functions here. -// 3. Change your NonDelegatingQueryInterface to handle IPersistStream -// 4. Implement SizeMax to return the number of bytes of data you save. -// If you save UNICODE data, don't forget a char is 2 bytes. -// 5. Whenever your data changes, call SetDirty() -// -// At some point you may decide to alter, or extend the format of your data. -// At that point you will wish that you had a version number in all the old -// saved graphs, so that you can tell, when you read them, whether they -// represent the old or new form. To assist you in this, this class -// writes and reads a version number. -// When it writes, it calls GetSoftwareVersion() to enquire what version -// of the software we have at the moment. (In effect this is a version number -// of the data layout in the file). It writes this as the first thing in the data. -// If you want to change the version, implement (override) GetSoftwareVersion(). -// It reads this from the file into mPS_dwFileVersion before calling ReadFromStream, -// so in ReadFromStream you can check mPS_dwFileVersion to see if you are reading -// an old version file. -// Normally you should accept files whose version is no newer than the software -// version that's reading them. - - -// CPersistStream -// -// Implements IPersistStream. -// See 'OLE Programmers Reference (Vol 1):Structured Storage Overview' for -// more implementation information. -class CPersistStream : public IPersistStream { - private: - - // Internal state: - - protected: - DWORD mPS_dwFileVersion; // version number of file (being read) - BOOL mPS_fDirty; - - public: - - // IPersistStream methods - - STDMETHODIMP IsDirty() - {return (mPS_fDirty ? S_OK : S_FALSE);} // note FALSE means clean - STDMETHODIMP Load(LPSTREAM pStm); - STDMETHODIMP Save(LPSTREAM pStm, BOOL fClearDirty); - STDMETHODIMP GetSizeMax(ULARGE_INTEGER * pcbSize) - // Allow 24 bytes for version. - { pcbSize->QuadPart = 12*sizeof(WCHAR)+SizeMax(); return NOERROR; } - - // implementation - - CPersistStream(IUnknown *punk, HRESULT *phr); - ~CPersistStream(); - - HRESULT SetDirty(BOOL fDirty) - { mPS_fDirty = fDirty; return NOERROR;} - - - // override to reveal IPersist & IPersistStream - // STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // --- IPersist --- - - // You must override this to provide your own class id - STDMETHODIMP GetClassID(CLSID *pClsid) PURE; - - // overrideable if you want - // file version number. Override it if you ever change format - virtual DWORD GetSoftwareVersion(void) { return 0; } - - - //========================================================================= - // OVERRIDE THESE to read and write your data - // OVERRIDE THESE to read and write your data - // OVERRIDE THESE to read and write your data - - virtual int SizeMax() {return 0;} - virtual HRESULT WriteToStream(IStream *pStream); - virtual HRESULT ReadFromStream(IStream *pStream); - //========================================================================= - - private: - -}; - - -// --- Useful helpers --- - - -// Writes an int to an IStream as UNICODE. -STDAPI WriteInt(IStream *pIStream, int n); - -// inverse of WriteInt -STDAPI_(int) ReadInt(IStream *pIStream, HRESULT &hr); - -#endif // __PSTREAM__ diff --git a/plugins/gs/gsdx9/baseclasses/pullpin.cpp b/plugins/gs/gsdx9/baseclasses/pullpin.cpp deleted file mode 100644 index 8a3ae5f3e4..0000000000 --- a/plugins/gs/gsdx9/baseclasses/pullpin.cpp +++ /dev/null @@ -1,527 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PullPin.cpp -// -// Desc: DirectShow base classes - implements CPullPin class that pulls data -// from IAsyncReader. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include "pullpin.h" - - - -CPullPin::CPullPin() - : m_pReader(NULL), - m_pAlloc(NULL), - m_State(TM_Exit) -{ -} - -CPullPin::~CPullPin() -{ - Disconnect(); -} - -// returns S_OK if successfully connected to an IAsyncReader interface -// from this object -// Optional allocator should be proposed as a preferred allocator if -// necessary -HRESULT -CPullPin::Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync) -{ - CAutoLock lock(&m_AccessLock); - - if (m_pReader) { - return VFW_E_ALREADY_CONNECTED; - } - - HRESULT hr = pUnk->QueryInterface(IID_IAsyncReader, (void**)&m_pReader); - if (FAILED(hr)) { - return(hr); - } - - hr = DecideAllocator(pAlloc, NULL); - if (FAILED(hr)) { - Disconnect(); - return hr; - } - - LONGLONG llTotal, llAvail; - hr = m_pReader->Length(&llTotal, &llAvail); - if (FAILED(hr)) { - Disconnect(); - return hr; - } - - // convert from file position to reference time - m_tDuration = llTotal * UNITS; - m_tStop = m_tDuration; - m_tStart = 0; - - m_bSync = bSync; - - return S_OK; -} - -// disconnect any connection made in Connect -HRESULT -CPullPin::Disconnect() -{ - CAutoLock lock(&m_AccessLock); - - StopThread(); - - if (m_pReader) { - m_pReader->Release(); - m_pReader = NULL; - } - - if (m_pAlloc) { - m_pAlloc->Release(); - m_pAlloc = NULL; - } - - return S_OK; -} - -// agree an allocator using RequestAllocator - optional -// props param specifies your requirements (non-zero fields). -// returns an error code if fail to match requirements. -// optional IMemAllocator interface is offered as a preferred allocator -// but no error occurs if it can't be met. -HRESULT -CPullPin::DecideAllocator( - IMemAllocator * pAlloc, - ALLOCATOR_PROPERTIES * pProps) -{ - ALLOCATOR_PROPERTIES *pRequest; - ALLOCATOR_PROPERTIES Request; - if (pProps == NULL) { - Request.cBuffers = 3; - Request.cbBuffer = 64*1024; - Request.cbAlign = 0; - Request.cbPrefix = 0; - pRequest = &Request; - } else { - pRequest = pProps; - } - HRESULT hr = m_pReader->RequestAllocator( - pAlloc, - pRequest, - &m_pAlloc); - return hr; -} - -// start pulling data -HRESULT -CPullPin::Active(void) -{ - ASSERT(!ThreadExists()); - return StartThread(); -} - -// stop pulling data -HRESULT -CPullPin::Inactive(void) -{ - StopThread(); - - return S_OK; -} - -HRESULT -CPullPin::Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop) -{ - CAutoLock lock(&m_AccessLock); - - ThreadMsg AtStart = m_State; - - if (AtStart == TM_Start) { - BeginFlush(); - PauseThread(); - EndFlush(); - } - - m_tStart = tStart; - m_tStop = tStop; - - HRESULT hr = S_OK; - if (AtStart == TM_Start) { - hr = StartThread(); - } - - return hr; -} - -HRESULT -CPullPin::Duration(REFERENCE_TIME* ptDuration) -{ - *ptDuration = m_tDuration; - return S_OK; -} - - -HRESULT -CPullPin::StartThread() -{ - CAutoLock lock(&m_AccessLock); - - if (!m_pAlloc || !m_pReader) { - return E_UNEXPECTED; - } - - HRESULT hr; - if (!ThreadExists()) { - - // commit allocator - hr = m_pAlloc->Commit(); - if (FAILED(hr)) { - return hr; - } - - // start thread - if (!Create()) { - return E_FAIL; - } - } - - m_State = TM_Start; - hr = (HRESULT) CallWorker(m_State); - return hr; -} - -HRESULT -CPullPin::PauseThread() -{ - CAutoLock lock(&m_AccessLock); - - if (!ThreadExists()) { - return E_UNEXPECTED; - } - - // need to flush to ensure the thread is not blocked - // in WaitForNext - HRESULT hr = m_pReader->BeginFlush(); - if (FAILED(hr)) { - return hr; - } - - m_State = TM_Pause; - hr = CallWorker(TM_Pause); - - m_pReader->EndFlush(); - return hr; -} - -HRESULT -CPullPin::StopThread() -{ - CAutoLock lock(&m_AccessLock); - - if (!ThreadExists()) { - return S_FALSE; - } - - // need to flush to ensure the thread is not blocked - // in WaitForNext - HRESULT hr = m_pReader->BeginFlush(); - if (FAILED(hr)) { - return hr; - } - - m_State = TM_Exit; - hr = CallWorker(TM_Exit); - - m_pReader->EndFlush(); - - // wait for thread to completely exit - Close(); - - // decommit allocator - if (m_pAlloc) { - m_pAlloc->Decommit(); - } - - return S_OK; -} - - -DWORD -CPullPin::ThreadProc(void) -{ - while(1) { - DWORD cmd = GetRequest(); - switch(cmd) { - case TM_Exit: - Reply(S_OK); - return 0; - - case TM_Pause: - // we are paused already - Reply(S_OK); - break; - - case TM_Start: - Reply(S_OK); - Process(); - break; - } - - // at this point, there should be no outstanding requests on the - // upstream filter. - // We should force begin/endflush to ensure that this is true. - // !!!Note that we may currently be inside a BeginFlush/EndFlush pair - // on another thread, but the premature EndFlush will do no harm now - // that we are idle. - m_pReader->BeginFlush(); - CleanupCancelled(); - m_pReader->EndFlush(); - } -} - -HRESULT -CPullPin::QueueSample( - REFERENCE_TIME& tCurrent, - REFERENCE_TIME tAlignStop, - BOOL bDiscontinuity - ) -{ - IMediaSample* pSample; - - HRESULT hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0); - if (FAILED(hr)) { - return hr; - } - - LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS); - if (tStopThis > tAlignStop) { - tStopThis = tAlignStop; - } - pSample->SetTime(&tCurrent, &tStopThis); - tCurrent = tStopThis; - - pSample->SetDiscontinuity(bDiscontinuity); - - hr = m_pReader->Request( - pSample, - 0); - if (FAILED(hr)) { - pSample->Release(); - - CleanupCancelled(); - OnError(hr); - } - return hr; -} - -HRESULT -CPullPin::CollectAndDeliver( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop) -{ - IMediaSample* pSample = NULL; // better be sure pSample is set - DWORD_PTR dwUnused; - HRESULT hr = m_pReader->WaitForNext( - INFINITE, - &pSample, - &dwUnused); - if (FAILED(hr)) { - if (pSample) { - pSample->Release(); - } - } else { - hr = DeliverSample(pSample, tStart, tStop); - } - if (FAILED(hr)) { - CleanupCancelled(); - OnError(hr); - } - return hr; - -} - -HRESULT -CPullPin::DeliverSample( - IMediaSample* pSample, - REFERENCE_TIME tStart, - REFERENCE_TIME tStop - ) -{ - // fix up sample if past actual stop (for sector alignment) - REFERENCE_TIME t1, t2; - pSample->GetTime(&t1, &t2); - if (t2 > tStop) { - t2 = tStop; - } - - // adjust times to be relative to (aligned) start time - t1 -= tStart; - t2 -= tStart; - pSample->SetTime(&t1, &t2); - - - HRESULT hr = Receive(pSample); - pSample->Release(); - return hr; -} - -void -CPullPin::Process(void) -{ - // is there anything to do? - if (m_tStop <= m_tStart) { - EndOfStream(); - return; - } - - BOOL bDiscontinuity = TRUE; - - // if there is more than one sample at the allocator, - // then try to queue 2 at once in order to overlap. - // -- get buffer count and required alignment - ALLOCATOR_PROPERTIES Actual; - HRESULT hr = m_pAlloc->GetProperties(&Actual); - - // align the start position downwards - REFERENCE_TIME tStart = AlignDown(m_tStart / UNITS, Actual.cbAlign) * UNITS; - REFERENCE_TIME tCurrent = tStart; - - REFERENCE_TIME tStop = m_tStop; - if (tStop > m_tDuration) { - tStop = m_tDuration; - } - - // align the stop position - may be past stop, but that - // doesn't matter - REFERENCE_TIME tAlignStop = AlignUp(tStop / UNITS, Actual.cbAlign) * UNITS; - - - DWORD dwRequest; - - if (!m_bSync) { - - // Break out of the loop either if we get to the end or we're asked - // to do something else - while (tCurrent < tAlignStop) { - - // Break out without calling EndOfStream if we're asked to - // do something different - if (CheckRequest(&dwRequest)) { - return; - } - - // queue a first sample - if (Actual.cBuffers > 1) { - - hr = QueueSample(tCurrent, tAlignStop, TRUE); - bDiscontinuity = FALSE; - - if (FAILED(hr)) { - return; - } - } - - - - // loop queueing second and waiting for first.. - while (tCurrent < tAlignStop) { - - hr = QueueSample(tCurrent, tAlignStop, bDiscontinuity); - bDiscontinuity = FALSE; - - if (FAILED(hr)) { - return; - } - - hr = CollectAndDeliver(tStart, tStop); - if (S_OK != hr) { - - // stop if error, or if downstream filter said - // to stop. - return; - } - } - - if (Actual.cBuffers > 1) { - hr = CollectAndDeliver(tStart, tStop); - if (FAILED(hr)) { - return; - } - } - } - } else { - - // sync version of above loop - while (tCurrent < tAlignStop) { - - // Break out without calling EndOfStream if we're asked to - // do something different - if (CheckRequest(&dwRequest)) { - return; - } - - IMediaSample* pSample; - - hr = m_pAlloc->GetBuffer(&pSample, NULL, NULL, 0); - if (FAILED(hr)) { - OnError(hr); - return; - } - - LONGLONG tStopThis = tCurrent + (pSample->GetSize() * UNITS); - if (tStopThis > tAlignStop) { - tStopThis = tAlignStop; - } - pSample->SetTime(&tCurrent, &tStopThis); - tCurrent = tStopThis; - - if (bDiscontinuity) { - pSample->SetDiscontinuity(TRUE); - bDiscontinuity = FALSE; - } - - hr = m_pReader->SyncReadAligned(pSample); - - if (FAILED(hr)) { - pSample->Release(); - OnError(hr); - return; - } - - hr = DeliverSample(pSample, tStart, tStop); - if (hr != S_OK) { - if (FAILED(hr)) { - OnError(hr); - } - return; - } - } - } - - EndOfStream(); -} - -// after a flush, cancelled i/o will be waiting for collection -// and release -void -CPullPin::CleanupCancelled(void) -{ - while (1) { - IMediaSample * pSample; - DWORD_PTR dwUnused; - - HRESULT hr = m_pReader->WaitForNext( - 0, // no wait - &pSample, - &dwUnused); - if(pSample) { - pSample->Release(); - } else { - // no more samples - return; - } - } -} diff --git a/plugins/gs/gsdx9/baseclasses/pullpin.h b/plugins/gs/gsdx9/baseclasses/pullpin.h deleted file mode 100644 index 254ffe248a..0000000000 --- a/plugins/gs/gsdx9/baseclasses/pullpin.h +++ /dev/null @@ -1,152 +0,0 @@ -//------------------------------------------------------------------------------ -// File: PullPin.h -// -// Desc: DirectShow base classes - defines CPullPin class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __PULLPIN_H__ -#define __PULLPIN_H__ - -// -// CPullPin -// -// object supporting pulling data from an IAsyncReader interface. -// Given a start/stop position, calls a pure Receive method with each -// IMediaSample received. -// -// This is essentially for use in a MemInputPin when it finds itself -// connected to an IAsyncReader pin instead of a pushing pin. -// - -class CPullPin : public CAMThread -{ - IAsyncReader* m_pReader; - REFERENCE_TIME m_tStart; - REFERENCE_TIME m_tStop; - REFERENCE_TIME m_tDuration; - BOOL m_bSync; - - enum ThreadMsg { - TM_Pause, // stop pulling and wait for next message - TM_Start, // start pulling - TM_Exit, // stop and exit - }; - - ThreadMsg m_State; - - // override pure thread proc from CAMThread - DWORD ThreadProc(void); - - // running pull method (check m_bSync) - void Process(void); - - // clean up any cancelled i/o after a flush - void CleanupCancelled(void); - - // suspend thread from pulling, eg during seek - HRESULT PauseThread(); - - // start thread pulling - create thread if necy - HRESULT StartThread(); - - // stop and close thread - HRESULT StopThread(); - - // called from ProcessAsync to queue and collect requests - HRESULT QueueSample( - REFERENCE_TIME& tCurrent, - REFERENCE_TIME tAlignStop, - BOOL bDiscontinuity); - - HRESULT CollectAndDeliver( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop); - - HRESULT DeliverSample( - IMediaSample* pSample, - REFERENCE_TIME tStart, - REFERENCE_TIME tStop); - -protected: - IMemAllocator * m_pAlloc; - -public: - CPullPin(); - virtual ~CPullPin(); - - // returns S_OK if successfully connected to an IAsyncReader interface - // from this object - // Optional allocator should be proposed as a preferred allocator if - // necessary - // bSync is TRUE if we are to use sync reads instead of the - // async methods. - HRESULT Connect(IUnknown* pUnk, IMemAllocator* pAlloc, BOOL bSync); - - // disconnect any connection made in Connect - HRESULT Disconnect(); - - // agree an allocator using RequestAllocator - optional - // props param specifies your requirements (non-zero fields). - // returns an error code if fail to match requirements. - // optional IMemAllocator interface is offered as a preferred allocator - // but no error occurs if it can't be met. - virtual HRESULT DecideAllocator( - IMemAllocator* pAlloc, - ALLOCATOR_PROPERTIES * pProps); - - // set start and stop position. if active, will start immediately at - // the new position. Default is 0 to duration - HRESULT Seek(REFERENCE_TIME tStart, REFERENCE_TIME tStop); - - // return the total duration - HRESULT Duration(REFERENCE_TIME* ptDuration); - - // start pulling data - HRESULT Active(void); - - // stop pulling data - HRESULT Inactive(void); - - // helper functions - LONGLONG AlignDown(LONGLONG ll, LONG lAlign) { - // aligning downwards is just truncation - return ll & ~(lAlign-1); - }; - - LONGLONG AlignUp(LONGLONG ll, LONG lAlign) { - // align up: round up to next boundary - return (ll + (lAlign -1)) & ~(lAlign -1); - }; - - // GetReader returns the (addrefed) IAsyncReader interface - // for SyncRead etc - IAsyncReader* GetReader() { - m_pReader->AddRef(); - return m_pReader; - }; - - // -- pure -- - - // override this to handle data arrival - // return value other than S_OK will stop data - virtual HRESULT Receive(IMediaSample*) PURE; - - // override this to handle end-of-stream - virtual HRESULT EndOfStream(void) PURE; - - // called on runtime errors that will have caused pulling - // to stop - // these errors are all returned from the upstream filter, who - // will have already reported any errors to the filtergraph. - virtual void OnError(HRESULT hr) PURE; - - // flush this pin and all downstream - virtual HRESULT BeginFlush() PURE; - virtual HRESULT EndFlush() PURE; - -}; - -#endif //__PULLPIN_H__ diff --git a/plugins/gs/gsdx9/baseclasses/refclock.cpp b/plugins/gs/gsdx9/baseclasses/refclock.cpp deleted file mode 100644 index d10dedd198..0000000000 --- a/plugins/gs/gsdx9/baseclasses/refclock.cpp +++ /dev/null @@ -1,340 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RefClock.cpp -// -// Desc: DirectShow base classes - implements the IReferenceClock interface. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - - - -// 'this' used in constructor list -#pragma warning(disable:4355) - - -STDMETHODIMP CBaseReferenceClock::NonDelegatingQueryInterface( - REFIID riid, - void ** ppv) -{ - HRESULT hr; - - if (riid == IID_IReferenceClock) - { - hr = GetInterface((IReferenceClock *) this, ppv); - } - else - { - hr = CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - return hr; -} - -CBaseReferenceClock::~CBaseReferenceClock() -{ - - if (m_TimerResolution) timeEndPeriod(m_TimerResolution); - - m_pSchedule->DumpLinkedList(); - - if (m_hThread) - { - m_bAbort = TRUE; - TriggerThread(); - WaitForSingleObject( m_hThread, INFINITE ); - EXECUTE_ASSERT( CloseHandle(m_hThread) ); - m_hThread = 0; - EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) ); - delete m_pSchedule; - } -} - -// A derived class may supply a hThreadEvent if it has its own thread that will take care -// of calling the schedulers Advise method. (Refere to CBaseReferenceClock::AdviseThread() -// to see what such a thread has to do.) -CBaseReferenceClock::CBaseReferenceClock( TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pShed ) -: CUnknown( pName, pUnk ) -, m_rtLastGotTime(0) -, m_TimerResolution(0) -, m_bAbort( FALSE ) -, m_pSchedule( pShed ? pShed : new CAMSchedule(CreateEvent(NULL, FALSE, FALSE, NULL)) ) -, m_hThread(0) -{ - - - ASSERT(m_pSchedule); - if (!m_pSchedule) - { - *phr = E_OUTOFMEMORY; - } - else - { - // Set up the highest resolution timer we can manage - TIMECAPS tc; - m_TimerResolution = (TIMERR_NOERROR == timeGetDevCaps(&tc, sizeof(tc))) - ? tc.wPeriodMin - : 1; - - timeBeginPeriod(m_TimerResolution); - - /* Initialise our system times - the derived clock should set the right values */ - m_dwPrevSystemTime = timeGetTime(); - m_rtPrivateTime = (UNITS / MILLISECONDS) * m_dwPrevSystemTime; - - #ifdef PERF - m_idGetSystemTime = MSR_REGISTER(TEXT("CBaseReferenceClock::GetTime")); - #endif - - if ( !pShed ) - { - DWORD ThreadID; - m_hThread = ::CreateThread(NULL, // Security attributes - (DWORD) 0, // Initial stack size - AdviseThreadFunction, // Thread start address - (LPVOID) this, // Thread parameter - (DWORD) 0, // Creation flags - &ThreadID); // Thread identifier - - if (m_hThread) - { - SetThreadPriority( m_hThread, THREAD_PRIORITY_TIME_CRITICAL ); - } - else - { - *phr = E_FAIL; - EXECUTE_ASSERT( CloseHandle(m_pSchedule->GetEvent()) ); - delete m_pSchedule; - } - } - } -} - -void CBaseReferenceClock::Restart (IN REFERENCE_TIME rtMinTime) -{ - Lock(); - m_rtLastGotTime = rtMinTime ; - Unlock(); -} - -STDMETHODIMP CBaseReferenceClock::GetTime(REFERENCE_TIME *pTime) -{ - HRESULT hr; - if (pTime) - { - REFERENCE_TIME rtNow; - Lock(); - rtNow = GetPrivateTime(); - if (rtNow > m_rtLastGotTime) - { - m_rtLastGotTime = rtNow; - hr = S_OK; - } - else - { - hr = S_FALSE; - } - *pTime = m_rtLastGotTime; - Unlock(); - MSR_INTEGER(m_idGetSystemTime, LONG((*pTime) / (UNITS/MILLISECONDS)) ); - } - else hr = E_POINTER; - - return hr; -} - -/* Ask for an async notification that a time has elapsed */ - -STDMETHODIMP CBaseReferenceClock::AdviseTime( - REFERENCE_TIME baseTime, // base reference time - REFERENCE_TIME streamTime, // stream offset time - HEVENT hEvent, // advise via this event - DWORD_PTR *pdwAdviseCookie) // where your cookie goes -{ - CheckPointer(pdwAdviseCookie, E_POINTER); - *pdwAdviseCookie = 0; - - // Check that the event is not already set - ASSERT(WAIT_TIMEOUT == WaitForSingleObject(HANDLE(hEvent),0)); - - HRESULT hr; - - const REFERENCE_TIME lRefTime = baseTime + streamTime; - if ( lRefTime <= 0 || lRefTime == MAX_TIME ) - { - hr = E_INVALIDARG; - } - else - { - *pdwAdviseCookie = m_pSchedule->AddAdvisePacket( lRefTime, 0, HANDLE(hEvent), FALSE ); - hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY; - } - return hr; -} - - -/* Ask for an asynchronous periodic notification that a time has elapsed */ - -STDMETHODIMP CBaseReferenceClock::AdvisePeriodic( - REFERENCE_TIME StartTime, // starting at this time - REFERENCE_TIME PeriodTime, // time between notifications - HSEMAPHORE hSemaphore, // advise via a semaphore - DWORD_PTR *pdwAdviseCookie) // where your cookie goes -{ - CheckPointer(pdwAdviseCookie, E_POINTER); - *pdwAdviseCookie = 0; - - HRESULT hr; - if (StartTime > 0 && PeriodTime > 0 && StartTime != MAX_TIME ) - { - *pdwAdviseCookie = m_pSchedule->AddAdvisePacket( StartTime, PeriodTime, HANDLE(hSemaphore), TRUE ); - hr = *pdwAdviseCookie ? NOERROR : E_OUTOFMEMORY; - } - else hr = E_INVALIDARG; - - return hr; -} - - -STDMETHODIMP CBaseReferenceClock::Unadvise(DWORD_PTR dwAdviseCookie) -{ - return m_pSchedule->Unadvise(dwAdviseCookie); -} - - -REFERENCE_TIME CBaseReferenceClock::GetPrivateTime() -{ - CAutoLock cObjectLock(this); - - - /* If the clock has wrapped then the current time will be less than - * the last time we were notified so add on the extra milliseconds - * - * The time period is long enough so that the likelihood of - * successive calls spanning the clock cycle is not considered. - */ - - DWORD dwTime = timeGetTime(); - { - m_rtPrivateTime += Int32x32To64(UNITS / MILLISECONDS, (DWORD)(dwTime - m_dwPrevSystemTime)); - m_dwPrevSystemTime = dwTime; - } - - return m_rtPrivateTime; -} - - -/* Adjust the current time by the input value. This allows an - external time source to work out some of the latency of the clock - system and adjust the "current" time accordingly. The intent is - that the time returned to the user is synchronised to a clock - source and allows drift to be catered for. - - For example: if the clock source detects a drift it can pass a delta - to the current time rather than having to set an explicit time. -*/ - -STDMETHODIMP CBaseReferenceClock::SetTimeDelta(const REFERENCE_TIME & TimeDelta) -{ -#ifdef DEBUG - - // Just break if passed an improper time delta value - LONGLONG llDelta = TimeDelta > 0 ? TimeDelta : -TimeDelta; - if (llDelta > UNITS * 1000) { - DbgLog((LOG_TRACE, 0, TEXT("Bad Time Delta"))); - //DebugBreak(); - } - - // We're going to calculate a "severity" for the time change. Max -1 - // min 8. We'll then use this as the debug logging level for a - // debug log message. - const LONG usDelta = LONG(TimeDelta/10); // Delta in micro-secs - - DWORD delta = abs(usDelta); // varying delta - // Severity == 8 - ceil(log(abs( micro-secs delta))) - int Severity = 8; - while ( delta > 0 ) - { - delta >>= 3; // div 8 - Severity--; - } - - // Sev == 0 => > 2 second delta! - DbgLog((LOG_TIMING, Severity < 0 ? 0 : Severity, - TEXT("Sev %2i: CSystemClock::SetTimeDelta(%8ld us) %lu -> %lu ms."), - Severity, usDelta, DWORD(ConvertToMilliseconds(m_rtPrivateTime)), - DWORD(ConvertToMilliseconds(TimeDelta+m_rtPrivateTime)) )); - - // Don't want the DbgBreak to fire when running stress on debug-builds. - #ifdef BREAK_ON_SEVERE_TIME_DELTA - if (Severity < 0) - DbgBreakPoint(TEXT("SetTimeDelta > 16 seconds!"), - TEXT(__FILE__),__LINE__); - #endif - -#endif - - CAutoLock cObjectLock(this); - m_rtPrivateTime += TimeDelta; - // If time goes forwards, and we have advises, then we need to - // trigger the thread so that it can re-evaluate its wait time. - // Since we don't want the cost of the thread switches if the change - // is really small, only do it if clock goes forward by more than - // 0.5 millisecond. If the time goes backwards, the thread will - // wake up "early" (relativly speaking) and will re-evaluate at - // that time. - if ( TimeDelta > 5000 && m_pSchedule->GetAdviseCount() > 0 ) TriggerThread(); - return NOERROR; -} - -// Thread stuff - -DWORD __stdcall CBaseReferenceClock::AdviseThreadFunction(LPVOID p) -{ - return DWORD(reinterpret_cast(p)->AdviseThread()); -} - -HRESULT CBaseReferenceClock::AdviseThread() -{ - DWORD dwWait = INFINITE; - - // The first thing we do is wait until something interesting happens - // (meaning a first advise or shutdown). This prevents us calling - // GetPrivateTime immediately which is goodness as that is a virtual - // routine and the derived class may not yet be constructed. (This - // thread is created in the base class constructor.) - - while ( !m_bAbort ) - { - // Wait for an interesting event to happen - DbgLog((LOG_TIMING, 3, TEXT("CBaseRefClock::AdviseThread() Delay: %lu ms"), dwWait )); - WaitForSingleObject(m_pSchedule->GetEvent(), dwWait); - if (m_bAbort) break; - - // There are several reasons why we need to work from the internal - // time, mainly to do with what happens when time goes backwards. - // Mainly, it stop us looping madly if an event is just about to - // expire when the clock goes backward (i.e. GetTime stop for a - // while). - const REFERENCE_TIME rtNow = GetPrivateTime(); - - DbgLog((LOG_TIMING, 3, - TEXT("CBaseRefClock::AdviseThread() Woke at = %lu ms"), - ConvertToMilliseconds(rtNow) )); - - // We must add in a millisecond, since this is the resolution of our - // WaitForSingleObject timer. Failure to do so will cause us to loop - // franticly for (approx) 1 a millisecond. - m_rtNextAdvise = m_pSchedule->Advise( 10000 + rtNow ); - LONGLONG llWait = m_rtNextAdvise - rtNow; - - ASSERT( llWait > 0 ); - - llWait = ConvertToMilliseconds(llWait); - // DON'T replace this with a max!! (The type's of these things is VERY important) - dwWait = (llWait > REFERENCE_TIME(UINT_MAX)) ? UINT_MAX : DWORD(llWait); - }; - return NOERROR; -} diff --git a/plugins/gs/gsdx9/baseclasses/refclock.h b/plugins/gs/gsdx9/baseclasses/refclock.h deleted file mode 100644 index a864f72b14..0000000000 --- a/plugins/gs/gsdx9/baseclasses/refclock.h +++ /dev/null @@ -1,171 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RefClock.h -// -// Desc: DirectShow base classes - defines the IReferenceClock interface. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __BASEREFCLOCK__ -#define __BASEREFCLOCK__ - -#include "dsschedule.h" - -const UINT RESOLUTION = 1; /* High resolution timer */ -const INT ADVISE_CACHE = 4; /* Default cache size */ -const LONGLONG MAX_TIME = 0x7FFFFFFFFFFFFFFF; /* Maximum LONGLONG value */ - -inline LONGLONG WINAPI ConvertToMilliseconds(const REFERENCE_TIME& RT) -{ - /* This converts an arbitrary value representing a reference time - into a MILLISECONDS value for use in subsequent system calls */ - - return (RT / (UNITS / MILLISECONDS)); -} - -/* This class hierarchy will support an IReferenceClock interface so - that an audio card (or other externally driven clock) can update the - system wide clock that everyone uses. - - The interface will be pretty thin with probably just one update method - This interface has not yet been defined. - */ - -/* This abstract base class implements the IReferenceClock - * interface. Classes that actually provide clock signals (from - * whatever source) have to be derived from this class. - * - * The abstract class provides implementations for: - * CUnknown support - * locking support (CCritSec) - * client advise code (creates a thread) - * - * Question: what can we do about quality? Change the timer - * resolution to lower the system load? Up the priority of the - * timer thread to force more responsive signals? - * - * During class construction we create a worker thread that is destroyed during - * destuction. This thread executes a series of WaitForSingleObject calls, - * waking up when a command is given to the thread or the next wake up point - * is reached. The wakeup points are determined by clients making Advise - * calls. - * - * Each advise call defines a point in time when they wish to be notified. A - * periodic advise is a series of these such events. We maintain a list of - * advise links and calculate when the nearest event notification is due for. - * We then call WaitForSingleObject with a timeout equal to this time. The - * handle we wait on is used by the class to signal that something has changed - * and that we must reschedule the next event. This typically happens when - * someone comes in and asks for an advise link while we are waiting for an - * event to timeout. - * - * While we are modifying the list of advise requests we - * are protected from interference through a critical section. Clients are NOT - * advised through callbacks. One shot clients have an event set, while - * periodic clients have a semaphore released for each event notification. A - * semaphore allows a client to be kept up to date with the number of events - * actually triggered and be assured that they can't miss multiple events being - * set. - * - * Keeping track of advises is taken care of by the CAMSchedule class. - */ - -class CBaseReferenceClock -: public CUnknown, public IReferenceClock, public CCritSec -{ -protected: - virtual ~CBaseReferenceClock(); // Don't let me be created on the stack! -public: - CBaseReferenceClock(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr, CAMSchedule * pSched = 0 ); - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void ** ppv); - - DECLARE_IUNKNOWN - - /* IReferenceClock methods */ - // Derived classes must implement GetPrivateTime(). All our GetTime - // does is call GetPrivateTime and then check so that time does not - // go backwards. A return code of S_FALSE implies that the internal - // clock has gone backwards and GetTime time has halted until internal - // time has caught up. (Don't know if this will be much use to folk, - // but it seems odd not to use the return code for something useful.) - STDMETHODIMP GetTime(REFERENCE_TIME *pTime); - // When this is called, it sets m_rtLastGotTime to the time it returns. - - /* Provide standard mechanisms for scheduling events */ - - /* Ask for an async notification that a time has elapsed */ - STDMETHODIMP AdviseTime( - REFERENCE_TIME baseTime, // base reference time - REFERENCE_TIME streamTime, // stream offset time - HEVENT hEvent, // advise via this event - DWORD_PTR *pdwAdviseCookie // where your cookie goes - ); - - /* Ask for an asynchronous periodic notification that a time has elapsed */ - STDMETHODIMP AdvisePeriodic( - REFERENCE_TIME StartTime, // starting at this time - REFERENCE_TIME PeriodTime, // time between notifications - HSEMAPHORE hSemaphore, // advise via a semaphore - DWORD_PTR *pdwAdviseCookie // where your cookie goes - ); - - /* Cancel a request for notification(s) - if the notification was - * a one shot timer then this function doesn't need to be called - * as the advise is automatically cancelled, however it does no - * harm to explicitly cancel a one-shot advise. It is REQUIRED that - * clients call Unadvise to clear a Periodic advise setting. - */ - - STDMETHODIMP Unadvise(DWORD_PTR dwAdviseCookie); - - /* Methods for the benefit of derived classes or outer objects */ - - // GetPrivateTime() is the REAL clock. GetTime is just a cover for - // it. Derived classes will probably override this method but not - // GetTime() itself. - // The important point about GetPrivateTime() is it's allowed to go - // backwards. Our GetTime() will keep returning the LastGotTime - // until GetPrivateTime() catches up. - virtual REFERENCE_TIME GetPrivateTime(); - - /* Provide a method for correcting drift */ - STDMETHODIMP SetTimeDelta( const REFERENCE_TIME& TimeDelta ); - - CAMSchedule * GetSchedule() const { return m_pSchedule; } - -private: - REFERENCE_TIME m_rtPrivateTime; // Current best estimate of time - DWORD m_dwPrevSystemTime; // Last vaule we got from timeGetTime - REFERENCE_TIME m_rtLastGotTime; // Last time returned by GetTime - REFERENCE_TIME m_rtNextAdvise; // Time of next advise - UINT m_TimerResolution; - -#ifdef PERF - int m_idGetSystemTime; -#endif - -// Thread stuff -public: - void TriggerThread() // Wakes thread up. Need to do this if - { // time to next advise needs reevaluating. - EXECUTE_ASSERT(SetEvent(m_pSchedule->GetEvent())); - } - - -private: - BOOL m_bAbort; // Flag used for thread shutdown - HANDLE m_hThread; // Thread handle - - HRESULT AdviseThread(); // Method in which the advise thread runs - static DWORD __stdcall AdviseThreadFunction(LPVOID); // Function used to get there - -protected: - CAMSchedule * const m_pSchedule; - - void Restart (IN REFERENCE_TIME rtMinTime = 0I64) ; -}; - -#endif - diff --git a/plugins/gs/gsdx9/baseclasses/reftime.h b/plugins/gs/gsdx9/baseclasses/reftime.h deleted file mode 100644 index 87c43b9fef..0000000000 --- a/plugins/gs/gsdx9/baseclasses/reftime.h +++ /dev/null @@ -1,116 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RefTime.h -// -// Desc: DirectShow base classes - defines CRefTime, a class that manages -// reference times. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// -// CRefTime -// -// Manage reference times. -// Shares same data layout as REFERENCE_TIME, but adds some (nonvirtual) -// functions providing simple comparison, conversion and arithmetic. -// -// A reference time (at the moment) is a unit of seconds represented in -// 100ns units as is used in the Win32 FILETIME structure. BUT the time -// a REFERENCE_TIME represents is NOT the time elapsed since 1/1/1601 it -// will either be stream time or reference time depending upon context -// -// This class provides simple arithmetic operations on reference times -// -// keep non-virtual otherwise the data layout will not be the same as -// REFERENCE_TIME - - -// ----- -// note that you are safe to cast a CRefTime* to a REFERENCE_TIME*, but -// you will need to do so explicitly -// ----- - - -#ifndef __REFTIME__ -#define __REFTIME__ - - -const LONGLONG MILLISECONDS = (1000); // 10 ^ 3 -const LONGLONG NANOSECONDS = (1000000000); // 10 ^ 9 -const LONGLONG UNITS = (NANOSECONDS / 100); // 10 ^ 7 - -/* Unfortunately an inline function here generates a call to __allmul - - even for constants! -*/ -#define MILLISECONDS_TO_100NS_UNITS(lMs) \ - Int32x32To64((lMs), (UNITS / MILLISECONDS)) - -class CRefTime -{ -public: - - // *MUST* be the only data member so that this class is exactly - // equivalent to a REFERENCE_TIME. - // Also, must be *no virtual functions* - - REFERENCE_TIME m_time; - - inline CRefTime() - { - // default to 0 time - m_time = 0; - }; - - inline CRefTime(LONG msecs) - { - m_time = MILLISECONDS_TO_100NS_UNITS(msecs); - }; - - inline CRefTime(REFERENCE_TIME rt) - { - m_time = rt; - }; - - inline operator REFERENCE_TIME() const - { - return m_time; - }; - - inline CRefTime& operator=(const CRefTime& rt) - { - m_time = rt.m_time; - return *this; - }; - - inline CRefTime& operator=(const LONGLONG ll) - { - m_time = ll; - return *this; - }; - - inline CRefTime& operator+=(const CRefTime& rt) - { - return (*this = *this + rt); - }; - - inline CRefTime& operator-=(const CRefTime& rt) - { - return (*this = *this - rt); - }; - - inline LONG Millisecs(void) - { - return (LONG)(m_time / (UNITS / MILLISECONDS)); - }; - - inline LONGLONG GetUnits(void) - { - return m_time; - }; -}; - -const LONGLONG TimeZero = 0; - -#endif /* __REFTIME__ */ - diff --git a/plugins/gs/gsdx9/baseclasses/renbase.cpp b/plugins/gs/gsdx9/baseclasses/renbase.cpp deleted file mode 100644 index 49b20f9bf0..0000000000 --- a/plugins/gs/gsdx9/baseclasses/renbase.cpp +++ /dev/null @@ -1,2844 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RenBase.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include // DirectShow base class definitions -#include // Needed for definition of timeGetTime -#include // Standard data type limit definitions -#include // Used for time critical log functions - -#pragma warning(disable:4355) - -// Helper function for clamping time differences -int inline TimeDiff(REFERENCE_TIME rt) -{ - if (rt < - (50 * UNITS)) { - return -(50 * UNITS); - } else - if (rt > 50 * UNITS) { - return 50 * UNITS; - } else return (int)rt; -} - -// Implements the CBaseRenderer class - -CBaseRenderer::CBaseRenderer(REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr) : // General OLE return code - - CBaseFilter(pName,pUnk,&m_InterfaceLock,RenderClass), - m_evComplete(TRUE), - m_bAbort(FALSE), - m_pPosition(NULL), - m_ThreadSignal(TRUE), - m_bStreaming(FALSE), - m_bEOS(FALSE), - m_bEOSDelivered(FALSE), - m_pMediaSample(NULL), - m_dwAdvise(0), - m_pQSink(NULL), - m_pInputPin(NULL), - m_bRepaintStatus(TRUE), - m_SignalTime(0), - m_bInReceive(FALSE), - m_EndOfStreamTimer(0) -{ - Ready(); -#ifdef PERF - m_idBaseStamp = MSR_REGISTER(TEXT("BaseRenderer: sample time stamp")); - m_idBaseRenderTime = MSR_REGISTER(TEXT("BaseRenderer: draw time (msec)")); - m_idBaseAccuracy = MSR_REGISTER(TEXT("BaseRenderer: Accuracy (msec)")); -#endif -} - - -// Delete the dynamically allocated IMediaPosition and IMediaSeeking helper -// object. The object is created when somebody queries us. These are standard -// control interfaces for seeking and setting start/stop positions and rates. -// We will probably also have made an input pin based on CRendererInputPin -// that has to be deleted, it's created when an enumerator calls our GetPin - -CBaseRenderer::~CBaseRenderer() -{ - ASSERT(m_bStreaming == FALSE); - ASSERT(m_EndOfStreamTimer == 0); - StopStreaming(); - ClearPendingSample(); - - // Delete any IMediaPosition implementation - - if (m_pPosition) { - delete m_pPosition; - m_pPosition = NULL; - } - - // Delete any input pin created - - if (m_pInputPin) { - delete m_pInputPin; - m_pInputPin = NULL; - } - - // Release any Quality sink - - ASSERT(m_pQSink == NULL); -} - - -// This returns the IMediaPosition and IMediaSeeking interfaces - -HRESULT CBaseRenderer::GetMediaPositionInterface(REFIID riid,void **ppv) -{ - CAutoLock cObjectCreationLock(&m_ObjectCreationLock); - if (m_pPosition) { - return m_pPosition->NonDelegatingQueryInterface(riid,ppv); - } - - HRESULT hr = NOERROR; - - // Create implementation of this dynamically since sometimes we may - // never try and do a seek. The helper object implements a position - // control interface (IMediaPosition) which in fact simply takes the - // calls normally from the filter graph and passes them upstream - - m_pPosition = new CRendererPosPassThru(NAME("Renderer CPosPassThru"), - CBaseFilter::GetOwner(), - (HRESULT *) &hr, - GetPin(0)); - if (m_pPosition == NULL) { - return E_OUTOFMEMORY; - } - - if (FAILED(hr)) { - delete m_pPosition; - m_pPosition = NULL; - return E_NOINTERFACE; - } - return GetMediaPositionInterface(riid,ppv); -} - - -// Overriden to say what interfaces we support and where - -STDMETHODIMP CBaseRenderer::NonDelegatingQueryInterface(REFIID riid,void **ppv) -{ - // Do we have this interface - - if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) { - return GetMediaPositionInterface(riid,ppv); - } else { - return CBaseFilter::NonDelegatingQueryInterface(riid,ppv); - } -} - - -// This is called whenever we change states, we have a manual reset event that -// is signalled whenever we don't won't the source filter thread to wait in us -// (such as in a stopped state) and likewise is not signalled whenever it can -// wait (during paused and running) this function sets or resets the thread -// event. The event is used to stop source filter threads waiting in Receive - -HRESULT CBaseRenderer::SourceThreadCanWait(BOOL bCanWait) -{ - if (bCanWait == TRUE) { - m_ThreadSignal.Reset(); - } else { - m_ThreadSignal.Set(); - } - return NOERROR; -} - - -#ifdef DEBUG -// Dump the current renderer state to the debug terminal. The hardest part of -// the renderer is the window where we unlock everything to wait for a clock -// to signal it is time to draw or for the application to cancel everything -// by stopping the filter. If we get things wrong we can leave the thread in -// WaitForRenderTime with no way for it to ever get out and we will deadlock - -void CBaseRenderer::DisplayRendererState() -{ - DbgLog((LOG_TIMING, 1, TEXT("\nTimed out in WaitForRenderTime"))); - - // No way should this be signalled at this point - - BOOL bSignalled = m_ThreadSignal.Check(); - DbgLog((LOG_TIMING, 1, TEXT("Signal sanity check %d"),bSignalled)); - - // Now output the current renderer state variables - - DbgLog((LOG_TIMING, 1, TEXT("Filter state %d"),m_State)); - - DbgLog((LOG_TIMING, 1, TEXT("Abort flag %d"),m_bAbort)); - - DbgLog((LOG_TIMING, 1, TEXT("Streaming flag %d"),m_bStreaming)); - - DbgLog((LOG_TIMING, 1, TEXT("Clock advise link %d"),m_dwAdvise)); - - DbgLog((LOG_TIMING, 1, TEXT("Current media sample %x"),m_pMediaSample)); - - DbgLog((LOG_TIMING, 1, TEXT("EOS signalled %d"),m_bEOS)); - - DbgLog((LOG_TIMING, 1, TEXT("EOS delivered %d"),m_bEOSDelivered)); - - DbgLog((LOG_TIMING, 1, TEXT("Repaint status %d"),m_bRepaintStatus)); - - - // Output the delayed end of stream timer information - - DbgLog((LOG_TIMING, 1, TEXT("End of stream timer %x"),m_EndOfStreamTimer)); - - DbgLog((LOG_TIMING, 1, TEXT("Deliver time %s"),CDisp((LONGLONG)m_SignalTime))); - - - // Should never timeout during a flushing state - - BOOL bFlushing = m_pInputPin->IsFlushing(); - DbgLog((LOG_TIMING, 1, TEXT("Flushing sanity check %d"),bFlushing)); - - // Display the time we were told to start at - DbgLog((LOG_TIMING, 1, TEXT("Last run time %s"),CDisp((LONGLONG)m_tStart.m_time))); - - // Have we got a reference clock - if (m_pClock == NULL) return; - - // Get the current time from the wall clock - - CRefTime CurrentTime,StartTime,EndTime; - m_pClock->GetTime((REFERENCE_TIME*) &CurrentTime); - CRefTime Offset = CurrentTime - m_tStart; - - // Display the current time from the clock - - DbgLog((LOG_TIMING, 1, TEXT("Clock time %s"),CDisp((LONGLONG)CurrentTime.m_time))); - - DbgLog((LOG_TIMING, 1, TEXT("Time difference %dms"),Offset.Millisecs())); - - - // Do we have a sample ready to render - if (m_pMediaSample == NULL) return; - - m_pMediaSample->GetTime((REFERENCE_TIME*)&StartTime, (REFERENCE_TIME*)&EndTime); - DbgLog((LOG_TIMING, 1, TEXT("Next sample stream times (Start %d End %d ms)"), - StartTime.Millisecs(),EndTime.Millisecs())); - - // Calculate how long it is until it is due for rendering - CRefTime Wait = (m_tStart + StartTime) - CurrentTime; - DbgLog((LOG_TIMING, 1, TEXT("Wait required %d ms"),Wait.Millisecs())); -} -#endif - - -// Wait until the clock sets the timer event or we're otherwise signalled. We -// set an arbitrary timeout for this wait and if it fires then we display the -// current renderer state on the debugger. It will often fire if the filter's -// left paused in an application however it may also fire during stress tests -// if the synchronisation with application seeks and state changes is faulty - -#define RENDER_TIMEOUT 10000 - -HRESULT CBaseRenderer::WaitForRenderTime() -{ - HANDLE WaitObjects[] = { m_ThreadSignal, m_RenderEvent }; - DWORD Result = WAIT_TIMEOUT; - - // Wait for either the time to arrive or for us to be stopped - - OnWaitStart(); - while (Result == WAIT_TIMEOUT) { - Result = WaitForMultipleObjects(2,WaitObjects,FALSE,RENDER_TIMEOUT); - -#ifdef DEBUG - if (Result == WAIT_TIMEOUT) DisplayRendererState(); -#endif - - } - OnWaitEnd(); - - // We may have been awoken without the timer firing - - if (Result == WAIT_OBJECT_0) { - return VFW_E_STATE_CHANGED; - } - - SignalTimerFired(); - return NOERROR; -} - - -// Poll waiting for Receive to complete. This really matters when -// Receive may set the palette and cause window messages -// The problem is that if we don't really wait for a renderer to -// stop processing we can deadlock waiting for a transform which -// is calling the renderer's Receive() method because the transform's -// Stop method doesn't know to process window messages to unblock -// the renderer's Receive processing -void CBaseRenderer::WaitForReceiveToComplete() -{ - for (;;) { - if (!m_bInReceive) { - break; - } - - MSG msg; - // Receive all interthread sendmessages - PeekMessage(&msg, NULL, WM_NULL, WM_NULL, PM_NOREMOVE); - - Sleep(1); - } - - // If the wakebit for QS_POSTMESSAGE is set, the PeekMessage call - // above just cleared the changebit which will cause some messaging - // calls to block (waitMessage, MsgWaitFor...) now. - // Post a dummy message to set the QS_POSTMESSAGE bit again - if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) { - // Send dummy message - PostThreadMessage(GetCurrentThreadId(), WM_NULL, 0, 0); - } -} - -// A filter can have four discrete states, namely Stopped, Running, Paused, -// Intermediate. We are in an intermediate state if we are currently trying -// to pause but haven't yet got the first sample (or if we have been flushed -// in paused state and therefore still have to wait for a sample to arrive) - -// This class contains an event called m_evComplete which is signalled when -// the current state is completed and is not signalled when we are waiting to -// complete the last state transition. As mentioned above the only time we -// use this at the moment is when we wait for a media sample in paused state -// If while we are waiting we receive an end of stream notification from the -// source filter then we know no data is imminent so we can reset the event -// This means that when we transition to paused the source filter must call -// end of stream on us or send us an image otherwise we'll hang indefinately - - -// Simple internal way of getting the real state - -FILTER_STATE CBaseRenderer::GetRealState() { - return m_State; -} - - -// The renderer doesn't complete the full transition to paused states until -// it has got one media sample to render. If you ask it for its state while -// it's waiting it will return the state along with VFW_S_STATE_INTERMEDIATE - -STDMETHODIMP CBaseRenderer::GetState(DWORD dwMSecs,FILTER_STATE *State) -{ - CheckPointer(State,E_POINTER); - - if (WaitDispatchingMessages(m_evComplete, dwMSecs) == WAIT_TIMEOUT) { - *State = m_State; - return VFW_S_STATE_INTERMEDIATE; - } - *State = m_State; - return NOERROR; -} - - -// If we're pausing and we have no samples we don't complete the transition -// to State_Paused and we return S_FALSE. However if the m_bAbort flag has -// been set then all samples are rejected so there is no point waiting for -// one. If we do have a sample then return NOERROR. We will only ever return -// VFW_S_STATE_INTERMEDIATE from GetState after being paused with no sample -// (calling GetState after either being stopped or Run will NOT return this) - -HRESULT CBaseRenderer::CompleteStateChange(FILTER_STATE OldState) -{ - // Allow us to be paused when disconnected - - if (m_pInputPin->IsConnected() == FALSE) { - Ready(); - return S_OK; - } - - // Have we run off the end of stream - - if (IsEndOfStream() == TRUE) { - Ready(); - return S_OK; - } - - // Make sure we get fresh data after being stopped - - if (HaveCurrentSample() == TRUE) { - if (OldState != State_Stopped) { - Ready(); - return S_OK; - } - } - NotReady(); - return S_FALSE; -} - - -// When we stop the filter the things we do are:- - -// Decommit the allocator being used in the connection -// Release the source filter if it's waiting in Receive -// Cancel any advise link we set up with the clock -// Any end of stream signalled is now obsolete so reset -// Allow us to be stopped when we are not connected - -STDMETHODIMP CBaseRenderer::Stop() -{ - CAutoLock cRendererLock(&m_InterfaceLock); - - // Make sure there really is a state change - - if (m_State == State_Stopped) { - return NOERROR; - } - - // Is our input pin connected - - if (m_pInputPin->IsConnected() == FALSE) { - NOTE("Input pin is not connected"); - m_State = State_Stopped; - return NOERROR; - } - - CBaseFilter::Stop(); - - // If we are going into a stopped state then we must decommit whatever - // allocator we are using it so that any source filter waiting in the - // GetBuffer can be released and unlock themselves for a state change - - if (m_pInputPin->Allocator()) { - m_pInputPin->Allocator()->Decommit(); - } - - // Cancel any scheduled rendering - - SetRepaintStatus(TRUE); - StopStreaming(); - SourceThreadCanWait(FALSE); - ResetEndOfStream(); - CancelNotification(); - - // There should be no outstanding clock advise - ASSERT(CancelNotification() == S_FALSE); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(m_EndOfStreamTimer == 0); - - Ready(); - WaitForReceiveToComplete(); - m_bAbort = FALSE; - - return NOERROR; -} - - -// When we pause the filter the things we do are:- - -// Commit the allocator being used in the connection -// Allow a source filter thread to wait in Receive -// Cancel any clock advise link (we may be running) -// Possibly complete the state change if we have data -// Allow us to be paused when we are not connected - -STDMETHODIMP CBaseRenderer::Pause() -{ - CAutoLock cRendererLock(&m_InterfaceLock); - FILTER_STATE OldState = m_State; - ASSERT(m_pInputPin->IsFlushing() == FALSE); - - // Make sure there really is a state change - - if (m_State == State_Paused) { - return CompleteStateChange(State_Paused); - } - - // Has our input pin been connected - - if (m_pInputPin->IsConnected() == FALSE) { - NOTE("Input pin is not connected"); - m_State = State_Paused; - return CompleteStateChange(State_Paused); - } - - // Pause the base filter class - - HRESULT hr = CBaseFilter::Pause(); - if (FAILED(hr)) { - NOTE("Pause failed"); - return hr; - } - - // Enable EC_REPAINT events again - - SetRepaintStatus(TRUE); - StopStreaming(); - SourceThreadCanWait(TRUE); - CancelNotification(); - ResetEndOfStreamTimer(); - - // If we are going into a paused state then we must commit whatever - // allocator we are using it so that any source filter can call the - // GetBuffer and expect to get a buffer without returning an error - - if (m_pInputPin->Allocator()) { - m_pInputPin->Allocator()->Commit(); - } - - // There should be no outstanding advise - ASSERT(CancelNotification() == S_FALSE); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(m_EndOfStreamTimer == 0); - ASSERT(m_pInputPin->IsFlushing() == FALSE); - - // When we come out of a stopped state we must clear any image we were - // holding onto for frame refreshing. Since renderers see state changes - // first we can reset ourselves ready to accept the source thread data - // Paused or running after being stopped causes the current position to - // be reset so we're not interested in passing end of stream signals - - if (OldState == State_Stopped) { - m_bAbort = FALSE; - ClearPendingSample(); - } - return CompleteStateChange(OldState); -} - - -// When we run the filter the things we do are:- - -// Commit the allocator being used in the connection -// Allow a source filter thread to wait in Receive -// Signal the render event just to get us going -// Start the base class by calling StartStreaming -// Allow us to be run when we are not connected -// Signal EC_COMPLETE if we are not connected - -STDMETHODIMP CBaseRenderer::Run(REFERENCE_TIME StartTime) -{ - CAutoLock cRendererLock(&m_InterfaceLock); - FILTER_STATE OldState = m_State; - - // Make sure there really is a state change - - if (m_State == State_Running) { - return NOERROR; - } - - // Send EC_COMPLETE if we're not connected - - if (m_pInputPin->IsConnected() == FALSE) { - NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this); - m_State = State_Running; - return NOERROR; - } - - Ready(); - - // Pause the base filter class - - HRESULT hr = CBaseFilter::Run(StartTime); - if (FAILED(hr)) { - NOTE("Run failed"); - return hr; - } - - // Allow the source thread to wait - ASSERT(m_pInputPin->IsFlushing() == FALSE); - SourceThreadCanWait(TRUE); - SetRepaintStatus(FALSE); - - // There should be no outstanding advise - ASSERT(CancelNotification() == S_FALSE); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(m_EndOfStreamTimer == 0); - ASSERT(m_pInputPin->IsFlushing() == FALSE); - - // If we are going into a running state then we must commit whatever - // allocator we are using it so that any source filter can call the - // GetBuffer and expect to get a buffer without returning an error - - if (m_pInputPin->Allocator()) { - m_pInputPin->Allocator()->Commit(); - } - - // When we come out of a stopped state we must clear any image we were - // holding onto for frame refreshing. Since renderers see state changes - // first we can reset ourselves ready to accept the source thread data - // Paused or running after being stopped causes the current position to - // be reset so we're not interested in passing end of stream signals - - if (OldState == State_Stopped) { - m_bAbort = FALSE; - ClearPendingSample(); - } - return StartStreaming(); -} - - -// Return the number of input pins we support - -int CBaseRenderer::GetPinCount() -{ - return 1; -} - - -// We only support one input pin and it is numbered zero - -CBasePin *CBaseRenderer::GetPin(int n) -{ - CAutoLock cObjectCreationLock(&m_ObjectCreationLock); - - // Should only ever be called with zero - ASSERT(n == 0); - - if (n != 0) { - return NULL; - } - - // Create the input pin if not already done so - - if (m_pInputPin == NULL) { - - // hr must be initialized to NOERROR because - // CRendererInputPin's constructor only changes - // hr's value if an error occurs. - HRESULT hr = NOERROR; - - m_pInputPin = new CRendererInputPin(this,&hr,L"In"); - if (NULL == m_pInputPin) { - return NULL; - } - - if (FAILED(hr)) { - delete m_pInputPin; - m_pInputPin = NULL; - return NULL; - } - } - return m_pInputPin; -} - - -// If "In" then return the IPin for our input pin, otherwise NULL and error - -STDMETHODIMP CBaseRenderer::FindPin(LPCWSTR Id, IPin **ppPin) -{ - CheckPointer(ppPin,E_POINTER); - - if (0==lstrcmpW(Id,L"In")) { - *ppPin = GetPin(0); - ASSERT(*ppPin); - (*ppPin)->AddRef(); - } else { - *ppPin = NULL; - return VFW_E_NOT_FOUND; - } - return NOERROR; -} - - -// Called when the input pin receives an EndOfStream notification. If we have -// not got a sample, then notify EC_COMPLETE now. If we have samples, then set -// m_bEOS and check for this on completing samples. If we're waiting to pause -// then complete the transition to paused state by setting the state event - -HRESULT CBaseRenderer::EndOfStream() -{ - // Ignore these calls if we are stopped - - if (m_State == State_Stopped) { - return NOERROR; - } - - // If we have a sample then wait for it to be rendered - - m_bEOS = TRUE; - if (m_pMediaSample) { - return NOERROR; - } - - // If we are waiting for pause then we are now ready since we cannot now - // carry on waiting for a sample to arrive since we are being told there - // won't be any. This sets an event that the GetState function picks up - - Ready(); - - // Only signal completion now if we are running otherwise queue it until - // we do run in StartStreaming. This is used when we seek because a seek - // causes a pause where early notification of completion is misleading - - if (m_bStreaming) { - SendEndOfStream(); - } - return NOERROR; -} - - -// When we are told to flush we should release the source thread - -HRESULT CBaseRenderer::BeginFlush() -{ - // If paused then report state intermediate until we get some data - - if (m_State == State_Paused) { - NotReady(); - } - - SourceThreadCanWait(FALSE); - CancelNotification(); - ClearPendingSample(); - // Wait for Receive to complete - WaitForReceiveToComplete(); - - return NOERROR; -} - - -// After flushing the source thread can wait in Receive again - -HRESULT CBaseRenderer::EndFlush() -{ - // Reset the current sample media time - if (m_pPosition) m_pPosition->ResetMediaTime(); - - // There should be no outstanding advise - - ASSERT(CancelNotification() == S_FALSE); - SourceThreadCanWait(TRUE); - return NOERROR; -} - - -// We can now send EC_REPAINTs if so required - -HRESULT CBaseRenderer::CompleteConnect(IPin *pReceivePin) -{ - // The caller should always hold the interface lock because - // the function uses CBaseFilter::m_State. - ASSERT(CritCheckIn(&m_InterfaceLock)); - - m_bAbort = FALSE; - - if (State_Running == GetRealState()) { - HRESULT hr = StartStreaming(); - if (FAILED(hr)) { - return hr; - } - - SetRepaintStatus(FALSE); - } else { - SetRepaintStatus(TRUE); - } - - return NOERROR; -} - - -// Called when we go paused or running - -HRESULT CBaseRenderer::Active() -{ - return NOERROR; -} - - -// Called when we go into a stopped state - -HRESULT CBaseRenderer::Inactive() -{ - if (m_pPosition) { - m_pPosition->ResetMediaTime(); - } - // People who derive from this may want to override this behaviour - // to keep hold of the sample in some circumstances - ClearPendingSample(); - - return NOERROR; -} - - -// Tell derived classes about the media type agreed - -HRESULT CBaseRenderer::SetMediaType(const CMediaType *pmt) -{ - return NOERROR; -} - - -// When we break the input pin connection we should reset the EOS flags. When -// we are asked for either IMediaPosition or IMediaSeeking we will create a -// CPosPassThru object to handles media time pass through. When we're handed -// samples we store (by calling CPosPassThru::RegisterMediaTime) their media -// times so we can then return a real current position of data being rendered - -HRESULT CBaseRenderer::BreakConnect() -{ - // Do we have a quality management sink - - if (m_pQSink) { - m_pQSink->Release(); - m_pQSink = NULL; - } - - // Check we have a valid connection - - if (m_pInputPin->IsConnected() == FALSE) { - return S_FALSE; - } - - // Check we are stopped before disconnecting - if (m_State != State_Stopped && !m_pInputPin->CanReconnectWhenActive()) { - return VFW_E_NOT_STOPPED; - } - - SetRepaintStatus(FALSE); - ResetEndOfStream(); - ClearPendingSample(); - m_bAbort = FALSE; - - if (State_Running == m_State) { - StopStreaming(); - } - - return NOERROR; -} - - -// Retrieves the sample times for this samples (note the sample times are -// passed in by reference not value). We return S_FALSE to say schedule this -// sample according to the times on the sample. We also return S_OK in -// which case the object should simply render the sample data immediately - -HRESULT CBaseRenderer::GetSampleTimes(IMediaSample *pMediaSample, - REFERENCE_TIME *pStartTime, - REFERENCE_TIME *pEndTime) -{ - ASSERT(m_dwAdvise == 0); - ASSERT(pMediaSample); - - // If the stop time for this sample is before or the same as start time, - // then just ignore it (release it) and schedule the next one in line - // Source filters should always fill in the start and end times properly! - - if (SUCCEEDED(pMediaSample->GetTime(pStartTime, pEndTime))) { - if (*pEndTime < *pStartTime) { - return VFW_E_START_TIME_AFTER_END; - } - } else { - // no time set in the sample... draw it now? - return S_OK; - } - - // Can't synchronise without a clock so we return S_OK which tells the - // caller that the sample should be rendered immediately without going - // through the overhead of setting a timer advise link with the clock - - if (m_pClock == NULL) { - return S_OK; - } - return ShouldDrawSampleNow(pMediaSample,pStartTime,pEndTime); -} - - -// By default all samples are drawn according to their time stamps so we -// return S_FALSE. Returning S_OK means draw immediately, this is used -// by the derived video renderer class in its quality management. - -HRESULT CBaseRenderer::ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd) -{ - return S_FALSE; -} - - -// We must always reset the current advise time to zero after a timer fires -// because there are several possible ways which lead us not to do any more -// scheduling such as the pending image being cleared after state changes - -void CBaseRenderer::SignalTimerFired() -{ - m_dwAdvise = 0; -} - - -// Cancel any notification currently scheduled. This is called by the owning -// window object when it is told to stop streaming. If there is no timer link -// outstanding then calling this is benign otherwise we go ahead and cancel -// We must always reset the render event as the quality management code can -// signal immediate rendering by setting the event without setting an advise -// link. If we're subsequently stopped and run the first attempt to setup an -// advise link with the reference clock will find the event still signalled - -HRESULT CBaseRenderer::CancelNotification() -{ - ASSERT(m_dwAdvise == 0 || m_pClock); - DWORD_PTR dwAdvise = m_dwAdvise; - - // Have we a live advise link - - if (m_dwAdvise) { - m_pClock->Unadvise(m_dwAdvise); - SignalTimerFired(); - ASSERT(m_dwAdvise == 0); - } - - // Clear the event and return our status - - m_RenderEvent.Reset(); - return (dwAdvise ? S_OK : S_FALSE); -} - - -// Responsible for setting up one shot advise links with the clock -// Return FALSE if the sample is to be dropped (not drawn at all) -// Return TRUE if the sample is to be drawn and in this case also -// arrange for m_RenderEvent to be set at the appropriate time - -BOOL CBaseRenderer::ScheduleSample(IMediaSample *pMediaSample) -{ - REFERENCE_TIME StartSample, EndSample; - - // Is someone pulling our leg - - if (pMediaSample == NULL) { - return FALSE; - } - - // Get the next sample due up for rendering. If there aren't any ready - // then GetNextSampleTimes returns an error. If there is one to be done - // then it succeeds and yields the sample times. If it is due now then - // it returns S_OK other if it's to be done when due it returns S_FALSE - - HRESULT hr = GetSampleTimes(pMediaSample, &StartSample, &EndSample); - if (FAILED(hr)) { - return FALSE; - } - - // If we don't have a reference clock then we cannot set up the advise - // time so we simply set the event indicating an image to render. This - // will cause us to run flat out without any timing or synchronisation - - if (hr == S_OK) { - EXECUTE_ASSERT(SetEvent((HANDLE) m_RenderEvent)); - return TRUE; - } - - ASSERT(m_dwAdvise == 0); - ASSERT(m_pClock); - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - - // We do have a valid reference clock interface so we can ask it to - // set an event when the image comes due for rendering. We pass in - // the reference time we were told to start at and also the current - // stream time which is the offset from the start reference time - - hr = m_pClock->AdviseTime( - (REFERENCE_TIME) m_tStart, // Start run time - StartSample, // Stream time - (HEVENT)(HANDLE) m_RenderEvent, // Render notification - &m_dwAdvise); // Advise cookie - - if (SUCCEEDED(hr)) { - return TRUE; - } - - // We could not schedule the next sample for rendering despite the fact - // we have a valid sample here. This is a fair indication that either - // the system clock is wrong or the time stamp for the sample is duff - - ASSERT(m_dwAdvise == 0); - return FALSE; -} - - -// This is called when a sample comes due for rendering. We pass the sample -// on to the derived class. After rendering we will initialise the timer for -// the next sample, NOTE signal that the last one fired first, if we don't -// do this it thinks there is still one outstanding that hasn't completed - -HRESULT CBaseRenderer::Render(IMediaSample *pMediaSample) -{ - // If the media sample is NULL then we will have been notified by the - // clock that another sample is ready but in the mean time someone has - // stopped us streaming which causes the next sample to be released - - if (pMediaSample == NULL) { - return S_FALSE; - } - - // If we have stopped streaming then don't render any more samples, the - // thread that got in and locked us and then reset this flag does not - // clear the pending sample as we can use it to refresh any output device - - if (m_bStreaming == FALSE) { - return S_FALSE; - } - - // Time how long the rendering takes - - OnRenderStart(pMediaSample); - DoRenderSample(pMediaSample); - OnRenderEnd(pMediaSample); - - return NOERROR; -} - - -// Checks if there is a sample waiting at the renderer - -BOOL CBaseRenderer::HaveCurrentSample() -{ - CAutoLock cRendererLock(&m_RendererLock); - return (m_pMediaSample == NULL ? FALSE : TRUE); -} - - -// Returns the current sample waiting at the video renderer. We AddRef the -// sample before returning so that should it come due for rendering the -// person who called this method will hold the remaining reference count -// that will stop the sample being added back onto the allocator free list - -IMediaSample *CBaseRenderer::GetCurrentSample() -{ - CAutoLock cRendererLock(&m_RendererLock); - if (m_pMediaSample) { - m_pMediaSample->AddRef(); - } - return m_pMediaSample; -} - - -// Called when the source delivers us a sample. We go through a few checks to -// make sure the sample can be rendered. If we are running (streaming) then we -// have the sample scheduled with the reference clock, if we are not streaming -// then we have received an sample in paused mode so we can complete any state -// transition. On leaving this function everything will be unlocked so an app -// thread may get in and change our state to stopped (for example) in which -// case it will also signal the thread event so that our wait call is stopped - -HRESULT CBaseRenderer::PrepareReceive(IMediaSample *pMediaSample) -{ - CAutoLock cInterfaceLock(&m_InterfaceLock); - m_bInReceive = TRUE; - - // Check our flushing and filter state - - // This function must hold the interface lock because it calls - // CBaseInputPin::Receive() and CBaseInputPin::Receive() uses - // CBasePin::m_bRunTimeError. - HRESULT hr = m_pInputPin->CBaseInputPin::Receive(pMediaSample); - - if (hr != NOERROR) { - m_bInReceive = FALSE; - return E_FAIL; - } - - // Has the type changed on a media sample. We do all rendering - // synchronously on the source thread, which has a side effect - // that only one buffer is ever outstanding. Therefore when we - // have Receive called we can go ahead and change the format - // Since the format change can cause a SendMessage we just don't - // lock - if (m_pInputPin->SampleProps()->pMediaType) { - hr = m_pInputPin->SetMediaType( - (CMediaType *)m_pInputPin->SampleProps()->pMediaType); - if (FAILED(hr)) { - m_bInReceive = FALSE; - return hr; - } - } - - - CAutoLock cSampleLock(&m_RendererLock); - - ASSERT(IsActive() == TRUE); - ASSERT(m_pInputPin->IsFlushing() == FALSE); - ASSERT(m_pInputPin->IsConnected() == TRUE); - ASSERT(m_pMediaSample == NULL); - - // Return an error if we already have a sample waiting for rendering - // source pins must serialise the Receive calls - we also check that - // no data is being sent after the source signalled an end of stream - - if (m_pMediaSample || m_bEOS || m_bAbort) { - Ready(); - m_bInReceive = FALSE; - return E_UNEXPECTED; - } - - // Store the media times from this sample - if (m_pPosition) m_pPosition->RegisterMediaTime(pMediaSample); - - // Schedule the next sample if we are streaming - - if ((m_bStreaming == TRUE) && (ScheduleSample(pMediaSample) == FALSE)) { - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(CancelNotification() == S_FALSE); - m_bInReceive = FALSE; - return VFW_E_SAMPLE_REJECTED; - } - - // Store the sample end time for EC_COMPLETE handling - m_SignalTime = m_pInputPin->SampleProps()->tStop; - - // BEWARE we sometimes keep the sample even after returning the thread to - // the source filter such as when we go into a stopped state (we keep it - // to refresh the device with) so we must AddRef it to keep it safely. If - // we start flushing the source thread is released and any sample waiting - // will be released otherwise GetBuffer may never return (see BeginFlush) - - m_pMediaSample = pMediaSample; - m_pMediaSample->AddRef(); - - if (m_bStreaming == FALSE) { - SetRepaintStatus(TRUE); - } - return NOERROR; -} - - -// Called by the source filter when we have a sample to render. Under normal -// circumstances we set an advise link with the clock, wait for the time to -// arrive and then render the data using the PURE virtual DoRenderSample that -// the derived class will have overriden. After rendering the sample we may -// also signal EOS if it was the last one sent before EndOfStream was called - -HRESULT CBaseRenderer::Receive(IMediaSample *pSample) -{ - ASSERT(pSample); - - // It may return VFW_E_SAMPLE_REJECTED code to say don't bother - - HRESULT hr = PrepareReceive(pSample); - ASSERT(m_bInReceive == SUCCEEDED(hr)); - if (FAILED(hr)) { - if (hr == VFW_E_SAMPLE_REJECTED) { - return NOERROR; - } - return hr; - } - - // We realize the palette in "PrepareRender()" so we have to give away the - // filter lock here. - if (m_State == State_Paused) { - PrepareRender(); - // no need to use InterlockedExchange - m_bInReceive = FALSE; - { - // We must hold both these locks - CAutoLock cRendererLock(&m_InterfaceLock); - if (m_State == State_Stopped) - return NOERROR; - - m_bInReceive = TRUE; - CAutoLock cSampleLock(&m_RendererLock); - OnReceiveFirstSample(pSample); - } - Ready(); - } - // Having set an advise link with the clock we sit and wait. We may be - // awoken by the clock firing or by a state change. The rendering call - // will lock the critical section and check we can still render the data - - hr = WaitForRenderTime(); - if (FAILED(hr)) { - m_bInReceive = FALSE; - return NOERROR; - } - - PrepareRender(); - - // Set this here and poll it until we work out the locking correctly - // It can't be right that the streaming stuff grabs the interface - // lock - after all we want to be able to wait for this stuff - // to complete - m_bInReceive = FALSE; - - // We must hold both these locks - CAutoLock cRendererLock(&m_InterfaceLock); - - // since we gave away the filter wide lock, the sate of the filter could - // have chnaged to Stopped - if (m_State == State_Stopped) - return NOERROR; - - CAutoLock cSampleLock(&m_RendererLock); - - // Deal with this sample - - Render(m_pMediaSample); - ClearPendingSample(); - SendEndOfStream(); - CancelNotification(); - return NOERROR; -} - - -// This is called when we stop or are inactivated to clear the pending sample -// We release the media sample interface so that they can be allocated to the -// source filter again, unless of course we are changing state to inactive in -// which case GetBuffer will return an error. We must also reset the current -// media sample to NULL so that we know we do not currently have an image - -HRESULT CBaseRenderer::ClearPendingSample() -{ - CAutoLock cRendererLock(&m_RendererLock); - if (m_pMediaSample) { - m_pMediaSample->Release(); - m_pMediaSample = NULL; - } - return NOERROR; -} - - -// Used to signal end of stream according to the sample end time - -void CALLBACK EndOfStreamTimer(UINT uID, // Timer identifier - UINT uMsg, // Not currently used - DWORD_PTR dwUser,// User information - DWORD_PTR dw1, // Windows reserved - DWORD_PTR dw2) // is also reserved -{ - CBaseRenderer *pRenderer = (CBaseRenderer *) dwUser; - NOTE1("EndOfStreamTimer called (%d)",uID); - pRenderer->TimerCallback(); -} - -// Do the timer callback work -void CBaseRenderer::TimerCallback() -{ - // Lock for synchronization (but don't hold this lock when calling - // timeKillEvent) - CAutoLock cRendererLock(&m_RendererLock); - - // See if we should signal end of stream now - - if (m_EndOfStreamTimer) { - m_EndOfStreamTimer = 0; - SendEndOfStream(); - } -} - - -// If we are at the end of the stream signal the filter graph but do not set -// the state flag back to FALSE. Once we drop off the end of the stream we -// leave the flag set (until a subsequent ResetEndOfStream). Each sample we -// get delivered will update m_SignalTime to be the last sample's end time. -// We must wait this long before signalling end of stream to the filtergraph - -#define TIMEOUT_DELIVERYWAIT 50 -#define TIMEOUT_RESOLUTION 10 - -HRESULT CBaseRenderer::SendEndOfStream() -{ - ASSERT(CritCheckIn(&m_RendererLock)); - if (m_bEOS == FALSE || m_bEOSDelivered || m_EndOfStreamTimer) { - return NOERROR; - } - - // If there is no clock then signal immediately - if (m_pClock == NULL) { - return NotifyEndOfStream(); - } - - // How long into the future is the delivery time - - REFERENCE_TIME Signal = m_tStart + m_SignalTime; - REFERENCE_TIME CurrentTime; - m_pClock->GetTime(&CurrentTime); - LONG Delay = LONG((Signal - CurrentTime) / 10000); - - // Dump the timing information to the debugger - - NOTE1("Delay until end of stream delivery %d",Delay); - NOTE1("Current %s",(LPCTSTR)CDisp((LONGLONG)CurrentTime)); - NOTE1("Signal %s",(LPCTSTR)CDisp((LONGLONG)Signal)); - - // Wait for the delivery time to arrive - - if (Delay < TIMEOUT_DELIVERYWAIT) { - return NotifyEndOfStream(); - } - - // Signal a timer callback on another worker thread - - m_EndOfStreamTimer = CompatibleTimeSetEvent((UINT) Delay, // Period of timer - TIMEOUT_RESOLUTION, // Timer resolution - EndOfStreamTimer, // Callback function - DWORD_PTR(this), // Used information - TIME_ONESHOT); // Type of callback - if (m_EndOfStreamTimer == 0) { - return NotifyEndOfStream(); - } - return NOERROR; -} - - -// Signals EC_COMPLETE to the filtergraph manager - -HRESULT CBaseRenderer::NotifyEndOfStream() -{ - CAutoLock cRendererLock(&m_RendererLock); - ASSERT(m_bEOSDelivered == FALSE); - ASSERT(m_EndOfStreamTimer == 0); - - // Has the filter changed state - - if (m_bStreaming == FALSE) { - ASSERT(m_EndOfStreamTimer == 0); - return NOERROR; - } - - // Reset the end of stream timer - m_EndOfStreamTimer = 0; - - // If we've been using the IMediaPosition interface, set it's start - // and end media "times" to the stop position by hand. This ensures - // that we actually get to the end, even if the MPEG guestimate has - // been bad or if the quality management dropped the last few frames - - if (m_pPosition) m_pPosition->EOS(); - m_bEOSDelivered = TRUE; - NOTE("Sending EC_COMPLETE..."); - return NotifyEvent(EC_COMPLETE,S_OK,(LONG_PTR)(IBaseFilter *)this); -} - - -// Reset the end of stream flag, this is typically called when we transfer to -// stopped states since that resets the current position back to the start so -// we will receive more samples or another EndOfStream if there aren't any. We -// keep two separate flags one to say we have run off the end of the stream -// (this is the m_bEOS flag) and another to say we have delivered EC_COMPLETE -// to the filter graph. We need the latter otherwise we can end up sending an -// EC_COMPLETE every time the source changes state and calls our EndOfStream - -HRESULT CBaseRenderer::ResetEndOfStream() -{ - ResetEndOfStreamTimer(); - CAutoLock cRendererLock(&m_RendererLock); - - m_bEOS = FALSE; - m_bEOSDelivered = FALSE; - m_SignalTime = 0; - - return NOERROR; -} - - -// Kills any outstanding end of stream timer - -void CBaseRenderer::ResetEndOfStreamTimer() -{ - ASSERT(CritCheckOut(&m_RendererLock)); - if (m_EndOfStreamTimer) { - timeKillEvent(m_EndOfStreamTimer); - m_EndOfStreamTimer = 0; - } -} - - -// This is called when we start running so that we can schedule any pending -// image we have with the clock and display any timing information. If we -// don't have any sample but we have queued an EOS flag then we send it. If -// we do have a sample then we wait until that has been rendered before we -// signal the filter graph otherwise we may change state before it's done - -HRESULT CBaseRenderer::StartStreaming() -{ - CAutoLock cRendererLock(&m_RendererLock); - if (m_bStreaming == TRUE) { - return NOERROR; - } - - // Reset the streaming times ready for running - - m_bStreaming = TRUE; - - timeBeginPeriod(1); - OnStartStreaming(); - - // There should be no outstanding advise - ASSERT(WAIT_TIMEOUT == WaitForSingleObject((HANDLE)m_RenderEvent,0)); - ASSERT(CancelNotification() == S_FALSE); - - // If we have an EOS and no data then deliver it now - - if (m_pMediaSample == NULL) { - return SendEndOfStream(); - } - - // Have the data rendered - - ASSERT(m_pMediaSample); - if (!ScheduleSample(m_pMediaSample)) - m_RenderEvent.Set(); - - return NOERROR; -} - - -// This is called when we stop streaming so that we can set our internal flag -// indicating we are not now to schedule any more samples arriving. The state -// change methods in the filter implementation take care of cancelling any -// clock advise link we have set up and clearing any pending sample we have - -HRESULT CBaseRenderer::StopStreaming() -{ - CAutoLock cRendererLock(&m_RendererLock); - m_bEOSDelivered = FALSE; - - if (m_bStreaming == TRUE) { - m_bStreaming = FALSE; - OnStopStreaming(); - timeEndPeriod(1); - } - return NOERROR; -} - - -// We have a boolean flag that is reset when we have signalled EC_REPAINT to -// the filter graph. We set this when we receive an image so that should any -// conditions arise again we can send another one. By having a flag we ensure -// we don't flood the filter graph with redundant calls. We do not set the -// event when we receive an EndOfStream call since there is no point in us -// sending further EC_REPAINTs. In particular the AutoShowWindow method and -// the DirectDraw object use this method to control the window repainting - -void CBaseRenderer::SetRepaintStatus(BOOL bRepaint) -{ - CAutoLock cSampleLock(&m_RendererLock); - m_bRepaintStatus = bRepaint; -} - - -// Pass the window handle to the upstream filter - -void CBaseRenderer::SendNotifyWindow(IPin *pPin,HWND hwnd) -{ - IMediaEventSink *pSink; - - // Does the pin support IMediaEventSink - HRESULT hr = pPin->QueryInterface(IID_IMediaEventSink,(void **)&pSink); - if (SUCCEEDED(hr)) { - pSink->Notify(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0); - pSink->Release(); - } - NotifyEvent(EC_NOTIFY_WINDOW,LONG_PTR(hwnd),0); -} - - -// Signal an EC_REPAINT to the filter graph. This can be used to have data -// sent to us. For example when a video window is first displayed it may -// not have an image to display, at which point it signals EC_REPAINT. The -// filtergraph will either pause the graph if stopped or if already paused -// it will call put_CurrentPosition of the current position. Setting the -// current position to itself has the stream flushed and the image resent - -#define RLOG(_x_) DbgLog((LOG_TRACE,1,TEXT(_x_))); - -void CBaseRenderer::SendRepaint() -{ - CAutoLock cSampleLock(&m_RendererLock); - ASSERT(m_pInputPin); - - // We should not send repaint notifications when... - // - An end of stream has been notified - // - Our input pin is being flushed - // - The input pin is not connected - // - We have aborted a video playback - // - There is a repaint already sent - - if (m_bAbort == FALSE) { - if (m_pInputPin->IsConnected() == TRUE) { - if (m_pInputPin->IsFlushing() == FALSE) { - if (IsEndOfStream() == FALSE) { - if (m_bRepaintStatus == TRUE) { - IPin *pPin = (IPin *) m_pInputPin; - NotifyEvent(EC_REPAINT,(LONG_PTR) pPin,0); - SetRepaintStatus(FALSE); - RLOG("Sending repaint"); - } - } - } - } - } -} - - -// When a video window detects a display change (WM_DISPLAYCHANGE message) it -// can send an EC_DISPLAY_CHANGED event code along with the renderer pin. The -// filtergraph will stop everyone and reconnect our input pin. As we're then -// reconnected we can accept the media type that matches the new display mode -// since we may no longer be able to draw the current image type efficiently - -BOOL CBaseRenderer::OnDisplayChange() -{ - // Ignore if we are not connected yet - - CAutoLock cSampleLock(&m_RendererLock); - if (m_pInputPin->IsConnected() == FALSE) { - return FALSE; - } - - RLOG("Notification of EC_DISPLAY_CHANGE"); - - // Pass our input pin as parameter on the event - - IPin *pPin = (IPin *) m_pInputPin; - m_pInputPin->AddRef(); - NotifyEvent(EC_DISPLAY_CHANGED,(LONG_PTR) pPin,0); - SetAbortSignal(TRUE); - ClearPendingSample(); - m_pInputPin->Release(); - - return TRUE; -} - - -// Called just before we start drawing. -// Store the current time in m_trRenderStart to allow the rendering time to be -// logged. Log the time stamp of the sample and how late it is (neg is early) - -void CBaseRenderer::OnRenderStart(IMediaSample *pMediaSample) -{ -#ifdef PERF - REFERENCE_TIME trStart, trEnd; - pMediaSample->GetTime(&trStart, &trEnd); - - MSR_INTEGER(m_idBaseStamp, (int)trStart); // dump low order 32 bits - - m_pClock->GetTime(&m_trRenderStart); - MSR_INTEGER(0, (int)m_trRenderStart); - REFERENCE_TIME trStream; - trStream = m_trRenderStart-m_tStart; // convert reftime to stream time - MSR_INTEGER(0,(int)trStream); - - const int trLate = (int)(trStream - trStart); - MSR_INTEGER(m_idBaseAccuracy, trLate/10000); // dump in mSec -#endif - -} // OnRenderStart - - -// Called directly after drawing an image. -// calculate the time spent drawing and log it. - -void CBaseRenderer::OnRenderEnd(IMediaSample *pMediaSample) -{ -#ifdef PERF - REFERENCE_TIME trNow; - m_pClock->GetTime(&trNow); - MSR_INTEGER(0,(int)trNow); - int t = (int)((trNow - m_trRenderStart)/10000); // convert UNITS->msec - MSR_INTEGER(m_idBaseRenderTime, t); -#endif -} // OnRenderEnd - - - - -// Constructor must be passed the base renderer object - -CRendererInputPin::CRendererInputPin(CBaseRenderer *pRenderer, - HRESULT *phr, - LPCWSTR pPinName) : - CBaseInputPin(NAME("Renderer pin"), - pRenderer, - &pRenderer->m_InterfaceLock, - (HRESULT *) phr, - pPinName) -{ - m_pRenderer = pRenderer; - ASSERT(m_pRenderer); -} - - -// Signals end of data stream on the input pin - -STDMETHODIMP CRendererInputPin::EndOfStream() -{ - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - CAutoLock cSampleLock(&m_pRenderer->m_RendererLock); - - // Make sure we're streaming ok - - HRESULT hr = CheckStreaming(); - if (hr != NOERROR) { - return hr; - } - - // Pass it onto the renderer - - hr = m_pRenderer->EndOfStream(); - if (SUCCEEDED(hr)) { - hr = CBaseInputPin::EndOfStream(); - } - return hr; -} - - -// Signals start of flushing on the input pin - we do the final reset end of -// stream with the renderer lock unlocked but with the interface lock locked -// We must do this because we call timeKillEvent, our timer callback method -// has to take the renderer lock to serialise our state. Therefore holding a -// renderer lock when calling timeKillEvent could cause a deadlock condition - -STDMETHODIMP CRendererInputPin::BeginFlush() -{ - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - { - CAutoLock cSampleLock(&m_pRenderer->m_RendererLock); - CBaseInputPin::BeginFlush(); - m_pRenderer->BeginFlush(); - } - return m_pRenderer->ResetEndOfStream(); -} - - -// Signals end of flushing on the input pin - -STDMETHODIMP CRendererInputPin::EndFlush() -{ - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - CAutoLock cSampleLock(&m_pRenderer->m_RendererLock); - - HRESULT hr = m_pRenderer->EndFlush(); - if (SUCCEEDED(hr)) { - hr = CBaseInputPin::EndFlush(); - } - return hr; -} - - -// Pass the sample straight through to the renderer object - -STDMETHODIMP CRendererInputPin::Receive(IMediaSample *pSample) -{ - HRESULT hr = m_pRenderer->Receive(pSample); - if (FAILED(hr)) { - - // A deadlock could occur if the caller holds the renderer lock and - // attempts to acquire the interface lock. - ASSERT(CritCheckOut(&m_pRenderer->m_RendererLock)); - - { - // The interface lock must be held when the filter is calling - // IsStopped() or IsFlushing(). The interface lock must also - // be held because the function uses m_bRunTimeError. - CAutoLock cRendererLock(&m_pRenderer->m_InterfaceLock); - - // We do not report errors which occur while the filter is stopping, - // flushing or if the m_bAbort flag is set . Errors are expected to - // occur during these operations and the streaming thread correctly - // handles the errors. - if (!IsStopped() && !IsFlushing() && !m_pRenderer->m_bAbort && !m_bRunTimeError) { - - // EC_ERRORABORT's first parameter is the error which caused - // the event and its' last parameter is 0. See the Direct - // Show SDK documentation for more information. - m_pRenderer->NotifyEvent(EC_ERRORABORT,hr,0); - - { - CAutoLock alRendererLock(&m_pRenderer->m_RendererLock); - if (m_pRenderer->IsStreaming() && !m_pRenderer->IsEndOfStreamDelivered()) { - m_pRenderer->NotifyEndOfStream(); - } - } - - m_bRunTimeError = TRUE; - } - } - } - - return hr; -} - - -// Called when the input pin is disconnected - -HRESULT CRendererInputPin::BreakConnect() -{ - HRESULT hr = m_pRenderer->BreakConnect(); - if (FAILED(hr)) { - return hr; - } - return CBaseInputPin::BreakConnect(); -} - - -// Called when the input pin is connected - -HRESULT CRendererInputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = m_pRenderer->CompleteConnect(pReceivePin); - if (FAILED(hr)) { - return hr; - } - return CBaseInputPin::CompleteConnect(pReceivePin); -} - - -// Give the pin id of our one and only pin - -STDMETHODIMP CRendererInputPin::QueryId(LPWSTR *Id) -{ - CheckPointer(Id,E_POINTER); - - const size_t len = 4; - *Id = (LPWSTR)CoTaskMemAlloc(len * sizeof(WCHAR)); - if (*Id == NULL) { - return E_OUTOFMEMORY; - } - (void)StringCchCopyW(*Id, len, L"In"); - return NOERROR; -} - - -// Will the filter accept this media type - -HRESULT CRendererInputPin::CheckMediaType(const CMediaType *pmt) -{ - return m_pRenderer->CheckMediaType(pmt); -} - - -// Called when we go paused or running - -HRESULT CRendererInputPin::Active() -{ - return m_pRenderer->Active(); -} - - -// Called when we go into a stopped state - -HRESULT CRendererInputPin::Inactive() -{ - // The caller must hold the interface lock because - // this function uses m_bRunTimeError. - ASSERT(CritCheckIn(&m_pRenderer->m_InterfaceLock)); - - m_bRunTimeError = FALSE; - - return m_pRenderer->Inactive(); -} - - -// Tell derived classes about the media type agreed - -HRESULT CRendererInputPin::SetMediaType(const CMediaType *pmt) -{ - HRESULT hr = CBaseInputPin::SetMediaType(pmt); - if (FAILED(hr)) { - return hr; - } - return m_pRenderer->SetMediaType(pmt); -} - - -// We do not keep an event object to use when setting up a timer link with -// the clock but are given a pointer to one by the owning object through the -// SetNotificationObject method - this must be initialised before starting -// We can override the default quality management process to have it always -// draw late frames, this is currently done by having the following registry -// key (actually an INI key) called DrawLateFrames set to 1 (default is 0) - -const TCHAR AMQUALITY[] = TEXT("ActiveMovie"); -const TCHAR DRAWLATEFRAMES[] = TEXT("DrawLateFrames"); - -CBaseVideoRenderer::CBaseVideoRenderer( - REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr) : // General OLE return code - - CBaseRenderer(RenderClass,pName,pUnk,phr), - m_cFramesDropped(0), - m_cFramesDrawn(0), - m_bSupplierHandlingQuality(FALSE) -{ - ResetStreamingTimes(); - -#ifdef PERF - m_idTimeStamp = MSR_REGISTER(TEXT("Frame time stamp")); - m_idEarliness = MSR_REGISTER(TEXT("Earliness fudge")); - m_idTarget = MSR_REGISTER(TEXT("Target (mSec)")); - m_idSchLateTime = MSR_REGISTER(TEXT("mSec late when scheduled")); - m_idDecision = MSR_REGISTER(TEXT("Scheduler decision code")); - m_idQualityRate = MSR_REGISTER(TEXT("Quality rate sent")); - m_idQualityTime = MSR_REGISTER(TEXT("Quality time sent")); - m_idWaitReal = MSR_REGISTER(TEXT("Render wait")); - // m_idWait = MSR_REGISTER(TEXT("wait time recorded (msec)")); - m_idFrameAccuracy = MSR_REGISTER(TEXT("Frame accuracy (msecs)")); - m_bDrawLateFrames = GetProfileInt(AMQUALITY, DRAWLATEFRAMES, FALSE); - //m_idSendQuality = MSR_REGISTER(TEXT("Processing Quality message")); - - m_idRenderAvg = MSR_REGISTER(TEXT("Render draw time Avg")); - m_idFrameAvg = MSR_REGISTER(TEXT("FrameAvg")); - m_idWaitAvg = MSR_REGISTER(TEXT("WaitAvg")); - m_idDuration = MSR_REGISTER(TEXT("Duration")); - m_idThrottle = MSR_REGISTER(TEXT("Audio-video throttle wait")); - // m_idDebug = MSR_REGISTER(TEXT("Debug stuff")); -#endif // PERF -} // Constructor - - -// Destructor is just a placeholder - -CBaseVideoRenderer::~CBaseVideoRenderer() -{ - ASSERT(m_dwAdvise == 0); -} - - -// The timing functions in this class are called by the window object and by -// the renderer's allocator. -// The windows object calls timing functions as it receives media sample -// images for drawing using GDI. -// The allocator calls timing functions when it starts passing DCI/DirectDraw -// surfaces which are not rendered in the same way; The decompressor writes -// directly to the surface with no separate rendering, so those code paths -// call direct into us. Since we only ever hand out DCI/DirectDraw surfaces -// when we have allocated one and only one image we know there cannot be any -// conflict between the two. -// -// We use timeGetTime to return the timing counts we use (since it's relative -// performance we are interested in rather than absolute compared to a clock) -// The window object sets the accuracy of the system clock (normally 1ms) by -// calling timeBeginPeriod/timeEndPeriod when it changes streaming states - - -// Reset all times controlling streaming. -// Set them so that -// 1. Frames will not initially be dropped -// 2. The first frame will definitely be drawn (achieved by saying that there -// has not ben a frame drawn for a long time). - -HRESULT CBaseVideoRenderer::ResetStreamingTimes() -{ - m_trLastDraw = -1000; // set up as first frame since ages (1 sec) ago - m_tStreamingStart = timeGetTime(); - m_trRenderAvg = 0; - m_trFrameAvg = -1; // -1000 fps == "unset" - m_trDuration = 0; // 0 - strange value - m_trRenderLast = 0; - m_trWaitAvg = 0; - m_tRenderStart = 0; - m_cFramesDrawn = 0; - m_cFramesDropped = 0; - m_iTotAcc = 0; - m_iSumSqAcc = 0; - m_iSumSqFrameTime = 0; - m_trFrame = 0; // hygiene - not really needed - m_trLate = 0; // hygiene - not really needed - m_iSumFrameTime = 0; - m_nNormal = 0; - m_trEarliness = 0; - m_trTarget = -300000; // 30mSec early - m_trThrottle = 0; - m_trRememberStampForPerf = 0; - -#ifdef PERF - m_trRememberFrameForPerf = 0; -#endif - - return NOERROR; -} // ResetStreamingTimes - - -// Reset all times controlling streaming. Note that we're now streaming. We -// don't need to set the rendering event to have the source filter released -// as it is done during the Run processing. When we are run we immediately -// release the source filter thread and draw any image waiting (that image -// may already have been drawn once as a poster frame while we were paused) - -HRESULT CBaseVideoRenderer::OnStartStreaming() -{ - ResetStreamingTimes(); - return NOERROR; -} // OnStartStreaming - - -// Called at end of streaming. Fixes times for property page report - -HRESULT CBaseVideoRenderer::OnStopStreaming() -{ - m_tStreamingStart = timeGetTime()-m_tStreamingStart; - return NOERROR; -} // OnStopStreaming - - -// Called when we start waiting for a rendering event. -// Used to update times spent waiting and not waiting. - -void CBaseVideoRenderer::OnWaitStart() -{ - MSR_START(m_idWaitReal); -} // OnWaitStart - - -// Called when we are awoken from the wait in the window OR by our allocator -// when it is hanging around until the next sample is due for rendering on a -// DCI/DirectDraw surface. We add the wait time into our rolling average. -// We grab the interface lock so that we're serialised with the application -// thread going through the run code - which in due course ends up calling -// ResetStreaming times - possibly as we run through this section of code - -void CBaseVideoRenderer::OnWaitEnd() -{ -#ifdef PERF - MSR_STOP(m_idWaitReal); - // for a perf build we want to know just exactly how late we REALLY are. - // even if this means that we have to look at the clock again. - - REFERENCE_TIME trRealStream; // the real time now expressed as stream time. -#if 0 - m_pClock->GetTime(&trRealStream); // Calling clock here causes W95 deadlock! -#else - // We will be discarding overflows like mad here! - // This is wrong really because timeGetTime() can wrap but it's - // only for PERF - REFERENCE_TIME tr = timeGetTime()*10000; - trRealStream = tr + m_llTimeOffset; -#endif - trRealStream -= m_tStart; // convert to stream time (this is a reftime) - - if (m_trRememberStampForPerf==0) { - // This is probably the poster frame at the start, and it is not scheduled - // in the usual way at all. Just count it. The rememberstamp gets set - // in ShouldDrawSampleNow, so this does invalid frame recording until we - // actually start playing. - PreparePerformanceData(0, 0); - } else { - int trLate = (int)(trRealStream - m_trRememberStampForPerf); - int trFrame = (int)(tr - m_trRememberFrameForPerf); - PreparePerformanceData(trLate, trFrame); - } - m_trRememberFrameForPerf = tr; -#endif //PERF -} // OnWaitEnd - - -// Put data on one side that describes the lateness of the current frame. -// We don't yet know whether it will actually be drawn. In direct draw mode, -// this decision is up to the filter upstream, and it could change its mind. -// The rules say that if it did draw it must call Receive(). One way or -// another we eventually get into either OnRenderStart or OnDirectRender and -// these both call RecordFrameLateness to update the statistics. - -void CBaseVideoRenderer::PreparePerformanceData(int trLate, int trFrame) -{ - m_trLate = trLate; - m_trFrame = trFrame; -} // PreparePerformanceData - - -// update the statistics: -// m_iTotAcc, m_iSumSqAcc, m_iSumSqFrameTime, m_iSumFrameTime, m_cFramesDrawn -// Note that because the properties page reports using these variables, -// 1. We need to be inside a critical section -// 2. They must all be updated together. Updating the sums here and the count -// elsewhere can result in imaginary jitter (i.e. attempts to find square roots -// of negative numbers) in the property page code. - -void CBaseVideoRenderer::RecordFrameLateness(int trLate, int trFrame) -{ - // Record how timely we are. - int tLate = trLate/10000; - - // Best estimate of moment of appearing on the screen is average of - // start and end draw times. Here we have only the end time. This may - // tend to show us as spuriously late by up to 1/2 frame rate achieved. - // Decoder probably monitors draw time. We don't bother. - MSR_INTEGER( m_idFrameAccuracy, tLate ); - - // This is a kludge - we can get frames that are very late - // especially (at start-up) and they invalidate the statistics. - // So ignore things that are more than 1 sec off. - if (tLate>1000 || tLate<-1000) { - if (m_cFramesDrawn<=1) { - tLate = 0; - } else if (tLate>0) { - tLate = 1000; - } else { - tLate = -1000; - } - } - // The very first frame often has a invalid time, so don't - // count it into the statistics. (???) - if (m_cFramesDrawn>1) { - m_iTotAcc += tLate; - m_iSumSqAcc += (tLate*tLate); - } - - // calculate inter-frame time. Doesn't make sense for first frame - // second frame suffers from invalid first frame stamp. - if (m_cFramesDrawn>2) { - int tFrame = trFrame/10000; // convert to mSec else it overflows - - // This is a kludge. It can overflow anyway (a pause can cause - // a very long inter-frame time) and it overflows at 2**31/10**7 - // or about 215 seconds i.e. 3min 35sec - if (tFrame>1000||tFrame<0) tFrame = 1000; - m_iSumSqFrameTime += tFrame*tFrame; - ASSERT(m_iSumSqFrameTime>=0); - m_iSumFrameTime += tFrame; - } - ++m_cFramesDrawn; - -} // RecordFrameLateness - - -void CBaseVideoRenderer::ThrottleWait() -{ - if (m_trThrottle>0) { - int iThrottle = m_trThrottle/10000; // convert to mSec - MSR_INTEGER( m_idThrottle, iThrottle); - DbgLog((LOG_TRACE, 0, TEXT("Throttle %d ms"), iThrottle)); - Sleep(iThrottle); - } else { - Sleep(0); - } -} // ThrottleWait - - -// Whenever a frame is rendered it goes though either OnRenderStart -// or OnDirectRender. Data that are generated during ShouldDrawSample -// are added to the statistics by calling RecordFrameLateness from both -// these two places. - -// Called in place of OnRenderStart..OnRenderEnd -// When a DirectDraw image is drawn -void CBaseVideoRenderer::OnDirectRender(IMediaSample *pMediaSample) -{ - m_trRenderAvg = 0; - m_trRenderLast = 5000000; // If we mode switch, we do NOT want this - // to inhibit the new average getting going! - // so we set it to half a second - // MSR_INTEGER(m_idRenderAvg, m_trRenderAvg/10000); - RecordFrameLateness(m_trLate, m_trFrame); - ThrottleWait(); -} // OnDirectRender - - -// Called just before we start drawing. All we do is to get the current clock -// time (from the system) and return. We have to store the start render time -// in a member variable because it isn't used until we complete the drawing -// The rest is just performance logging. - -void CBaseVideoRenderer::OnRenderStart(IMediaSample *pMediaSample) -{ - RecordFrameLateness(m_trLate, m_trFrame); - m_tRenderStart = timeGetTime(); -} // OnRenderStart - - -// Called directly after drawing an image. We calculate the time spent in the -// drawing code and if this doesn't appear to have any odd looking spikes in -// it then we add it to the current average draw time. Measurement spikes may -// occur if the drawing thread is interrupted and switched to somewhere else. - -void CBaseVideoRenderer::OnRenderEnd(IMediaSample *pMediaSample) -{ - // The renderer time can vary erratically if we are interrupted so we do - // some smoothing to help get more sensible figures out but even that is - // not enough as figures can go 9,10,9,9,83,9 and we must disregard 83 - - int tr = (timeGetTime() - m_tRenderStart)*10000; // convert mSec->UNITS - if (tr < m_trRenderAvg*2 || tr < 2 * m_trRenderLast) { - // DO_MOVING_AVG(m_trRenderAvg, tr); - m_trRenderAvg = (tr + (AVGPERIOD-1)*m_trRenderAvg)/AVGPERIOD; - } - m_trRenderLast = tr; - ThrottleWait(); -} // OnRenderEnd - - -STDMETHODIMP CBaseVideoRenderer::SetSink( IQualityControl * piqc) -{ - - m_pQSink = piqc; - - return NOERROR; -} // SetSink - - -STDMETHODIMP CBaseVideoRenderer::Notify( IBaseFilter * pSelf, Quality q) -{ - // NOTE: We are NOT getting any locks here. We could be called - // asynchronously and possibly even on a time critical thread of - // someone else's - so we do the minumum. We only set one state - // variable (an integer) and if that happens to be in the middle - // of another thread reading it they will just get either the new - // or the old value. Locking would achieve no more than this. - - // It might be nice to check that we are being called from m_pGraph, but - // it turns out to be a millisecond or so per throw! - - // This is heuristics, these numbers are aimed at being "what works" - // rather than anything based on some theory. - // We use a hyperbola because it's easy to calculate and it includes - // a panic button asymptote (which we push off just to the left) - // The throttling fits the following table (roughly) - // Proportion Throttle (msec) - // >=1000 0 - // 900 3 - // 800 7 - // 700 11 - // 600 17 - // 500 25 - // 400 35 - // 300 50 - // 200 72 - // 125 100 - // 100 112 - // 50 146 - // 0 200 - - // (some evidence that we could go for a sharper kink - e.g. no throttling - // until below the 750 mark - might give fractionally more frames on a - // P60-ish machine). The easy way to get these coefficients is to use - // Renbase.xls follow the instructions therein using excel solver. - - if (q.Proportion>=1000) { m_trThrottle = 0; } - else { - // The DWORD is to make quite sure I get unsigned arithmetic - // as the constant is between 2**31 and 2**32 - m_trThrottle = -330000 + (388880000/(q.Proportion+167)); - } - return NOERROR; -} // Notify - - -// Send a message to indicate what our supplier should do about quality. -// Theory: -// What a supplier wants to know is "is the frame I'm working on NOW -// going to be late?". -// F1 is the frame at the supplier (as above) -// Tf1 is the due time for F1 -// T1 is the time at that point (NOW!) -// Tr1 is the time that f1 WILL actually be rendered -// L1 is the latency of the graph for frame F1 = Tr1-T1 -// D1 (for delay) is how late F1 will be beyond its due time i.e. -// D1 = (Tr1-Tf1) which is what the supplier really wants to know. -// Unfortunately Tr1 is in the future and is unknown, so is L1 -// -// We could estimate L1 by its value for a previous frame, -// L0 = Tr0-T0 and work off -// D1' = ((T1+L0)-Tf1) = (T1 + (Tr0-T0) -Tf1) -// Rearranging terms: -// D1' = (T1-T0) + (Tr0-Tf1) -// adding (Tf0-Tf0) and rearranging again: -// = (T1-T0) + (Tr0-Tf0) + (Tf0-Tf1) -// = (T1-T0) - (Tf1-Tf0) + (Tr0-Tf0) -// But (Tr0-Tf0) is just D0 - how late frame zero was, and this is the -// Late field in the quality message that we send. -// The other two terms just state what correction should be applied before -// using the lateness of F0 to predict the lateness of F1. -// (T1-T0) says how much time has actually passed (we have lost this much) -// (Tf1-Tf0) says how much time should have passed if we were keeping pace -// (we have gained this much). -// -// Suppliers should therefore work off: -// Quality.Late + (T1-T0) - (Tf1-Tf0) -// and see if this is "acceptably late" or even early (i.e. negative). -// They get T1 and T0 by polling the clock, they get Tf1 and Tf0 from -// the time stamps in the frames. They get Quality.Late from us. -// - -HRESULT CBaseVideoRenderer::SendQuality(REFERENCE_TIME trLate, - REFERENCE_TIME trRealStream) -{ - Quality q; - HRESULT hr; - - // If we are the main user of time, then report this as Flood/Dry. - // If our suppliers are, then report it as Famine/Glut. - // - // We need to take action, but avoid hunting. Hunting is caused by - // 1. Taking too much action too soon and overshooting - // 2. Taking too long to react (so averaging can CAUSE hunting). - // - // The reason why we use trLate as well as Wait is to reduce hunting; - // if the wait time is coming down and about to go into the red, we do - // NOT want to rely on some average which is only telling is that it used - // to be OK once. - - q.TimeStamp = (REFERENCE_TIME)trRealStream; - - if (m_trFrameAvg<0) { - q.Type = Famine; // guess - } - // Is the greater part of the time taken bltting or something else - else if (m_trFrameAvg > 2*m_trRenderAvg) { - q.Type = Famine; // mainly other - } else { - q.Type = Flood; // mainly bltting - } - - q.Proportion = 1000; // default - - if (m_trFrameAvg<0) { - // leave it alone - we don't know enough - } - else if ( trLate> 0 ) { - // try to catch up over the next second - // We could be Really, REALLY late, but rendering all the frames - // anyway, just because it's so cheap. - - q.Proportion = 1000 - (int)((trLate)/(UNITS/1000)); - if (q.Proportion<500) { - q.Proportion = 500; // don't go daft. (could've been negative!) - } else { - } - - } else if ( m_trWaitAvg>20000 - && trLate<-20000 - ){ - // Go cautiously faster - aim at 2mSec wait. - if (m_trWaitAvg>=m_trFrameAvg) { - // This can happen because of some fudges. - // The waitAvg is how long we originally planned to wait - // The frameAvg is more honest. - // It means that we are spending a LOT of time waiting - q.Proportion = 2000; // double. - } else { - if (m_trFrameAvg+20000 > m_trWaitAvg) { - q.Proportion - = 1000 * (m_trFrameAvg / (m_trFrameAvg + 20000 - m_trWaitAvg)); - } else { - // We're apparently spending more than the whole frame time waiting. - // Assume that the averages are slightly out of kilter, but that we - // are indeed doing a lot of waiting. (This leg probably never - // happens, but the code avoids any potential divide by zero). - q.Proportion = 2000; - } - } - - if (q.Proportion>2000) { - q.Proportion = 2000; // don't go crazy. - } - } - - // Tell the supplier how late frames are when they get rendered - // That's how late we are now. - // If we are in directdraw mode then the guy upstream can see the drawing - // times and we'll just report on the start time. He can figure out any - // offset to apply. If we are in DIB Section mode then we will apply an - // extra offset which is half of our drawing time. This is usually small - // but can sometimes be the dominant effect. For this we will use the - // average drawing time rather than the last frame. If the last frame took - // a long time to draw and made us late, that's already in the lateness - // figure. We should not add it in again unless we expect the next frame - // to be the same. We don't, we expect the average to be a better shot. - // In direct draw mode the RenderAvg will be zero. - - q.Late = trLate + m_trRenderAvg/2; - - // log what we're doing - MSR_INTEGER(m_idQualityRate, q.Proportion); - MSR_INTEGER( m_idQualityTime, (int)q.Late / 10000 ); - - // A specific sink interface may be set through IPin - - if (m_pQSink==NULL) { - // Get our input pin's peer. We send quality management messages - // to any nominated receiver of these things (set in the IPin - // interface), or else to our source filter. - - IQualityControl *pQC = NULL; - IPin *pOutputPin = m_pInputPin->GetConnected(); - ASSERT(pOutputPin != NULL); - - // And get an AddRef'd quality control interface - - hr = pOutputPin->QueryInterface(IID_IQualityControl,(void**) &pQC); - if (SUCCEEDED(hr)) { - m_pQSink = pQC; - } - } - if (m_pQSink) { - return m_pQSink->Notify(this,q); - } - - return S_FALSE; - -} // SendQuality - - -// We are called with a valid IMediaSample image to decide whether this is to -// be drawn or not. There must be a reference clock in operation. -// Return S_OK if it is to be drawn Now (as soon as possible) -// Return S_FALSE if it is to be drawn when it's due -// Return an error if we want to drop it -// m_nNormal=-1 indicates that we dropped the previous frame and so this -// one should be drawn early. Respect it and update it. -// Use current stream time plus a number of heuristics (detailed below) -// to make the decision - -HRESULT CBaseVideoRenderer::ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd) -{ - - // Don't call us unless there's a clock interface to synchronise with - ASSERT(m_pClock); - - MSR_INTEGER(m_idTimeStamp, (int)((*ptrStart)>>32)); // high order 32 bits - MSR_INTEGER(m_idTimeStamp, (int)(*ptrStart)); // low order 32 bits - - // We lose a bit of time depending on the monitor type waiting for the next - // screen refresh. On average this might be about 8mSec - so it will be - // later than we think when the picture appears. To compensate a bit - // we bias the media samples by -8mSec i.e. 80000 UNITs. - // We don't ever make a stream time negative (call it paranoia) - if (*ptrStart>=80000) { - *ptrStart -= 80000; - *ptrEnd -= 80000; // bias stop to to retain valid frame duration - } - - // Cache the time stamp now. We will want to compare what we did with what - // we started with (after making the monitor allowance). - m_trRememberStampForPerf = *ptrStart; - - // Get reference times (current and late) - REFERENCE_TIME trRealStream; // the real time now expressed as stream time. - m_pClock->GetTime(&trRealStream); -#ifdef PERF - // While the reference clock is expensive: - // Remember the offset from timeGetTime and use that. - // This overflows all over the place, but when we subtract to get - // differences the overflows all cancel out. - m_llTimeOffset = trRealStream-timeGetTime()*10000; -#endif - trRealStream -= m_tStart; // convert to stream time (this is a reftime) - - // We have to wory about two versions of "lateness". The truth, which we - // try to work out here and the one measured against m_trTarget which - // includes long term feedback. We report statistics against the truth - // but for operational decisions we work to the target. - // We use TimeDiff to make sure we get an integer because we - // may actually be late (or more likely early if there is a big time - // gap) by a very long time. - const int trTrueLate = TimeDiff(trRealStream - *ptrStart); - const int trLate = trTrueLate; - - MSR_INTEGER(m_idSchLateTime, trTrueLate/10000); - - // Send quality control messages upstream, measured against target - HRESULT hr = SendQuality(trLate, trRealStream); - // Note: the filter upstream is allowed to this FAIL meaning "you do it". - m_bSupplierHandlingQuality = (hr==S_OK); - - // Decision time! Do we drop, draw when ready or draw immediately? - - const int trDuration = (int)(*ptrEnd - *ptrStart); - { - // We need to see if the frame rate of the file has just changed. - // This would make comparing our previous frame rate with the current - // frame rate inefficent. Hang on a moment though. I've seen files - // where the frames vary between 33 and 34 mSec so as to average - // 30fps. A minor variation like that won't hurt us. - int t = m_trDuration/32; - if ( trDuration > m_trDuration+t - || trDuration < m_trDuration-t - ) { - // There's a major variation. Reset the average frame rate to - // exactly the current rate to disable decision 9002 for this frame, - // and remember the new rate. - m_trFrameAvg = trDuration; - m_trDuration = trDuration; - } - } - - MSR_INTEGER(m_idEarliness, m_trEarliness/10000); - MSR_INTEGER(m_idRenderAvg, m_trRenderAvg/10000); - MSR_INTEGER(m_idFrameAvg, m_trFrameAvg/10000); - MSR_INTEGER(m_idWaitAvg, m_trWaitAvg/10000); - MSR_INTEGER(m_idDuration, trDuration/10000); - -#ifdef PERF - if (S_OK==pMediaSample->IsDiscontinuity()) { - MSR_INTEGER(m_idDecision, 9000); - } -#endif - - // Control the graceful slide back from slow to fast machine mode. - // After a frame drop accept an early frame and set the earliness to here - // If this frame is already later than the earliness then slide it to here - // otherwise do the standard slide (reduce by about 12% per frame). - // Note: earliness is normally NEGATIVE - BOOL bJustDroppedFrame - = ( m_bSupplierHandlingQuality - // Can't use the pin sample properties because we might - // not be in Receive when we call this - && (S_OK == pMediaSample->IsDiscontinuity()) // he just dropped one - ) - || (m_nNormal==-1); // we just dropped one - - - // Set m_trEarliness (slide back from slow to fast machine mode) - if (trLate>0) { - m_trEarliness = 0; // we are no longer in fast machine mode at all! - } else if ( (trLate>=m_trEarliness) || bJustDroppedFrame) { - m_trEarliness = trLate; // Things have slipped of their own accord - } else { - m_trEarliness = m_trEarliness - m_trEarliness/8; // graceful slide - } - - // prepare the new wait average - but don't pollute the old one until - // we have finished with it. - int trWaitAvg; - { - // We never mix in a negative wait. This causes us to believe in fast machines - // slightly more. - int trL = trLate<0 ? -trLate : 0; - trWaitAvg = (trL + m_trWaitAvg*(AVGPERIOD-1))/AVGPERIOD; - } - - - int trFrame; - { - REFERENCE_TIME tr = trRealStream - m_trLastDraw; // Cd be large - 4 min pause! - if (tr>10000000) { - tr = 10000000; // 1 second - arbitrarily. - } - trFrame = int(tr); - } - - // We will DRAW this frame IF... - if ( - // ...the time we are spending drawing is a small fraction of the total - // observed inter-frame time so that dropping it won't help much. - (3*m_trRenderAvg <= m_trFrameAvg) - - // ...or our supplier is NOT handling things and the next frame would - // be less timely than this one or our supplier CLAIMS to be handling - // things, and is now less than a full FOUR frames late. - || ( m_bSupplierHandlingQuality - ? (trLate <= trDuration*4) - : (trLate+trLate < trDuration) - ) - - // ...or we are on average waiting for over eight milliseconds then - // this may be just a glitch. Draw it and we'll hope to catch up. - || (m_trWaitAvg > 80000) - - // ...or we haven't drawn an image for over a second. We will update - // the display, which stops the video looking hung. - // Do this regardless of how late this media sample is. - || ((trRealStream - m_trLastDraw) > UNITS) - - ) { - HRESULT Result; - - // We are going to play this frame. We may want to play it early. - // We will play it early if we think we are in slow machine mode. - // If we think we are NOT in slow machine mode, we will still play - // it early by m_trEarliness as this controls the graceful slide back. - // and in addition we aim at being m_trTarget late rather than "on time". - - BOOL bPlayASAP = FALSE; - - // we will play it AT ONCE (slow machine mode) if... - - // ...we are playing catch-up - if ( bJustDroppedFrame) { - bPlayASAP = TRUE; - MSR_INTEGER(m_idDecision, 9001); - } - - // ...or if we are running below the true frame rate - // exact comparisons are glitchy, for these measurements, - // so add an extra 5% or so - else if ( (m_trFrameAvg > trDuration + trDuration/16) - - // It's possible to get into a state where we are losing ground, but - // are a very long way ahead. To avoid this or recover from it - // we refuse to play early by more than 10 frames. - && (trLate > - trDuration*10) - ){ - bPlayASAP = TRUE; - MSR_INTEGER(m_idDecision, 9002); - } -#if 0 - // ...or if we have been late and are less than one frame early - else if ( (trLate + trDuration > 0) - && (m_trWaitAvg<=20000) - ) { - bPlayASAP = TRUE; - MSR_INTEGER(m_idDecision, 9003); - } -#endif - // We will NOT play it at once if we are grossly early. On very slow frame - // rate movies - e.g. clock.avi - it is not a good idea to leap ahead just - // because we got starved (for instance by the net) and dropped one frame - // some time or other. If we are more than 900mSec early, then wait. - if (trLate<-9000000) { - bPlayASAP = FALSE; - } - - if (bPlayASAP) { - - m_nNormal = 0; - MSR_INTEGER(m_idDecision, 0); - // When we are here, we are in slow-machine mode. trLate may well - // oscillate between negative and positive when the supplier is - // dropping frames to keep sync. We should not let that mislead - // us into thinking that we have as much as zero spare time! - // We just update with a zero wait. - m_trWaitAvg = (m_trWaitAvg*(AVGPERIOD-1))/AVGPERIOD; - - // Assume that we draw it immediately. Update inter-frame stats - m_trFrameAvg = (trFrame + m_trFrameAvg*(AVGPERIOD-1))/AVGPERIOD; -#ifndef PERF - // If this is NOT a perf build, then report what we know so far - // without looking at the clock any more. This assumes that we - // actually wait for exactly the time we hope to. It also reports - // how close we get to the manipulated time stamps that we now have - // rather than the ones we originally started with. It will - // therefore be a little optimistic. However it's fast. - PreparePerformanceData(trTrueLate, trFrame); -#endif - m_trLastDraw = trRealStream; - if (m_trEarliness > trLate) { - m_trEarliness = trLate; // if we are actually early, this is neg - } - Result = S_OK; // Draw it now - - } else { - ++m_nNormal; - // Set the average frame rate to EXACTLY the ideal rate. - // If we are exiting slow-machine mode then we will have caught up - // and be running ahead, so as we slide back to exact timing we will - // have a longer than usual gap at this point. If we record this - // real gap then we'll think that we're running slow and go back - // into slow-machine mode and vever get it straight. - m_trFrameAvg = trDuration; - MSR_INTEGER(m_idDecision, 1); - - // Play it early by m_trEarliness and by m_trTarget - - { - int trE = m_trEarliness; - if (trE < -m_trFrameAvg) { - trE = -m_trFrameAvg; - } - *ptrStart += trE; // N.B. earliness is negative - } - - int Delay = -trTrueLate; - Result = Delay<=0 ? S_OK : S_FALSE; // OK = draw now, FALSE = wait - - m_trWaitAvg = trWaitAvg; - - // Predict when it will actually be drawn and update frame stats - - if (Result==S_FALSE) { // We are going to wait - trFrame = TimeDiff(*ptrStart-m_trLastDraw); - m_trLastDraw = *ptrStart; - } else { - // trFrame is already = trRealStream-m_trLastDraw; - m_trLastDraw = trRealStream; - } -#ifndef PERF - int iAccuracy; - if (Delay>0) { - // Report lateness based on when we intend to play it - iAccuracy = TimeDiff(*ptrStart-m_trRememberStampForPerf); - } else { - // Report lateness based on playing it *now*. - iAccuracy = trTrueLate; // trRealStream-RememberStampForPerf; - } - PreparePerformanceData(iAccuracy, trFrame); -#endif - } - return Result; - } - - // We are going to drop this frame! - // Of course in DirectDraw mode the guy upstream may draw it anyway. - - // This will probably give a large negative wack to the wait avg. - m_trWaitAvg = trWaitAvg; - -#ifdef PERF - // Respect registry setting - debug only! - if (m_bDrawLateFrames) { - return S_OK; // draw it when it's ready - } // even though it's late. -#endif - - // We are going to drop this frame so draw the next one early - // n.b. if the supplier is doing direct draw then he may draw it anyway - // but he's doing something funny to arrive here in that case. - - MSR_INTEGER(m_idDecision, 2); - m_nNormal = -1; - return E_FAIL; // drop it - -} // ShouldDrawSampleNow - - -// NOTE we're called by both the window thread and the source filter thread -// so we have to be protected by a critical section (locked before called) -// Also, when the window thread gets signalled to render an image, it always -// does so regardless of how late it is. All the degradation is done when we -// are scheduling the next sample to be drawn. Hence when we start an advise -// link to draw a sample, that sample's time will always become the last one -// drawn - unless of course we stop streaming in which case we cancel links - -BOOL CBaseVideoRenderer::ScheduleSample(IMediaSample *pMediaSample) -{ - // We override ShouldDrawSampleNow to add quality management - - BOOL bDrawImage = CBaseRenderer::ScheduleSample(pMediaSample); - if (bDrawImage == FALSE) { - ++m_cFramesDropped; - return FALSE; - } - - // m_cFramesDrawn must NOT be updated here. It has to be updated - // in RecordFrameLateness at the same time as the other statistics. - return TRUE; -} - - -// Implementation of IQualProp interface needed to support the property page -// This is how the property page gets the data out of the scheduler. We are -// passed into the constructor the owning object in the COM sense, this will -// either be the video renderer or an external IUnknown if we're aggregated. -// We initialise our CUnknown base class with this interface pointer. Then -// all we have to do is to override NonDelegatingQueryInterface to expose -// our IQualProp interface. The AddRef and Release are handled automatically -// by the base class and will be passed on to the appropriate outer object - -STDMETHODIMP CBaseVideoRenderer::get_FramesDroppedInRenderer(int *pcFramesDropped) -{ - CheckPointer(pcFramesDropped,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - *pcFramesDropped = m_cFramesDropped; - return NOERROR; -} // get_FramesDroppedInRenderer - - -// Set *pcFramesDrawn to the number of frames drawn since -// streaming started. - -STDMETHODIMP CBaseVideoRenderer::get_FramesDrawn( int *pcFramesDrawn) -{ - CheckPointer(pcFramesDrawn,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - *pcFramesDrawn = m_cFramesDrawn; - return NOERROR; -} // get_FramesDrawn - - -// Set iAvgFrameRate to the frames per hundred secs since -// streaming started. 0 otherwise. - -STDMETHODIMP CBaseVideoRenderer::get_AvgFrameRate( int *piAvgFrameRate) -{ - CheckPointer(piAvgFrameRate,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - - int t; - if (m_bStreaming) { - t = timeGetTime()-m_tStreamingStart; - } else { - t = m_tStreamingStart; - } - - if (t<=0) { - *piAvgFrameRate = 0; - ASSERT(m_cFramesDrawn == 0); - } else { - // i is frames per hundred seconds - *piAvgFrameRate = MulDiv(100000, m_cFramesDrawn, t); - } - return NOERROR; -} // get_AvgFrameRate - - -// Set *piAvg to the average sync offset since streaming started -// in mSec. The sync offset is the time in mSec between when the frame -// should have been drawn and when the frame was actually drawn. - -STDMETHODIMP CBaseVideoRenderer::get_AvgSyncOffset( int *piAvg) -{ - CheckPointer(piAvg,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - - if (NULL==m_pClock) { - *piAvg = 0; - return NOERROR; - } - - // Note that we didn't gather the stats on the first frame - // so we use m_cFramesDrawn-1 here - if (m_cFramesDrawn<=1) { - *piAvg = 0; - } else { - *piAvg = (int)(m_iTotAcc / (m_cFramesDrawn-1)); - } - return NOERROR; -} // get_AvgSyncOffset - - -// To avoid dragging in the maths library - a cheap -// approximate integer square root. -// We do this by getting a starting guess which is between 1 -// and 2 times too large, followed by THREE iterations of -// Newton Raphson. (That will give accuracy to the nearest mSec -// for the range in question - roughly 0..1000) -// -// It would be faster to use a linear interpolation and ONE NR, but -// who cares. If anyone does - the best linear interpolation is -// to approximates sqrt(x) by -// y = x * (sqrt(2)-1) + 1 - 1/sqrt(2) + 1/(8*(sqrt(2)-1)) -// 0r y = x*0.41421 + 0.59467 -// This minimises the maximal error in the range in question. -// (error is about +0.008883 and then one NR will give error .0000something -// (Of course these are integers, so you can't just multiply by 0.41421 -// you'd have to do some sort of MulDiv). -// Anyone wanna check my maths? (This is only for a property display!) - -int isqrt(int x) -{ - int s = 1; - // Make s an initial guess for sqrt(x) - if (x > 0x40000000) { - s = 0x8000; // prevent any conceivable closed loop - } else { - while (s*s=0) s = (s*s+x)/(2*s); - if (s>=0) s = (s*s+x)/(2*s); - } - } - return s; -} - -// -// Do estimates for standard deviations for per-frame -// statistics -// -HRESULT CBaseVideoRenderer::GetStdDev( - int nSamples, - int *piResult, - LONGLONG llSumSq, - LONGLONG iTot -) -{ - CheckPointer(piResult,E_POINTER); - CAutoLock cVideoLock(&m_InterfaceLock); - - if (NULL==m_pClock) { - *piResult = 0; - return NOERROR; - } - - // If S is the Sum of the Squares of observations and - // T the Total (i.e. sum) of the observations and there were - // N observations, then an estimate of the standard deviation is - // sqrt( (S - T**2/N) / (N-1) ) - - if (nSamples<=1) { - *piResult = 0; - } else { - LONGLONG x; - // First frames have invalid stamps, so we get no stats for them - // So we need 2 frames to get 1 datum, so N is cFramesDrawn-1 - - // so we use m_cFramesDrawn-1 here - x = llSumSq - llMulDiv(iTot, iTot, nSamples, 0); - x = x / (nSamples-1); - ASSERT(x>=0); - *piResult = isqrt((LONG)x); - } - return NOERROR; -} - -// Set *piDev to the standard deviation in mSec of the sync offset -// of each frame since streaming started. - -STDMETHODIMP CBaseVideoRenderer::get_DevSyncOffset( int *piDev) -{ - // First frames have invalid stamps, so we get no stats for them - // So we need 2 frames to get 1 datum, so N is cFramesDrawn-1 - return GetStdDev(m_cFramesDrawn - 1, - piDev, - m_iSumSqAcc, - m_iTotAcc); -} // get_DevSyncOffset - - -// Set *piJitter to the standard deviation in mSec of the inter-frame time -// of frames since streaming started. - -STDMETHODIMP CBaseVideoRenderer::get_Jitter( int *piJitter) -{ - // First frames have invalid stamps, so we get no stats for them - // So second frame gives invalid inter-frame time - // So we need 3 frames to get 1 datum, so N is cFramesDrawn-2 - return GetStdDev(m_cFramesDrawn - 2, - piJitter, - m_iSumSqFrameTime, - m_iSumFrameTime); -} // get_Jitter - - -// Overidden to return our IQualProp interface - -STDMETHODIMP -CBaseVideoRenderer::NonDelegatingQueryInterface(REFIID riid,VOID **ppv) -{ - // We return IQualProp and delegate everything else - - if (riid == IID_IQualProp) { - return GetInterface( (IQualProp *)this, ppv); - } else if (riid == IID_IQualityControl) { - return GetInterface( (IQualityControl *)this, ppv); - } - return CBaseRenderer::NonDelegatingQueryInterface(riid,ppv); -} - - -// Override JoinFilterGraph so that, just before leaving -// the graph we can send an EC_WINDOW_DESTROYED event - -STDMETHODIMP -CBaseVideoRenderer::JoinFilterGraph(IFilterGraph *pGraph,LPCWSTR pName) -{ - // Since we send EC_ACTIVATE, we also need to ensure - // we send EC_WINDOW_DESTROYED or the resource manager may be - // holding us as a focus object - if (!pGraph && m_pGraph) { - - // We were in a graph and now we're not - // Do this properly in case we are aggregated - IBaseFilter* pFilter; - QueryInterface(IID_IBaseFilter,(void **) &pFilter); - NotifyEvent(EC_WINDOW_DESTROYED, (LPARAM) pFilter, 0); - pFilter->Release(); - } - return CBaseFilter::JoinFilterGraph(pGraph, pName); -} - - -// This removes a large number of level 4 warnings from the -// Microsoft compiler which in this case are not very useful -#pragma warning(disable: 4514) - diff --git a/plugins/gs/gsdx9/baseclasses/renbase.h b/plugins/gs/gsdx9/baseclasses/renbase.h deleted file mode 100644 index f30a3fad19..0000000000 --- a/plugins/gs/gsdx9/baseclasses/renbase.h +++ /dev/null @@ -1,478 +0,0 @@ -//------------------------------------------------------------------------------ -// File: RenBase.h -// -// Desc: DirectShow base classes - defines a generic ActiveX base renderer -// class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __RENBASE__ -#define __RENBASE__ - -// Forward class declarations - -class CBaseRenderer; -class CBaseVideoRenderer; -class CRendererInputPin; - -// This is our input pin class that channels calls to the renderer - -class CRendererInputPin : public CBaseInputPin -{ -protected: - - CBaseRenderer *m_pRenderer; - -public: - - CRendererInputPin(CBaseRenderer *pRenderer, - HRESULT *phr, - LPCWSTR Name); - - // Overriden from the base pin classes - - HRESULT BreakConnect(); - HRESULT CompleteConnect(IPin *pReceivePin); - HRESULT SetMediaType(const CMediaType *pmt); - HRESULT CheckMediaType(const CMediaType *pmt); - HRESULT Active(); - HRESULT Inactive(); - - // Add rendering behaviour to interface functions - - STDMETHODIMP QueryId(LPWSTR *Id); - STDMETHODIMP EndOfStream(); - STDMETHODIMP BeginFlush(); - STDMETHODIMP EndFlush(); - STDMETHODIMP Receive(IMediaSample *pMediaSample); - - // Helper - IMemAllocator inline *Allocator() const - { - return m_pAllocator; - } -}; - -// Main renderer class that handles synchronisation and state changes - -class CBaseRenderer : public CBaseFilter -{ -protected: - - friend class CRendererInputPin; - - friend void CALLBACK EndOfStreamTimer(UINT uID, // Timer identifier - UINT uMsg, // Not currently used - DWORD_PTR dwUser, // User information - DWORD_PTR dw1, // Windows reserved - DWORD_PTR dw2); // Is also reserved - - CRendererPosPassThru *m_pPosition; // Media seeking pass by object - CAMEvent m_RenderEvent; // Used to signal timer events - CAMEvent m_ThreadSignal; // Signalled to release worker thread - CAMEvent m_evComplete; // Signalled when state complete - BOOL m_bAbort; // Stop us from rendering more data - BOOL m_bStreaming; // Are we currently streaming - DWORD_PTR m_dwAdvise; // Timer advise cookie - IMediaSample *m_pMediaSample; // Current image media sample - BOOL m_bEOS; // Any more samples in the stream - BOOL m_bEOSDelivered; // Have we delivered an EC_COMPLETE - CRendererInputPin *m_pInputPin; // Our renderer input pin object - CCritSec m_InterfaceLock; // Critical section for interfaces - CCritSec m_RendererLock; // Controls access to internals - IQualityControl * m_pQSink; // QualityControl sink - BOOL m_bRepaintStatus; // Can we signal an EC_REPAINT - // Avoid some deadlocks by tracking filter during stop - volatile BOOL m_bInReceive; // Inside Receive between PrepareReceive - // And actually processing the sample - REFERENCE_TIME m_SignalTime; // Time when we signal EC_COMPLETE - UINT m_EndOfStreamTimer; // Used to signal end of stream - CCritSec m_ObjectCreationLock; // This lock protects the creation and - // of m_pPosition and m_pInputPin. It - // ensures that two threads cannot create - // either object simultaneously. - -public: - - CBaseRenderer(REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr); // General OLE return code - - ~CBaseRenderer(); - - // Overriden to say what interfaces we support and where - - virtual HRESULT GetMediaPositionInterface(REFIID riid,void **ppv); - STDMETHODIMP NonDelegatingQueryInterface(REFIID, void **); - - virtual HRESULT SourceThreadCanWait(BOOL bCanWait); - -#ifdef DEBUG - // Debug only dump of the renderer state - void DisplayRendererState(); -#endif - virtual HRESULT WaitForRenderTime(); - virtual HRESULT CompleteStateChange(FILTER_STATE OldState); - - // Return internal information about this filter - - BOOL IsEndOfStream() { return m_bEOS; }; - BOOL IsEndOfStreamDelivered() { return m_bEOSDelivered; }; - BOOL IsStreaming() { return m_bStreaming; }; - void SetAbortSignal(BOOL bAbort) { m_bAbort = bAbort; }; - virtual void OnReceiveFirstSample(IMediaSample *pMediaSample) { }; - CAMEvent *GetRenderEvent() { return &m_RenderEvent; }; - - // Permit access to the transition state - - void Ready() { m_evComplete.Set(); }; - void NotReady() { m_evComplete.Reset(); }; - BOOL CheckReady() { return m_evComplete.Check(); }; - - virtual int GetPinCount(); - virtual CBasePin *GetPin(int n); - FILTER_STATE GetRealState(); - void SendRepaint(); - void SendNotifyWindow(IPin *pPin,HWND hwnd); - BOOL OnDisplayChange(); - void SetRepaintStatus(BOOL bRepaint); - - // Override the filter and pin interface functions - - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - STDMETHODIMP Run(REFERENCE_TIME StartTime); - STDMETHODIMP GetState(DWORD dwMSecs,FILTER_STATE *State); - STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin); - - // These are available for a quality management implementation - - virtual void OnRenderStart(IMediaSample *pMediaSample); - virtual void OnRenderEnd(IMediaSample *pMediaSample); - virtual HRESULT OnStartStreaming() { return NOERROR; }; - virtual HRESULT OnStopStreaming() { return NOERROR; }; - virtual void OnWaitStart() { }; - virtual void OnWaitEnd() { }; - virtual void PrepareRender() { }; - -#ifdef PERF - REFERENCE_TIME m_trRenderStart; // Just before we started drawing - // Set in OnRenderStart, Used in OnRenderEnd - int m_idBaseStamp; // MSR_id for frame time stamp - int m_idBaseRenderTime; // MSR_id for true wait time - int m_idBaseAccuracy; // MSR_id for time frame is late (int) -#endif - - // Quality management implementation for scheduling rendering - - virtual BOOL ScheduleSample(IMediaSample *pMediaSample); - virtual HRESULT GetSampleTimes(IMediaSample *pMediaSample, - REFERENCE_TIME *pStartTime, - REFERENCE_TIME *pEndTime); - - virtual HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd); - - // Lots of end of stream complexities - - void TimerCallback(); - void ResetEndOfStreamTimer(); - HRESULT NotifyEndOfStream(); - virtual HRESULT SendEndOfStream(); - virtual HRESULT ResetEndOfStream(); - virtual HRESULT EndOfStream(); - - // Rendering is based around the clock - - void SignalTimerFired(); - virtual HRESULT CancelNotification(); - virtual HRESULT ClearPendingSample(); - - // Called when the filter changes state - - virtual HRESULT Active(); - virtual HRESULT Inactive(); - virtual HRESULT StartStreaming(); - virtual HRESULT StopStreaming(); - virtual HRESULT BeginFlush(); - virtual HRESULT EndFlush(); - - // Deal with connections and type changes - - virtual HRESULT BreakConnect(); - virtual HRESULT SetMediaType(const CMediaType *pmt); - virtual HRESULT CompleteConnect(IPin *pReceivePin); - - // These look after the handling of data samples - - virtual HRESULT PrepareReceive(IMediaSample *pMediaSample); - virtual HRESULT Receive(IMediaSample *pMediaSample); - virtual BOOL HaveCurrentSample(); - virtual IMediaSample *GetCurrentSample(); - virtual HRESULT Render(IMediaSample *pMediaSample); - - // Derived classes MUST override these - virtual HRESULT DoRenderSample(IMediaSample *pMediaSample) PURE; - virtual HRESULT CheckMediaType(const CMediaType *) PURE; - - // Helper - void WaitForReceiveToComplete(); -}; - - -// CBaseVideoRenderer is a renderer class (see its ancestor class) and -// it handles scheduling of media samples so that they are drawn at the -// correct time by the reference clock. It implements a degradation -// strategy. Possible degradation modes are: -// Drop frames here (only useful if the drawing takes significant time) -// Signal supplier (upstream) to drop some frame(s) - i.e. one-off skip. -// Signal supplier to change the frame rate - i.e. ongoing skipping. -// Or any combination of the above. -// In order to determine what's useful to try we need to know what's going -// on. This is done by timing various operations (including the supplier). -// This timing is done by using timeGetTime as it is accurate enough and -// usually cheaper than calling the reference clock. It also tells the -// truth if there is an audio break and the reference clock stops. -// We provide a number of public entry points (named OnXxxStart, OnXxxEnd) -// which the rest of the renderer calls at significant moments. These do -// the timing. - -// the number of frames that the sliding averages are averaged over. -// the rule is (1024*NewObservation + (AVGPERIOD-1) * PreviousAverage)/AVGPERIOD -#define AVGPERIOD 4 -#define DO_MOVING_AVG(avg,obs) (avg = (1024*obs + (AVGPERIOD-1)*avg)/AVGPERIOD) -// Spot the bug in this macro - I can't. but it doesn't work! - -class CBaseVideoRenderer : public CBaseRenderer, // Base renderer class - public IQualProp, // Property page guff - public IQualityControl // Allow throttling -{ -protected: - - // Hungarian: - // tFoo is the time Foo in mSec (beware m_tStart from filter.h) - // trBar is the time Bar by the reference clock - - //****************************************************************** - // State variables to control synchronisation - //****************************************************************** - - // Control of sending Quality messages. We need to know whether - // we are in trouble (e.g. frames being dropped) and where the time - // is being spent. - - // When we drop a frame we play the next one early. - // The frame after that is likely to wait before drawing and counting this - // wait as spare time is unfair, so we count it as a zero wait. - // We therefore need to know whether we are playing frames early or not. - - int m_nNormal; // The number of consecutive frames - // drawn at their normal time (not early) - // -1 means we just dropped a frame. - -#ifdef PERF - BOOL m_bDrawLateFrames; // Don't drop any frames (debug and I'm - // not keen on people using it!) -#endif - - BOOL m_bSupplierHandlingQuality;// The response to Quality messages says - // our supplier is handling things. - // We will allow things to go extra late - // before dropping frames. We will play - // very early after he has dropped one. - - // Control of scheduling, frame dropping etc. - // We need to know where the time is being spent so as to tell whether - // we should be taking action here, signalling supplier or what. - // The variables are initialised to a mode of NOT dropping frames. - // They will tell the truth after a few frames. - // We typically record a start time for an event, later we get the time - // again and subtract to get the elapsed time, and we average this over - // a few frames. The average is used to tell what mode we are in. - - // Although these are reference times (64 bit) they are all DIFFERENCES - // between times which are small. An int will go up to 214 secs before - // overflow. Avoiding 64 bit multiplications and divisions seems - // worth while. - - - - // Audio-video throttling. If the user has turned up audio quality - // very high (in principle it could be any other stream, not just audio) - // then we can receive cries for help via the graph manager. In this case - // we put in a wait for some time after rendering each frame. - int m_trThrottle; - - // The time taken to render (i.e. BitBlt) frames controls which component - // needs to degrade. If the blt is expensive, the renderer degrades. - // If the blt is cheap it's done anyway and the supplier degrades. - int m_trRenderAvg; // Time frames are taking to blt - int m_trRenderLast; // Time for last frame blt - int m_tRenderStart; // Just before we started drawing (mSec) - // derived from timeGetTime. - - // When frames are dropped we will play the next frame as early as we can. - // If it was a false alarm and the machine is fast we slide gently back to - // normal timing. To do this, we record the offset showing just how early - // we really are. This will normally be negative meaning early or zero. - int m_trEarliness; - - // Target provides slow long-term feedback to try to reduce the - // average sync offset to zero. Whenever a frame is actually rendered - // early we add a msec or two, whenever late we take off a few. - // We add or take off 1/32 of the error time. - // Eventually we should be hovering around zero. For a really bad case - // where we were (say) 300mSec off, it might take 100 odd frames to - // settle down. The rate of change of this is intended to be slower - // than any other mechanism in Quartz, thereby avoiding hunting. - int m_trTarget; - - // The proportion of time spent waiting for the right moment to blt - // controls whether we bother to drop a frame or whether we reckon that - // we're doing well enough that we can stand a one-frame glitch. - int m_trWaitAvg; // Average of last few wait times - // (actually we just average how early - // we were). Negative here means LATE. - - // The average inter-frame time. - // This is used to calculate the proportion of the time used by the - // three operations (supplying us, waiting, rendering) - int m_trFrameAvg; // Average inter-frame time - int m_trDuration; // duration of last frame. - -#ifdef PERF - // Performance logging identifiers - int m_idTimeStamp; // MSR_id for frame time stamp - int m_idEarliness; // MSR_id for earliness fudge - int m_idTarget; // MSR_id for Target fudge - int m_idWaitReal; // MSR_id for true wait time - int m_idWait; // MSR_id for wait time recorded - int m_idFrameAccuracy; // MSR_id for time frame is late (int) - int m_idRenderAvg; // MSR_id for Render time recorded (int) - int m_idSchLateTime; // MSR_id for lateness at scheduler - int m_idQualityRate; // MSR_id for Quality rate requested - int m_idQualityTime; // MSR_id for Quality time requested - int m_idDecision; // MSR_id for decision code - int m_idDuration; // MSR_id for duration of a frame - int m_idThrottle; // MSR_id for audio-video throttling - //int m_idDebug; // MSR_id for trace style debugging - //int m_idSendQuality; // MSR_id for timing the notifications per se -#endif // PERF - REFERENCE_TIME m_trRememberStampForPerf; // original time stamp of frame - // with no earliness fudges etc. -#ifdef PERF - REFERENCE_TIME m_trRememberFrameForPerf; // time when previous frame rendered - - // debug... - int m_idFrameAvg; - int m_idWaitAvg; -#endif - - // PROPERTY PAGE - // This has edit fields that show the user what's happening - // These member variables hold these counts. - - int m_cFramesDropped; // cumulative frames dropped IN THE RENDERER - int m_cFramesDrawn; // Frames since streaming started seen BY THE - // RENDERER (some may be dropped upstream) - - // Next two support average sync offset and standard deviation of sync offset. - LONGLONG m_iTotAcc; // Sum of accuracies in mSec - LONGLONG m_iSumSqAcc; // Sum of squares of (accuracies in mSec) - - // Next two allow jitter calculation. Jitter is std deviation of frame time. - REFERENCE_TIME m_trLastDraw; // Time of prev frame (for inter-frame times) - LONGLONG m_iSumSqFrameTime; // Sum of squares of (inter-frame time in mSec) - LONGLONG m_iSumFrameTime; // Sum of inter-frame times in mSec - - // To get performance statistics on frame rate, jitter etc, we need - // to record the lateness and inter-frame time. What we actually need are the - // data above (sum, sum of squares and number of entries for each) but the data - // is generated just ahead of time and only later do we discover whether the - // frame was actually drawn or not. So we have to hang on to the data - int m_trLate; // hold onto frame lateness - int m_trFrame; // hold onto inter-frame time - - int m_tStreamingStart; // if streaming then time streaming started - // else time of last streaming session - // used for property page statistics -#ifdef PERF - LONGLONG m_llTimeOffset; // timeGetTime()*10000+m_llTimeOffset==ref time -#endif - -public: - - - CBaseVideoRenderer(REFCLSID RenderClass, // CLSID for this renderer - TCHAR *pName, // Debug ONLY description - LPUNKNOWN pUnk, // Aggregated owner object - HRESULT *phr); // General OLE return code - - ~CBaseVideoRenderer(); - - // IQualityControl methods - Notify allows audio-video throttling - - STDMETHODIMP SetSink( IQualityControl * piqc); - STDMETHODIMP Notify( IBaseFilter * pSelf, Quality q); - - // These provide a full video quality management implementation - - void OnRenderStart(IMediaSample *pMediaSample); - void OnRenderEnd(IMediaSample *pMediaSample); - void OnWaitStart(); - void OnWaitEnd(); - HRESULT OnStartStreaming(); - HRESULT OnStopStreaming(); - void ThrottleWait(); - - // Handle the statistics gathering for our quality management - - void PreparePerformanceData(int trLate, int trFrame); - virtual void RecordFrameLateness(int trLate, int trFrame); - virtual void OnDirectRender(IMediaSample *pMediaSample); - virtual HRESULT ResetStreamingTimes(); - BOOL ScheduleSample(IMediaSample *pMediaSample); - HRESULT ShouldDrawSampleNow(IMediaSample *pMediaSample, - REFERENCE_TIME *ptrStart, - REFERENCE_TIME *ptrEnd); - - virtual HRESULT SendQuality(REFERENCE_TIME trLate, REFERENCE_TIME trRealStream); - STDMETHODIMP JoinFilterGraph(IFilterGraph * pGraph, LPCWSTR pName); - - // - // Do estimates for standard deviations for per-frame - // statistics - // - // *piResult = (llSumSq - iTot * iTot / m_cFramesDrawn - 1) / - // (m_cFramesDrawn - 2) - // or 0 if m_cFramesDrawn <= 3 - // - HRESULT GetStdDev( - int nSamples, - int *piResult, - LONGLONG llSumSq, - LONGLONG iTot - ); -public: - - // IQualProp property page support - - STDMETHODIMP get_FramesDroppedInRenderer(int *cFramesDropped); - STDMETHODIMP get_FramesDrawn(int *pcFramesDrawn); - STDMETHODIMP get_AvgFrameRate(int *piAvgFrameRate); - STDMETHODIMP get_Jitter(int *piJitter); - STDMETHODIMP get_AvgSyncOffset(int *piAvg); - STDMETHODIMP get_DevSyncOffset(int *piDev); - - // Implement an IUnknown interface and expose IQualProp - - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,VOID **ppv); -}; - -#endif // __RENBASE__ - diff --git a/plugins/gs/gsdx9/baseclasses/schedule.cpp b/plugins/gs/gsdx9/baseclasses/schedule.cpp deleted file mode 100644 index b4d5658b45..0000000000 --- a/plugins/gs/gsdx9/baseclasses/schedule.cpp +++ /dev/null @@ -1,284 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Schedule.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -// DbgLog values (all on LOG_TIMING): -// -// 2 for schedulting, firing and shunting of events -// 3 for wait delays and wake-up times of event thread -// 4 for details of whats on the list when the thread awakes - -/* Construct & destructors */ - -CAMSchedule::CAMSchedule( HANDLE ev ) -: CBaseObject(TEXT("CAMSchedule")) -, head(&z, 0), z(0, MAX_TIME) -, m_dwNextCookie(0), m_dwAdviseCount(0) -, m_pAdviseCache(0), m_dwCacheCount(0) -, m_ev( ev ) -{ - head.m_dwAdviseCookie = z.m_dwAdviseCookie = 0; -} - -CAMSchedule::~CAMSchedule() -{ - m_Serialize.Lock(); - - // Delete cache - CAdvisePacket * p = m_pAdviseCache; - while (p) - { - CAdvisePacket *const p_next = p->m_next; - delete p; - p = p_next; - } - - ASSERT( m_dwAdviseCount == 0 ); - // Better to be safe than sorry - if ( m_dwAdviseCount > 0 ) - { - DumpLinkedList(); - while ( !head.m_next->IsZ() ) - { - head.DeleteNext(); - --m_dwAdviseCount; - } - } - - // If, in the debug version, we assert twice, it means, not only - // did we have left over advises, but we have also let m_dwAdviseCount - // get out of sync. with the number of advises actually on the list. - ASSERT( m_dwAdviseCount == 0 ); - - m_Serialize.Unlock(); -} - -/* Public methods */ - -DWORD CAMSchedule::GetAdviseCount() -{ - // No need to lock, m_dwAdviseCount is 32bits & declared volatile - return m_dwAdviseCount; -} - -REFERENCE_TIME CAMSchedule::GetNextAdviseTime() -{ - CAutoLock lck(&m_Serialize); // Need to stop the linked list from changing - return head.m_next->m_rtEventTime; -} - -DWORD_PTR CAMSchedule::AddAdvisePacket -( const REFERENCE_TIME & time1 -, const REFERENCE_TIME & time2 -, HANDLE h, BOOL periodic -) -{ - // Since we use MAX_TIME as a sentry, we can't afford to - // schedule a notification at MAX_TIME - ASSERT( time1 < MAX_TIME ); - DWORD_PTR Result; - CAdvisePacket * p; - - m_Serialize.Lock(); - - if (m_pAdviseCache) - { - p = m_pAdviseCache; - m_pAdviseCache = p->m_next; - --m_dwCacheCount; - } - else - { - p = new CAdvisePacket(); - } - if (p) - { - p->m_rtEventTime = time1; p->m_rtPeriod = time2; - p->m_hNotify = h; p->m_bPeriodic = periodic; - Result = AddAdvisePacket( p ); - } - else Result = 0; - - m_Serialize.Unlock(); - - return Result; -} - -HRESULT CAMSchedule::Unadvise(DWORD_PTR dwAdviseCookie) -{ - HRESULT hr = S_FALSE; - CAdvisePacket * p_prev = &head; - CAdvisePacket * p_n; - m_Serialize.Lock(); - while ( p_n = p_prev->Next() ) // The Next() method returns NULL when it hits z - { - if ( p_n->m_dwAdviseCookie == dwAdviseCookie ) - { - Delete( p_prev->RemoveNext() ); - --m_dwAdviseCount; - hr = S_OK; - // Having found one cookie that matches, there should be no more - #ifdef DEBUG - while (p_n = p_prev->Next()) - { - ASSERT(p_n->m_dwAdviseCookie != dwAdviseCookie); - p_prev = p_n; - } - #endif - break; - } - p_prev = p_n; - }; - m_Serialize.Unlock(); - return hr; -} - -REFERENCE_TIME CAMSchedule::Advise( const REFERENCE_TIME & rtTime ) -{ - REFERENCE_TIME rtNextTime; - CAdvisePacket * pAdvise; - - DbgLog((LOG_TIMING, 2, - TEXT("CAMSchedule::Advise( %lu ms )"), ULONG(rtTime / (UNITS / MILLISECONDS)))); - - CAutoLock lck(&m_Serialize); - - #ifdef DEBUG - if (DbgCheckModuleLevel(LOG_TIMING, 4)) DumpLinkedList(); - #endif - - // Note - DON'T cache the difference, it might overflow - while ( rtTime >= (rtNextTime = (pAdvise=head.m_next)->m_rtEventTime) && - !pAdvise->IsZ() ) - { - ASSERT(pAdvise->m_dwAdviseCookie); // If this is zero, its the head or the tail!! - - ASSERT(pAdvise->m_hNotify != INVALID_HANDLE_VALUE); - - if (pAdvise->m_bPeriodic == TRUE) - { - ReleaseSemaphore(pAdvise->m_hNotify,1,NULL); - pAdvise->m_rtEventTime += pAdvise->m_rtPeriod; - ShuntHead(); - } - else - { - ASSERT( pAdvise->m_bPeriodic == FALSE ); - EXECUTE_ASSERT(SetEvent(pAdvise->m_hNotify)); - --m_dwAdviseCount; - Delete( head.RemoveNext() ); - } - - } - - DbgLog((LOG_TIMING, 3, - TEXT("CAMSchedule::Advise() Next time stamp: %lu ms, for advise %lu."), - DWORD(rtNextTime / (UNITS / MILLISECONDS)), pAdvise->m_dwAdviseCookie )); - - return rtNextTime; -} - -/* Private methods */ - -DWORD_PTR CAMSchedule::AddAdvisePacket( CAdvisePacket * pPacket ) -{ - ASSERT(pPacket->m_rtEventTime >= 0 && pPacket->m_rtEventTime < MAX_TIME); - ASSERT(CritCheckIn(&m_Serialize)); - - CAdvisePacket * p_prev = &head; - CAdvisePacket * p_n; - - const DWORD_PTR Result = pPacket->m_dwAdviseCookie = ++m_dwNextCookie; - // This relies on the fact that z is a sentry with a maximal m_rtEventTime - for(;;p_prev = p_n) - { - p_n = p_prev->m_next; - if ( p_n->m_rtEventTime >= pPacket->m_rtEventTime ) break; - } - p_prev->InsertAfter( pPacket ); - ++m_dwAdviseCount; - - DbgLog((LOG_TIMING, 2, TEXT("Added advise %lu, for thread 0x%02X, scheduled at %lu"), - pPacket->m_dwAdviseCookie, GetCurrentThreadId(), (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) )); - - // If packet added at the head, then clock needs to re-evaluate wait time. - if ( p_prev == &head ) SetEvent( m_ev ); - - return Result; -} - -void CAMSchedule::Delete( CAdvisePacket * pPacket ) -{ - if ( m_dwCacheCount >= dwCacheMax ) delete pPacket; - else - { - m_Serialize.Lock(); - pPacket->m_next = m_pAdviseCache; - m_pAdviseCache = pPacket; - ++m_dwCacheCount; - m_Serialize.Unlock(); - } -} - - -// Takes the head of the list & repositions it -void CAMSchedule::ShuntHead() -{ - CAdvisePacket * p_prev = &head; - CAdvisePacket * p_n; - - m_Serialize.Lock(); - CAdvisePacket *const pPacket = head.m_next; - - // This will catch both an empty list, - // and if somehow a MAX_TIME time gets into the list - // (which would also break this method). - ASSERT( pPacket->m_rtEventTime < MAX_TIME ); - - // This relies on the fact that z is a sentry with a maximal m_rtEventTime - for(;;p_prev = p_n) - { - p_n = p_prev->m_next; - if ( p_n->m_rtEventTime > pPacket->m_rtEventTime ) break; - } - // If p_prev == pPacket then we're already in the right place - if (p_prev != pPacket) - { - head.m_next = pPacket->m_next; - (p_prev->m_next = pPacket)->m_next = p_n; - } - #ifdef DEBUG - DbgLog((LOG_TIMING, 2, TEXT("Periodic advise %lu, shunted to %lu"), - pPacket->m_dwAdviseCookie, (pPacket->m_rtEventTime / (UNITS / MILLISECONDS)) )); - #endif - m_Serialize.Unlock(); -} - - -#ifdef DEBUG -void CAMSchedule::DumpLinkedList() -{ - m_Serialize.Lock(); - int i=0; - DbgLog((LOG_TIMING, 1, TEXT("CAMSchedule::DumpLinkedList() this = 0x%p"), this)); - for ( CAdvisePacket * p = &head - ; p - ; p = p->m_next , i++ - ) - { - DbgLog((LOG_TIMING, 1, TEXT("Advise List # %lu, Cookie %d, RefTime %lu"), - i, - p->m_dwAdviseCookie, - p->m_rtEventTime / (UNITS / MILLISECONDS) - )); - } - m_Serialize.Unlock(); -} -#endif diff --git a/plugins/gs/gsdx9/baseclasses/schedule.h b/plugins/gs/gsdx9/baseclasses/schedule.h deleted file mode 100644 index 2d01911b31..0000000000 --- a/plugins/gs/gsdx9/baseclasses/schedule.h +++ /dev/null @@ -1,128 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Schedule.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __CAMSchedule__ -#define __CAMSchedule__ - -class CAMSchedule : private CBaseObject -{ -public: - virtual ~CAMSchedule(); - // ev is the event we should fire if the advise time needs re-evaluating - CAMSchedule( HANDLE ev ); - - DWORD GetAdviseCount(); - REFERENCE_TIME GetNextAdviseTime(); - - // We need a method for derived classes to add advise packets, we return the cookie - DWORD_PTR AddAdvisePacket( const REFERENCE_TIME & time1, const REFERENCE_TIME & time2, HANDLE h, BOOL periodic ); - // And a way to cancel - HRESULT Unadvise(DWORD_PTR dwAdviseCookie); - - // Tell us the time please, and we'll dispatch the expired events. We return the time of the next event. - // NB: The time returned will be "useless" if you start adding extra Advises. But that's the problem of - // whoever is using this helper class (typically a clock). - REFERENCE_TIME Advise( const REFERENCE_TIME & rtTime ); - - // Get the event handle which will be set if advise time requires re-evaluation. - HANDLE GetEvent() const { return m_ev; } - -private: - // We define the nodes that will be used in our singly linked list - // of advise packets. The list is ordered by time, with the - // elements that will expire first at the front. - class CAdvisePacket - { - public: - CAdvisePacket() - {} - - CAdvisePacket * m_next; - DWORD_PTR m_dwAdviseCookie; - REFERENCE_TIME m_rtEventTime; // Time at which event should be set - REFERENCE_TIME m_rtPeriod; // Periodic time - HANDLE m_hNotify; // Handle to event or semephore - BOOL m_bPeriodic; // TRUE => Periodic event - - CAdvisePacket( CAdvisePacket * next, LONGLONG time ) : m_next(next), m_rtEventTime(time) - {} - - void InsertAfter( CAdvisePacket * p ) - { - p->m_next = m_next; - m_next = p; - } - - int IsZ() const // That is, is it the node that represents the end of the list - { return m_next == 0; } - - CAdvisePacket * RemoveNext() - { - CAdvisePacket *const next = m_next; - CAdvisePacket *const new_next = next->m_next; - m_next = new_next; - return next; - } - - void DeleteNext() - { - delete RemoveNext(); - } - - CAdvisePacket * Next() const - { - CAdvisePacket * result = m_next; - if (result->IsZ()) result = 0; - return result; - } - - DWORD_PTR Cookie() const - { return m_dwAdviseCookie; } - }; - - // Structure is: - // head -> elmt1 -> elmt2 -> z -> null - // So an empty list is: head -> z -> null - // Having head & z as links makes insertaion, - // deletion and shunting much easier. - CAdvisePacket head, z; // z is both a tail and a sentry - - volatile DWORD_PTR m_dwNextCookie; // Strictly increasing - volatile DWORD m_dwAdviseCount; // Number of elements on list - - CCritSec m_Serialize; - - // AddAdvisePacket: adds the packet, returns the cookie (0 if failed) - DWORD_PTR AddAdvisePacket( CAdvisePacket * pPacket ); - // Event that we should set if the packed added above will be the next to fire. - const HANDLE m_ev; - - // A Shunt is where we have changed the first element in the - // list and want it re-evaluating (i.e. repositioned) in - // the list. - void ShuntHead(); - - // Rather than delete advise packets, we cache them for future use - CAdvisePacket * m_pAdviseCache; - DWORD m_dwCacheCount; - enum { dwCacheMax = 5 }; // Don't bother caching more than five - - void Delete( CAdvisePacket * pLink );// This "Delete" will cache the Link - -// Attributes and methods for debugging -public: -#ifdef DEBUG - void DumpLinkedList(); -#else - void DumpLinkedList() {} -#endif - -}; - -#endif // __CAMSchedule__ diff --git a/plugins/gs/gsdx9/baseclasses/seekpt.cpp b/plugins/gs/gsdx9/baseclasses/seekpt.cpp deleted file mode 100644 index bf70e8a5bd..0000000000 --- a/plugins/gs/gsdx9/baseclasses/seekpt.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SeekPT.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include "seekpt.h" - -//================================================================== -// CreateInstance -// This goes in the factory template table to create new instances -// If there is already a mapper instance - return that, else make one -// and save it in a static variable so that forever after we can return that. -//================================================================== - -CUnknown * CSeekingPassThru::CreateInstance(LPUNKNOWN pUnk, HRESULT *phr) -{ - return new CSeekingPassThru(NAME("Seeking PassThru"),pUnk, phr); -} - - -STDMETHODIMP CSeekingPassThru::NonDelegatingQueryInterface(REFIID riid, void ** ppv) -{ - if (riid == IID_ISeekingPassThru) { - return GetInterface((ISeekingPassThru *) this, ppv); - } else { - if (m_pPosPassThru && - (riid == IID_IMediaSeeking || - riid == IID_IMediaPosition)) { - return m_pPosPassThru->NonDelegatingQueryInterface(riid,ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid, ppv); - } - } -} - - -CSeekingPassThru::CSeekingPassThru( TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr ) - : CUnknown(pName, pUnk, phr), - m_pPosPassThru(NULL) -{ -} - - -CSeekingPassThru::~CSeekingPassThru() -{ - delete m_pPosPassThru; -} - -STDMETHODIMP CSeekingPassThru::Init(BOOL bRendererSeeking, IPin *pPin) -{ - HRESULT hr = NOERROR; - if (m_pPosPassThru) { - hr = E_FAIL; - } else { - m_pPosPassThru = - bRendererSeeking ? - new CRendererPosPassThru( - NAME("Render Seeking COM object"), - (IUnknown *)this, - &hr, - pPin) : - new CPosPassThru( - NAME("Render Seeking COM object"), - (IUnknown *)this, - &hr, - pPin); - if (!m_pPosPassThru) { - hr = E_OUTOFMEMORY; - } else { - if (FAILED(hr)) { - delete m_pPosPassThru; - m_pPosPassThru = NULL; - } - } - } - return hr; -} - diff --git a/plugins/gs/gsdx9/baseclasses/seekpt.h b/plugins/gs/gsdx9/baseclasses/seekpt.h deleted file mode 100644 index 93b7061398..0000000000 --- a/plugins/gs/gsdx9/baseclasses/seekpt.h +++ /dev/null @@ -1,30 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SeekPT.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __seekpt_h__ -#define __seekpt_h__ - - -class CSeekingPassThru : public ISeekingPassThru, public CUnknown -{ -public: - static CUnknown *CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); - CSeekingPassThru(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr); - ~CSeekingPassThru(); - - DECLARE_IUNKNOWN; - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void ** ppv); - - STDMETHODIMP Init(BOOL bSupportRendering, IPin *pPin); - -private: - CPosPassThru *m_pPosPassThru; -}; - -#endif diff --git a/plugins/gs/gsdx9/baseclasses/source.cpp b/plugins/gs/gsdx9/baseclasses/source.cpp deleted file mode 100644 index cbdc52a810..0000000000 --- a/plugins/gs/gsdx9/baseclasses/source.cpp +++ /dev/null @@ -1,522 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Source.cpp -// -// Desc: DirectShow base classes - implements CSource, which is a Quartz -// source filter 'template.' -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Locking Strategy. -// -// Hold the filter critical section (m_pFilter->pStateLock()) to serialise -// access to functions. Note that, in general, this lock may be held -// by a function when the worker thread may want to hold it. Therefore -// if you wish to access shared state from the worker thread you will -// need to add another critical section object. The execption is during -// the threads processing loop, when it is safe to get the filter critical -// section from within FillBuffer(). - -#include - - -// -// CSource::Constructor -// -// Initialise the pin count for the filter. The user will create the pins in -// the derived class. -CSource::CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) -{ -} - -CSource::CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) -{ - UNREFERENCED_PARAMETER(phr); -} - -#ifdef UNICODE -CSource::CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) -{ -} - -CSource::CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr) - : CBaseFilter(pName, lpunk, &m_cStateLock, clsid), - m_iPins(0), - m_paStreams(NULL) -{ - UNREFERENCED_PARAMETER(phr); -} -#endif - -// -// CSource::Destructor -// -CSource::~CSource() -{ - /* Free our pins and pin array */ - while (m_iPins != 0) { - // deleting the pins causes them to be removed from the array... - delete m_paStreams[m_iPins - 1]; - } - - ASSERT(m_paStreams == NULL); -} - - -// -// Add a new pin -// -HRESULT CSource::AddPin(CSourceStream *pStream) -{ - CAutoLock lock(&m_cStateLock); - - /* Allocate space for this pin and the old ones */ - CSourceStream **paStreams = new CSourceStream *[m_iPins + 1]; - if (paStreams == NULL) { - return E_OUTOFMEMORY; - } - if (m_paStreams != NULL) { - CopyMemory((PVOID)paStreams, (PVOID)m_paStreams, - m_iPins * sizeof(m_paStreams[0])); - paStreams[m_iPins] = pStream; - delete [] m_paStreams; - } - m_paStreams = paStreams; - m_paStreams[m_iPins] = pStream; - m_iPins++; - return S_OK; -} - -// -// Remove a pin - pStream is NOT deleted -// -HRESULT CSource::RemovePin(CSourceStream *pStream) -{ - int i; - for (i = 0; i < m_iPins; i++) { - if (m_paStreams[i] == pStream) { - if (m_iPins == 1) { - delete [] m_paStreams; - m_paStreams = NULL; - } else { - /* no need to reallocate */ - while (++i < m_iPins) - m_paStreams[i - 1] = m_paStreams[i]; - } - m_iPins--; - return S_OK; - } - } - return S_FALSE; -} - -// -// FindPin -// -// Set *ppPin to the IPin* that has the id Id. -// or to NULL if the Id cannot be matched. -STDMETHODIMP CSource::FindPin(LPCWSTR Id, IPin **ppPin) -{ - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - // The -1 undoes the +1 in QueryId and ensures that totally invalid - // strings (for which WstrToInt delivers 0) give a deliver a NULL pin. - int i = WstrToInt(Id) -1; - *ppPin = GetPin(i); - if (*ppPin!=NULL){ - (*ppPin)->AddRef(); - return NOERROR; - } else { - return VFW_E_NOT_FOUND; - } -} - -// -// FindPinNumber -// -// return the number of the pin with this IPin* or -1 if none -int CSource::FindPinNumber(IPin *iPin) { - int i; - for (i=0; in && n>=0 it follows that m_iPins>0 - // which is what used to be checked (i.e. checking that we have a pin) - if ((n >= 0) && (n < m_iPins)) { - - ASSERT(m_paStreams[n]); - return m_paStreams[n]; - } - return NULL; -} - - -// - - -// * -// * --- CSourceStream ---- -// * - -// -// Set Id to point to a CoTaskMemAlloc'd -STDMETHODIMP CSourceStream::QueryId(LPWSTR *Id) { - CheckPointer(Id,E_POINTER); - ValidateReadWritePtr(Id,sizeof(LPWSTR)); - - // We give the pins id's which are 1,2,... - // FindPinNumber returns -1 for an invalid pin - int i = 1+ m_pFilter->FindPinNumber(this); - if (i<1) return VFW_E_NOT_FOUND; - *Id = (LPWSTR)CoTaskMemAlloc(4*sizeof(WCHAR)); - if (*Id==NULL) { - return E_OUTOFMEMORY; - } - IntToWstr(i, *Id, 4); - return NOERROR; -} - - - -// -// CSourceStream::Constructor -// -// increments the number of pins present on the filter -CSourceStream::CSourceStream( - TCHAR *pObjectName, - HRESULT *phr, - CSource *ps, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName), - m_pFilter(ps) { - - *phr = m_pFilter->AddPin(this); -} - -#ifdef UNICODE -CSourceStream::CSourceStream( - char *pObjectName, - HRESULT *phr, - CSource *ps, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, ps, ps->pStateLock(), phr, pPinName), - m_pFilter(ps) { - - *phr = m_pFilter->AddPin(this); -} -#endif -// -// CSourceStream::Destructor -// -// Decrements the number of pins on this filter -CSourceStream::~CSourceStream(void) { - - m_pFilter->RemovePin(this); -} - - -// -// CheckMediaType -// -// Do we support this type? Provides the default support for 1 type. -HRESULT CSourceStream::CheckMediaType(const CMediaType *pMediaType) { - - CAutoLock lock(m_pFilter->pStateLock()); - - CMediaType mt; - GetMediaType(&mt); - - if (mt == *pMediaType) { - return NOERROR; - } - - return E_FAIL; -} - - -// -// GetMediaType/3 -// -// By default we support only one type -// iPosition indexes are 0-n -HRESULT CSourceStream::GetMediaType(int iPosition, CMediaType *pMediaType) { - - CAutoLock lock(m_pFilter->pStateLock()); - - if (iPosition<0) { - return E_INVALIDARG; - } - if (iPosition>0) { - return VFW_S_NO_MORE_ITEMS; - } - return GetMediaType(pMediaType); -} - - -// -// Active -// -// The pin is active - start up the worker thread -HRESULT CSourceStream::Active(void) { - - CAutoLock lock(m_pFilter->pStateLock()); - - HRESULT hr; - - if (m_pFilter->IsActive()) { - return S_FALSE; // succeeded, but did not allocate resources (they already exist...) - } - - // do nothing if not connected - its ok not to connect to - // all pins of a source filter - if (!IsConnected()) { - return NOERROR; - } - - hr = CBaseOutputPin::Active(); - if (FAILED(hr)) { - return hr; - } - - ASSERT(!ThreadExists()); - - // start the thread - if (!Create()) { - return E_FAIL; - } - - // Tell thread to initialize. If OnThreadCreate Fails, so does this. - hr = Init(); - if (FAILED(hr)) - return hr; - - return Pause(); -} - - -// -// Inactive -// -// Pin is inactive - shut down the worker thread -// Waits for the worker to exit before returning. -HRESULT CSourceStream::Inactive(void) { - - CAutoLock lock(m_pFilter->pStateLock()); - - HRESULT hr; - - // do nothing if not connected - its ok not to connect to - // all pins of a source filter - if (!IsConnected()) { - return NOERROR; - } - - // !!! need to do this before trying to stop the thread, because - // we may be stuck waiting for our own allocator!!! - - hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator - if (FAILED(hr)) { - return hr; - } - - if (ThreadExists()) { - hr = Stop(); - - if (FAILED(hr)) { - return hr; - } - - hr = Exit(); - if (FAILED(hr)) { - return hr; - } - - Close(); // Wait for the thread to exit, then tidy up. - } - - // hr = CBaseOutputPin::Inactive(); // call this first to Decommit the allocator - //if (FAILED(hr)) { - // return hr; - //} - - return NOERROR; -} - - -// -// ThreadProc -// -// When this returns the thread exits -// Return codes > 0 indicate an error occured -DWORD CSourceStream::ThreadProc(void) { - - HRESULT hr; // the return code from calls - Command com; - - do { - com = GetRequest(); - if (com != CMD_INIT) { - DbgLog((LOG_ERROR, 1, TEXT("Thread expected init command"))); - Reply((DWORD) E_UNEXPECTED); - } - } while (com != CMD_INIT); - - DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread initializing"))); - - hr = OnThreadCreate(); // perform set up tasks - if (FAILED(hr)) { - DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadCreate failed. Aborting thread."))); - OnThreadDestroy(); - Reply(hr); // send failed return code from OnThreadCreate - return 1; - } - - // Initialisation suceeded - Reply(NOERROR); - - Command cmd; - do { - cmd = GetRequest(); - - switch (cmd) { - - case CMD_EXIT: - Reply(NOERROR); - break; - - case CMD_RUN: - DbgLog((LOG_ERROR, 1, TEXT("CMD_RUN received before a CMD_PAUSE???"))); - // !!! fall through??? - - case CMD_PAUSE: - Reply(NOERROR); - DoBufferProcessingLoop(); - break; - - case CMD_STOP: - Reply(NOERROR); - break; - - default: - DbgLog((LOG_ERROR, 1, TEXT("Unknown command %d received!"), cmd)); - Reply((DWORD) E_NOTIMPL); - break; - } - } while (cmd != CMD_EXIT); - - hr = OnThreadDestroy(); // tidy up. - if (FAILED(hr)) { - DbgLog((LOG_ERROR, 1, TEXT("CSourceStream::OnThreadDestroy failed. Exiting thread."))); - return 1; - } - - DbgLog((LOG_TRACE, 1, TEXT("CSourceStream worker thread exiting"))); - return 0; -} - - -// -// DoBufferProcessingLoop -// -// Grabs a buffer and calls the users processing function. -// Overridable, so that different delivery styles can be catered for. -HRESULT CSourceStream::DoBufferProcessingLoop(void) { - - Command com; - - OnThreadStartPlay(); - - do { - while (!CheckRequest(&com)) { - - IMediaSample *pSample; - - HRESULT hr = GetDeliveryBuffer(&pSample,NULL,NULL,0); - if (FAILED(hr)) { - Sleep(1); - continue; // go round again. Perhaps the error will go away - // or the allocator is decommited & we will be asked to - // exit soon. - } - - // Virtual function user will override. - hr = FillBuffer(pSample); - - if (hr == S_OK) { - hr = Deliver(pSample); - pSample->Release(); - - // downstream filter returns S_FALSE if it wants us to - // stop or an error if it's reporting an error. - if(hr != S_OK) - { - DbgLog((LOG_TRACE, 2, TEXT("Deliver() returned %08x; stopping"), hr)); - return S_OK; - } - - } else if (hr == S_FALSE) { - // derived class wants us to stop pushing data - pSample->Release(); - DeliverEndOfStream(); - return S_OK; - } else { - // derived class encountered an error - pSample->Release(); - DbgLog((LOG_ERROR, 1, TEXT("Error %08lX from FillBuffer!!!"), hr)); - DeliverEndOfStream(); - m_pFilter->NotifyEvent(EC_ERRORABORT, hr, 0); - return hr; - } - - // all paths release the sample - } - - // For all commands sent to us there must be a Reply call! - - if (com == CMD_RUN || com == CMD_PAUSE) { - Reply(NOERROR); - } else if (com != CMD_STOP) { - Reply((DWORD) E_UNEXPECTED); - DbgLog((LOG_ERROR, 1, TEXT("Unexpected command!!!"))); - } - } while (com != CMD_STOP); - - return S_FALSE; -} - diff --git a/plugins/gs/gsdx9/baseclasses/source.h b/plugins/gs/gsdx9/baseclasses/source.h deleted file mode 100644 index 6dff3e7569..0000000000 --- a/plugins/gs/gsdx9/baseclasses/source.h +++ /dev/null @@ -1,172 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Source.h -// -// Desc: DirectShow base classes - defines classes to simplify creation of -// ActiveX source filters that support continuous generation of data. -// No support is provided for IMediaControl or IMediaPosition. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// -// Derive your source filter from CSource. -// During construction either: -// Create some CSourceStream objects to manage your pins -// Provide the user with a means of doing so eg, an IPersistFile interface. -// -// CSource provides: -// IBaseFilter interface management -// IMediaFilter interface management, via CBaseFilter -// Pin counting for CBaseFilter -// -// Derive a class from CSourceStream to manage your output pin types -// Implement GetMediaType/1 to return the type you support. If you support multiple -// types then overide GetMediaType/3, CheckMediaType and GetMediaTypeCount. -// Implement Fillbuffer() to put data into one buffer. -// -// CSourceStream provides: -// IPin management via CBaseOutputPin -// Worker thread management - -#ifndef __CSOURCE__ -#define __CSOURCE__ - -class CSourceStream; // The class that will handle each pin - - -// -// CSource -// -// Override construction to provide a means of creating -// CSourceStream derived objects - ie a way of creating pins. -class CSource : public CBaseFilter { -public: - - CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr); - CSource(TCHAR *pName, LPUNKNOWN lpunk, CLSID clsid); -#ifdef UNICODE - CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid, HRESULT *phr); - CSource(CHAR *pName, LPUNKNOWN lpunk, CLSID clsid); -#endif - ~CSource(); - - int GetPinCount(void); - CBasePin *GetPin(int n); - - // -- Utilities -- - - CCritSec* pStateLock(void) { return &m_cStateLock; } // provide our critical section - - HRESULT AddPin(CSourceStream *); - HRESULT RemovePin(CSourceStream *); - - STDMETHODIMP FindPin( - LPCWSTR Id, - IPin ** ppPin - ); - - int FindPinNumber(IPin *iPin); - -protected: - - int m_iPins; // The number of pins on this filter. Updated by CSourceStream - // constructors & destructors. - CSourceStream **m_paStreams; // the pins on this filter. - - CCritSec m_cStateLock; // Lock this to serialize function accesses to the filter state - -}; - - -// -// CSourceStream -// -// Use this class to manage a stream of data that comes from a -// pin. -// Uses a worker thread to put data on the pin. -class CSourceStream : public CAMThread, public CBaseOutputPin { -public: - - CSourceStream(TCHAR *pObjectName, - HRESULT *phr, - CSource *pms, - LPCWSTR pName); -#ifdef UNICODE - CSourceStream(CHAR *pObjectName, - HRESULT *phr, - CSource *pms, - LPCWSTR pName); -#endif - virtual ~CSourceStream(void); // virtual destructor ensures derived class destructors are called too. - -protected: - - CSource *m_pFilter; // The parent of this stream - - // * - // * Data Source - // * - // * The following three functions: FillBuffer, OnThreadCreate/Destroy, are - // * called from within the ThreadProc. They are used in the creation of - // * the media samples this pin will provide - // * - - // Override this to provide the worker thread a means - // of processing a buffer - virtual HRESULT FillBuffer(IMediaSample *pSamp) PURE; - - // Called as the thread is created/destroyed - use to perform - // jobs such as start/stop streaming mode - // If OnThreadCreate returns an error the thread will exit. - virtual HRESULT OnThreadCreate(void) {return NOERROR;}; - virtual HRESULT OnThreadDestroy(void) {return NOERROR;}; - virtual HRESULT OnThreadStartPlay(void) {return NOERROR;}; - - // * - // * Worker Thread - // * - - HRESULT Active(void); // Starts up the worker thread - HRESULT Inactive(void); // Exits the worker thread. - -public: - // thread commands - enum Command {CMD_INIT, CMD_PAUSE, CMD_RUN, CMD_STOP, CMD_EXIT}; - HRESULT Init(void) { return CallWorker(CMD_INIT); } - HRESULT Exit(void) { return CallWorker(CMD_EXIT); } - HRESULT Run(void) { return CallWorker(CMD_RUN); } - HRESULT Pause(void) { return CallWorker(CMD_PAUSE); } - HRESULT Stop(void) { return CallWorker(CMD_STOP); } - -protected: - Command GetRequest(void) { return (Command) CAMThread::GetRequest(); } - BOOL CheckRequest(Command *pCom) { return CAMThread::CheckRequest( (DWORD *) pCom); } - - // override these if you want to add thread commands - virtual DWORD ThreadProc(void); // the thread function - - virtual HRESULT DoBufferProcessingLoop(void); // the loop executed whilst running - - - // * - // * AM_MEDIA_TYPE support - // * - - // If you support more than one media type then override these 2 functions - virtual HRESULT CheckMediaType(const CMediaType *pMediaType); - virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType); // List pos. 0-n - - // If you support only one type then override this fn. - // This will only be called by the default implementations - // of CheckMediaType and GetMediaType(int, CMediaType*) - // You must override this fn. or the above 2! - virtual HRESULT GetMediaType(CMediaType *pMediaType) {return E_UNEXPECTED;} - - STDMETHODIMP QueryId( - LPWSTR * Id - ); -}; - -#endif // __CSOURCE__ - diff --git a/plugins/gs/gsdx9/baseclasses/streams.h b/plugins/gs/gsdx9/baseclasses/streams.h deleted file mode 100644 index 736c46756a..0000000000 --- a/plugins/gs/gsdx9/baseclasses/streams.h +++ /dev/null @@ -1,190 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Streams.h -// -// Desc: DirectShow base classes - defines overall streams architecture. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __STREAMS__ -#define __STREAMS__ - -#ifdef _MSC_VER -// disable some level-4 warnings, use #pragma warning(enable:###) to re-enable -#pragma warning(disable:4100) // warning C4100: unreferenced formal parameter -#pragma warning(disable:4127) // warning C4127: conditional expression is constant -#pragma warning(disable:4189) // warning C4189: local variable is initialized but not referenced -#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union -#pragma warning(disable:4511) // warning C4511: copy constructor could not be generated -#pragma warning(disable:4512) // warning C4512: assignment operator could not be generated -#pragma warning(disable:4514) // warning C4514: unreferenced inline function has been removed -#pragma warning(disable:4710) // warning C4710: 'function' not inlined - -#if _MSC_VER>=1100 -#define AM_NOVTABLE __declspec(novtable) -#else -#define AM_NOVTABLE -#endif -#endif // MSC_VER - -// Because of differences between Visual C++ and older Microsoft SDKs, -// you may have defined _DEBUG without defining DEBUG. This logic -// ensures that both will be set if Visual C++ sets _DEBUG. -#ifdef _DEBUG -#ifndef DEBUG -#define DEBUG -#endif -#endif - -#include -#include -#include -#include - -// Disable warning message for C4201 - use of nameless struct/union -// Otherwise, strmif.h will generate warnings for Win32 debug builds -#pragma warning( disable : 4201 ) - -#include - -#ifndef NUMELMS - #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0])) -#endif - -/////////////////////////////////////////////////////////////////////////// -// The following definitions come from the Platform SDK and are required if -// the applicaiton is being compiled with the headers from Visual C++ 6.0. -/////////////////////////////////////////////////////////////////////////// -#ifndef InterlockedExchangePointer - #define InterlockedExchangePointer(Target, Value) \ - (PVOID)InterlockedExchange((PLONG)(Target), (LONG)(Value)) -#endif - -#ifndef _WAVEFORMATEXTENSIBLE_ -#define _WAVEFORMATEXTENSIBLE_ -typedef struct { - WAVEFORMATEX Format; - union { - WORD wValidBitsPerSample; /* bits of precision */ - WORD wSamplesPerBlock; /* valid if wBitsPerSample==0 */ - WORD wReserved; /* If neither applies, set to zero. */ - } Samples; - DWORD dwChannelMask; /* which channels are */ - /* present in stream */ - GUID SubFormat; -} WAVEFORMATEXTENSIBLE, *PWAVEFORMATEXTENSIBLE; -#endif // !_WAVEFORMATEXTENSIBLE_ - -#if !defined(WAVE_FORMAT_EXTENSIBLE) -#define WAVE_FORMAT_EXTENSIBLE 0xFFFE -#endif // !defined(WAVE_FORMAT_EXTENSIBLE) - -#ifndef GetWindowLongPtr - #define GetWindowLongPtrA GetWindowLongA - #define GetWindowLongPtrW GetWindowLongW - #ifdef UNICODE - #define GetWindowLongPtr GetWindowLongPtrW - #else - #define GetWindowLongPtr GetWindowLongPtrA - #endif // !UNICODE -#endif // !GetWindowLongPtr - -#ifndef SetWindowLongPtr - #define SetWindowLongPtrA SetWindowLongA - #define SetWindowLongPtrW SetWindowLongW - #ifdef UNICODE - #define SetWindowLongPtr SetWindowLongPtrW - #else - #define SetWindowLongPtr SetWindowLongPtrA - #endif // !UNICODE -#endif // !SetWindowLongPtr - -#ifndef GWLP_WNDPROC - #define GWLP_WNDPROC (-4) -#endif -#ifndef GWLP_HINSTANCE - #define GWLP_HINSTANCE (-6) -#endif -#ifndef GWLP_HWNDPARENT - #define GWLP_HWNDPARENT (-8) -#endif -#ifndef GWLP_USERDATA - #define GWLP_USERDATA (-21) -#endif -#ifndef GWLP_ID - #define GWLP_ID (-12) -#endif -#ifndef DWLP_MSGRESULT - #define DWLP_MSGRESULT 0 -#endif -#ifndef DWLP_DLGPROC - #define DWLP_DLGPROC DWLP_MSGRESULT + sizeof(LRESULT) -#endif -#ifndef DWLP_USER - #define DWLP_USER DWLP_DLGPROC + sizeof(DLGPROC) -#endif -/////////////////////////////////////////////////////////////////////////// -// End Platform SDK definitions -/////////////////////////////////////////////////////////////////////////// - - -#pragma warning(disable:4201) // warning C4201: nonstandard extension used : nameless struct/union -#include // Generated IDL header file for streams interfaces - -#include "reftime.h" // Helper class for REFERENCE_TIME management -#include "wxdebug.h" // Debug support for logging and ASSERTs -#include "amvideo.h" // ActiveMovie video interfaces and definitions -//include amaudio.h explicitly if you need it. it requires the DirectX SDK. -//#include "amaudio.h" // ActiveMovie audio interfaces and definitions -#include "wxutil.h" // General helper classes for threads etc -#include "combase.h" // Base COM classes to support IUnknown -#include "dllsetup.h" // Filter registration support functions -#include "measure.h" // Performance measurement -#include "comlite.h" // Light weight com function prototypes - -#include "cache.h" // Simple cache container class -#include "wxlist.h" // Non MFC generic list class -#include "msgthrd.h" // CMsgThread -#include "mtype.h" // Helper class for managing media types -#include "fourcc.h" // conversions between FOURCCs and GUIDs -#include "control.h" // generated from control.odl -#include "ctlutil.h" // control interface utility classes -#include "evcode.h" // event code definitions -#include "amfilter.h" // Main streams architecture class hierachy -#include "transfrm.h" // Generic transform filter -#include "transip.h" // Generic transform-in-place filter -#include "uuids.h" // declaration of type GUIDs and well-known clsids -#include "source.h" // Generic source filter -#include "outputq.h" // Output pin queueing -#include "errors.h" // HRESULT status and error definitions -#include "renbase.h" // Base class for writing ActiveX renderers -#include "winutil.h" // Helps with filters that manage windows -#include "winctrl.h" // Implements the IVideoWindow interface -#include "videoctl.h" // Specifically video related classes -#include "refclock.h" // Base clock class -#include "sysclock.h" // System clock -#include "pstream.h" // IPersistStream helper class -#include "vtrans.h" // Video Transform Filter base class -#include "amextra.h" -#include "cprop.h" // Base property page class -#include "strmctl.h" // IAMStreamControl support -#include "edevdefs.h" // External device control interface defines -#include "audevcod.h" // audio filter device error event codes - -#include - -#define NO_SHLWAPI_STRFCNS -#include -#include - -#ifndef NUMELMS - #define NUMELMS(aa) (sizeof(aa)/sizeof((aa)[0])) -#endif - -#else - #ifdef DEBUG - #pragma message("STREAMS.H included TWICE") - #endif -#endif // __STREAMS__ - diff --git a/plugins/gs/gsdx9/baseclasses/strmctl.cpp b/plugins/gs/gsdx9/baseclasses/strmctl.cpp deleted file mode 100644 index bc467e64c4..0000000000 --- a/plugins/gs/gsdx9/baseclasses/strmctl.cpp +++ /dev/null @@ -1,401 +0,0 @@ -//------------------------------------------------------------------------------ -// File: StrmCtl.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - -CBaseStreamControl::CBaseStreamControl() -: m_StreamState(STREAM_FLOWING) -, m_StreamStateOnStop(STREAM_FLOWING) // means no pending stop -, m_tStartTime(MAX_TIME) -, m_tStopTime(MAX_TIME) -, m_dwStartCookie(0) -, m_dwStopCookie(0) -, m_pRefClock(NULL) -, m_FilterState(State_Stopped) -, m_bIsFlushing(FALSE) -, m_bStopSendExtra(FALSE) -{} - -CBaseStreamControl::~CBaseStreamControl() -{ - // Make sure we release the clock. - SetSyncSource(NULL); - return; -} - - -STDMETHODIMP CBaseStreamControl::StopAt(const REFERENCE_TIME * ptStop, BOOL bSendExtra, DWORD dwCookie) -{ - CAutoLock lck(&m_CritSec); - m_bStopSendExtra = FALSE; // reset - m_bStopExtraSent = FALSE; - if (ptStop) - { - if (*ptStop == MAX_TIME) - { - DbgLog((LOG_TRACE,2,TEXT("StopAt: Cancel stop"))); - CancelStop(); - // If there's now a command to start in the future, we assume - // they want to be stopped when the graph is first run - if (m_FilterState == State_Stopped && m_tStartTime < MAX_TIME) { - m_StreamState = STREAM_DISCARDING; - DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING"))); - } - return NOERROR; - } - DbgLog((LOG_TRACE,2,TEXT("StopAt: %dms extra=%d"), - (int)(*ptStop/10000), bSendExtra)); - // if the first command is to stop in the future, then we assume they - // want to be started when the graph is first run - if (m_FilterState == State_Stopped && m_tStartTime > *ptStop) { - m_StreamState = STREAM_FLOWING; - DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING"))); - } - m_bStopSendExtra = bSendExtra; - m_tStopTime = *ptStop; - m_dwStopCookie = dwCookie; - m_StreamStateOnStop = STREAM_DISCARDING; - } - else - { - DbgLog((LOG_TRACE,2,TEXT("StopAt: now"))); - // sending an extra frame when told to stop now would mess people up - m_bStopSendExtra = FALSE; - m_tStopTime = MAX_TIME; - m_dwStopCookie = 0; - m_StreamState = STREAM_DISCARDING; - m_StreamStateOnStop = STREAM_FLOWING; // no pending stop - } - // we might change our mind what to do with a sample we're blocking - m_StreamEvent.Set(); - return NOERROR; -} - -STDMETHODIMP CBaseStreamControl::StartAt -( const REFERENCE_TIME *ptStart, DWORD dwCookie ) -{ - CAutoLock lck(&m_CritSec); - if (ptStart) - { - if (*ptStart == MAX_TIME) - { - DbgLog((LOG_TRACE,2,TEXT("StartAt: Cancel start"))); - CancelStart(); - // If there's now a command to stop in the future, we assume - // they want to be started when the graph is first run - if (m_FilterState == State_Stopped && m_tStopTime < MAX_TIME) { - DbgLog((LOG_TRACE,2,TEXT("graph will begin by FLOWING"))); - m_StreamState = STREAM_FLOWING; - } - return NOERROR; - } - DbgLog((LOG_TRACE,2,TEXT("StartAt: %dms"), (int)(*ptStart/10000))); - // if the first command is to start in the future, then we assume they - // want to be stopped when the graph is first run - if (m_FilterState == State_Stopped && m_tStopTime >= *ptStart) { - DbgLog((LOG_TRACE,2,TEXT("graph will begin by DISCARDING"))); - m_StreamState = STREAM_DISCARDING; - } - m_tStartTime = *ptStart; - m_dwStartCookie = dwCookie; - // if (m_tStopTime == m_tStartTime) CancelStop(); - } - else - { - DbgLog((LOG_TRACE,2,TEXT("StartAt: now"))); - m_tStartTime = MAX_TIME; - m_dwStartCookie = 0; - m_StreamState = STREAM_FLOWING; - } - // we might change our mind what to do with a sample we're blocking - m_StreamEvent.Set(); - return NOERROR; -} - -// Retrieve information about current settings -STDMETHODIMP CBaseStreamControl::GetInfo(AM_STREAM_INFO *pInfo) -{ - if (pInfo == NULL) - return E_POINTER; - - pInfo->tStart = m_tStartTime; - pInfo->tStop = m_tStopTime; - pInfo->dwStartCookie = m_dwStartCookie; - pInfo->dwStopCookie = m_dwStopCookie; - pInfo->dwFlags = m_bStopSendExtra ? AM_STREAM_INFO_STOP_SEND_EXTRA : 0; - pInfo->dwFlags |= m_tStartTime == MAX_TIME ? 0 : AM_STREAM_INFO_START_DEFINED; - pInfo->dwFlags |= m_tStopTime == MAX_TIME ? 0 : AM_STREAM_INFO_STOP_DEFINED; - switch (m_StreamState) { - default: - DbgBreak("Invalid stream state"); - case STREAM_FLOWING: - break; - case STREAM_DISCARDING: - pInfo->dwFlags |= AM_STREAM_INFO_DISCARDING; - break; - } - return S_OK; -} - - -void CBaseStreamControl::ExecuteStop() -{ - ASSERT(CritCheckIn(&m_CritSec)); - m_StreamState = m_StreamStateOnStop; - if (m_dwStopCookie && m_pSink) { - DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STOPPED (%d)"), - m_dwStopCookie)); - m_pSink->Notify(EC_STREAM_CONTROL_STOPPED, (LONG_PTR)this, m_dwStopCookie); - } - CancelStop(); // This will do the tidy up -} - -void CBaseStreamControl::ExecuteStart() -{ - ASSERT(CritCheckIn(&m_CritSec)); - m_StreamState = STREAM_FLOWING; - if (m_dwStartCookie) { - DbgLog((LOG_TRACE,2,TEXT("*sending EC_STREAM_CONTROL_STARTED (%d)"), - m_dwStartCookie)); - m_pSink->Notify(EC_STREAM_CONTROL_STARTED, (LONG_PTR)this, m_dwStartCookie); - } - CancelStart(); // This will do the tidy up -} - -void CBaseStreamControl::CancelStop() -{ - ASSERT(CritCheckIn(&m_CritSec)); - m_tStopTime = MAX_TIME; - m_dwStopCookie = 0; - m_StreamStateOnStop = STREAM_FLOWING; -} - -void CBaseStreamControl::CancelStart() -{ - ASSERT(CritCheckIn(&m_CritSec)); - m_tStartTime = MAX_TIME; - m_dwStartCookie = 0; -} - - -// This guy will return one of the three StreamControlState's. Here's what the caller -// should do for each one: -// -// STREAM_FLOWING: Proceed as usual (render or pass the sample on) -// STREAM_DISCARDING: Calculate the time 'til *pSampleStart and wait that long -// for the event handle (GetStreamEventHandle()). If the -// wait expires, throw the sample away. If the event -// fires, call me back, I've changed my mind. -// I use pSampleStart (not Stop) so that live sources don't -// block for the duration of their samples, since the clock -// will always read approximately pSampleStart when called - - -// All through this code, you'll notice the following rules: -// - When start and stop time are the same, it's as if start was first -// - An event is considered inside the sample when it's >= sample start time -// but < sample stop time -// - if any part of the sample is supposed to be sent, we'll send the whole -// thing since we don't break it into smaller pieces -// - If we skip over a start or stop without doing it, we still signal the event -// and reset ourselves in case somebody's waiting for the event, and to make -// sure we notice that the event is past and should be forgotten -// Here are the 19 cases that have to be handled (x=start o=stop <-->=sample): -// -// 1. xo<--> start then stop -// 2. ox<--> stop then start -// 3. x start -// 4. o stop then start -// 5. x<-->o start -// 6. o<-->x stop -// 7. o start -// 8. x no change -// 9. start -// 10. stop then start -// 11. <-->xo no change -// 12. <-->ox no change -// 13. x<--> start -// 14. start -// 15. <-->x no change -// 16. o<--> stop -// 17. no change -// 18. <-->o no change -// 19. <--> no change - - -enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckSampleTimes -( const REFERENCE_TIME * pSampleStart, const REFERENCE_TIME * pSampleStop ) -{ - CAutoLock lck(&m_CritSec); - - ASSERT(!m_bIsFlushing); - ASSERT(pSampleStart && pSampleStop); - - // Don't ask me how I came up with the code below to handle all 19 cases - // - DannyMi - - if (m_tStopTime >= *pSampleStart) - { - if (m_tStartTime >= *pSampleStop) - return m_StreamState; // cases 8 11 12 15 17 18 19 - if (m_tStopTime < m_tStartTime) - ExecuteStop(); // case 10 - ExecuteStart(); // cases 3 5 7 9 13 14 - return m_StreamState; - } - - if (m_tStartTime >= *pSampleStop) - { - ExecuteStop(); // cases 6 16 - return m_StreamState; - } - - if (m_tStartTime <= m_tStopTime) - { - ExecuteStart(); - ExecuteStop(); - return m_StreamState; // case 1 - } - else - { - ExecuteStop(); - ExecuteStart(); - return m_StreamState; // cases 2 4 - } -} - - -enum CBaseStreamControl::StreamControlState CBaseStreamControl::CheckStreamState( IMediaSample * pSample ) -{ - - REFERENCE_TIME rtBufferStart, rtBufferStop; - const BOOL bNoBufferTimes = - pSample == NULL || - FAILED(pSample->GetTime(&rtBufferStart, &rtBufferStop)); - - StreamControlState state; - LONG lWait; - - do - { - // something has to break out of the blocking - if (m_bIsFlushing || m_FilterState == State_Stopped) - return STREAM_DISCARDING; - - if (bNoBufferTimes) { - // Can't do anything until we get a time stamp - state = m_StreamState; - break; - } else { - state = CheckSampleTimes( &rtBufferStart, &rtBufferStop ); - if (state == STREAM_FLOWING) - break; - - // we aren't supposed to send this, but we've been - // told to send one more than we were supposed to - // (and the stop isn't still pending and we're streaming) - if (m_bStopSendExtra && !m_bStopExtraSent && - m_tStopTime == MAX_TIME && - m_FilterState != State_Stopped) { - m_bStopExtraSent = TRUE; - DbgLog((LOG_TRACE,2,TEXT("%d sending an EXTRA frame"), - m_dwStopCookie)); - state = STREAM_FLOWING; - break; - } - } - - // We're in discarding mode - - // If we've no clock, discard as fast as we can - if (!m_pRefClock) { - break; - - // If we're paused, we can't discard in a timely manner because - // there's no such thing as stream times. We must block until - // we run or stop, or we'll end up throwing the whole stream away - // as quickly as possible - } else if (m_FilterState == State_Paused) { - lWait = INFINITE; - - } else { - // wait until it's time for the sample until we say "discard" - // ("discard in a timely fashion") - REFERENCE_TIME rtNow; - EXECUTE_ASSERT(SUCCEEDED(m_pRefClock->GetTime(&rtNow))); - rtNow -= m_tRunStart; // Into relative ref-time - lWait = LONG((rtBufferStart - rtNow)/10000); // 100ns -> ms - if (lWait < 10) break; // Not worth waiting - discard early - } - - } while(WaitForSingleObject(GetStreamEventHandle(), lWait) != WAIT_TIMEOUT); - - return state; -} - - -void CBaseStreamControl::NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart ) -{ - CAutoLock lck(&m_CritSec); - - // or we will get confused - if (m_FilterState == new_state) - return; - - switch (new_state) - { - case State_Stopped: - - DbgLog((LOG_TRACE,2,TEXT("Filter is STOPPED"))); - - // execute any pending starts and stops in the right order, - // to make sure all notifications get sent, and we end up - // in the right state to begin next time (??? why not?) - - if (m_tStartTime != MAX_TIME && m_tStopTime == MAX_TIME) { - ExecuteStart(); - } else if (m_tStopTime != MAX_TIME && m_tStartTime == MAX_TIME) { - ExecuteStop(); - } else if (m_tStopTime != MAX_TIME && m_tStartTime != MAX_TIME) { - if (m_tStartTime <= m_tStopTime) { - ExecuteStart(); - ExecuteStop(); - } else { - ExecuteStop(); - ExecuteStart(); - } - } - // always start off flowing when the graph starts streaming - // unless told otherwise - m_StreamState = STREAM_FLOWING; - m_FilterState = new_state; - break; - - case State_Running: - - DbgLog((LOG_TRACE,2,TEXT("Filter is RUNNING"))); - - m_tRunStart = tStart; - // fall-through - - default: // case State_Paused: - m_FilterState = new_state; - } - // unblock! - m_StreamEvent.Set(); -} - - -void CBaseStreamControl::Flushing(BOOL bInProgress) -{ - CAutoLock lck(&m_CritSec); - m_bIsFlushing = bInProgress; - m_StreamEvent.Set(); -} diff --git a/plugins/gs/gsdx9/baseclasses/strmctl.h b/plugins/gs/gsdx9/baseclasses/strmctl.h deleted file mode 100644 index 2a1475fe3a..0000000000 --- a/plugins/gs/gsdx9/baseclasses/strmctl.h +++ /dev/null @@ -1,157 +0,0 @@ -//------------------------------------------------------------------------------ -// File: StrmCtl.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __strmctl_h__ -#define __strmctl_h__ - -class CBaseStreamControl : public IAMStreamControl -{ -public: - // Used by the implementation - enum StreamControlState - { STREAM_FLOWING = 0x1000, - STREAM_DISCARDING - }; - -private: - enum StreamControlState m_StreamState; // Current stream state - enum StreamControlState m_StreamStateOnStop; // State after next stop - // (i.e.Blocking or Discarding) - - REFERENCE_TIME m_tStartTime; // MAX_TIME implies none - REFERENCE_TIME m_tStopTime; // MAX_TIME implies none - DWORD m_dwStartCookie; // Cookie for notification to app - DWORD m_dwStopCookie; // Cookie for notification to app - volatile BOOL m_bIsFlushing; // No optimization pls! - volatile BOOL m_bStopSendExtra; // bSendExtra was set - volatile BOOL m_bStopExtraSent; // the extra one was sent - - CCritSec m_CritSec; // CritSec to guard above attributes - - // Event to fire when we can come - // out of blocking, or to come out of waiting - // to discard if we change our minds. - // - CAMEvent m_StreamEvent; - - // All of these methods execute immediately. Helpers for others. - // - void ExecuteStop(); - void ExecuteStart(); - void CancelStop(); - void CancelStart(); - - // Some things we need to be told by our owning filter - // Your pin must also expose IAMStreamControl when QI'd for it! - // - IReferenceClock * m_pRefClock; // Need it to set advises - // Filter must tell us via - // SetSyncSource - IMediaEventSink * m_pSink; // Event sink - // Filter must tell us after it - // creates it in JoinFilterGraph() - FILTER_STATE m_FilterState; // Just need it! - // Filter must tell us via - // NotifyFilterState - REFERENCE_TIME m_tRunStart; // Per the Run call to the filter - - // This guy will return one of the three StreamControlState's. Here's what - // the caller should do for each one: - // - // STREAM_FLOWING: Proceed as usual (render or pass the sample on) - // STREAM_DISCARDING: Calculate the time 'til *pSampleStop and wait - // that long for the event handle - // (GetStreamEventHandle()). If the wait - // expires, throw the sample away. If the event - // fires, call me back - I've changed my mind. - // - enum StreamControlState CheckSampleTimes( const REFERENCE_TIME * pSampleStart, - const REFERENCE_TIME * pSampleStop ); - -public: - // You don't have to tell us much when we're created, but there are other - // obligations that must be met. See SetSyncSource & NotifyFilterState - // below. - // - CBaseStreamControl(); - ~CBaseStreamControl(); - - // If you want this class to work properly, there are thing you need to - // (keep) telling it. Filters with pins that use this class - // should ensure that they pass through to this method any calls they - // receive on their SetSyncSource. - - // We need a clock to see what time it is. This is for the - // "discard in a timely fashion" logic. If we discard everything as - // quick as possible, a whole 60 minute file could get discarded in the - // first 10 seconds, and if somebody wants to turn streaming on at 30 - // minutes into the file, and they make the call more than a few seconds - // after the graph is run, it may be too late! - // So we hold every sample until it's time has gone, then we discard it. - // The filter should call this when it gets a SetSyncSource - // - void SetSyncSource( IReferenceClock * pRefClock ) - { - CAutoLock lck(&m_CritSec); - if (m_pRefClock) m_pRefClock->Release(); - m_pRefClock = pRefClock; - if (m_pRefClock) m_pRefClock->AddRef(); - } - - // Set event sink for notifications - // The filter should call this in its JoinFilterGraph after it creates the - // IMediaEventSink - // - void SetFilterGraph( IMediaEventSink *pSink ) { - m_pSink = pSink; - } - - // Since we schedule in stream time, we need the tStart and must track the - // state of our owning filter. - // The app should call this ever state change - // - void NotifyFilterState( FILTER_STATE new_state, REFERENCE_TIME tStart = 0 ); - - // Filter should call Flushing(TRUE) in BeginFlush, - // and Flushing(FALSE) in EndFlush. - // - void Flushing( BOOL bInProgress ); - - - // The two main methods of IAMStreamControl - - // Class adds default values suitable for immediate - // muting and unmuting of the stream. - - STDMETHODIMP StopAt( const REFERENCE_TIME * ptStop = NULL, - BOOL bSendExtra = FALSE, - DWORD dwCookie = 0 ); - STDMETHODIMP StartAt( const REFERENCE_TIME * ptStart = NULL, - DWORD dwCookie = 0 ); - STDMETHODIMP GetInfo( AM_STREAM_INFO *pInfo); - - // Helper function for pin's receive method. Call this with - // the sample and we'll tell you what to do with it. We'll do a - // WaitForSingleObject within this call if one is required. This is - // a "What should I do with this sample?" kind of call. We'll tell the - // caller to either flow it or discard it. - // If pSample is NULL we evaluate based on the current state - // settings - enum StreamControlState CheckStreamState( IMediaSample * pSample ); - -private: - // These don't require locking, but we are relying on the fact that - // m_StreamState can be retrieved with integrity, and is a snap shot that - // may have just been, or may be just about to be, changed. - HANDLE GetStreamEventHandle() const { return m_StreamEvent; } - enum StreamControlState GetStreamState() const { return m_StreamState; } - BOOL IsStreaming() const { return m_StreamState == STREAM_FLOWING; } -}; - -#endif diff --git a/plugins/gs/gsdx9/baseclasses/strmiids.lib b/plugins/gs/gsdx9/baseclasses/strmiids.lib deleted file mode 100644 index bd8725da07..0000000000 Binary files a/plugins/gs/gsdx9/baseclasses/strmiids.lib and /dev/null differ diff --git a/plugins/gs/gsdx9/baseclasses/sysclock.cpp b/plugins/gs/gsdx9/baseclasses/sysclock.cpp deleted file mode 100644 index ed8f3fe912..0000000000 --- a/plugins/gs/gsdx9/baseclasses/sysclock.cpp +++ /dev/null @@ -1,74 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SysClock.cpp -// -// Desc: DirectShow base classes - implements a system clock based on -// IReferenceClock. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - - -#ifdef FILTER_DLL - -/* List of class IDs and creator functions for the class factory. This - provides the link between the OLE entry point in the DLL and an object - being created. The class factory will call the static CreateInstance - function when it is asked to create a CLSID_SystemClock object */ - -CFactoryTemplate g_Templates[1] = { - {&CLSID_SystemClock, CSystemClock::CreateInstance} -}; - -int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]); -#endif - -/* This goes in the factory template table to create new instances */ -CUnknown * WINAPI CSystemClock::CreateInstance(LPUNKNOWN pUnk,HRESULT *phr) -{ - return new CSystemClock(NAME("System reference clock"),pUnk, phr); -} - - -CSystemClock::CSystemClock(TCHAR *pName,LPUNKNOWN pUnk,HRESULT *phr) : - CBaseReferenceClock(pName, pUnk, phr) -{ -} - -STDMETHODIMP CSystemClock::NonDelegatingQueryInterface( - REFIID riid, - void ** ppv) -{ - if (riid == IID_IPersist) - { - return GetInterface(static_cast(this), ppv); - } - else if (riid == IID_IAMClockAdjust) - { - return GetInterface(static_cast(this), ppv); - } - else - { - return CBaseReferenceClock::NonDelegatingQueryInterface(riid, ppv); - } -} - -/* Return the clock's clsid */ -STDMETHODIMP -CSystemClock::GetClassID(CLSID *pClsID) -{ - CheckPointer(pClsID,E_POINTER); - ValidateReadWritePtr(pClsID,sizeof(CLSID)); - *pClsID = CLSID_SystemClock; - return NOERROR; -} - - -STDMETHODIMP -CSystemClock::SetClockDelta(REFERENCE_TIME rtDelta) -{ - return SetTimeDelta(rtDelta); -} diff --git a/plugins/gs/gsdx9/baseclasses/sysclock.h b/plugins/gs/gsdx9/baseclasses/sysclock.h deleted file mode 100644 index 53c8e4cefe..0000000000 --- a/plugins/gs/gsdx9/baseclasses/sysclock.h +++ /dev/null @@ -1,39 +0,0 @@ -//------------------------------------------------------------------------------ -// File: SysClock.h -// -// Desc: DirectShow base classes - defines a system clock implementation of -// IReferenceClock. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __SYSTEMCLOCK__ -#define __SYSTEMCLOCK__ - -// -// Base clock. Uses timeGetTime ONLY -// Uses most of the code in the base reference clock. -// Provides GetTime -// - -class CSystemClock : public CBaseReferenceClock, public IAMClockAdjust, public IPersist -{ -public: - // We must be able to create an instance of ourselves - static CUnknown * WINAPI CreateInstance(LPUNKNOWN pUnk, HRESULT *phr); - CSystemClock(TCHAR *pName, LPUNKNOWN pUnk, HRESULT *phr); - - DECLARE_IUNKNOWN - - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void ** ppv); - - // Yield up our class id so that we can be persisted - // Implement required Ipersist method - STDMETHODIMP GetClassID(CLSID *pClsID); - - // IAMClockAdjust methods - STDMETHODIMP SetClockDelta(REFERENCE_TIME rtDelta); -}; //CSystemClock - -#endif /* __SYSTEMCLOCK__ */ diff --git a/plugins/gs/gsdx9/baseclasses/transfrm.cpp b/plugins/gs/gsdx9/baseclasses/transfrm.cpp deleted file mode 100644 index 58d1090b18..0000000000 --- a/plugins/gs/gsdx9/baseclasses/transfrm.cpp +++ /dev/null @@ -1,1016 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Transfrm.cpp -// -// Desc: DirectShow base classes - implements class for simple transform -// filters such as video decompressors. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include - - -// ================================================================= -// Implements the CTransformFilter class -// ================================================================= - -CTransformFilter::CTransformFilter(TCHAR *pName, - LPUNKNOWN pUnk, - REFCLSID clsid) : - CBaseFilter(pName,pUnk,&m_csFilter, clsid), - m_pInput(NULL), - m_pOutput(NULL), - m_bEOSDelivered(FALSE), - m_bQualityChanged(FALSE), - m_bSampleSkipped(FALSE) -{ -#ifdef PERF - RegisterPerfId(); -#endif // PERF -} - -#ifdef UNICODE -CTransformFilter::CTransformFilter(char *pName, - LPUNKNOWN pUnk, - REFCLSID clsid) : - CBaseFilter(pName,pUnk,&m_csFilter, clsid), - m_pInput(NULL), - m_pOutput(NULL), - m_bEOSDelivered(FALSE), - m_bQualityChanged(FALSE), - m_bSampleSkipped(FALSE) -{ -#ifdef PERF - RegisterPerfId(); -#endif // PERF -} -#endif - -// destructor - -CTransformFilter::~CTransformFilter() -{ - // Delete the pins - - delete m_pInput; - delete m_pOutput; -} - - -// Transform place holder - should never be called -HRESULT CTransformFilter::Transform(IMediaSample * pIn, IMediaSample *pOut) -{ - UNREFERENCED_PARAMETER(pIn); - UNREFERENCED_PARAMETER(pOut); - DbgBreak("CTransformFilter::Transform() should never be called"); - return E_UNEXPECTED; -} - - -// return the number of pins we provide - -int CTransformFilter::GetPinCount() -{ - return 2; -} - - -// return a non-addrefed CBasePin * for the user to addref if he holds onto it -// for longer than his pointer to us. We create the pins dynamically when they -// are asked for rather than in the constructor. This is because we want to -// give the derived class an oppportunity to return different pin objects - -// We return the objects as and when they are needed. If either of these fails -// then we return NULL, the assumption being that the caller will realise the -// whole deal is off and destroy us - which in turn will delete everything. - -CBasePin * -CTransformFilter::GetPin(int n) -{ - HRESULT hr = S_OK; - - // Create an input pin if necessary - - if (m_pInput == NULL) { - - m_pInput = new CTransformInputPin(NAME("Transform input pin"), - this, // Owner filter - &hr, // Result code - L"XForm In"); // Pin name - - - // Can't fail - ASSERT(SUCCEEDED(hr)); - if (m_pInput == NULL) { - return NULL; - } - m_pOutput = (CTransformOutputPin *) - new CTransformOutputPin(NAME("Transform output pin"), - this, // Owner filter - &hr, // Result code - L"XForm Out"); // Pin name - - - // Can't fail - ASSERT(SUCCEEDED(hr)); - if (m_pOutput == NULL) { - delete m_pInput; - m_pInput = NULL; - } - } - - // Return the appropriate pin - - if (n == 0) { - return m_pInput; - } else - if (n == 1) { - return m_pOutput; - } else { - return NULL; - } -} - - -// -// FindPin -// -// If Id is In or Out then return the IPin* for that pin -// creating the pin if need be. Otherwise return NULL with an error. - -STDMETHODIMP CTransformFilter::FindPin(LPCWSTR Id, IPin **ppPin) -{ - CheckPointer(ppPin,E_POINTER); - ValidateReadWritePtr(ppPin,sizeof(IPin *)); - - if (0==lstrcmpW(Id,L"In")) { - *ppPin = GetPin(0); - } else if (0==lstrcmpW(Id,L"Out")) { - *ppPin = GetPin(1); - } else { - *ppPin = NULL; - return VFW_E_NOT_FOUND; - } - - HRESULT hr = NOERROR; - // AddRef() returned pointer - but GetPin could fail if memory is low. - if (*ppPin) { - (*ppPin)->AddRef(); - } else { - hr = E_OUTOFMEMORY; // probably. There's no pin anyway. - } - return hr; -} - - -// override these two functions if you want to inform something -// about entry to or exit from streaming state. - -HRESULT -CTransformFilter::StartStreaming() -{ - return NOERROR; -} - - -HRESULT -CTransformFilter::StopStreaming() -{ - return NOERROR; -} - - -// override this to grab extra interfaces on connection - -HRESULT -CTransformFilter::CheckConnect(PIN_DIRECTION dir,IPin *pPin) -{ - UNREFERENCED_PARAMETER(dir); - UNREFERENCED_PARAMETER(pPin); - return NOERROR; -} - - -// place holder to allow derived classes to release any extra interfaces - -HRESULT -CTransformFilter::BreakConnect(PIN_DIRECTION dir) -{ - UNREFERENCED_PARAMETER(dir); - return NOERROR; -} - - -// Let derived classes know about connection completion - -HRESULT -CTransformFilter::CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin) -{ - UNREFERENCED_PARAMETER(direction); - UNREFERENCED_PARAMETER(pReceivePin); - return NOERROR; -} - - -// override this to know when the media type is really set - -HRESULT -CTransformFilter::SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt) -{ - UNREFERENCED_PARAMETER(direction); - UNREFERENCED_PARAMETER(pmt); - return NOERROR; -} - - -// Set up our output sample -HRESULT -CTransformFilter::InitializeOutputSample(IMediaSample *pSample, IMediaSample **ppOutSample) -{ - IMediaSample *pOutSample; - - // default - times are the same - - AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); - DWORD dwFlags = m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0; - - // This will prevent the image renderer from switching us to DirectDraw - // when we can't do it without skipping frames because we're not on a - // keyframe. If it really has to switch us, it still will, but then we - // will have to wait for the next keyframe - if (!(pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT)) { - dwFlags |= AM_GBF_NOTASYNCPOINT; - } - - ASSERT(m_pOutput->m_pAllocator != NULL); - HRESULT hr = m_pOutput->m_pAllocator->GetBuffer( - &pOutSample - , pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID ? - &pProps->tStart : NULL - , pProps->dwSampleFlags & AM_SAMPLE_STOPVALID ? - &pProps->tStop : NULL - , dwFlags - ); - *ppOutSample = pOutSample; - if (FAILED(hr)) { - return hr; - } - - ASSERT(pOutSample); - IMediaSample2 *pOutSample2; - if (SUCCEEDED(pOutSample->QueryInterface(IID_IMediaSample2, - (void **)&pOutSample2))) { - /* Modify it */ - AM_SAMPLE2_PROPERTIES OutProps; - EXECUTE_ASSERT(SUCCEEDED(pOutSample2->GetProperties( - FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, tStart), (PBYTE)&OutProps) - )); - OutProps.dwTypeSpecificFlags = pProps->dwTypeSpecificFlags; - OutProps.dwSampleFlags = - (OutProps.dwSampleFlags & AM_SAMPLE_TYPECHANGED) | - (pProps->dwSampleFlags & ~AM_SAMPLE_TYPECHANGED); - OutProps.tStart = pProps->tStart; - OutProps.tStop = pProps->tStop; - OutProps.cbData = FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId); - hr = pOutSample2->SetProperties( - FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, dwStreamId), - (PBYTE)&OutProps - ); - if (pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) { - m_bSampleSkipped = FALSE; - } - pOutSample2->Release(); - } else { - if (pProps->dwSampleFlags & AM_SAMPLE_TIMEVALID) { - pOutSample->SetTime(&pProps->tStart, - &pProps->tStop); - } - if (pProps->dwSampleFlags & AM_SAMPLE_SPLICEPOINT) { - pOutSample->SetSyncPoint(TRUE); - } - if (pProps->dwSampleFlags & AM_SAMPLE_DATADISCONTINUITY) { - pOutSample->SetDiscontinuity(TRUE); - m_bSampleSkipped = FALSE; - } - // Copy the media times - - LONGLONG MediaStart, MediaEnd; - if (pSample->GetMediaTime(&MediaStart,&MediaEnd) == NOERROR) { - pOutSample->SetMediaTime(&MediaStart,&MediaEnd); - } - } - return S_OK; -} - -// override this to customize the transform process - -HRESULT -CTransformFilter::Receive(IMediaSample *pSample) -{ - /* Check for other streams and pass them on */ - AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); - if (pProps->dwStreamId != AM_STREAM_MEDIA) { - return m_pOutput->m_pInputPin->Receive(pSample); - } - HRESULT hr; - ASSERT(pSample); - IMediaSample * pOutSample; - - // If no output to deliver to then no point sending us data - - ASSERT (m_pOutput != NULL) ; - - // Set up the output sample - hr = InitializeOutputSample(pSample, &pOutSample); - - if (FAILED(hr)) { - return hr; - } - - // Start timing the transform (if PERF is defined) - MSR_START(m_idTransform); - - // have the derived class transform the data - - hr = Transform(pSample, pOutSample); - - // Stop the clock and log it (if PERF is defined) - MSR_STOP(m_idTransform); - - if (FAILED(hr)) { - DbgLog((LOG_TRACE,1,TEXT("Error from transform"))); - } else { - // the Transform() function can return S_FALSE to indicate that the - // sample should not be delivered; we only deliver the sample if it's - // really S_OK (same as NOERROR, of course.) - if (hr == NOERROR) { - hr = m_pOutput->m_pInputPin->Receive(pOutSample); - m_bSampleSkipped = FALSE; // last thing no longer dropped - } else { - // S_FALSE returned from Transform is a PRIVATE agreement - // We should return NOERROR from Receive() in this cause because returning S_FALSE - // from Receive() means that this is the end of the stream and no more data should - // be sent. - if (S_FALSE == hr) { - - // Release the sample before calling notify to avoid - // deadlocks if the sample holds a lock on the system - // such as DirectDraw buffers do - pOutSample->Release(); - m_bSampleSkipped = TRUE; - if (!m_bQualityChanged) { - NotifyEvent(EC_QUALITY_CHANGE,0,0); - m_bQualityChanged = TRUE; - } - return NOERROR; - } - } - } - - // release the output buffer. If the connected pin still needs it, - // it will have addrefed it itself. - pOutSample->Release(); - - return hr; -} - - -// Return S_FALSE to mean "pass the note on upstream" -// Return NOERROR (Same as S_OK) -// to mean "I've done something about it, don't pass it on" -HRESULT CTransformFilter::AlterQuality(Quality q) -{ - UNREFERENCED_PARAMETER(q); - return S_FALSE; -} - - -// EndOfStream received. Default behaviour is to deliver straight -// downstream, since we have no queued data. If you overrode Receive -// and have queue data, then you need to handle this and deliver EOS after -// all queued data is sent -HRESULT -CTransformFilter::EndOfStream(void) -{ - HRESULT hr = NOERROR; - if (m_pOutput != NULL) { - hr = m_pOutput->DeliverEndOfStream(); - } - - return hr; -} - - -// enter flush state. Receives already blocked -// must override this if you have queued data or a worker thread -HRESULT -CTransformFilter::BeginFlush(void) -{ - HRESULT hr = NOERROR; - if (m_pOutput != NULL) { - // block receives -- done by caller (CBaseInputPin::BeginFlush) - - // discard queued data -- we have no queued data - - // free anyone blocked on receive - not possible in this filter - - // call downstream - hr = m_pOutput->DeliverBeginFlush(); - } - return hr; -} - - -// leave flush state. must override this if you have queued data -// or a worker thread -HRESULT -CTransformFilter::EndFlush(void) -{ - // sync with pushing thread -- we have no worker thread - - // ensure no more data to go downstream -- we have no queued data - - // call EndFlush on downstream pins - ASSERT (m_pOutput != NULL); - return m_pOutput->DeliverEndFlush(); - - // caller (the input pin's method) will unblock Receives -} - - -// override these so that the derived filter can catch them - -STDMETHODIMP -CTransformFilter::Stop() -{ - CAutoLock lck1(&m_csFilter); - if (m_State == State_Stopped) { - return NOERROR; - } - - // Succeed the Stop if we are not completely connected - - ASSERT(m_pInput == NULL || m_pOutput != NULL); - if (m_pInput == NULL || m_pInput->IsConnected() == FALSE || - m_pOutput->IsConnected() == FALSE) { - m_State = State_Stopped; - m_bEOSDelivered = FALSE; - return NOERROR; - } - - ASSERT(m_pInput); - ASSERT(m_pOutput); - - // decommit the input pin before locking or we can deadlock - m_pInput->Inactive(); - - // synchronize with Receive calls - - CAutoLock lck2(&m_csReceive); - m_pOutput->Inactive(); - - // allow a class derived from CTransformFilter - // to know about starting and stopping streaming - - HRESULT hr = StopStreaming(); - if (SUCCEEDED(hr)) { - // complete the state transition - m_State = State_Stopped; - m_bEOSDelivered = FALSE; - } - return hr; -} - - -STDMETHODIMP -CTransformFilter::Pause() -{ - CAutoLock lck(&m_csFilter); - HRESULT hr = NOERROR; - - if (m_State == State_Paused) { - // (This space left deliberately blank) - } - - // If we have no input pin or it isn't yet connected then when we are - // asked to pause we deliver an end of stream to the downstream filter. - // This makes sure that it doesn't sit there forever waiting for - // samples which we cannot ever deliver without an input connection. - - else if (m_pInput == NULL || m_pInput->IsConnected() == FALSE) { - if (m_pOutput && m_bEOSDelivered == FALSE) { - m_pOutput->DeliverEndOfStream(); - m_bEOSDelivered = TRUE; - } - m_State = State_Paused; - } - - // We may have an input connection but no output connection - // However, if we have an input pin we do have an output pin - - else if (m_pOutput->IsConnected() == FALSE) { - m_State = State_Paused; - } - - else { - if (m_State == State_Stopped) { - // allow a class derived from CTransformFilter - // to know about starting and stopping streaming - CAutoLock lck2(&m_csReceive); - hr = StartStreaming(); - } - if (SUCCEEDED(hr)) { - hr = CBaseFilter::Pause(); - } - } - - m_bSampleSkipped = FALSE; - m_bQualityChanged = FALSE; - return hr; -} - -HRESULT -CTransformFilter::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) -{ - if (m_pOutput != NULL) { - return m_pOutput->DeliverNewSegment(tStart, tStop, dRate); - } - return S_OK; -} - -// Check streaming status -HRESULT -CTransformInputPin::CheckStreaming() -{ - ASSERT(m_pTransformFilter->m_pOutput != NULL); - if (!m_pTransformFilter->m_pOutput->IsConnected()) { - return VFW_E_NOT_CONNECTED; - } else { - // Shouldn't be able to get any data if we're not connected! - ASSERT(IsConnected()); - - // we're flushing - if (m_bFlushing) { - return S_FALSE; - } - // Don't process stuff in Stopped state - if (IsStopped()) { - return VFW_E_WRONG_STATE; - } - if (m_bRunTimeError) { - return VFW_E_RUNTIME_ERROR; - } - return S_OK; - } -} - - -// ================================================================= -// Implements the CTransformInputPin class -// ================================================================= - - -// constructor - -CTransformInputPin::CTransformInputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName) - : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName) -{ - DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin"))); - m_pTransformFilter = pTransformFilter; -} - -#ifdef UNICODE -CTransformInputPin::CTransformInputPin( - CHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName) - : CBaseInputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pName) -{ - DbgLog((LOG_TRACE,2,TEXT("CTransformInputPin::CTransformInputPin"))); - m_pTransformFilter = pTransformFilter; -} -#endif - -// provides derived filter a chance to grab extra interfaces - -HRESULT -CTransformInputPin::CheckConnect(IPin *pPin) -{ - HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_INPUT,pPin); - if (FAILED(hr)) { - return hr; - } - return CBaseInputPin::CheckConnect(pPin); -} - - -// provides derived filter a chance to release it's extra interfaces - -HRESULT -CTransformInputPin::BreakConnect() -{ - // Can't disconnect unless stopped - ASSERT(IsStopped()); - m_pTransformFilter->BreakConnect(PINDIR_INPUT); - return CBaseInputPin::BreakConnect(); -} - - -// Let derived class know when the input pin is connected - -HRESULT -CTransformInputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_INPUT,pReceivePin); - if (FAILED(hr)) { - return hr; - } - return CBaseInputPin::CompleteConnect(pReceivePin); -} - - -// check that we can support a given media type - -HRESULT -CTransformInputPin::CheckMediaType(const CMediaType* pmt) -{ - // Check the input type - - HRESULT hr = m_pTransformFilter->CheckInputType(pmt); - if (S_OK != hr) { - return hr; - } - - // if the output pin is still connected, then we have - // to check the transform not just the input format - - if ((m_pTransformFilter->m_pOutput != NULL) && - (m_pTransformFilter->m_pOutput->IsConnected())) { - return m_pTransformFilter->CheckTransform( - pmt, - &m_pTransformFilter->m_pOutput->CurrentMediaType()); - } else { - return hr; - } -} - - -// set the media type for this connection - -HRESULT -CTransformInputPin::SetMediaType(const CMediaType* mtIn) -{ - // Set the base class media type (should always succeed) - HRESULT hr = CBasePin::SetMediaType(mtIn); - if (FAILED(hr)) { - return hr; - } - - // check the transform can be done (should always succeed) - ASSERT(SUCCEEDED(m_pTransformFilter->CheckInputType(mtIn))); - - return m_pTransformFilter->SetMediaType(PINDIR_INPUT,mtIn); -} - - -// ================================================================= -// Implements IMemInputPin interface -// ================================================================= - - -// provide EndOfStream that passes straight downstream -// (there is no queued data) -STDMETHODIMP -CTransformInputPin::EndOfStream(void) -{ - CAutoLock lck(&m_pTransformFilter->m_csReceive); - HRESULT hr = CheckStreaming(); - if (S_OK == hr) { - hr = m_pTransformFilter->EndOfStream(); - } - return hr; -} - - -// enter flushing state. Call default handler to block Receives, then -// pass to overridable method in filter -STDMETHODIMP -CTransformInputPin::BeginFlush(void) -{ - CAutoLock lck(&m_pTransformFilter->m_csFilter); - // Are we actually doing anything? - ASSERT(m_pTransformFilter->m_pOutput != NULL); - if (!IsConnected() || - !m_pTransformFilter->m_pOutput->IsConnected()) { - return VFW_E_NOT_CONNECTED; - } - HRESULT hr = CBaseInputPin::BeginFlush(); - if (FAILED(hr)) { - return hr; - } - - return m_pTransformFilter->BeginFlush(); -} - - -// leave flushing state. -// Pass to overridable method in filter, then call base class -// to unblock receives (finally) -STDMETHODIMP -CTransformInputPin::EndFlush(void) -{ - CAutoLock lck(&m_pTransformFilter->m_csFilter); - // Are we actually doing anything? - ASSERT(m_pTransformFilter->m_pOutput != NULL); - if (!IsConnected() || - !m_pTransformFilter->m_pOutput->IsConnected()) { - return VFW_E_NOT_CONNECTED; - } - - HRESULT hr = m_pTransformFilter->EndFlush(); - if (FAILED(hr)) { - return hr; - } - - return CBaseInputPin::EndFlush(); -} - - -// here's the next block of data from the stream. -// AddRef it yourself if you need to hold it beyond the end -// of this call. - -HRESULT -CTransformInputPin::Receive(IMediaSample * pSample) -{ - HRESULT hr; - CAutoLock lck(&m_pTransformFilter->m_csReceive); - ASSERT(pSample); - - // check all is well with the base class - hr = CBaseInputPin::Receive(pSample); - if (S_OK == hr) { - hr = m_pTransformFilter->Receive(pSample); - } - return hr; -} - - - - -// override to pass downstream -STDMETHODIMP -CTransformInputPin::NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate) -{ - // Save the values in the pin - CBasePin::NewSegment(tStart, tStop, dRate); - return m_pTransformFilter->NewSegment(tStart, tStop, dRate); -} - - - - -// ================================================================= -// Implements the CTransformOutputPin class -// ================================================================= - - -// constructor - -CTransformOutputPin::CTransformOutputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName), - m_pPosition(NULL) -{ - DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin"))); - m_pTransformFilter = pTransformFilter; - -} - -#ifdef UNICODE -CTransformOutputPin::CTransformOutputPin( - CHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pPinName) - : CBaseOutputPin(pObjectName, pTransformFilter, &pTransformFilter->m_csFilter, phr, pPinName), - m_pPosition(NULL) -{ - DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::CTransformOutputPin"))); - m_pTransformFilter = pTransformFilter; - -} -#endif - -// destructor - -CTransformOutputPin::~CTransformOutputPin() -{ - DbgLog((LOG_TRACE,2,TEXT("CTransformOutputPin::~CTransformOutputPin"))); - - if (m_pPosition) m_pPosition->Release(); -} - - -// overriden to expose IMediaPosition and IMediaSeeking control interfaces - -STDMETHODIMP -CTransformOutputPin::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - CheckPointer(ppv,E_POINTER); - ValidateReadWritePtr(ppv,sizeof(PVOID)); - *ppv = NULL; - - if (riid == IID_IMediaPosition || riid == IID_IMediaSeeking) { - - // we should have an input pin by now - - ASSERT(m_pTransformFilter->m_pInput != NULL); - - if (m_pPosition == NULL) { - - HRESULT hr = CreatePosPassThru( - GetOwner(), - FALSE, - (IPin *)m_pTransformFilter->m_pInput, - &m_pPosition); - if (FAILED(hr)) { - return hr; - } - } - return m_pPosition->QueryInterface(riid, ppv); - } else { - return CBaseOutputPin::NonDelegatingQueryInterface(riid, ppv); - } -} - - -// provides derived filter a chance to grab extra interfaces - -HRESULT -CTransformOutputPin::CheckConnect(IPin *pPin) -{ - // we should have an input connection first - - ASSERT(m_pTransformFilter->m_pInput != NULL); - if ((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) { - return E_UNEXPECTED; - } - - HRESULT hr = m_pTransformFilter->CheckConnect(PINDIR_OUTPUT,pPin); - if (FAILED(hr)) { - return hr; - } - return CBaseOutputPin::CheckConnect(pPin); -} - - -// provides derived filter a chance to release it's extra interfaces - -HRESULT -CTransformOutputPin::BreakConnect() -{ - // Can't disconnect unless stopped - ASSERT(IsStopped()); - m_pTransformFilter->BreakConnect(PINDIR_OUTPUT); - return CBaseOutputPin::BreakConnect(); -} - - -// Let derived class know when the output pin is connected - -HRESULT -CTransformOutputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin); - if (FAILED(hr)) { - return hr; - } - return CBaseOutputPin::CompleteConnect(pReceivePin); -} - - -// check a given transform - must have selected input type first - -HRESULT -CTransformOutputPin::CheckMediaType(const CMediaType* pmtOut) -{ - // must have selected input first - ASSERT(m_pTransformFilter->m_pInput != NULL); - if ((m_pTransformFilter->m_pInput->IsConnected() == FALSE)) { - return E_INVALIDARG; - } - - return m_pTransformFilter->CheckTransform( - &m_pTransformFilter->m_pInput->CurrentMediaType(), - pmtOut); -} - - -// called after we have agreed a media type to actually set it in which case -// we run the CheckTransform function to get the output format type again - -HRESULT -CTransformOutputPin::SetMediaType(const CMediaType* pmtOut) -{ - HRESULT hr = NOERROR; - ASSERT(m_pTransformFilter->m_pInput != NULL); - - ASSERT(m_pTransformFilter->m_pInput->CurrentMediaType().IsValid()); - - // Set the base class media type (should always succeed) - hr = CBasePin::SetMediaType(pmtOut); - if (FAILED(hr)) { - return hr; - } - -#ifdef DEBUG - if (FAILED(m_pTransformFilter->CheckTransform(&m_pTransformFilter-> - m_pInput->CurrentMediaType(),pmtOut))) { - DbgLog((LOG_ERROR,0,TEXT("*** This filter is accepting an output media type"))); - DbgLog((LOG_ERROR,0,TEXT(" that it can't currently transform to. I hope"))); - DbgLog((LOG_ERROR,0,TEXT(" it's smart enough to reconnect its input."))); - } -#endif - - return m_pTransformFilter->SetMediaType(PINDIR_OUTPUT,pmtOut); -} - - -// pass the buffer size decision through to the main transform class - -HRESULT -CTransformOutputPin::DecideBufferSize( - IMemAllocator * pAllocator, - ALLOCATOR_PROPERTIES* pProp) -{ - return m_pTransformFilter->DecideBufferSize(pAllocator, pProp); -} - - - -// return a specific media type indexed by iPosition - -HRESULT -CTransformOutputPin::GetMediaType( - int iPosition, - CMediaType *pMediaType) -{ - ASSERT(m_pTransformFilter->m_pInput != NULL); - - // We don't have any media types if our input is not connected - - if (m_pTransformFilter->m_pInput->IsConnected()) { - return m_pTransformFilter->GetMediaType(iPosition,pMediaType); - } else { - return VFW_S_NO_MORE_ITEMS; - } -} - - -// Override this if you can do something constructive to act on the -// quality message. Consider passing it upstream as well - -// Pass the quality mesage on upstream. - -STDMETHODIMP -CTransformOutputPin::Notify(IBaseFilter * pSender, Quality q) -{ - UNREFERENCED_PARAMETER(pSender); - ValidateReadPtr(pSender,sizeof(IBaseFilter)); - - // First see if we want to handle this ourselves - HRESULT hr = m_pTransformFilter->AlterQuality(q); - if (hr!=S_FALSE) { - return hr; // either S_OK or a failure - } - - // S_FALSE means we pass the message on. - // Find the quality sink for our input pin and send it there - - ASSERT(m_pTransformFilter->m_pInput != NULL); - - return m_pTransformFilter->m_pInput->PassNotify(q); - -} // Notify - - -// the following removes a very large number of level 4 warnings from the microsoft -// compiler output, which are not useful at all in this case. -#pragma warning(disable:4514) diff --git a/plugins/gs/gsdx9/baseclasses/transfrm.h b/plugins/gs/gsdx9/baseclasses/transfrm.h deleted file mode 100644 index 55a07dcab5..0000000000 --- a/plugins/gs/gsdx9/baseclasses/transfrm.h +++ /dev/null @@ -1,304 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Transfrm.h -// -// Desc: DirectShow base classes - defines classes from which simple -// transform codecs may be derived. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// It assumes the codec has one input and one output stream, and has no -// interest in memory management, interface negotiation or anything else. -// -// derive your class from this, and supply Transform and the media type/format -// negotiation functions. Implement that class, compile and link and -// you're done. - - -#ifndef __TRANSFRM__ -#define __TRANSFRM__ - -// ====================================================================== -// This is the com object that represents a simple transform filter. It -// supports IBaseFilter, IMediaFilter and two pins through nested interfaces -// ====================================================================== - -class CTransformFilter; - -// ================================================== -// Implements the input pin -// ================================================== - -class CTransformInputPin : public CBaseInputPin -{ - friend class CTransformFilter; - -protected: - CTransformFilter *m_pTransformFilter; - - -public: - - CTransformInputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#ifdef UNICODE - CTransformInputPin( - char *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#endif - - STDMETHODIMP QueryId(LPWSTR * Id) - { - return AMGetWideString(L"In", Id); - } - - // Grab and release extra interfaces if required - - HRESULT CheckConnect(IPin *pPin); - HRESULT BreakConnect(); - HRESULT CompleteConnect(IPin *pReceivePin); - - // check that we can support this output type - HRESULT CheckMediaType(const CMediaType* mtIn); - - // set the connection media type - HRESULT SetMediaType(const CMediaType* mt); - - // --- IMemInputPin ----- - - // here's the next block of data from the stream. - // AddRef it yourself if you need to hold it beyond the end - // of this call. - STDMETHODIMP Receive(IMediaSample * pSample); - - // provide EndOfStream that passes straight downstream - // (there is no queued data) - STDMETHODIMP EndOfStream(void); - - // passes it to CTransformFilter::BeginFlush - STDMETHODIMP BeginFlush(void); - - // passes it to CTransformFilter::EndFlush - STDMETHODIMP EndFlush(void); - - STDMETHODIMP NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - - // Check if it's OK to process samples - virtual HRESULT CheckStreaming(); - - // Media type -public: - CMediaType& CurrentMediaType() { return m_mt; }; - -}; - -// ================================================== -// Implements the output pin -// ================================================== - -class CTransformOutputPin : public CBaseOutputPin -{ - friend class CTransformFilter; - -protected: - CTransformFilter *m_pTransformFilter; - -public: - - // implement IMediaPosition by passing upstream - IUnknown * m_pPosition; - - CTransformOutputPin( - TCHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#ifdef UNICODE - CTransformOutputPin( - CHAR *pObjectName, - CTransformFilter *pTransformFilter, - HRESULT * phr, - LPCWSTR pName); -#endif - ~CTransformOutputPin(); - - // override to expose IMediaPosition - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid, void **ppv); - - // --- CBaseOutputPin ------------ - - STDMETHODIMP QueryId(LPWSTR * Id) - { - return AMGetWideString(L"Out", Id); - } - - // Grab and release extra interfaces if required - - HRESULT CheckConnect(IPin *pPin); - HRESULT BreakConnect(); - HRESULT CompleteConnect(IPin *pReceivePin); - - // check that we can support this output type - HRESULT CheckMediaType(const CMediaType* mtOut); - - // set the connection media type - HRESULT SetMediaType(const CMediaType *pmt); - - // called from CBaseOutputPin during connection to ask for - // the count and size of buffers we need. - HRESULT DecideBufferSize( - IMemAllocator * pAlloc, - ALLOCATOR_PROPERTIES *pProp); - - // returns the preferred formats for a pin - HRESULT GetMediaType(int iPosition,CMediaType *pMediaType); - - // inherited from IQualityControl via CBasePin - STDMETHODIMP Notify(IBaseFilter * pSender, Quality q); - - // Media type -public: - CMediaType& CurrentMediaType() { return m_mt; }; -}; - - -class AM_NOVTABLE CTransformFilter : public CBaseFilter -{ - -public: - - // map getpin/getpincount for base enum of pins to owner - // override this to return more specialised pin objects - - virtual int GetPinCount(); - virtual CBasePin * GetPin(int n); - STDMETHODIMP FindPin(LPCWSTR Id, IPin **ppPin); - - // override state changes to allow derived transform filter - // to control streaming start/stop - STDMETHODIMP Stop(); - STDMETHODIMP Pause(); - -public: - - CTransformFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid); -#ifdef UNICODE - CTransformFilter(CHAR *, LPUNKNOWN, REFCLSID clsid); -#endif - ~CTransformFilter(); - - // ================================================================= - // ----- override these bits --------------------------------------- - // ================================================================= - - // These must be supplied in a derived class - - virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut); - - // check if you can support mtIn - virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE; - - // check if you can support the transform from this input to this output - virtual HRESULT CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut) PURE; - - // this goes in the factory template table to create new instances - // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *); - - // call the SetProperties function with appropriate arguments - virtual HRESULT DecideBufferSize( - IMemAllocator * pAllocator, - ALLOCATOR_PROPERTIES *pprop) PURE; - - // override to suggest OUTPUT pin media types - virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) PURE; - - - - // ================================================================= - // ----- Optional Override Methods ----------------------- - // ================================================================= - - // you can also override these if you want to know about streaming - virtual HRESULT StartStreaming(); - virtual HRESULT StopStreaming(); - - // override if you can do anything constructive with quality notifications - virtual HRESULT AlterQuality(Quality q); - - // override this to know when the media type is actually set - virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt); - - // chance to grab extra interfaces on connection - virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin); - virtual HRESULT BreakConnect(PIN_DIRECTION dir); - virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin); - - // chance to customize the transform process - virtual HRESULT Receive(IMediaSample *pSample); - - // Standard setup for output sample - HRESULT InitializeOutputSample(IMediaSample *pSample, IMediaSample **ppOutSample); - - // if you override Receive, you may need to override these three too - virtual HRESULT EndOfStream(void); - virtual HRESULT BeginFlush(void); - virtual HRESULT EndFlush(void); - virtual HRESULT NewSegment( - REFERENCE_TIME tStart, - REFERENCE_TIME tStop, - double dRate); - -#ifdef PERF - // Override to register performance measurement with a less generic string - // You should do this to avoid confusion with other filters - virtual void RegisterPerfId() - {m_idTransform = MSR_REGISTER(TEXT("Transform"));} -#endif // PERF - - -// implementation details - -protected: - -#ifdef PERF - int m_idTransform; // performance measuring id -#endif - BOOL m_bEOSDelivered; // have we sent EndOfStream - BOOL m_bSampleSkipped; // Did we just skip a frame - BOOL m_bQualityChanged; // Have we degraded? - - // critical section protecting filter state. - - CCritSec m_csFilter; - - // critical section stopping state changes (ie Stop) while we're - // processing a sample. - // - // This critical section is held when processing - // events that occur on the receive thread - Receive() and EndOfStream(). - // - // If you want to hold both m_csReceive and m_csFilter then grab - // m_csFilter FIRST - like CTransformFilter::Stop() does. - - CCritSec m_csReceive; - - // these hold our input and output pins - - friend class CTransformInputPin; - friend class CTransformOutputPin; - CTransformInputPin *m_pInput; - CTransformOutputPin *m_pOutput; -}; - -#endif /* __TRANSFRM__ */ - - diff --git a/plugins/gs/gsdx9/baseclasses/transip.cpp b/plugins/gs/gsdx9/baseclasses/transip.cpp deleted file mode 100644 index 538b018bd4..0000000000 --- a/plugins/gs/gsdx9/baseclasses/transip.cpp +++ /dev/null @@ -1,966 +0,0 @@ -//------------------------------------------------------------------------------ -// File: TransIP.cpp -// -// Desc: DirectShow base classes - implements class for simple Transform- -// In-Place filters such as audio. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// How allocators are decided. -// -// An in-place transform tries to do its work in someone else's buffers. -// It tries to persuade the filters on either side to use the same allocator -// (and for that matter the same media type). In desperation, if the downstream -// filter refuses to supply an allocator and the upstream filter offers only -// a read-only one then it will provide an allocator. -// if the upstream filter insists on a read-only allocator then the transform -// filter will (reluctantly) copy the data before transforming it. -// -// In order to pass an allocator through it needs to remember the one it got -// from the first connection to pass it on to the second one. -// -// It is good if we can avoid insisting on a particular order of connection -// (There is a precedent for insisting on the input -// being connected first. Insisting on the output being connected first is -// not allowed. That would break RenderFile.) -// -// The base pin classes (CBaseOutputPin and CBaseInputPin) both have a -// m_pAllocator member which is used in places like -// CBaseOutputPin::GetDeliveryBuffer and CBaseInputPin::Inactive. -// To avoid lots of extra overriding, we should keep these happy -// by using these pointers. -// -// When each pin is connected, it will set the corresponding m_pAllocator -// and will have a single ref-count on that allocator. -// -// Refcounts are acquired by GetAllocator calls which return AddReffed -// allocators and are released in one of: -// CBaseInputPin::Disconnect -// CBaseOutputPin::BreakConect -// In each case m_pAllocator is set to NULL after the release, so this -// is the last chance to ever release it. If there should ever be -// multiple refcounts associated with the same pointer, this had better -// be cleared up before that happens. To avoid such problems, we'll -// stick with one per pointer. - - - -// RECONNECTING and STATE CHANGES -// -// Each pin could be disconnected, connected with a read-only allocator, -// connected with an upstream read/write allocator, connected with an -// allocator from downstream or connected with its own allocator. -// Five states for each pin gives a data space of 25 states. -// -// Notation: -// -// R/W == read/write -// R-O == read-only -// -// -// -// 00 means an unconnected pin. -// <- means using a R/W allocator from the upstream filter -// <= means using a R-O allocator from an upstream filter -// || means using our own (R/W) allocator. -// -> means using a R/W allocator from a downstream filter -// (a R-O allocator from downstream is nonsense, it can't ever work). -// -// -// That makes 25 possible states. Some states are nonsense (two different -// allocators from the same place). These are just an artifact of the notation. -// <= <- Nonsense. -// <- <= Nonsense -// Some states are illegal (the output pin never accepts a R-O allocator): -// 00 <= !! Error !! -// <= <= !! Error !! -// || <= !! Error !! -// -> <= !! Error !! -// Three states appears to be inaccessible: -// -> || Inaccessible -// || -> Inaccessible -// || <- Inaccessible -// Some states only ever occur as intermediates with a pending reconnect which -// is guaranteed to finish in another state. -// -> 00 ?? unstable goes to || 00 -// 00 <- ?? unstable goes to 00 || -// -> <- ?? unstable goes to -> -> -// <- || ?? unstable goes to <- <- -// <- -> ?? unstable goes to <- <- -// And that leaves 11 possible resting states: -// 1 00 00 Nothing connected. -// 2 <- 00 Input pin connected. -// 3 <= 00 Input pin connected using R-O allocator. -// 4 || 00 Needs several state changes to get here. -// 5 00 || Output pin connected using our allocator -// 6 00 -> Downstream only connected -// 7 || || Undesirable but can be forced upon us. -// 8 <= || Copy forced. <= -> is preferable -// 9 <= -> OK - forced to copy. -// 10 <- <- Transform in place (ideal) -// 11 -> -> Transform in place (ideal) -// -// The object of the exercise is to ensure that we finish up in states -// 10 or 11 whenever possible. State 10 is only possible if the upstream -// filter has a R/W allocator (the AVI splitter notoriously -// doesn't) and state 11 is only possible if the downstream filter does -// offer an allocator. -// -// The transition table (entries marked * go via a reconnect) -// -// There are 8 possible transitions: -// A: Connect upstream to filter with R-O allocator that insists on using it. -// B: Connect upstream to filter with R-O allocator but chooses not to use it. -// C: Connect upstream to filter with R/W allocator and insists on using it. -// D: Connect upstream to filter with R/W allocator but chooses not to use it. -// E: Connect downstream to a filter that offers an allocator -// F: Connect downstream to a filter that does not offer an allocator -// G: disconnect upstream -// H: Disconnect downstream -// -// A B C D E F G H -// --------------------------------------------------------- -// 00 00 1 | 3 3 2 2 6 5 . . |1 00 00 -// <- 00 2 | . . . . *10/11 10 1 . |2 <- 00 -// <= 00 3 | . . . . *9/11 *7/8 1 . |3 <= 00 -// || 00 4 | . . . . *8 *7 1 . |4 || 00 -// 00 || 5 | 8 7 *10 7 . . . 1 |5 00 || -// 00 -> 6 | 9 11 *10 11 . . . 1 |6 00 -> -// || || 7 | . . . . . . 5 4 |7 || || -// <= || 8 | . . . . . . 5 3 |8 <= || -// <= -> 9 | . . . . . . 6 3 |9 <= -> -// <- <- 10| . . . . . . *5/6 2 |10 <- <- -// -> -> 11| . . . . . . 6 *2/3 |11 -> -> -// --------------------------------------------------------- -// A B C D E F G H -// -// All these states are accessible without requiring any filter to -// change its behaviour but not all transitions are accessible, for -// instance a transition from state 4 to anywhere other than -// state 8 requires that the upstream filter first offer a R-O allocator -// and then changes its mind and offer R/W. This is NOT allowable - it -// leads to things like the output pin getting a R/W allocator from -// upstream and then the input pin being told it can only have a R-O one. -// Note that you CAN change (say) the upstream filter for a different one, but -// only as a disconnect / connect, not as a Reconnect. (Exercise for -// the reader is to see how you get into state 4). -// -// The reconnection stuff goes as follows (some of the cases shown here as -// "no reconnect" may get one to finalise media type - an old story). -// If there is a reconnect where it says "no reconnect" here then the -// reconnection must not change the allocator choice. -// -// state 2: <- 00 transition E <- <- case C <- <- (no change) -// case D -> <- and then to -> -> -// -// state 2: <- 00 transition F <- <- (no reconnect) -// -// state 3: <= 00 transition E <= -> case A <= -> (no change) -// case B -> -> -// transition F <= || case A <= || (no change) -// case B || || -// -// state 4: || 00 transition E || || case B -> || and then all cases to -> -> -// F || || case B || || (no change) -// -// state 5: 00 || transition A <= || (no reconnect) -// B || || (no reconnect) -// C <- || all cases <- <- -// D || || (unfortunate, but upstream's choice) -// -// state 6: 00 -> transition A <= -> (no reconnect) -// B -> -> (no reconnect) -// C <- -> all cases <- <- -// D -> -> (no reconnect) -// -// state 10:<- <- transition G 00 <- case E 00 -> -// case F 00 || -// -// state 11:-> -> transition H -> 00 case A <= 00 (schizo) -// case B <= 00 -// case C <- 00 (schizo) -// case D <- 00 -// -// The Rules: -// To sort out media types: -// The input is reconnected -// if the input pin is connected and the output pin connects -// The output is reconnected -// If the output pin is connected -// and the input pin connects to a different media type -// -// To sort out allocators: -// The input is reconnected -// if the output disconnects and the input was using a downstream allocator -// The output pin calls SetAllocator to pass on a new allocator -// if the output is connected and -// if the input disconnects and the output was using an upstream allocator -// if the input acquires an allocator different from the output one -// and that new allocator is not R-O -// -// Data is copied (i.e. call getbuffer and copy the data before transforming it) -// if the two allocators are different. - - - -// CHAINS of filters: -// -// We sit between two filters (call them A and Z). We should finish up -// with the same allocator on both of our pins and that should be the -// same one that A and Z would have agreed on if we hadn't been in the -// way. Furthermore, it should not matter how many in-place transforms -// are in the way. Let B, C, D... be in-place transforms ("us"). -// Here's how it goes: -// -// 1. -// A connects to B. They agree on A's allocator. -// A-a->B -// -// 2. -// B connects to C. Same story. There is no point in a reconnect, but -// B will request an input reconnect anyway. -// A-a->B-a->C -// -// 3. -// C connects to Z. -// C insists on using A's allocator, but compromises by requesting a reconnect. -// of C's input. -// A-a->B-?->C-a->Z -// -// We now have pending reconnects on both A--->B and B--->C -// -// 4. -// The A--->B link is reconnected. -// A asks B for an allocator. B sees that it has a downstream connection so -// asks its downstream input pin i.e. C's input pin for an allocator. C sees -// that it too has a downstream connection so asks Z for an allocator. -// -// Even though Z's input pin is connected, it is being asked for an allocator. -// It could refuse, in which case the chain is done and will use A's allocator -// Alternatively, Z may supply one. A chooses either Z's or A's own one. -// B's input pin gets NotifyAllocator called to tell it the decision and it -// propagates this downstream by calling ReceiveAllocator on its output pin -// which calls NotifyAllocator on the next input pin downstream etc. -// If the choice is Z then it goes: -// A-z->B-a->C-a->Z -// A-z->B-z->C-a->Z -// A-z->B-z->C-z->Z -// -// And that's IT!! Any further (essentially spurious) reconnects peter out -// with no change in the chain. - -#include -#include -#include - - -// ================================================================= -// Implements the CTransInPlaceFilter class -// ================================================================= - -CTransInPlaceFilter::CTransInPlaceFilter - ( TCHAR *pName, - LPUNKNOWN pUnk, - REFCLSID clsid, - HRESULT *phr, - bool bModifiesData - ) - : CTransformFilter(pName, pUnk, clsid), - m_bModifiesData(bModifiesData) -{ -#ifdef PERF - RegisterPerfId(); -#endif // PERF - -} // constructor - -#ifdef UNICODE -CTransInPlaceFilter::CTransInPlaceFilter - ( CHAR *pName, - LPUNKNOWN pUnk, - REFCLSID clsid, - HRESULT *phr, - bool bModifiesData - ) - : CTransformFilter(pName, pUnk, clsid), - m_bModifiesData(bModifiesData) -{ -#ifdef PERF - RegisterPerfId(); -#endif // PERF - -} // constructor -#endif - -// return a non-addrefed CBasePin * for the user to addref if he holds onto it -// for longer than his pointer to us. We create the pins dynamically when they -// are asked for rather than in the constructor. This is because we want to -// give the derived class an oppportunity to return different pin objects - -// As soon as any pin is needed we create both (this is different from the -// usual transform filter) because enumerators, allocators etc are passed -// through from one pin to another and it becomes very painful if the other -// pin isn't there. If we fail to create either pin we ensure we fail both. - -CBasePin * -CTransInPlaceFilter::GetPin(int n) -{ - HRESULT hr = S_OK; - - // Create an input pin if not already done - - if (m_pInput == NULL) { - - m_pInput = new CTransInPlaceInputPin( NAME("TransInPlace input pin") - , this // Owner filter - , &hr // Result code - , L"Input" // Pin name - ); - - // Constructor for CTransInPlaceInputPin can't fail - ASSERT(SUCCEEDED(hr)); - } - - // Create an output pin if not already done - - if (m_pInput!=NULL && m_pOutput == NULL) { - - m_pOutput = new CTransInPlaceOutputPin( NAME("TransInPlace output pin") - , this // Owner filter - , &hr // Result code - , L"Output" // Pin name - ); - - // a failed return code should delete the object - - ASSERT(SUCCEEDED(hr)); - if (m_pOutput == NULL) { - delete m_pInput; - m_pInput = NULL; - } - } - - // Return the appropriate pin - - ASSERT (n>=0 && n<=1); - if (n == 0) { - return m_pInput; - } else if (n==1) { - return m_pOutput; - } else { - return NULL; - } - -} // GetPin - - - -// dir is the direction of our pin. -// pReceivePin is the pin we are connecting to. -HRESULT CTransInPlaceFilter::CompleteConnect(PIN_DIRECTION dir,IPin *pReceivePin) -{ - UNREFERENCED_PARAMETER(pReceivePin); - ASSERT(m_pInput); - ASSERT(m_pOutput); - - // if we are not part of a graph, then don't indirect the pointer - // this probably prevents use of the filter without a filtergraph - if (!m_pGraph) { - return VFW_E_NOT_IN_GRAPH; - } - - // Always reconnect the input to account for buffering changes - // - // Because we don't get to suggest a type on ReceiveConnection - // we need another way of making sure the right type gets used. - // - // One way would be to have our EnumMediaTypes return our output - // connection type first but more deterministic and simple is to - // call ReconnectEx passing the type we want to reconnect with - // via the base class ReconeectPin method. - - if (dir == PINDIR_OUTPUT) { - if( m_pInput->IsConnected() ) { - return ReconnectPin( m_pInput, &m_pOutput->CurrentMediaType() ); - } - return NOERROR; - } - - ASSERT(dir == PINDIR_INPUT); - - // Reconnect output if necessary - - if( m_pOutput->IsConnected() ) { - - if ( m_pInput->CurrentMediaType() - != m_pOutput->CurrentMediaType() - ) { - return ReconnectPin( m_pOutput, &m_pInput->CurrentMediaType() ); - } - } - return NOERROR; - -} // ComnpleteConnect - - -// -// DecideBufferSize -// -// Tell the output pin's allocator what size buffers we require. -// *pAlloc will be the allocator our output pin is using. -// - -HRESULT CTransInPlaceFilter::DecideBufferSize - ( IMemAllocator *pAlloc - , ALLOCATOR_PROPERTIES *pProperties - ) -{ - ALLOCATOR_PROPERTIES Request, Actual; - HRESULT hr; - - // If we are connected upstream, get his views - if (m_pInput->IsConnected()) { - // Get the input pin allocator, and get its size and count. - // we don't care about his alignment and prefix. - - hr = InputPin()->PeekAllocator()->GetProperties(&Request); - if (FAILED(hr)) { - // Input connected but with a secretive allocator - enough! - return hr; - } - } else { - // We're reduced to blind guessing. Let's guess one byte and if - // this isn't enough then when the other pin does get connected - // we can revise it. - ZeroMemory(&Request, sizeof(Request)); - Request.cBuffers = 1; - Request.cbBuffer = 1; - } - - - DbgLog((LOG_MEMORY,1,TEXT("Setting Allocator Requirements"))); - DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d"), - Request.cBuffers, Request.cbBuffer)); - - // Pass the allocator requirements to our output side - // but do a little sanity checking first or we'll just hit - // asserts in the allocator. - - pProperties->cBuffers = Request.cBuffers; - pProperties->cbBuffer = Request.cbBuffer; - pProperties->cbAlign = Request.cbAlign; - if (pProperties->cBuffers<=0) {pProperties->cBuffers = 1; } - if (pProperties->cbBuffer<=0) {pProperties->cbBuffer = 1; } - hr = pAlloc->SetProperties(pProperties, &Actual); - - if (FAILED(hr)) { - return hr; - } - - DbgLog((LOG_MEMORY,1,TEXT("Obtained Allocator Requirements"))); - DbgLog((LOG_MEMORY,1,TEXT("Count %d, Size %d, Alignment %d"), - Actual.cBuffers, Actual.cbBuffer, Actual.cbAlign)); - - // Make sure we got the right alignment and at least the minimum required - - if ( (Request.cBuffers > Actual.cBuffers) - || (Request.cbBuffer > Actual.cbBuffer) - || (Request.cbAlign > Actual.cbAlign) - ) { - return E_FAIL; - } - return NOERROR; - -} // DecideBufferSize - -// -// Copy -// -// return a pointer to an identical copy of pSample -IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource) -{ - IMediaSample * pDest; - - HRESULT hr; - REFERENCE_TIME tStart, tStop; - const BOOL bTime = S_OK == pSource->GetTime( &tStart, &tStop); - - // this may block for an indeterminate amount of time - hr = OutputPin()->PeekAllocator()->GetBuffer( - &pDest - , bTime ? &tStart : NULL - , bTime ? &tStop : NULL - , m_bSampleSkipped ? AM_GBF_PREVFRAMESKIPPED : 0 - ); - - if (FAILED(hr)) { - return NULL; - } - - ASSERT(pDest); - IMediaSample2 *pSample2; - if (SUCCEEDED(pDest->QueryInterface(IID_IMediaSample2, (void **)&pSample2))) { - HRESULT hr = pSample2->SetProperties( - FIELD_OFFSET(AM_SAMPLE2_PROPERTIES, pbBuffer), - (PBYTE)m_pInput->SampleProps()); - pSample2->Release(); - if (FAILED(hr)) { - pDest->Release(); - return NULL; - } - } else { - if (bTime) { - pDest->SetTime(&tStart, &tStop); - } - - if (S_OK == pSource->IsSyncPoint()) { - pDest->SetSyncPoint(TRUE); - } - if (S_OK == pSource->IsDiscontinuity() || m_bSampleSkipped) { - pDest->SetDiscontinuity(TRUE); - } - if (S_OK == pSource->IsPreroll()) { - pDest->SetPreroll(TRUE); - } - - // Copy the media type - AM_MEDIA_TYPE *pMediaType; - if (S_OK == pSource->GetMediaType(&pMediaType)) { - pDest->SetMediaType(pMediaType); - DeleteMediaType( pMediaType ); - } - - } - - m_bSampleSkipped = FALSE; - - // Copy the sample media times - REFERENCE_TIME TimeStart, TimeEnd; - if (pSource->GetMediaTime(&TimeStart,&TimeEnd) == NOERROR) { - pDest->SetMediaTime(&TimeStart,&TimeEnd); - } - - // Copy the actual data length and the actual data. - { - const long lDataLength = pSource->GetActualDataLength(); - pDest->SetActualDataLength(lDataLength); - - // Copy the sample data - { - BYTE *pSourceBuffer, *pDestBuffer; - long lSourceSize = pSource->GetSize(); - long lDestSize = pDest->GetSize(); - - ASSERT(lDestSize >= lSourceSize && lDestSize >= lDataLength); - - pSource->GetPointer(&pSourceBuffer); - pDest->GetPointer(&pDestBuffer); - ASSERT(lDestSize == 0 || pSourceBuffer != NULL && pDestBuffer != NULL); - - CopyMemory( (PVOID) pDestBuffer, (PVOID) pSourceBuffer, lDataLength ); - } - } - - return pDest; - -} // Copy - - -// override this to customize the transform process - -HRESULT -CTransInPlaceFilter::Receive(IMediaSample *pSample) -{ - /* Check for other streams and pass them on */ - AM_SAMPLE2_PROPERTIES * const pProps = m_pInput->SampleProps(); - if (pProps->dwStreamId != AM_STREAM_MEDIA) { - return m_pOutput->Deliver(pSample); - } - HRESULT hr; - - // Start timing the TransInPlace (if PERF is defined) - MSR_START(m_idTransInPlace); - - if (UsingDifferentAllocators()) { - - // We have to copy the data. - - pSample = Copy(pSample); - - if (pSample==NULL) { - MSR_STOP(m_idTransInPlace); - return E_UNEXPECTED; - } - } - - // have the derived class transform the data - hr = Transform(pSample); - - // Stop the clock and log it (if PERF is defined) - MSR_STOP(m_idTransInPlace); - - if (FAILED(hr)) { - DbgLog((LOG_TRACE, 1, TEXT("Error from TransInPlace"))); - if (UsingDifferentAllocators()) { - pSample->Release(); - } - return hr; - } - - // the Transform() function can return S_FALSE to indicate that the - // sample should not be delivered; we only deliver the sample if it's - // really S_OK (same as NOERROR, of course.) - if (hr == NOERROR) { - hr = m_pOutput->Deliver(pSample); - } else { - // But it would be an error to return this private workaround - // to the caller ... - if (S_FALSE == hr) { - // S_FALSE returned from Transform is a PRIVATE agreement - // We should return NOERROR from Receive() in this cause because - // returning S_FALSE from Receive() means that this is the end - // of the stream and no more data should be sent. - m_bSampleSkipped = TRUE; - if (!m_bQualityChanged) { - NotifyEvent(EC_QUALITY_CHANGE,0,0); - m_bQualityChanged = TRUE; - } - hr = NOERROR; - } - } - - // release the output buffer. If the connected pin still needs it, - // it will have addrefed it itself. - if (UsingDifferentAllocators()) { - pSample->Release(); - } - - return hr; - -} // Receive - - - -// ================================================================= -// Implements the CTransInPlaceInputPin class -// ================================================================= - - -// constructor - -CTransInPlaceInputPin::CTransInPlaceInputPin - ( TCHAR *pObjectName - , CTransInPlaceFilter *pFilter - , HRESULT *phr - , LPCWSTR pName - ) - : CTransformInputPin(pObjectName, - pFilter, - phr, - pName) - , m_bReadOnly(FALSE) - , m_pTIPFilter(pFilter) -{ - DbgLog((LOG_TRACE, 2 - , TEXT("CTransInPlaceInputPin::CTransInPlaceInputPin"))); - -} // constructor - - -// ================================================================= -// Implements IMemInputPin interface -// ================================================================= - - -// If the downstream filter has one then offer that (even if our own output -// pin is not using it yet. If the upstream filter chooses it then we will -// tell our output pin to ReceiveAllocator). -// Else if our output pin is using an allocator then offer that. -// ( This could mean offering the upstream filter his own allocator, -// it could mean offerring our own -// ) or it could mean offering the one from downstream -// Else fail to offer any allocator at all. - -STDMETHODIMP CTransInPlaceInputPin::GetAllocator(IMemAllocator ** ppAllocator) -{ - CheckPointer(ppAllocator,E_POINTER); - ValidateReadWritePtr(ppAllocator,sizeof(IMemAllocator *)); - CAutoLock cObjectLock(m_pLock); - - HRESULT hr; - - if ( m_pTIPFilter->m_pOutput->IsConnected() ) { - // Store the allocator we got - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() - ->GetAllocator( ppAllocator ); - if (SUCCEEDED(hr)) { - m_pTIPFilter->OutputPin()->SetAllocator( *ppAllocator ); - } - } - else { - // Help upstream filter (eg TIP filter which is having to do a copy) - // by providing a temp allocator here - we'll never use - // this allocator because when our output is connected we'll - // reconnect this pin - hr = CTransformInputPin::GetAllocator( ppAllocator ); - } - return hr; - -} // GetAllocator - - - -/* Get told which allocator the upstream output pin is actually going to use */ - - -STDMETHODIMP -CTransInPlaceInputPin::NotifyAllocator( - IMemAllocator * pAllocator, - BOOL bReadOnly) -{ - HRESULT hr = S_OK; - CheckPointer(pAllocator,E_POINTER); - ValidateReadPtr(pAllocator,sizeof(IMemAllocator)); - - CAutoLock cObjectLock(m_pLock); - - m_bReadOnly = bReadOnly; - // If we modify data then don't accept the allocator if it's - // the same as the output pin's allocator - - // If our output is not connected just accept the allocator - // We're never going to use this allocator because when our - // output pin is connected we'll reconnect this pin - if (!m_pTIPFilter->OutputPin()->IsConnected()) { - return CTransformInputPin::NotifyAllocator(pAllocator, bReadOnly); - } - - // If the allocator is read-only and we're modifying data - // and the allocator is the same as the output pin's - // then reject - if (bReadOnly && m_pTIPFilter->m_bModifiesData) { - IMemAllocator *pOutputAllocator = - m_pTIPFilter->OutputPin()->PeekAllocator(); - - // Make sure we have an output allocator - if (pOutputAllocator == NULL) { - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin()-> - GetAllocator(&pOutputAllocator); - if(FAILED(hr)) { - hr = CreateMemoryAllocator(&pOutputAllocator); - } - if (SUCCEEDED(hr)) { - m_pTIPFilter->OutputPin()->SetAllocator(pOutputAllocator); - pOutputAllocator->Release(); - } - } - if (pAllocator == pOutputAllocator) { - hr = E_FAIL; - } else if(SUCCEEDED(hr)) { - // Must copy so set the allocator properties on the output - ALLOCATOR_PROPERTIES Props, Actual; - hr = pAllocator->GetProperties(&Props); - if (SUCCEEDED(hr)) { - hr = pOutputAllocator->SetProperties(&Props, &Actual); - } - if (SUCCEEDED(hr)) { - if ( (Props.cBuffers > Actual.cBuffers) - || (Props.cbBuffer > Actual.cbBuffer) - || (Props.cbAlign > Actual.cbAlign) - ) { - hr = E_FAIL; - } - } - - // Set the allocator on the output pin - if (SUCCEEDED(hr)) { - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() - ->NotifyAllocator( pOutputAllocator, FALSE ); - } - } - } else { - hr = m_pTIPFilter->OutputPin()->ConnectedIMemInputPin() - ->NotifyAllocator( pAllocator, bReadOnly ); - if (SUCCEEDED(hr)) { - m_pTIPFilter->OutputPin()->SetAllocator( pAllocator ); - } - } - - if (SUCCEEDED(hr)) { - - // It's possible that the old and the new are the same thing. - // AddRef before release ensures that we don't unload it. - pAllocator->AddRef(); - - if( m_pAllocator != NULL ) - m_pAllocator->Release(); - - m_pAllocator = pAllocator; // We have an allocator for the input pin - } - - return hr; - -} // NotifyAllocator - - -// EnumMediaTypes -// - pass through to our downstream filter -STDMETHODIMP CTransInPlaceInputPin::EnumMediaTypes( IEnumMediaTypes **ppEnum ) -{ - // Can only pass through if connected - if( !m_pTIPFilter->m_pOutput->IsConnected() ) - return VFW_E_NOT_CONNECTED; - - return m_pTIPFilter->m_pOutput->GetConnected()->EnumMediaTypes( ppEnum ); - -} // EnumMediaTypes - - -// CheckMediaType -// - agree to anything if not connected, -// otherwise pass through to the downstream filter. -// This assumes that the filter does not change the media type. - -HRESULT CTransInPlaceInputPin::CheckMediaType(const CMediaType *pmt ) -{ - HRESULT hr = m_pTIPFilter->CheckInputType(pmt); - if (hr!=S_OK) return hr; - - if( m_pTIPFilter->m_pOutput->IsConnected() ) - return m_pTIPFilter->m_pOutput->GetConnected()->QueryAccept( pmt ); - else - return S_OK; - -} // CheckMediaType - - -// If upstream asks us what our requirements are, we will try to ask downstream -// if that doesn't work, we'll just take the defaults. -STDMETHODIMP -CTransInPlaceInputPin::GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps) -{ - - if( m_pTIPFilter->m_pOutput->IsConnected() ) - return m_pTIPFilter->OutputPin() - ->ConnectedIMemInputPin()->GetAllocatorRequirements( pProps ); - else - return E_NOTIMPL; - -} // GetAllocatorRequirements - - -// CTransInPlaceInputPin::CompleteConnect() calls CBaseInputPin::CompleteConnect() -// and then calls CTransInPlaceFilter::CompleteConnect(). It does this because -// CTransInPlaceFilter::CompleteConnect() can reconnect a pin and we do not -// want to reconnect a pin if CBaseInputPin::CompleteConnect() fails. -HRESULT -CTransInPlaceInputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = CBaseInputPin::CompleteConnect(pReceivePin); - if (FAILED(hr)) { - return hr; - } - - return m_pTransformFilter->CompleteConnect(PINDIR_INPUT,pReceivePin); -} // CompleteConnect - - -// ================================================================= -// Implements the CTransInPlaceOutputPin class -// ================================================================= - - -// constructor - -CTransInPlaceOutputPin::CTransInPlaceOutputPin( - TCHAR *pObjectName, - CTransInPlaceFilter *pFilter, - HRESULT * phr, - LPCWSTR pPinName) - : CTransformOutputPin( pObjectName - , pFilter - , phr - , pPinName), - m_pTIPFilter(pFilter) -{ - DbgLog(( LOG_TRACE, 2 - , TEXT("CTransInPlaceOutputPin::CTransInPlaceOutputPin"))); - -} // constructor - - -// EnumMediaTypes -// - pass through to our upstream filter -STDMETHODIMP CTransInPlaceOutputPin::EnumMediaTypes( IEnumMediaTypes **ppEnum ) -{ - // Can only pass through if connected. - if( ! m_pTIPFilter->m_pInput->IsConnected() ) - return VFW_E_NOT_CONNECTED; - - return m_pTIPFilter->m_pInput->GetConnected()->EnumMediaTypes( ppEnum ); - -} // EnumMediaTypes - - - -// CheckMediaType -// - agree to anything if not connected, -// otherwise pass through to the upstream filter. - -HRESULT CTransInPlaceOutputPin::CheckMediaType(const CMediaType *pmt ) -{ - // Don't accept any output pin type changes if we're copying - // between allocators - it's too late to change the input - // allocator size. - if (m_pTIPFilter->UsingDifferentAllocators() && !m_pFilter->IsStopped()) { - if (*pmt == m_mt) { - return S_OK; - } else { - return VFW_E_TYPE_NOT_ACCEPTED; - } - } - - // Assumes the type does not change. That's why we're calling - // CheckINPUTType here on the OUTPUT pin. - HRESULT hr = m_pTIPFilter->CheckInputType(pmt); - if (hr!=S_OK) return hr; - - if( m_pTIPFilter->m_pInput->IsConnected() ) - return m_pTIPFilter->m_pInput->GetConnected()->QueryAccept( pmt ); - else - return S_OK; - -} // CheckMediaType - - -/* Save the allocator pointer in the output pin -*/ -void -CTransInPlaceOutputPin::SetAllocator(IMemAllocator * pAllocator) -{ - pAllocator->AddRef(); - if (m_pAllocator) { - m_pAllocator->Release(); - } - m_pAllocator = pAllocator; -} // SetAllocator - - -// CTransInPlaceOutputPin::CompleteConnect() calls CBaseOutputPin::CompleteConnect() -// and then calls CTransInPlaceFilter::CompleteConnect(). It does this because -// CTransInPlaceFilter::CompleteConnect() can reconnect a pin and we do not want to -// reconnect a pin if CBaseOutputPin::CompleteConnect() fails. -// CBaseOutputPin::CompleteConnect() often fails when our output pin is being connected -// to the Video Mixing Renderer. -HRESULT -CTransInPlaceOutputPin::CompleteConnect(IPin *pReceivePin) -{ - HRESULT hr = CBaseOutputPin::CompleteConnect(pReceivePin); - if (FAILED(hr)) { - return hr; - } - - return m_pTransformFilter->CompleteConnect(PINDIR_OUTPUT,pReceivePin); -} // CompleteConnect diff --git a/plugins/gs/gsdx9/baseclasses/transip.h b/plugins/gs/gsdx9/baseclasses/transip.h deleted file mode 100644 index 2c1e5114ac..0000000000 --- a/plugins/gs/gsdx9/baseclasses/transip.h +++ /dev/null @@ -1,250 +0,0 @@ -//------------------------------------------------------------------------------ -// File: TransIP.h -// -// Desc: DirectShow base classes - defines classes from which simple -// Transform-In-Place filters may be derived. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// -// The difference between this and Transfrm.h is that Transfrm copies the data. -// -// It assumes the filter has one input and one output stream, and has no -// interest in memory management, interface negotiation or anything else. -// -// Derive your class from this, and supply Transform and the media type/format -// negotiation functions. Implement that class, compile and link and -// you're done. - - -#ifndef __TRANSIP__ -#define __TRANSIP__ - -// ====================================================================== -// This is the com object that represents a simple transform filter. It -// supports IBaseFilter, IMediaFilter and two pins through nested interfaces -// ====================================================================== - -class CTransInPlaceFilter; - -// Several of the pin functions call filter functions to do the work, -// so you can often use the pin classes unaltered, just overriding the -// functions in CTransInPlaceFilter. If that's not enough and you want -// to derive your own pin class, override GetPin in the filter to supply -// your own pin classes to the filter. - -// ================================================== -// Implements the input pin -// ================================================== - -class CTransInPlaceInputPin : public CTransformInputPin -{ - -protected: - CTransInPlaceFilter * const m_pTIPFilter; // our filter - BOOL m_bReadOnly; // incoming stream is read only - -public: - - CTransInPlaceInputPin( - TCHAR *pObjectName, - CTransInPlaceFilter *pFilter, - HRESULT *phr, - LPCWSTR pName); - - // --- IMemInputPin ----- - - // Provide an enumerator for media types by getting one from downstream - STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum ); - - // Say whether media type is acceptable. - HRESULT CheckMediaType(const CMediaType* pmt); - - // Return our upstream allocator - STDMETHODIMP GetAllocator(IMemAllocator ** ppAllocator); - - // get told which allocator the upstream output pin is actually - // going to use. - STDMETHODIMP NotifyAllocator(IMemAllocator * pAllocator, - BOOL bReadOnly); - - // Allow the filter to see what allocator we have - // N.B. This does NOT AddRef - IMemAllocator * PeekAllocator() const - { return m_pAllocator; } - - // Pass this on downstream if it ever gets called. - STDMETHODIMP GetAllocatorRequirements(ALLOCATOR_PROPERTIES *pProps); - - HRESULT CompleteConnect(IPin *pReceivePin); - - inline const BOOL ReadOnly() { return m_bReadOnly ; } - -}; // CTransInPlaceInputPin - -// ================================================== -// Implements the output pin -// ================================================== - -class CTransInPlaceOutputPin : public CTransformOutputPin -{ - -protected: - // m_pFilter points to our CBaseFilter - CTransInPlaceFilter * const m_pTIPFilter; - -public: - - CTransInPlaceOutputPin( - TCHAR *pObjectName, - CTransInPlaceFilter *pFilter, - HRESULT *phr, - LPCWSTR pName); - - - // --- CBaseOutputPin ------------ - - // negotiate the allocator and its buffer size/count - // Insists on using our own allocator. (Actually the one upstream of us). - // We don't override this - instead we just agree the default - // then let the upstream filter decide for itself on reconnect - // virtual HRESULT DecideAllocator(IMemInputPin * pPin, IMemAllocator ** pAlloc); - - // Provide a media type enumerator. Get it from upstream. - STDMETHODIMP EnumMediaTypes( IEnumMediaTypes **ppEnum ); - - // Say whether media type is acceptable. - HRESULT CheckMediaType(const CMediaType* pmt); - - // This just saves the allocator being used on the output pin - // Also called by input pin's GetAllocator() - void SetAllocator(IMemAllocator * pAllocator); - - IMemInputPin * ConnectedIMemInputPin() - { return m_pInputPin; } - - // Allow the filter to see what allocator we have - // N.B. This does NOT AddRef - IMemAllocator * PeekAllocator() const - { return m_pAllocator; } - - HRESULT CompleteConnect(IPin *pReceivePin); - -}; // CTransInPlaceOutputPin - - -class AM_NOVTABLE CTransInPlaceFilter : public CTransformFilter -{ - -public: - - // map getpin/getpincount for base enum of pins to owner - // override this to return more specialised pin objects - - virtual CBasePin *GetPin(int n); - -public: - - // Set bModifiesData == false if your derived filter does - // not modify the data samples (for instance it's just copying - // them somewhere else or looking at the timestamps). - - CTransInPlaceFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid, HRESULT *, - bool bModifiesData = true); -#ifdef UNICODE - CTransInPlaceFilter(CHAR *, LPUNKNOWN, REFCLSID clsid, HRESULT *, - bool bModifiesData = true); -#endif - // The following are defined to avoid undefined pure virtuals. - // Even if they are never called, they will give linkage warnings/errors - - // We override EnumMediaTypes to bypass the transform class enumerator - // which would otherwise call this. - HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) - { DbgBreak("CTransInPlaceFilter::GetMediaType should never be called"); - return E_UNEXPECTED; - } - - // This is called when we actually have to provide out own allocator. - HRESULT DecideBufferSize(IMemAllocator*, ALLOCATOR_PROPERTIES *); - - // The functions which call this in CTransform are overridden in this - // class to call CheckInputType with the assumption that the type - // does not change. In Debug builds some calls will be made and - // we just ensure that they do not assert. - HRESULT CheckTransform(const CMediaType *mtIn, const CMediaType *mtOut) - { - return S_OK; - }; - - - // ================================================================= - // ----- You may want to override this ----------------------------- - // ================================================================= - - HRESULT CompleteConnect(PIN_DIRECTION dir,IPin *pReceivePin); - - // chance to customize the transform process - virtual HRESULT Receive(IMediaSample *pSample); - - // ================================================================= - // ----- You MUST override these ----------------------------------- - // ================================================================= - - virtual HRESULT Transform(IMediaSample *pSample) PURE; - - // this goes in the factory template table to create new instances - // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *); - - -#ifdef PERF - // Override to register performance measurement with a less generic string - // You should do this to avoid confusion with other filters - virtual void RegisterPerfId() - {m_idTransInPlace = MSR_REGISTER(TEXT("TransInPlace"));} -#endif // PERF - - -// implementation details - -protected: - - IMediaSample * CTransInPlaceFilter::Copy(IMediaSample *pSource); - -#ifdef PERF - int m_idTransInPlace; // performance measuring id -#endif // PERF - bool m_bModifiesData; // Does this filter change the data? - - // these hold our input and output pins - - friend class CTransInPlaceInputPin; - friend class CTransInPlaceOutputPin; - - CTransInPlaceInputPin *InputPin() const - { - return (CTransInPlaceInputPin *)m_pInput; - }; - CTransInPlaceOutputPin *OutputPin() const - { - return (CTransInPlaceOutputPin *)m_pOutput; - }; - - // Helper to see if the input and output types match - BOOL TypesMatch() - { - return InputPin()->CurrentMediaType() == - OutputPin()->CurrentMediaType(); - } - - // Are the input and output allocators different? - BOOL UsingDifferentAllocators() const - { - return InputPin()->PeekAllocator() != OutputPin()->PeekAllocator(); - } -}; // CTransInPlaceFilter - -#endif /* __TRANSIP__ */ - diff --git a/plugins/gs/gsdx9/baseclasses/vfwmsgs.h b/plugins/gs/gsdx9/baseclasses/vfwmsgs.h deleted file mode 100644 index a0309f88f7..0000000000 --- a/plugins/gs/gsdx9/baseclasses/vfwmsgs.h +++ /dev/null @@ -1,1365 +0,0 @@ - // no longer used - but might get - // our own facility in the future? - // FacilityNames=(FACILITY_VFW=0x4) - // To add a message: - // - // The MessageId is the number of the message. - // Accepted severities are 'Success' and 'Warning'. - // - // Facility should be FACILITY_ITF (was FACILITY_VFW). - // - // The SymbolicName is the name used in the code to identify the message. - // The text of a message starts the line after 'Language=' and - // ends before a line with only a '.' in column one. -// -// Values are 32 bit values layed out as follows: -// -// 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 -// 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 -// +---+-+-+-----------------------+-------------------------------+ -// |Sev|C|R| Facility | Code | -// +---+-+-+-----------------------+-------------------------------+ -// -// where -// -// Sev - is the severity code -// -// 00 - Success -// 01 - Informational -// 10 - Warning -// 11 - Error -// -// C - is the Customer code flag -// -// R - is a reserved bit -// -// Facility - is the facility code -// -// Code - is the facility's status code -// -// -// Define the facility codes -// - - -// -// Define the severity codes -// - - -// -// MessageId: VFW_E_INVALIDMEDIATYPE -// -// MessageText: -// -// An invalid media type was specified.%0 -// -#define VFW_E_INVALIDMEDIATYPE ((HRESULT)0x80040200L) - -// -// MessageId: VFW_E_INVALIDSUBTYPE -// -// MessageText: -// -// An invalid media subtype was specified.%0 -// -#define VFW_E_INVALIDSUBTYPE ((HRESULT)0x80040201L) - -// -// MessageId: VFW_E_NEED_OWNER -// -// MessageText: -// -// This object can only be created as an aggregated object.%0 -// -#define VFW_E_NEED_OWNER ((HRESULT)0x80040202L) - -// -// MessageId: VFW_E_ENUM_OUT_OF_SYNC -// -// MessageText: -// -// The enumerator has become invalid.%0 -// -#define VFW_E_ENUM_OUT_OF_SYNC ((HRESULT)0x80040203L) - -// -// MessageId: VFW_E_ALREADY_CONNECTED -// -// MessageText: -// -// At least one of the pins involved in the operation is already connected.%0 -// -#define VFW_E_ALREADY_CONNECTED ((HRESULT)0x80040204L) - -// -// MessageId: VFW_E_FILTER_ACTIVE -// -// MessageText: -// -// This operation cannot be performed because the filter is active.%0 -// -#define VFW_E_FILTER_ACTIVE ((HRESULT)0x80040205L) - -// -// MessageId: VFW_E_NO_TYPES -// -// MessageText: -// -// One of the specified pins supports no media types.%0 -// -#define VFW_E_NO_TYPES ((HRESULT)0x80040206L) - -// -// MessageId: VFW_E_NO_ACCEPTABLE_TYPES -// -// MessageText: -// -// There is no common media type between these pins.%0 -// -#define VFW_E_NO_ACCEPTABLE_TYPES ((HRESULT)0x80040207L) - -// -// MessageId: VFW_E_INVALID_DIRECTION -// -// MessageText: -// -// Two pins of the same direction cannot be connected together.%0 -// -#define VFW_E_INVALID_DIRECTION ((HRESULT)0x80040208L) - -// -// MessageId: VFW_E_NOT_CONNECTED -// -// MessageText: -// -// The operation cannot be performed because the pins are not connected.%0 -// -#define VFW_E_NOT_CONNECTED ((HRESULT)0x80040209L) - -// -// MessageId: VFW_E_NO_ALLOCATOR -// -// MessageText: -// -// No sample buffer allocator is available.%0 -// -#define VFW_E_NO_ALLOCATOR ((HRESULT)0x8004020AL) - -// -// MessageId: VFW_E_RUNTIME_ERROR -// -// MessageText: -// -// A run-time error occurred.%0 -// -#define VFW_E_RUNTIME_ERROR ((HRESULT)0x8004020BL) - -// -// MessageId: VFW_E_BUFFER_NOTSET -// -// MessageText: -// -// No buffer space has been set.%0 -// -#define VFW_E_BUFFER_NOTSET ((HRESULT)0x8004020CL) - -// -// MessageId: VFW_E_BUFFER_OVERFLOW -// -// MessageText: -// -// The buffer is not big enough.%0 -// -#define VFW_E_BUFFER_OVERFLOW ((HRESULT)0x8004020DL) - -// -// MessageId: VFW_E_BADALIGN -// -// MessageText: -// -// An invalid alignment was specified.%0 -// -#define VFW_E_BADALIGN ((HRESULT)0x8004020EL) - -// -// MessageId: VFW_E_ALREADY_COMMITTED -// -// MessageText: -// -// Cannot change allocated memory while the filter is active.%0 -// -#define VFW_E_ALREADY_COMMITTED ((HRESULT)0x8004020FL) - -// -// MessageId: VFW_E_BUFFERS_OUTSTANDING -// -// MessageText: -// -// One or more buffers are still active.%0 -// -#define VFW_E_BUFFERS_OUTSTANDING ((HRESULT)0x80040210L) - -// -// MessageId: VFW_E_NOT_COMMITTED -// -// MessageText: -// -// Cannot allocate a sample when the allocator is not active.%0 -// -#define VFW_E_NOT_COMMITTED ((HRESULT)0x80040211L) - -// -// MessageId: VFW_E_SIZENOTSET -// -// MessageText: -// -// Cannot allocate memory because no size has been set.%0 -// -#define VFW_E_SIZENOTSET ((HRESULT)0x80040212L) - -// -// MessageId: VFW_E_NO_CLOCK -// -// MessageText: -// -// Cannot lock for synchronization because no clock has been defined.%0 -// -#define VFW_E_NO_CLOCK ((HRESULT)0x80040213L) - -// -// MessageId: VFW_E_NO_SINK -// -// MessageText: -// -// Quality messages could not be sent because no quality sink has been defined.%0 -// -#define VFW_E_NO_SINK ((HRESULT)0x80040214L) - -// -// MessageId: VFW_E_NO_INTERFACE -// -// MessageText: -// -// A required interface has not been implemented.%0 -// -#define VFW_E_NO_INTERFACE ((HRESULT)0x80040215L) - -// -// MessageId: VFW_E_NOT_FOUND -// -// MessageText: -// -// An object or name was not found.%0 -// -#define VFW_E_NOT_FOUND ((HRESULT)0x80040216L) - -// -// MessageId: VFW_E_CANNOT_CONNECT -// -// MessageText: -// -// No combination of intermediate filters could be found to make the connection.%0 -// -#define VFW_E_CANNOT_CONNECT ((HRESULT)0x80040217L) - -// -// MessageId: VFW_E_CANNOT_RENDER -// -// MessageText: -// -// No combination of filters could be found to render the stream.%0 -// -#define VFW_E_CANNOT_RENDER ((HRESULT)0x80040218L) - -// -// MessageId: VFW_E_CHANGING_FORMAT -// -// MessageText: -// -// Could not change formats dynamically.%0 -// -#define VFW_E_CHANGING_FORMAT ((HRESULT)0x80040219L) - -// -// MessageId: VFW_E_NO_COLOR_KEY_SET -// -// MessageText: -// -// No color key has been set.%0 -// -#define VFW_E_NO_COLOR_KEY_SET ((HRESULT)0x8004021AL) - -// -// MessageId: VFW_E_NOT_OVERLAY_CONNECTION -// -// MessageText: -// -// Current pin connection is not using the IOverlay transport.%0 -// -#define VFW_E_NOT_OVERLAY_CONNECTION ((HRESULT)0x8004021BL) - -// -// MessageId: VFW_E_NOT_SAMPLE_CONNECTION -// -// MessageText: -// -// Current pin connection is not using the IMemInputPin transport.%0 -// -#define VFW_E_NOT_SAMPLE_CONNECTION ((HRESULT)0x8004021CL) - -// -// MessageId: VFW_E_PALETTE_SET -// -// MessageText: -// -// Setting a color key would conflict with the palette already set.%0 -// -#define VFW_E_PALETTE_SET ((HRESULT)0x8004021DL) - -// -// MessageId: VFW_E_COLOR_KEY_SET -// -// MessageText: -// -// Setting a palette would conflict with the color key already set.%0 -// -#define VFW_E_COLOR_KEY_SET ((HRESULT)0x8004021EL) - -// -// MessageId: VFW_E_NO_COLOR_KEY_FOUND -// -// MessageText: -// -// No matching color key is available.%0 -// -#define VFW_E_NO_COLOR_KEY_FOUND ((HRESULT)0x8004021FL) - -// -// MessageId: VFW_E_NO_PALETTE_AVAILABLE -// -// MessageText: -// -// No palette is available.%0 -// -#define VFW_E_NO_PALETTE_AVAILABLE ((HRESULT)0x80040220L) - -// -// MessageId: VFW_E_NO_DISPLAY_PALETTE -// -// MessageText: -// -// Display does not use a palette.%0 -// -#define VFW_E_NO_DISPLAY_PALETTE ((HRESULT)0x80040221L) - -// -// MessageId: VFW_E_TOO_MANY_COLORS -// -// MessageText: -// -// Too many colors for the current display settings.%0 -// -#define VFW_E_TOO_MANY_COLORS ((HRESULT)0x80040222L) - -// -// MessageId: VFW_E_STATE_CHANGED -// -// MessageText: -// -// The state changed while waiting to process the sample.%0 -// -#define VFW_E_STATE_CHANGED ((HRESULT)0x80040223L) - -// -// MessageId: VFW_E_NOT_STOPPED -// -// MessageText: -// -// The operation could not be performed because the filter is not stopped.%0 -// -#define VFW_E_NOT_STOPPED ((HRESULT)0x80040224L) - -// -// MessageId: VFW_E_NOT_PAUSED -// -// MessageText: -// -// The operation could not be performed because the filter is not paused.%0 -// -#define VFW_E_NOT_PAUSED ((HRESULT)0x80040225L) - -// -// MessageId: VFW_E_NOT_RUNNING -// -// MessageText: -// -// The operation could not be performed because the filter is not running.%0 -// -#define VFW_E_NOT_RUNNING ((HRESULT)0x80040226L) - -// -// MessageId: VFW_E_WRONG_STATE -// -// MessageText: -// -// The operation could not be performed because the filter is in the wrong state.%0 -// -#define VFW_E_WRONG_STATE ((HRESULT)0x80040227L) - -// -// MessageId: VFW_E_START_TIME_AFTER_END -// -// MessageText: -// -// The sample start time is after the sample end time.%0 -// -#define VFW_E_START_TIME_AFTER_END ((HRESULT)0x80040228L) - -// -// MessageId: VFW_E_INVALID_RECT -// -// MessageText: -// -// The supplied rectangle is invalid.%0 -// -#define VFW_E_INVALID_RECT ((HRESULT)0x80040229L) - -// -// MessageId: VFW_E_TYPE_NOT_ACCEPTED -// -// MessageText: -// -// This pin cannot use the supplied media type.%0 -// -#define VFW_E_TYPE_NOT_ACCEPTED ((HRESULT)0x8004022AL) - -// -// MessageId: VFW_E_SAMPLE_REJECTED -// -// MessageText: -// -// This sample cannot be rendered.%0 -// -#define VFW_E_SAMPLE_REJECTED ((HRESULT)0x8004022BL) - -// -// MessageId: VFW_E_SAMPLE_REJECTED_EOS -// -// MessageText: -// -// This sample cannot be rendered because the end of the stream has been reached.%0 -// -#define VFW_E_SAMPLE_REJECTED_EOS ((HRESULT)0x8004022CL) - -// -// MessageId: VFW_E_DUPLICATE_NAME -// -// MessageText: -// -// An attempt to add a filter with a duplicate name failed.%0 -// -#define VFW_E_DUPLICATE_NAME ((HRESULT)0x8004022DL) - -// -// MessageId: VFW_S_DUPLICATE_NAME -// -// MessageText: -// -// An attempt to add a filter with a duplicate name succeeded with a modified name.%0 -// -#define VFW_S_DUPLICATE_NAME ((HRESULT)0x0004022DL) - -// -// MessageId: VFW_E_TIMEOUT -// -// MessageText: -// -// A time-out has expired.%0 -// -#define VFW_E_TIMEOUT ((HRESULT)0x8004022EL) - -// -// MessageId: VFW_E_INVALID_FILE_FORMAT -// -// MessageText: -// -// The file format is invalid.%0 -// -#define VFW_E_INVALID_FILE_FORMAT ((HRESULT)0x8004022FL) - -// -// MessageId: VFW_E_ENUM_OUT_OF_RANGE -// -// MessageText: -// -// The list has already been exhausted.%0 -// -#define VFW_E_ENUM_OUT_OF_RANGE ((HRESULT)0x80040230L) - -// -// MessageId: VFW_E_CIRCULAR_GRAPH -// -// MessageText: -// -// The filter graph is circular.%0 -// -#define VFW_E_CIRCULAR_GRAPH ((HRESULT)0x80040231L) - -// -// MessageId: VFW_E_NOT_ALLOWED_TO_SAVE -// -// MessageText: -// -// Updates are not allowed in this state.%0 -// -#define VFW_E_NOT_ALLOWED_TO_SAVE ((HRESULT)0x80040232L) - -// -// MessageId: VFW_E_TIME_ALREADY_PASSED -// -// MessageText: -// -// An attempt was made to queue a command for a time in the past.%0 -// -#define VFW_E_TIME_ALREADY_PASSED ((HRESULT)0x80040233L) - -// -// MessageId: VFW_E_ALREADY_CANCELLED -// -// MessageText: -// -// The queued command has already been canceled.%0 -// -#define VFW_E_ALREADY_CANCELLED ((HRESULT)0x80040234L) - -// -// MessageId: VFW_E_CORRUPT_GRAPH_FILE -// -// MessageText: -// -// Cannot render the file because it is corrupt.%0 -// -#define VFW_E_CORRUPT_GRAPH_FILE ((HRESULT)0x80040235L) - -// -// MessageId: VFW_E_ADVISE_ALREADY_SET -// -// MessageText: -// -// An overlay advise link already exists.%0 -// -#define VFW_E_ADVISE_ALREADY_SET ((HRESULT)0x80040236L) - -// -// MessageId: VFW_S_STATE_INTERMEDIATE -// -// MessageText: -// -// The state transition has not completed.%0 -// -#define VFW_S_STATE_INTERMEDIATE ((HRESULT)0x00040237L) - -// -// MessageId: VFW_E_NO_MODEX_AVAILABLE -// -// MessageText: -// -// No full-screen modes are available.%0 -// -#define VFW_E_NO_MODEX_AVAILABLE ((HRESULT)0x80040238L) - -// -// MessageId: VFW_E_NO_ADVISE_SET -// -// MessageText: -// -// This Advise cannot be canceled because it was not successfully set.%0 -// -#define VFW_E_NO_ADVISE_SET ((HRESULT)0x80040239L) - -// -// MessageId: VFW_E_NO_FULLSCREEN -// -// MessageText: -// -// A full-screen mode is not available.%0 -// -#define VFW_E_NO_FULLSCREEN ((HRESULT)0x8004023AL) - -// -// MessageId: VFW_E_IN_FULLSCREEN_MODE -// -// MessageText: -// -// Cannot call IVideoWindow methods while in full-screen mode.%0 -// -#define VFW_E_IN_FULLSCREEN_MODE ((HRESULT)0x8004023BL) - -// -// MessageId: VFW_E_UNKNOWN_FILE_TYPE -// -// MessageText: -// -// The media type of this file is not recognized.%0 -// -#define VFW_E_UNKNOWN_FILE_TYPE ((HRESULT)0x80040240L) - -// -// MessageId: VFW_E_CANNOT_LOAD_SOURCE_FILTER -// -// MessageText: -// -// The source filter for this file could not be loaded.%0 -// -#define VFW_E_CANNOT_LOAD_SOURCE_FILTER ((HRESULT)0x80040241L) - -// -// MessageId: VFW_S_PARTIAL_RENDER -// -// MessageText: -// -// Some of the streams in this movie are in an unsupported format.%0 -// -#define VFW_S_PARTIAL_RENDER ((HRESULT)0x00040242L) - -// -// MessageId: VFW_E_FILE_TOO_SHORT -// -// MessageText: -// -// A file appeared to be incomplete.%0 -// -#define VFW_E_FILE_TOO_SHORT ((HRESULT)0x80040243L) - -// -// MessageId: VFW_E_INVALID_FILE_VERSION -// -// MessageText: -// -// The version number of the file is invalid.%0 -// -#define VFW_E_INVALID_FILE_VERSION ((HRESULT)0x80040244L) - -// -// MessageId: VFW_S_SOME_DATA_IGNORED -// -// MessageText: -// -// The file contained some property settings that were not used.%0 -// -#define VFW_S_SOME_DATA_IGNORED ((HRESULT)0x00040245L) - -// -// MessageId: VFW_S_CONNECTIONS_DEFERRED -// -// MessageText: -// -// Some connections have failed and have been deferred.%0 -// -#define VFW_S_CONNECTIONS_DEFERRED ((HRESULT)0x00040246L) - -// -// MessageId: VFW_E_INVALID_CLSID -// -// MessageText: -// -// This file is corrupt: it contains an invalid class identifier.%0 -// -#define VFW_E_INVALID_CLSID ((HRESULT)0x80040247L) - -// -// MessageId: VFW_E_INVALID_MEDIA_TYPE -// -// MessageText: -// -// This file is corrupt: it contains an invalid media type.%0 -// -#define VFW_E_INVALID_MEDIA_TYPE ((HRESULT)0x80040248L) - - // Message id from WINWarning.H -// -// MessageId: VFW_E_BAD_KEY -// -// MessageText: -// -// A registry entry is corrupt.%0 -// -#define VFW_E_BAD_KEY ((HRESULT)0x800403F2L) - - // Message id from WINWarning.H -// -// MessageId: VFW_S_NO_MORE_ITEMS -// -// MessageText: -// -// The end of the list has been reached.%0 -// -#define VFW_S_NO_MORE_ITEMS ((HRESULT)0x00040103L) - -// -// MessageId: VFW_E_SAMPLE_TIME_NOT_SET -// -// MessageText: -// -// No time stamp has been set for this sample.%0 -// -#define VFW_E_SAMPLE_TIME_NOT_SET ((HRESULT)0x80040249L) - -// -// MessageId: VFW_S_RESOURCE_NOT_NEEDED -// -// MessageText: -// -// The resource specified is no longer needed.%0 -// -#define VFW_S_RESOURCE_NOT_NEEDED ((HRESULT)0x00040250L) - -// -// MessageId: VFW_E_MEDIA_TIME_NOT_SET -// -// MessageText: -// -// No media time stamp has been set for this sample.%0 -// -#define VFW_E_MEDIA_TIME_NOT_SET ((HRESULT)0x80040251L) - -// -// MessageId: VFW_E_NO_TIME_FORMAT_SET -// -// MessageText: -// -// No media time format has been selected.%0 -// -#define VFW_E_NO_TIME_FORMAT_SET ((HRESULT)0x80040252L) - -// -// MessageId: VFW_E_MONO_AUDIO_HW -// -// MessageText: -// -// Cannot change balance because audio device is mono only.%0 -// -#define VFW_E_MONO_AUDIO_HW ((HRESULT)0x80040253L) - -// -// MessageId: VFW_S_MEDIA_TYPE_IGNORED -// -// MessageText: -// -// A connection could not be made with the media type in the persistent graph,%0 -// but has been made with a negotiated media type.%0 -// -#define VFW_S_MEDIA_TYPE_IGNORED ((HRESULT)0x00040254L) - -// -// MessageId: VFW_E_NO_DECOMPRESSOR -// -// MessageText: -// -// Cannot play back the video stream: no suitable decompressor could be found.%0 -// -#define VFW_E_NO_DECOMPRESSOR ((HRESULT)0x80040255L) - -// -// MessageId: VFW_E_NO_AUDIO_HARDWARE -// -// MessageText: -// -// Cannot play back the audio stream: no audio hardware is available, or the hardware is not responding.%0 -// -#define VFW_E_NO_AUDIO_HARDWARE ((HRESULT)0x80040256L) - -// -// MessageId: VFW_S_VIDEO_NOT_RENDERED -// -// MessageText: -// -// Cannot play back the video stream: no suitable decompressor could be found.%0 -// -#define VFW_S_VIDEO_NOT_RENDERED ((HRESULT)0x00040257L) - -// -// MessageId: VFW_S_AUDIO_NOT_RENDERED -// -// MessageText: -// -// Cannot play back the audio stream: no audio hardware is available.%0 -// -#define VFW_S_AUDIO_NOT_RENDERED ((HRESULT)0x00040258L) - -// -// MessageId: VFW_E_RPZA -// -// MessageText: -// -// Cannot play back the video stream: format 'RPZA' is not supported.%0 -// -#define VFW_E_RPZA ((HRESULT)0x80040259L) - -// -// MessageId: VFW_S_RPZA -// -// MessageText: -// -// Cannot play back the video stream: format 'RPZA' is not supported.%0 -// -#define VFW_S_RPZA ((HRESULT)0x0004025AL) - -// -// MessageId: VFW_E_PROCESSOR_NOT_SUITABLE -// -// MessageText: -// -// ActiveMovie cannot play MPEG movies on this processor.%0 -// -#define VFW_E_PROCESSOR_NOT_SUITABLE ((HRESULT)0x8004025BL) - -// -// MessageId: VFW_E_UNSUPPORTED_AUDIO -// -// MessageText: -// -// Cannot play back the audio stream: the audio format is not supported.%0 -// -#define VFW_E_UNSUPPORTED_AUDIO ((HRESULT)0x8004025CL) - -// -// MessageId: VFW_E_UNSUPPORTED_VIDEO -// -// MessageText: -// -// Cannot play back the video stream: the video format is not supported.%0 -// -#define VFW_E_UNSUPPORTED_VIDEO ((HRESULT)0x8004025DL) - -// -// MessageId: VFW_E_MPEG_NOT_CONSTRAINED -// -// MessageText: -// -// ActiveMovie cannot play this video stream because it falls outside the constrained standard.%0 -// -#define VFW_E_MPEG_NOT_CONSTRAINED ((HRESULT)0x8004025EL) - -// -// MessageId: VFW_E_NOT_IN_GRAPH -// -// MessageText: -// -// Cannot perform the requested function on an object that is not in the filter graph.%0 -// -#define VFW_E_NOT_IN_GRAPH ((HRESULT)0x8004025FL) - -// -// MessageId: VFW_S_ESTIMATED -// -// MessageText: -// -// The value returned had to be estimated. It's accuracy can not be guaranteed.%0 -// -#define VFW_S_ESTIMATED ((HRESULT)0x00040260L) - -// -// MessageId: VFW_E_NO_TIME_FORMAT -// -// MessageText: -// -// Cannot get or set time related information on an object that is using a time format of TIME_FORMAT_NONE.%0 -// -#define VFW_E_NO_TIME_FORMAT ((HRESULT)0x80040261L) - -// -// MessageId: VFW_E_READ_ONLY -// -// MessageText: -// -// The connection cannot be made because the stream is read only and the filter alters the data.%0 -// -#define VFW_E_READ_ONLY ((HRESULT)0x80040262L) - -// -// MessageId: VFW_S_RESERVED -// -// MessageText: -// -// This success code is reserved for internal purposes within ActiveMovie.%0 -// -#define VFW_S_RESERVED ((HRESULT)0x00040263L) - -// -// MessageId: VFW_E_BUFFER_UNDERFLOW -// -// MessageText: -// -// The buffer is not full enough.%0 -// -#define VFW_E_BUFFER_UNDERFLOW ((HRESULT)0x80040264L) - -// -// MessageId: VFW_E_UNSUPPORTED_STREAM -// -// MessageText: -// -// Cannot play back the file. The format is not supported.%0 -// -#define VFW_E_UNSUPPORTED_STREAM ((HRESULT)0x80040265L) - -// -// MessageId: VFW_E_NO_TRANSPORT -// -// MessageText: -// -// Pins cannot connect due to not supporting the same transport.%0 -// -#define VFW_E_NO_TRANSPORT ((HRESULT)0x80040266L) - -// -// MessageId: VFW_S_STREAM_OFF -// -// MessageText: -// -// The stream has been turned off.%0 -// -#define VFW_S_STREAM_OFF ((HRESULT)0x00040267L) - -// -// MessageId: VFW_S_CANT_CUE -// -// MessageText: -// -// The graph can't be cued because of lack of or corrupt data.%0 -// -#define VFW_S_CANT_CUE ((HRESULT)0x00040268L) - -// -// MessageId: VFW_E_BAD_VIDEOCD -// -// MessageText: -// -// The Video CD can't be read correctly by the device or is the data is corrupt.%0 -// -#define VFW_E_BAD_VIDEOCD ((HRESULT)0x80040269L) - -// -// MessageId: VFW_S_NO_STOP_TIME -// -// MessageText: -// -// The stop time for the sample was not set.%0 -// -#define VFW_S_NO_STOP_TIME ((HRESULT)0x00040270L) - -// -// MessageId: VFW_E_OUT_OF_VIDEO_MEMORY -// -// MessageText: -// -// There is not enough Video Memory at this display resolution and number of colors. Reducing resolution might help.%0 -// -#define VFW_E_OUT_OF_VIDEO_MEMORY ((HRESULT)0x80040271L) - -// -// MessageId: VFW_E_VP_NEGOTIATION_FAILED -// -// MessageText: -// -// The VideoPort connection negotiation process has failed.%0 -// -#define VFW_E_VP_NEGOTIATION_FAILED ((HRESULT)0x80040272L) - -// -// MessageId: VFW_E_DDRAW_CAPS_NOT_SUITABLE -// -// MessageText: -// -// Either DirectDraw has not been installed or the Video Card capabilities are not suitable. Make sure the display is not in 16 color mode.%0 -// -#define VFW_E_DDRAW_CAPS_NOT_SUITABLE ((HRESULT)0x80040273L) - -// -// MessageId: VFW_E_NO_VP_HARDWARE -// -// MessageText: -// -// No VideoPort hardware is available, or the hardware is not responding.%0 -// -#define VFW_E_NO_VP_HARDWARE ((HRESULT)0x80040274L) - -// -// MessageId: VFW_E_NO_CAPTURE_HARDWARE -// -// MessageText: -// -// No Capture hardware is available, or the hardware is not responding.%0 -// -#define VFW_E_NO_CAPTURE_HARDWARE ((HRESULT)0x80040275L) - -// -// MessageId: VFW_E_DVD_OPERATION_INHIBITED -// -// MessageText: -// -// This User Operation is inhibited by DVD Content at this time.%0 -// -#define VFW_E_DVD_OPERATION_INHIBITED ((HRESULT)0x80040276L) - -// -// MessageId: VFW_E_DVD_INVALIDDOMAIN -// -// MessageText: -// -// This Operation is not permitted in the current domain.%0 -// -#define VFW_E_DVD_INVALIDDOMAIN ((HRESULT)0x80040277L) - -// -// MessageId: VFW_E_DVD_NO_BUTTON -// -// MessageText: -// -// The specified button is invalid or is not present at the current time, or there is no button present at the specified location.%0 -// -#define VFW_E_DVD_NO_BUTTON ((HRESULT)0x80040278L) - -// -// MessageId: VFW_E_DVD_GRAPHNOTREADY -// -// MessageText: -// -// DVD-Video playback graph has not been built yet.%0 -// -#define VFW_E_DVD_GRAPHNOTREADY ((HRESULT)0x80040279L) - -// -// MessageId: VFW_E_DVD_RENDERFAIL -// -// MessageText: -// -// DVD-Video playback graph building failed.%0 -// -#define VFW_E_DVD_RENDERFAIL ((HRESULT)0x8004027AL) - -// -// MessageId: VFW_E_DVD_DECNOTENOUGH -// -// MessageText: -// -// DVD-Video playback graph could not be built due to insufficient decoders.%0 -// -#define VFW_E_DVD_DECNOTENOUGH ((HRESULT)0x8004027BL) - -// -// MessageId: VFW_E_DDRAW_VERSION_NOT_SUITABLE -// -// MessageText: -// -// Version number of DirectDraw not suitable. Make sure to install dx5 or higher version.%0 -// -#define VFW_E_DDRAW_VERSION_NOT_SUITABLE ((HRESULT)0x8004027CL) - -// -// MessageId: VFW_E_COPYPROT_FAILED -// -// MessageText: -// -// Copy protection cannot be enabled. Please make sure any other copy protected content is not being shown now.%0 -// -#define VFW_E_COPYPROT_FAILED ((HRESULT)0x8004027DL) - -// -// MessageId: VFW_S_NOPREVIEWPIN -// -// MessageText: -// -// There was no preview pin available, so the capture pin output is being split to provide both capture and preview.%0 -// -#define VFW_S_NOPREVIEWPIN ((HRESULT)0x0004027EL) - -// -// MessageId: VFW_E_TIME_EXPIRED -// -// MessageText: -// -// This object cannot be used anymore as its time has expired.%0 -// -#define VFW_E_TIME_EXPIRED ((HRESULT)0x8004027FL) - -// -// MessageId: VFW_S_DVD_NON_ONE_SEQUENTIAL -// -// MessageText: -// -// The current title was not a sequential set of chapters (PGC), and the returned timing information might not be continuous.%0 -// -#define VFW_S_DVD_NON_ONE_SEQUENTIAL ((HRESULT)0x00040280L) - -// -// MessageId: VFW_E_DVD_WRONG_SPEED -// -// MessageText: -// -// The operation cannot be performed at the current playback speed.%0 -// -#define VFW_E_DVD_WRONG_SPEED ((HRESULT)0x80040281L) - -// -// MessageId: VFW_E_DVD_MENU_DOES_NOT_EXIST -// -// MessageText: -// -// The specified menu doesn't exist.%0 -// -#define VFW_E_DVD_MENU_DOES_NOT_EXIST ((HRESULT)0x80040282L) - -// -// MessageId: VFW_E_DVD_CMD_CANCELLED -// -// MessageText: -// -// The specified command was either cancelled or no longer exists.%0 -// -#define VFW_E_DVD_CMD_CANCELLED ((HRESULT)0x80040283L) - -// -// MessageId: VFW_E_DVD_STATE_WRONG_VERSION -// -// MessageText: -// -// The data did not contain a recognized version.%0 -// -#define VFW_E_DVD_STATE_WRONG_VERSION ((HRESULT)0x80040284L) - -// -// MessageId: VFW_E_DVD_STATE_CORRUPT -// -// MessageText: -// -// The state data was corrupt.%0 -// -#define VFW_E_DVD_STATE_CORRUPT ((HRESULT)0x80040285L) - -// -// MessageId: VFW_E_DVD_STATE_WRONG_DISC -// -// MessageText: -// -// The state data is from a different disc.%0 -// -#define VFW_E_DVD_STATE_WRONG_DISC ((HRESULT)0x80040286L) - -// -// MessageId: VFW_E_DVD_INCOMPATIBLE_REGION -// -// MessageText: -// -// The region was not compatible with the current drive.%0 -// -#define VFW_E_DVD_INCOMPATIBLE_REGION ((HRESULT)0x80040287L) - -// -// MessageId: VFW_E_DVD_NO_ATTRIBUTES -// -// MessageText: -// -// The requested DVD stream attribute does not exist.%0 -// -#define VFW_E_DVD_NO_ATTRIBUTES ((HRESULT)0x80040288L) - -// -// MessageId: VFW_E_DVD_NO_GOUP_PGC -// -// MessageText: -// -// Currently there is no GoUp (Annex J user function) program chain (PGC).%0 -// -#define VFW_E_DVD_NO_GOUP_PGC ((HRESULT)0x80040289L) - -// -// MessageId: VFW_E_DVD_LOW_PARENTAL_LEVEL -// -// MessageText: -// -// The current parental level was too low.%0 -// -#define VFW_E_DVD_LOW_PARENTAL_LEVEL ((HRESULT)0x8004028AL) - -// -// MessageId: VFW_E_DVD_NOT_IN_KARAOKE_MODE -// -// MessageText: -// -// The current audio is not karaoke content.%0 -// -#define VFW_E_DVD_NOT_IN_KARAOKE_MODE ((HRESULT)0x8004028BL) - -// -// MessageId: VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE -// -// MessageText: -// -// The audio stream did not contain sufficient information to determine the contents of each channel.%0 -// -#define VFW_S_DVD_CHANNEL_CONTENTS_NOT_AVAILABLE ((HRESULT)0x0004028CL) - -// -// MessageId: VFW_S_DVD_NOT_ACCURATE -// -// MessageText: -// -// The seek into the movie was not frame accurate.%0 -// -#define VFW_S_DVD_NOT_ACCURATE ((HRESULT)0x0004028DL) - -// -// MessageId: VFW_E_FRAME_STEP_UNSUPPORTED -// -// MessageText: -// -// Frame step is not supported on this configuration.%0 -// -#define VFW_E_FRAME_STEP_UNSUPPORTED ((HRESULT)0x8004028EL) - -// -// MessageId: VFW_E_DVD_STREAM_DISABLED -// -// MessageText: -// -// The specified stream is disabled and cannot be selected.%0 -// -#define VFW_E_DVD_STREAM_DISABLED ((HRESULT)0x8004028FL) - -// -// MessageId: VFW_E_DVD_TITLE_UNKNOWN -// -// MessageText: -// -// The operation depends on the current title number, however the navigator has not yet entered the VTSM or the title domains, -// so the 'current' title index is unknown.%0 -// -#define VFW_E_DVD_TITLE_UNKNOWN ((HRESULT)0x80040290L) - -// -// MessageId: VFW_E_DVD_INVALID_DISC -// -// MessageText: -// -// The specified path does not point to a valid DVD disc.%0 -// -#define VFW_E_DVD_INVALID_DISC ((HRESULT)0x80040291L) - -// -// MessageId: VFW_E_DVD_NO_RESUME_INFORMATION -// -// MessageText: -// -// There is currently no resume information.%0 -// -#define VFW_E_DVD_NO_RESUME_INFORMATION ((HRESULT)0x80040292L) - -// -// MessageId: VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD -// -// MessageText: -// -// This thread has already blocked this output pin. There is no need to call IPinFlowControl::Block() again.%0 -// -#define VFW_E_PIN_ALREADY_BLOCKED_ON_THIS_THREAD ((HRESULT)0x80040293L) - -// -// MessageId: VFW_E_PIN_ALREADY_BLOCKED -// -// MessageText: -// -// IPinFlowControl::Block() has been called on another thread. The current thread cannot make any assumptions about this pin's block state.%0 -// -#define VFW_E_PIN_ALREADY_BLOCKED ((HRESULT)0x80040294L) - -// -// MessageId: VFW_E_CERTIFICATION_FAILURE -// -// MessageText: -// -// An operation failed due to a certification failure.%0 -// -#define VFW_E_CERTIFICATION_FAILURE ((HRESULT)0x80040295L) - -// -// MessageId: VFW_E_VMR_NOT_IN_MIXER_MODE -// -// MessageText: -// -// The VMR has not yet created a mixing component. That is, IVMRFilterConfig::SetNumberofStreams has not yet been called.%0 -// -#define VFW_E_VMR_NOT_IN_MIXER_MODE ((HRESULT)0x80040296L) - -// -// MessageId: VFW_E_VMR_NO_AP_SUPPLIED -// -// MessageText: -// -// The application has not yet provided the VMR filter with a valid allocator-presenter object.%0 -// -#define VFW_E_VMR_NO_AP_SUPPLIED ((HRESULT)0x80040297L) -// -// MessageId: VFW_E_VMR_NO_DEINTERLACE_HW -// -// MessageText: -// -// The VMR could not find any de-interlacing hardware on the current display device.%0 -// -#define VFW_E_VMR_NO_DEINTERLACE_HW ((HRESULT)0x80040298L) -// -// MessageId: VFW_E_VMR_NO_PROCAMP_HW -// -// MessageText: -// -// The VMR could not find any ProcAmp hardware on the current display device.%0 -// -#define VFW_E_VMR_NO_PROCAMP_HW ((HRESULT)0x80040299L) -// -// MessageId: VFW_E_DVD_VMR9_INCOMPATIBLEDEC -// -// MessageText: -// -// VMR9 does not work with VPE-based hardware decoders.%0 -// -#define VFW_E_DVD_VMR9_INCOMPATIBLEDEC ((HRESULT)0x8004029AL) -// -// MessageId: VFW_E_NO_COPP_HW -// -// MessageText: -// -// The current display device does not support Content Output Protection Protocol (COPP) H/W.%0 -// -#define VFW_E_NO_COPP_HW ((HRESULT)0x8004029BL) -// -// -// E_PROP_SET_UNSUPPORTED and E_PROP_ID_UNSUPPORTED are added here using -// HRESULT_FROM_WIN32() because VC5 doesn't have WinNT's new error codes -// from winerror.h, and because it is more convienent to have them already -// formed as HRESULTs. These should correspond to: -// HRESULT_FROM_WIN32(ERROR_NOT_FOUND) == E_PROP_ID_UNSUPPORTED -// HRESULT_FROM_WIN32(ERROR_SET_NOT_FOUND) == E_PROP_SET_UNSUPPORTED -#if !defined(E_PROP_SET_UNSUPPORTED) -// -// MessageId: E_PROP_SET_UNSUPPORTED -// -// MessageText: -// -// The Specified property set is not supported.%0 -// -#define E_PROP_SET_UNSUPPORTED ((HRESULT)0x80070492L) - -#endif //!defined(E_PROP_SET_UNSUPPORTED) -#if !defined(E_PROP_ID_UNSUPPORTED) -// -// MessageId: E_PROP_ID_UNSUPPORTED -// -// MessageText: -// -// The specified property ID is not supported for the specified property set.%0 -// -#define E_PROP_ID_UNSUPPORTED ((HRESULT)0x80070490L) - -#endif //!defined(E_PROP_ID_UNSUPPORTED) diff --git a/plugins/gs/gsdx9/baseclasses/videoctl.cpp b/plugins/gs/gsdx9/baseclasses/videoctl.cpp deleted file mode 100644 index 6561f2946b..0000000000 --- a/plugins/gs/gsdx9/baseclasses/videoctl.cpp +++ /dev/null @@ -1,715 +0,0 @@ -//------------------------------------------------------------------------------ -// File: VideoCtl.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include "ddmm.h" - -// Load a string from the resource file string table. The buffer must be at -// least STR_MAX_LENGTH bytes. The easiest way to use this is to declare a -// buffer in the property page class and use it for all string loading. It -// cannot be static as multiple property pages may be active simultaneously - -TCHAR *WINAPI StringFromResource(TCHAR *pBuffer, int iResourceID) -{ - if (LoadString(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) { - return TEXT(""); - } - return pBuffer; -} - -#ifdef UNICODE -char *WINAPI StringFromResource(char *pBuffer, int iResourceID) -{ - if (LoadStringA(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH) == 0) { - return ""; - } - return pBuffer; -} -#endif - - - -// Property pages typically are called through their OLE interfaces. These -// use UNICODE strings regardless of how the binary is built. So when we -// load strings from the resource file we sometimes want to convert them -// to UNICODE. This method is passed the target UNICODE buffer and does a -// convert after loading the string (if built UNICODE this is not needed) -// On WinNT we can explicitly call LoadStringW which saves two conversions - -#ifndef UNICODE - -WCHAR * WINAPI WideStringFromResource(WCHAR *pBuffer, int iResourceID) -{ - *pBuffer = 0; - - if (g_amPlatform == VER_PLATFORM_WIN32_NT) { - LoadStringW(g_hInst,iResourceID,pBuffer,STR_MAX_LENGTH); - } else { - - CHAR szBuffer[STR_MAX_LENGTH]; - DWORD dwStringLength = LoadString(g_hInst,iResourceID,szBuffer,STR_MAX_LENGTH); - // if we loaded a string convert it to wide characters, ensuring - // that we also null terminate the result. - if (dwStringLength++) { - MultiByteToWideChar(CP_ACP,0,szBuffer,dwStringLength,pBuffer,STR_MAX_LENGTH); - } - } - return pBuffer; -} - -#endif - - -// Helper function to calculate the size of the dialog - -BOOL WINAPI GetDialogSize(int iResourceID, - DLGPROC pDlgProc, - LPARAM lParam, - SIZE *pResult) -{ - RECT rc; - HWND hwnd; - - // Create a temporary property page - - hwnd = CreateDialogParam(g_hInst, - MAKEINTRESOURCE(iResourceID), - GetDesktopWindow(), - pDlgProc, - lParam); - if (hwnd == NULL) { - return FALSE; - } - - GetWindowRect(hwnd, &rc); - pResult->cx = rc.right - rc.left; - pResult->cy = rc.bottom - rc.top; - - DestroyWindow(hwnd); - return TRUE; -} - - -// Class that aggregates on the IDirectDraw interface. Although DirectDraw -// has the ability in its interfaces to be aggregated they're not currently -// implemented. This makes it difficult for various parts of Quartz that want -// to aggregate these interfaces. In particular the video renderer passes out -// media samples that expose IDirectDraw and IDirectDrawSurface. The filter -// graph manager also exposes IDirectDraw as a plug in distributor. For these -// objects we provide these aggregation classes that republish the interfaces - -STDMETHODIMP CAggDirectDraw::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ASSERT(m_pDirectDraw); - - // Do we have this interface - - if (riid == IID_IDirectDraw) { - return GetInterface((IDirectDraw *)this,ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid,ppv); - } -} - - -STDMETHODIMP CAggDirectDraw::Compact() -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->Compact(); -} - - -STDMETHODIMP CAggDirectDraw::CreateClipper(DWORD dwFlags,LPDIRECTDRAWCLIPPER *lplpDDClipper,IUnknown *pUnkOuter) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->CreateClipper(dwFlags,lplpDDClipper,pUnkOuter); -} - - -STDMETHODIMP CAggDirectDraw::CreatePalette(DWORD dwFlags,LPPALETTEENTRY lpColorTable,LPDIRECTDRAWPALETTE *lplpDDPalette,IUnknown *pUnkOuter) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->CreatePalette(dwFlags,lpColorTable,lplpDDPalette,pUnkOuter); -} - - -STDMETHODIMP CAggDirectDraw::CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc,LPDIRECTDRAWSURFACE *lplpDDSurface,IUnknown *pUnkOuter) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->CreateSurface(lpDDSurfaceDesc,lplpDDSurface,pUnkOuter); -} - - -STDMETHODIMP CAggDirectDraw::DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface,LPDIRECTDRAWSURFACE *lplpDupDDSurface) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->DuplicateSurface(lpDDSurface,lplpDupDDSurface); -} - - -STDMETHODIMP CAggDirectDraw::EnumDisplayModes(DWORD dwSurfaceDescCount,LPDDSURFACEDESC lplpDDSurfaceDescList,LPVOID lpContext,LPDDENUMMODESCALLBACK lpEnumCallback) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->EnumDisplayModes(dwSurfaceDescCount,lplpDDSurfaceDescList,lpContext,lpEnumCallback); -} - - -STDMETHODIMP CAggDirectDraw::EnumSurfaces(DWORD dwFlags,LPDDSURFACEDESC lpDDSD,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumCallback) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->EnumSurfaces(dwFlags,lpDDSD,lpContext,lpEnumCallback); -} - - -STDMETHODIMP CAggDirectDraw::FlipToGDISurface() -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->FlipToGDISurface(); -} - - -STDMETHODIMP CAggDirectDraw::GetCaps(LPDDCAPS lpDDDriverCaps,LPDDCAPS lpDDHELCaps) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetCaps(lpDDDriverCaps,lpDDHELCaps); -} - - -STDMETHODIMP CAggDirectDraw::GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetDisplayMode(lpDDSurfaceDesc); -} - - -STDMETHODIMP CAggDirectDraw::GetFourCCCodes(LPDWORD lpNumCodes,LPDWORD lpCodes) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetFourCCCodes(lpNumCodes,lpCodes); -} - - -STDMETHODIMP CAggDirectDraw::GetGDISurface(LPDIRECTDRAWSURFACE *lplpGDIDDSurface) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetGDISurface(lplpGDIDDSurface); -} - - -STDMETHODIMP CAggDirectDraw::GetMonitorFrequency(LPDWORD lpdwFrequency) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetMonitorFrequency(lpdwFrequency); -} - - -STDMETHODIMP CAggDirectDraw::GetScanLine(LPDWORD lpdwScanLine) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetScanLine(lpdwScanLine); -} - - -STDMETHODIMP CAggDirectDraw::GetVerticalBlankStatus(LPBOOL lpblsInVB) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->GetVerticalBlankStatus(lpblsInVB); -} - - -STDMETHODIMP CAggDirectDraw::Initialize(GUID *lpGUID) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->Initialize(lpGUID); -} - - -STDMETHODIMP CAggDirectDraw::RestoreDisplayMode() -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->RestoreDisplayMode(); -} - - -STDMETHODIMP CAggDirectDraw::SetCooperativeLevel(HWND hWnd,DWORD dwFlags) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->SetCooperativeLevel(hWnd,dwFlags); -} - - -STDMETHODIMP CAggDirectDraw::SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->SetDisplayMode(dwWidth,dwHeight,dwBpp); -} - - -STDMETHODIMP CAggDirectDraw::WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent) -{ - ASSERT(m_pDirectDraw); - return m_pDirectDraw->WaitForVerticalBlank(dwFlags,hEvent); -} - - -// Class that aggregates an IDirectDrawSurface interface. Although DirectDraw -// has the ability in its interfaces to be aggregated they're not currently -// implemented. This makes it difficult for various parts of Quartz that want -// to aggregate these interfaces. In particular the video renderer passes out -// media samples that expose IDirectDraw and IDirectDrawSurface. The filter -// graph manager also exposes IDirectDraw as a plug in distributor. For these -// objects we provide these aggregation classes that republish the interfaces - -STDMETHODIMP CAggDrawSurface::NonDelegatingQueryInterface(REFIID riid, void **ppv) -{ - ASSERT(m_pDirectDrawSurface); - - // Do we have this interface - - if (riid == IID_IDirectDrawSurface) { - return GetInterface((IDirectDrawSurface *)this,ppv); - } else { - return CUnknown::NonDelegatingQueryInterface(riid,ppv); - } -} - - -STDMETHODIMP CAggDrawSurface::AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->AddAttachedSurface(lpDDSAttachedSurface); -} - - -STDMETHODIMP CAggDrawSurface::AddOverlayDirtyRect(LPRECT lpRect) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->AddOverlayDirtyRect(lpRect); -} - - -STDMETHODIMP CAggDrawSurface::Blt(LPRECT lpDestRect,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwFlags,LPDDBLTFX lpDDBltFx) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Blt(lpDestRect,lpDDSrcSurface,lpSrcRect,dwFlags,lpDDBltFx); -} - - -STDMETHODIMP CAggDrawSurface::BltBatch(LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->BltBatch(lpDDBltBatch,dwCount,dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::BltFast(DWORD dwX,DWORD dwY,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwTrans) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->BltFast(dwX,dwY,lpDDSrcSurface,lpSrcRect,dwTrans); -} - - -STDMETHODIMP CAggDrawSurface::DeleteAttachedSurface(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSAttachedSurface) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->DeleteAttachedSurface(dwFlags,lpDDSAttachedSurface); -} - - -STDMETHODIMP CAggDrawSurface::EnumAttachedSurfaces(LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->EnumAttachedSurfaces(lpContext,lpEnumSurfacesCallback); -} - - -STDMETHODIMP CAggDrawSurface::EnumOverlayZOrders(DWORD dwFlags,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpfnCallback) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->EnumOverlayZOrders(dwFlags,lpContext,lpfnCallback); -} - - -STDMETHODIMP CAggDrawSurface::Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Flip(lpDDSurfaceTargetOverride,dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::GetAttachedSurface(LPDDSCAPS lpDDSCaps,LPDIRECTDRAWSURFACE *lplpDDAttachedSurface) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetAttachedSurface(lpDDSCaps,lplpDDAttachedSurface); -} - - -STDMETHODIMP CAggDrawSurface::GetBltStatus(DWORD dwFlags) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetBltStatus(dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::GetCaps(LPDDSCAPS lpDDSCaps) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetCaps(lpDDSCaps); -} - - -STDMETHODIMP CAggDrawSurface::GetClipper(LPDIRECTDRAWCLIPPER *lplpDDClipper) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetClipper(lplpDDClipper); -} - - -STDMETHODIMP CAggDrawSurface::GetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetColorKey(dwFlags,lpDDColorKey); -} - - -STDMETHODIMP CAggDrawSurface::GetDC(HDC *lphDC) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetDC(lphDC); -} - - -STDMETHODIMP CAggDrawSurface::GetFlipStatus(DWORD dwFlags) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetFlipStatus(dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::GetOverlayPosition(LPLONG lpdwX,LPLONG lpdwY) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetOverlayPosition(lpdwX,lpdwY); -} - - -STDMETHODIMP CAggDrawSurface::GetPalette(LPDIRECTDRAWPALETTE *lplpDDPalette) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetPalette(lplpDDPalette); -} - - -STDMETHODIMP CAggDrawSurface::GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->GetPixelFormat(lpDDPixelFormat); -} - - -// A bit of a warning here: Our media samples in DirectShow aggregate on -// IDirectDraw and IDirectDrawSurface (ie are available through IMediaSample -// by QueryInterface). Unfortunately the underlying DirectDraw code cannot -// be aggregated so we have to use these classes. The snag is that when we -// call a different surface and pass in this interface as perhaps the source -// surface the call will fail because DirectDraw dereferences the pointer to -// get at its private data structures. Therefore we supply this workaround to give -// access to the real IDirectDraw surface. A filter can call GetSurfaceDesc -// and we will fill in the lpSurface pointer with the real underlying surface - -STDMETHODIMP CAggDrawSurface::GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc) -{ - ASSERT(m_pDirectDrawSurface); - - // First call down to the underlying DirectDraw - - HRESULT hr = m_pDirectDrawSurface->GetSurfaceDesc(lpDDSurfaceDesc); - if (FAILED(hr)) { - return hr; - } - - // Store the real DirectDrawSurface interface - lpDDSurfaceDesc->lpSurface = m_pDirectDrawSurface; - return hr; -} - - -STDMETHODIMP CAggDrawSurface::Initialize(LPDIRECTDRAW lpDD,LPDDSURFACEDESC lpDDSurfaceDesc) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Initialize(lpDD,lpDDSurfaceDesc); -} - - -STDMETHODIMP CAggDrawSurface::IsLost() -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->IsLost(); -} - - -STDMETHODIMP CAggDrawSurface::Lock(LPRECT lpDestRect,LPDDSURFACEDESC lpDDSurfaceDesc,DWORD dwFlags,HANDLE hEvent) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Lock(lpDestRect,lpDDSurfaceDesc,dwFlags,hEvent); -} - - -STDMETHODIMP CAggDrawSurface::ReleaseDC(HDC hDC) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->ReleaseDC(hDC); -} - - -STDMETHODIMP CAggDrawSurface::Restore() -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Restore(); -} - - -STDMETHODIMP CAggDrawSurface::SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetClipper(lpDDClipper); -} - - -STDMETHODIMP CAggDrawSurface::SetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetColorKey(dwFlags,lpDDColorKey); -} - - -STDMETHODIMP CAggDrawSurface::SetOverlayPosition(LONG dwX,LONG dwY) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetOverlayPosition(dwX,dwY); -} - - -STDMETHODIMP CAggDrawSurface::SetPalette(LPDIRECTDRAWPALETTE lpDDPalette) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->SetPalette(lpDDPalette); -} - - -STDMETHODIMP CAggDrawSurface::Unlock(LPVOID lpSurfaceData) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->Unlock(lpSurfaceData); -} - - -STDMETHODIMP CAggDrawSurface::UpdateOverlay(LPRECT lpSrcRect,LPDIRECTDRAWSURFACE lpDDDestSurface,LPRECT lpDestRect,DWORD dwFlags,LPDDOVERLAYFX lpDDOverlayFX) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->UpdateOverlay(lpSrcRect,lpDDDestSurface,lpDestRect,dwFlags,lpDDOverlayFX); -} - - -STDMETHODIMP CAggDrawSurface::UpdateOverlayDisplay(DWORD dwFlags) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->UpdateOverlayDisplay(dwFlags); -} - - -STDMETHODIMP CAggDrawSurface::UpdateOverlayZOrder(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSReference) -{ - ASSERT(m_pDirectDrawSurface); - return m_pDirectDrawSurface->UpdateOverlayZOrder(dwFlags,lpDDSReference); -} - - -// DirectShow must work on multiple platforms. In particular, it also runs on -// Windows NT 3.51 which does not have DirectDraw capabilities. The filters -// cannot therefore link statically to the DirectDraw library. To make their -// lives that little bit easier we provide this class that manages loading -// and unloading the library and creating the initial IDirectDraw interface - -CLoadDirectDraw::CLoadDirectDraw() : - m_pDirectDraw(NULL), - m_hDirectDraw(NULL) -{ -} - - -// Destructor forces unload - -CLoadDirectDraw::~CLoadDirectDraw() -{ - ReleaseDirectDraw(); - - if (m_hDirectDraw) { - NOTE("Unloading library"); - FreeLibrary(m_hDirectDraw); - } -} - - -// We can't be sure that DirectDraw is always available so we can't statically -// link to the library. Therefore we load the library, get the function entry -// point addresses and call them to create the driver objects. We return S_OK -// if we manage to load DirectDraw correctly otherwise we return E_NOINTERFACE -// We initialise a DirectDraw instance by explicitely loading the library and -// calling GetProcAddress on the DirectDrawCreate entry point that it exports - -// On a multi monitor system, we can get the DirectDraw object for any -// monitor (device) with the optional szDevice parameter - -HRESULT CLoadDirectDraw::LoadDirectDraw(LPSTR szDevice) -{ - PDRAWCREATE pDrawCreate; - PDRAWENUM pDrawEnum; - LPDIRECTDRAWENUMERATEEXA pDrawEnumEx; - HRESULT hr = NOERROR; - - NOTE("Entering DoLoadDirectDraw"); - - // Is DirectDraw already loaded - - if (m_pDirectDraw) { - NOTE("Already loaded"); - ASSERT(m_hDirectDraw); - return NOERROR; - } - - // Make sure the library is available - - if(!m_hDirectDraw) - { - UINT ErrorMode = SetErrorMode(SEM_NOOPENFILEERRORBOX); - m_hDirectDraw = LoadLibrary(TEXT("DDRAW.DLL")); - SetErrorMode(ErrorMode); - - if (m_hDirectDraw == NULL) { - DbgLog((LOG_ERROR,1,TEXT("Can't load DDRAW.DLL"))); - NOTE("No library"); - return E_NOINTERFACE; - } - } - - // Get the DLL address for the creator function - - pDrawCreate = (PDRAWCREATE)GetProcAddress(m_hDirectDraw,"DirectDrawCreate"); - // force ANSI, we assume it - pDrawEnum = (PDRAWENUM)GetProcAddress(m_hDirectDraw,"DirectDrawEnumerateA"); - pDrawEnumEx = (LPDIRECTDRAWENUMERATEEXA)GetProcAddress(m_hDirectDraw, - "DirectDrawEnumerateExA"); - - // We don't NEED DirectDrawEnumerateEx, that's just for multimon stuff - if (pDrawCreate == NULL || pDrawEnum == NULL) { - DbgLog((LOG_ERROR,1,TEXT("Can't get functions: Create=%x Enum=%x"), - pDrawCreate, pDrawEnum)); - NOTE("No entry point"); - ReleaseDirectDraw(); - return E_NOINTERFACE; - } - - DbgLog((LOG_TRACE,3,TEXT("Creating DDraw for device %s"), - szDevice ? szDevice : "")); - - // Create a DirectDraw display provider for this device, using the fancy - // multimon-aware version, if it exists - if (pDrawEnumEx) - m_pDirectDraw = DirectDrawCreateFromDeviceEx(szDevice, pDrawCreate, - pDrawEnumEx); - else - m_pDirectDraw = DirectDrawCreateFromDevice(szDevice, pDrawCreate, - pDrawEnum); - - if (m_pDirectDraw == NULL) { - DbgLog((LOG_ERROR,1,TEXT("Can't create DDraw"))); - NOTE("No instance"); - ReleaseDirectDraw(); - return E_NOINTERFACE; - } - return NOERROR; -} - - -// Called to release any DirectDraw provider we previously loaded. We may be -// called at any time especially when something goes horribly wrong and when -// we need to clean up before returning so we can't guarantee that all state -// variables are consistent so free only those really allocated allocated -// This should only be called once all reference counts have been released - -void CLoadDirectDraw::ReleaseDirectDraw() -{ - NOTE("Releasing DirectDraw driver"); - - // Release any DirectDraw provider interface - - if (m_pDirectDraw) { - NOTE("Releasing instance"); - m_pDirectDraw->Release(); - m_pDirectDraw = NULL; - } - -} - - -// Return NOERROR (S_OK) if DirectDraw has been loaded by this object - -HRESULT CLoadDirectDraw::IsDirectDrawLoaded() -{ - NOTE("Entering IsDirectDrawLoaded"); - - if (m_pDirectDraw == NULL) { - NOTE("DirectDraw not loaded"); - return S_FALSE; - } - return NOERROR; -} - - -// Return the IDirectDraw interface we look after - -LPDIRECTDRAW CLoadDirectDraw::GetDirectDraw() -{ - NOTE("Entering GetDirectDraw"); - - if (m_pDirectDraw == NULL) { - NOTE("No DirectDraw"); - return NULL; - } - - NOTE("Returning DirectDraw"); - m_pDirectDraw->AddRef(); - return m_pDirectDraw; -} - - -// Are we running on Direct Draw version 1? We need to find out as -// we rely on specific bug fixes in DirectDraw 2 for fullscreen playback. To -// find out, we simply see if it supports IDirectDraw2. Only version 2 and -// higher support this. - -BOOL CLoadDirectDraw::IsDirectDrawVersion1() -{ - - if (m_pDirectDraw == NULL) - return FALSE; - - IDirectDraw2 *p = NULL; - HRESULT hr = m_pDirectDraw->QueryInterface(IID_IDirectDraw2, (void **)&p); - if (p) - p->Release(); - if (hr == NOERROR) { - DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 2 or greater"))); - return FALSE; - } else { - DbgLog((LOG_TRACE,3,TEXT("Direct Draw Version 1"))); - return TRUE; - } -} diff --git a/plugins/gs/gsdx9/baseclasses/videoctl.h b/plugins/gs/gsdx9/baseclasses/videoctl.h deleted file mode 100644 index 3396daca21..0000000000 --- a/plugins/gs/gsdx9/baseclasses/videoctl.h +++ /dev/null @@ -1,178 +0,0 @@ -//------------------------------------------------------------------------------ -// File: VideoCtl.h -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __VIDEOCTL__ -#define __VIDEOCTL__ - -// These help with property page implementations. The first can be used to -// load any string from a resource file. The buffer to load into is passed -// as an input parameter. The same buffer is the return value if the string -// was found otherwise it returns TEXT(""). The GetDialogSize is passed the -// resource ID of a dialog box and returns the size of it in screen pixels - -#define STR_MAX_LENGTH 256 -TCHAR * WINAPI StringFromResource(TCHAR *pBuffer, int iResourceID); - -#ifdef UNICODE -#define WideStringFromResource StringFromResource -char* WINAPI StringFromResource(char*pBuffer, int iResourceID); -#else -WCHAR * WINAPI WideStringFromResource(WCHAR *pBuffer, int iResourceID); -#endif - - -BOOL WINAPI GetDialogSize(int iResourceID, // Dialog box resource identifier - DLGPROC pDlgProc, // Pointer to dialog procedure - LPARAM lParam, // Any user data wanted in pDlgProc - SIZE *pResult); // Returns the size of dialog box - -// Class that aggregates an IDirectDraw interface - -class CAggDirectDraw : public IDirectDraw, public CUnknown -{ -protected: - - LPDIRECTDRAW m_pDirectDraw; - -public: - - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - - // Constructor and destructor - - CAggDirectDraw(TCHAR *pName,LPUNKNOWN pUnk) : - CUnknown(pName,pUnk), - m_pDirectDraw(NULL) { }; - - virtual CAggDirectDraw::~CAggDirectDraw() { }; - - // Set the object we should be aggregating - void SetDirectDraw(LPDIRECTDRAW pDirectDraw) { - m_pDirectDraw = pDirectDraw; - } - - // IDirectDraw methods - - STDMETHODIMP Compact(); - STDMETHODIMP CreateClipper(DWORD dwFlags,LPDIRECTDRAWCLIPPER *lplpDDClipper,IUnknown *pUnkOuter); - STDMETHODIMP CreatePalette(DWORD dwFlags,LPPALETTEENTRY lpColorTable,LPDIRECTDRAWPALETTE *lplpDDPalette,IUnknown *pUnkOuter); - STDMETHODIMP CreateSurface(LPDDSURFACEDESC lpDDSurfaceDesc,LPDIRECTDRAWSURFACE *lplpDDSurface,IUnknown *pUnkOuter); - STDMETHODIMP DuplicateSurface(LPDIRECTDRAWSURFACE lpDDSurface,LPDIRECTDRAWSURFACE *lplpDupDDSurface); - STDMETHODIMP EnumDisplayModes(DWORD dwSurfaceDescCount,LPDDSURFACEDESC lplpDDSurfaceDescList,LPVOID lpContext,LPDDENUMMODESCALLBACK lpEnumCallback); - STDMETHODIMP EnumSurfaces(DWORD dwFlags,LPDDSURFACEDESC lpDDSD,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumCallback); - STDMETHODIMP FlipToGDISurface(); - STDMETHODIMP GetCaps(LPDDCAPS lpDDDriverCaps,LPDDCAPS lpDDHELCaps); - STDMETHODIMP GetDisplayMode(LPDDSURFACEDESC lpDDSurfaceDesc); - STDMETHODIMP GetFourCCCodes(LPDWORD lpNumCodes,LPDWORD lpCodes); - STDMETHODIMP GetGDISurface(LPDIRECTDRAWSURFACE *lplpGDIDDSurface); - STDMETHODIMP GetMonitorFrequency(LPDWORD lpdwFrequency); - STDMETHODIMP GetScanLine(LPDWORD lpdwScanLine); - STDMETHODIMP GetVerticalBlankStatus(LPBOOL lpblsInVB); - STDMETHODIMP Initialize(GUID *lpGUID); - STDMETHODIMP RestoreDisplayMode(); - STDMETHODIMP SetCooperativeLevel(HWND hWnd,DWORD dwFlags); - STDMETHODIMP SetDisplayMode(DWORD dwWidth,DWORD dwHeight,DWORD dwBpp); - STDMETHODIMP WaitForVerticalBlank(DWORD dwFlags,HANDLE hEvent); -}; - - -// Class that aggregates an IDirectDrawSurface interface - -class CAggDrawSurface : public IDirectDrawSurface, public CUnknown -{ -protected: - - LPDIRECTDRAWSURFACE m_pDirectDrawSurface; - -public: - - DECLARE_IUNKNOWN - STDMETHODIMP NonDelegatingQueryInterface(REFIID riid,void **ppv); - - // Constructor and destructor - - CAggDrawSurface(TCHAR *pName,LPUNKNOWN pUnk) : - CUnknown(pName,pUnk), - m_pDirectDrawSurface(NULL) { }; - - virtual ~CAggDrawSurface() { }; - - // Set the object we should be aggregating - void SetDirectDrawSurface(LPDIRECTDRAWSURFACE pDirectDrawSurface) { - m_pDirectDrawSurface = pDirectDrawSurface; - } - - // IDirectDrawSurface methods - - STDMETHODIMP AddAttachedSurface(LPDIRECTDRAWSURFACE lpDDSAttachedSurface); - STDMETHODIMP AddOverlayDirtyRect(LPRECT lpRect); - STDMETHODIMP Blt(LPRECT lpDestRect,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwFlags,LPDDBLTFX lpDDBltFx); - STDMETHODIMP BltBatch(LPDDBLTBATCH lpDDBltBatch,DWORD dwCount,DWORD dwFlags); - STDMETHODIMP BltFast(DWORD dwX,DWORD dwY,LPDIRECTDRAWSURFACE lpDDSrcSurface,LPRECT lpSrcRect,DWORD dwTrans); - STDMETHODIMP DeleteAttachedSurface(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSAttachedSurface); - STDMETHODIMP EnumAttachedSurfaces(LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback); - STDMETHODIMP EnumOverlayZOrders(DWORD dwFlags,LPVOID lpContext,LPDDENUMSURFACESCALLBACK lpfnCallback); - STDMETHODIMP Flip(LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride,DWORD dwFlags); - STDMETHODIMP GetAttachedSurface(LPDDSCAPS lpDDSCaps,LPDIRECTDRAWSURFACE *lplpDDAttachedSurface); - STDMETHODIMP GetBltStatus(DWORD dwFlags); - STDMETHODIMP GetCaps(LPDDSCAPS lpDDSCaps); - STDMETHODIMP GetClipper(LPDIRECTDRAWCLIPPER *lplpDDClipper); - STDMETHODIMP GetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey); - STDMETHODIMP GetDC(HDC *lphDC); - STDMETHODIMP GetFlipStatus(DWORD dwFlags); - STDMETHODIMP GetOverlayPosition(LPLONG lpdwX,LPLONG lpdwY); - STDMETHODIMP GetPalette(LPDIRECTDRAWPALETTE *lplpDDPalette); - STDMETHODIMP GetPixelFormat(LPDDPIXELFORMAT lpDDPixelFormat); - STDMETHODIMP GetSurfaceDesc(LPDDSURFACEDESC lpDDSurfaceDesc); - STDMETHODIMP Initialize(LPDIRECTDRAW lpDD,LPDDSURFACEDESC lpDDSurfaceDesc); - STDMETHODIMP IsLost(); - STDMETHODIMP Lock(LPRECT lpDestRect,LPDDSURFACEDESC lpDDSurfaceDesc,DWORD dwFlags,HANDLE hEvent); - STDMETHODIMP ReleaseDC(HDC hDC); - STDMETHODIMP Restore(); - STDMETHODIMP SetClipper(LPDIRECTDRAWCLIPPER lpDDClipper); - STDMETHODIMP SetColorKey(DWORD dwFlags,LPDDCOLORKEY lpDDColorKey); - STDMETHODIMP SetOverlayPosition(LONG dwX,LONG dwY); - STDMETHODIMP SetPalette(LPDIRECTDRAWPALETTE lpDDPalette); - STDMETHODIMP Unlock(LPVOID lpSurfaceData); - STDMETHODIMP UpdateOverlay(LPRECT lpSrcRect,LPDIRECTDRAWSURFACE lpDDDestSurface,LPRECT lpDestRect,DWORD dwFlags,LPDDOVERLAYFX lpDDOverlayFX); - STDMETHODIMP UpdateOverlayDisplay(DWORD dwFlags); - STDMETHODIMP UpdateOverlayZOrder(DWORD dwFlags,LPDIRECTDRAWSURFACE lpDDSReference); -}; - - -// DirectShow must work on multiple platforms. In particular, it also runs on -// Windows NT 3.51 which does not have DirectDraw capabilities. The filters -// cannot therefore link statically to the DirectDraw library. To make their -// lives that little bit easier we provide this class that manages loading -// and unloading the library and creating the initial IDirectDraw interface - -typedef DWORD (WINAPI *PGETFILEVERSIONINFOSIZE)(LPTSTR,LPDWORD); -typedef BOOL (WINAPI *PGETFILEVERSIONINFO)(LPTSTR,DWORD,DWORD,LPVOID); -typedef BOOL (WINAPI *PVERQUERYVALUE)(LPVOID,LPTSTR,LPVOID,PUINT); - -class CLoadDirectDraw -{ - LPDIRECTDRAW m_pDirectDraw; // The DirectDraw driver instance - HINSTANCE m_hDirectDraw; // Handle to the loaded library - -public: - - CLoadDirectDraw(); - ~CLoadDirectDraw(); - - HRESULT LoadDirectDraw(LPSTR szDevice); - void ReleaseDirectDraw(); - HRESULT IsDirectDrawLoaded(); - LPDIRECTDRAW GetDirectDraw(); - BOOL IsDirectDrawVersion1(); -}; - -#endif // __VIDEOCTL__ - diff --git a/plugins/gs/gsdx9/baseclasses/vtrans.cpp b/plugins/gs/gsdx9/baseclasses/vtrans.cpp deleted file mode 100644 index 359cd0fbdc..0000000000 --- a/plugins/gs/gsdx9/baseclasses/vtrans.cpp +++ /dev/null @@ -1,468 +0,0 @@ -//------------------------------------------------------------------------------ -// File: Vtrans.cpp -// -// Desc: DirectShow base classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include -// #include // now in precomp file streams.h - -CVideoTransformFilter::CVideoTransformFilter - ( TCHAR *pName, LPUNKNOWN pUnk, REFCLSID clsid) - : CTransformFilter(pName, pUnk, clsid) - , m_itrLate(0) - , m_nKeyFramePeriod(0) // No QM until we see at least 2 key frames - , m_nFramesSinceKeyFrame(0) - , m_bSkipping(FALSE) - , m_tDecodeStart(0) - , m_itrAvgDecode(300000) // 30mSec - probably allows skipping - , m_bQualityChanged(FALSE) -{ -#ifdef PERF - RegisterPerfId(); -#endif // PERF -} - - -CVideoTransformFilter::~CVideoTransformFilter() -{ - // nothing to do -} - - -// Reset our quality management state - -HRESULT CVideoTransformFilter::StartStreaming() -{ - m_itrLate = 0; - m_nKeyFramePeriod = 0; // No QM until we see at least 2 key frames - m_nFramesSinceKeyFrame = 0; - m_bSkipping = FALSE; - m_tDecodeStart = 0; - m_itrAvgDecode = 300000; // 30mSec - probably allows skipping - m_bQualityChanged = FALSE; - m_bSampleSkipped = FALSE; - return NOERROR; -} - - -// Overriden to reset quality management information - -HRESULT CVideoTransformFilter::EndFlush() -{ - { - // Synchronize - CAutoLock lck(&m_csReceive); - - // Reset our stats - // - // Note - we don't want to call derived classes here, - // we only want to reset our internal variables and this - // is a convenient way to do it - CVideoTransformFilter::StartStreaming(); - } - return CTransformFilter::EndFlush(); -} - - -HRESULT CVideoTransformFilter::AbortPlayback(HRESULT hr) -{ - NotifyEvent(EC_ERRORABORT, hr, 0); - m_pOutput->DeliverEndOfStream(); - return hr; -} - - -// Receive() -// -// Accept a sample from upstream, decide whether to process it -// or drop it. If we process it then get a buffer from the -// allocator of the downstream connection, transform it into the -// new buffer and deliver it to the downstream filter. -// If we decide not to process it then we do not get a buffer. - -// Remember that although this code will notice format changes coming into -// the input pin, it will NOT change its output format if that results -// in the filter needing to make a corresponding output format change. Your -// derived filter will have to take care of that. (eg. a palette change if -// the input and output is an 8 bit format). If the input sample is discarded -// and nothing is sent out for this Receive, please remember to put the format -// change on the first output sample that you actually do send. -// If your filter will produce the same output type even when the input type -// changes, then this base class code will do everything you need. - -HRESULT CVideoTransformFilter::Receive(IMediaSample *pSample) -{ - // If the next filter downstream is the video renderer, then it may - // be able to operate in DirectDraw mode which saves copying the data - // and gives higher performance. In that case the buffer which we - // get from GetDeliveryBuffer will be a DirectDraw buffer, and - // drawing into this buffer draws directly onto the display surface. - // This means that any waiting for the correct time to draw occurs - // during GetDeliveryBuffer, and that once the buffer is given to us - // the video renderer will count it in its statistics as a frame drawn. - // This means that any decision to drop the frame must be taken before - // calling GetDeliveryBuffer. - - ASSERT(CritCheckIn(&m_csReceive)); - AM_MEDIA_TYPE *pmtOut, *pmt; -#ifdef DEBUG - FOURCCMap fccOut; -#endif - HRESULT hr; - ASSERT(pSample); - IMediaSample * pOutSample; - - // If no output pin to deliver to then no point sending us data - ASSERT (m_pOutput != NULL) ; - - // The source filter may dynamically ask us to start transforming from a - // different media type than the one we're using now. If we don't, we'll - // draw garbage. (typically, this is a palette change in the movie, - // but could be something more sinister like the compression type changing, - // or even the video size changing) - -#define rcS1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcSource -#define rcT1 ((VIDEOINFOHEADER *)(pmt->pbFormat))->rcTarget - - pSample->GetMediaType(&pmt); - if (pmt != NULL && pmt->pbFormat != NULL) { - - // spew some debug output - ASSERT(!IsEqualGUID(pmt->majortype, GUID_NULL)); -#ifdef DEBUG - fccOut.SetFOURCC(&pmt->subtype); - LONG lCompression = HEADER(pmt->pbFormat)->biCompression; - LONG lBitCount = HEADER(pmt->pbFormat)->biBitCount; - LONG lStride = (HEADER(pmt->pbFormat)->biWidth * lBitCount + 7) / 8; - lStride = (lStride + 3) & ~3; - DbgLog((LOG_TRACE,3,TEXT("*Changing input type on the fly to"))); - DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"), - fccOut.GetFOURCC(), lCompression, lBitCount)); - DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"), - HEADER(pmt->pbFormat)->biHeight, - rcT1.left, rcT1.top, rcT1.right, rcT1.bottom)); - DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"), - rcS1.left, rcS1.top, rcS1.right, rcS1.bottom, - lStride)); -#endif - - // now switch to using the new format. I am assuming that the - // derived filter will do the right thing when its media type is - // switched and streaming is restarted. - - StopStreaming(); - m_pInput->CurrentMediaType() = *pmt; - DeleteMediaType(pmt); - // if this fails, playback will stop, so signal an error - hr = StartStreaming(); - if (FAILED(hr)) { - return AbortPlayback(hr); - } - } - - // Now that we have noticed any format changes on the input sample, it's - // OK to discard it. - - if (ShouldSkipFrame(pSample)) { - MSR_NOTE(m_idSkip); - m_bSampleSkipped = TRUE; - return NOERROR; - } - - // Set up the output sample - hr = InitializeOutputSample(pSample, &pOutSample); - - if (FAILED(hr)) { - return hr; - } - - m_bSampleSkipped = FALSE; - - // The renderer may ask us to on-the-fly to start transforming to a - // different format. If we don't obey it, we'll draw garbage - -#define rcS ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcSource -#define rcT ((VIDEOINFOHEADER *)(pmtOut->pbFormat))->rcTarget - - pOutSample->GetMediaType(&pmtOut); - if (pmtOut != NULL && pmtOut->pbFormat != NULL) { - - // spew some debug output - ASSERT(!IsEqualGUID(pmtOut->majortype, GUID_NULL)); -#ifdef DEBUG - fccOut.SetFOURCC(&pmtOut->subtype); - LONG lCompression = HEADER(pmtOut->pbFormat)->biCompression; - LONG lBitCount = HEADER(pmtOut->pbFormat)->biBitCount; - LONG lStride = (HEADER(pmtOut->pbFormat)->biWidth * lBitCount + 7) / 8; - lStride = (lStride + 3) & ~3; - DbgLog((LOG_TRACE,3,TEXT("*Changing output type on the fly to"))); - DbgLog((LOG_TRACE,3,TEXT("FourCC: %lx Compression: %lx BitCount: %ld"), - fccOut.GetFOURCC(), lCompression, lBitCount)); - DbgLog((LOG_TRACE,3,TEXT("biHeight: %ld rcDst: (%ld, %ld, %ld, %ld)"), - HEADER(pmtOut->pbFormat)->biHeight, - rcT.left, rcT.top, rcT.right, rcT.bottom)); - DbgLog((LOG_TRACE,3,TEXT("rcSrc: (%ld, %ld, %ld, %ld) Stride: %ld"), - rcS.left, rcS.top, rcS.right, rcS.bottom, - lStride)); -#endif - - // now switch to using the new format. I am assuming that the - // derived filter will do the right thing when its media type is - // switched and streaming is restarted. - - StopStreaming(); - m_pOutput->CurrentMediaType() = *pmtOut; - DeleteMediaType(pmtOut); - hr = StartStreaming(); - - if (SUCCEEDED(hr)) { - // a new format, means a new empty buffer, so wait for a keyframe - // before passing anything on to the renderer. - // !!! a keyframe may never come, so give up after 30 frames - DbgLog((LOG_TRACE,3,TEXT("Output format change means we must wait for a keyframe"))); - m_nWaitForKey = 30; - - // if this fails, playback will stop, so signal an error - } else { - - // Must release the sample before calling AbortPlayback - // because we might be holding the win16 lock or - // ddraw lock - pOutSample->Release(); - AbortPlayback(hr); - return hr; - } - } - - // After a discontinuity, we need to wait for the next key frame - if (pSample->IsDiscontinuity() == S_OK) { - DbgLog((LOG_TRACE,3,TEXT("Non-key discontinuity - wait for keyframe"))); - m_nWaitForKey = 30; - } - - // Start timing the transform (and log it if PERF is defined) - - if (SUCCEEDED(hr)) { - m_tDecodeStart = timeGetTime(); - MSR_START(m_idTransform); - - // have the derived class transform the data - hr = Transform(pSample, pOutSample); - - // Stop the clock (and log it if PERF is defined) - MSR_STOP(m_idTransform); - m_tDecodeStart = timeGetTime()-m_tDecodeStart; - m_itrAvgDecode = m_tDecodeStart*(10000/16) + 15*(m_itrAvgDecode/16); - - // Maybe we're waiting for a keyframe still? - if (m_nWaitForKey) - m_nWaitForKey--; - if (m_nWaitForKey && pSample->IsSyncPoint() == S_OK) - m_nWaitForKey = FALSE; - - // if so, then we don't want to pass this on to the renderer - if (m_nWaitForKey && hr == NOERROR) { - DbgLog((LOG_TRACE,3,TEXT("still waiting for a keyframe"))); - hr = S_FALSE; - } - } - - if (FAILED(hr)) { - DbgLog((LOG_TRACE,1,TEXT("Error from video transform"))); - } else { - // the Transform() function can return S_FALSE to indicate that the - // sample should not be delivered; we only deliver the sample if it's - // really S_OK (same as NOERROR, of course.) - // Try not to return S_FALSE to a direct draw buffer (it's wasteful) - // Try to take the decision earlier - before you get it. - - if (hr == NOERROR) { - hr = m_pOutput->Deliver(pOutSample); - } else { - // S_FALSE returned from Transform is a PRIVATE agreement - // We should return NOERROR from Receive() in this case because returning S_FALSE - // from Receive() means that this is the end of the stream and no more data should - // be sent. - if (S_FALSE == hr) { - - // We must Release() the sample before doing anything - // like calling the filter graph because having the - // sample means we may have the DirectDraw lock - // (== win16 lock on some versions) - pOutSample->Release(); - m_bSampleSkipped = TRUE; - if (!m_bQualityChanged) { - m_bQualityChanged = TRUE; - NotifyEvent(EC_QUALITY_CHANGE,0,0); - } - return NOERROR; - } - } - } - - // release the output buffer. If the connected pin still needs it, - // it will have addrefed it itself. - pOutSample->Release(); - ASSERT(CritCheckIn(&m_csReceive)); - - return hr; -} - - - -BOOL CVideoTransformFilter::ShouldSkipFrame( IMediaSample * pIn) -{ - REFERENCE_TIME trStart, trStopAt; - HRESULT hr = pIn->GetTime(&trStart, &trStopAt); - - // Don't skip frames with no timestamps - if (hr != S_OK) - return FALSE; - - int itrFrame = (int)(trStopAt - trStart); // frame duration - - if(S_OK==pIn->IsSyncPoint()) { - MSR_INTEGER(m_idFrameType, 1); - if ( m_nKeyFramePeriod < m_nFramesSinceKeyFrame ) { - // record the max - m_nKeyFramePeriod = m_nFramesSinceKeyFrame; - } - m_nFramesSinceKeyFrame = 0; - m_bSkipping = FALSE; - } else { - MSR_INTEGER(m_idFrameType, 2); - if ( m_nFramesSinceKeyFrame>m_nKeyFramePeriod - && m_nKeyFramePeriod>0 - ) { - // We haven't seen the key frame yet, but we were clearly being - // overoptimistic about how frequent they are. - m_nKeyFramePeriod = m_nFramesSinceKeyFrame; - } - } - - - // Whatever we might otherwise decide, - // if we are taking only a small fraction of the required frame time to decode - // then any quality problems are actually coming from somewhere else. - // Could be a net problem at the source for instance. In this case there's - // no point in us skipping frames here. - if (m_itrAvgDecode*4>itrFrame) { - - // Don't skip unless we are at least a whole frame late. - // (We would skip B frames if more than 1/2 frame late, but they're safe). - if ( m_itrLate > itrFrame ) { - - // Don't skip unless the anticipated key frame would be no more than - // 1 frame early. If the renderer has not been waiting (we *guess* - // it hasn't because we're late) then it will allow frames to be - // played early by up to a frame. - - // Let T = Stream time from now to anticipated next key frame - // = (frame duration) * (KeyFramePeriod - FramesSinceKeyFrame) - // So we skip if T - Late < one frame i.e. - // (duration) * (freq - FramesSince) - Late < duration - // or (duration) * (freq - FramesSince - 1) < Late - - // We don't dare skip until we have seen some key frames and have - // some idea how often they occur and they are reasonably frequent. - if (m_nKeyFramePeriod>0) { - // It would be crazy - but we could have a stream with key frames - // a very long way apart - and if they are further than about - // 3.5 minutes apart then we could get arithmetic overflow in - // reference time units. Therefore we switch to mSec at this point - int it = (itrFrame/10000) - * (m_nKeyFramePeriod-m_nFramesSinceKeyFrame - 1); - MSR_INTEGER(m_idTimeTillKey, it); - - // For debug - might want to see the details - dump them as scratch pad -#ifdef VTRANSPERF - MSR_INTEGER(0, itrFrame); - MSR_INTEGER(0, m_nFramesSinceKeyFrame); - MSR_INTEGER(0, m_nKeyFramePeriod); -#endif - if (m_itrLate/10000 > it) { - m_bSkipping = TRUE; - // Now we are committed. Once we start skipping, we - // cannot stop until we hit a key frame. - } else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777770); // not near enough to next key -#endif - } - } else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777771); // Next key not predictable -#endif - } - } else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777772); // Less than one frame late - MSR_INTEGER(0, m_itrLate); - MSR_INTEGER(0, itrFrame); -#endif - } - } else { -#ifdef VTRANSPERF - MSR_INTEGER(0, 777773); // Decode time short - not not worth skipping - MSR_INTEGER(0, m_itrAvgDecode); - MSR_INTEGER(0, itrFrame); -#endif - } - - ++m_nFramesSinceKeyFrame; - - if (m_bSkipping) { - // We will count down the lateness as we skip each frame. - // We re-assess each frame. The key frame might not arrive when expected. - // We reset m_itrLate if we get a new Quality message, but actually that's - // not likely because we're not sending frames on to the Renderer. In - // fact if we DID get another one it would mean that there's a long - // pipe between us and the renderer and we might need an altogether - // better strategy to avoid hunting! - m_itrLate = m_itrLate - itrFrame; - } - - MSR_INTEGER(m_idLate, (int)m_itrLate/10000 ); // Note how late we think we are - if (m_bSkipping) { - if (!m_bQualityChanged) { - m_bQualityChanged = TRUE; - NotifyEvent(EC_QUALITY_CHANGE,0,0); - } - } - return m_bSkipping; -} - - -HRESULT CVideoTransformFilter::AlterQuality(Quality q) -{ - // to reduce the amount of 64 bit arithmetic, m_itrLate is an int. - // +, -, >, == etc are not too bad, but * and / are painful. - if (m_itrLate>300000000) { - // Avoid overflow and silliness - more than 30 secs late is already silly - m_itrLate = 300000000; - } else { - m_itrLate = (int)q.Late; - } - // We ignore the other fields - - // We're actually not very good at handling this. In non-direct draw mode - // most of the time can be spent in the renderer which can skip any frame. - // In that case we'd rather the renderer handled things. - // Nevertheless we will keep an eye on it and if we really start getting - // a very long way behind then we will actually skip - but we'll still tell - // the renderer (or whoever is downstream) that they should handle quality. - - return E_FAIL; // Tell the renderer to do his thing. - -} - - - -// This will avoid several hundred useless warnings if compiled -W4 by MS VC++ v4 -#pragma warning(disable:4514) - diff --git a/plugins/gs/gsdx9/baseclasses/vtrans.h b/plugins/gs/gsdx9/baseclasses/vtrans.h deleted file mode 100644 index a9c1d6bde1..0000000000 --- a/plugins/gs/gsdx9/baseclasses/vtrans.h +++ /dev/null @@ -1,143 +0,0 @@ -//------------------------------------------------------------------------------ -// File: VTrans.h -// -// Desc: DirectShow base classes - defines a video transform class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// This class is derived from CTransformFilter, but is specialised to handle -// the requirements of video quality control by frame dropping. -// This is a non-in-place transform, (i.e. it copies the data) such as a decoder. - -class CVideoTransformFilter : public CTransformFilter -{ - public: - - CVideoTransformFilter(TCHAR *, LPUNKNOWN, REFCLSID clsid); - ~CVideoTransformFilter(); - HRESULT EndFlush(); - - // ================================================================= - // ----- override these bits --------------------------------------- - // ================================================================= - // The following methods are in CTransformFilter which is inherited. - // They are mentioned here for completeness - // - // These MUST be supplied in a derived class - // - // NOTE: - // virtual HRESULT Transform(IMediaSample * pIn, IMediaSample *pOut); - // virtual HRESULT CheckInputType(const CMediaType* mtIn) PURE; - // virtual HRESULT CheckTransform - // (const CMediaType* mtIn, const CMediaType* mtOut) PURE; - // static CCOMObject * CreateInstance(LPUNKNOWN, HRESULT *); - // virtual HRESULT DecideBufferSize - // (IMemAllocator * pAllocator, ALLOCATOR_PROPERTIES *pprop) PURE; - // virtual HRESULT GetMediaType(int iPosition, CMediaType *pMediaType) PURE; - // - // These MAY also be overridden - // - // virtual HRESULT StopStreaming(); - // virtual HRESULT SetMediaType(PIN_DIRECTION direction,const CMediaType *pmt); - // virtual HRESULT CheckConnect(PIN_DIRECTION dir,IPin *pPin); - // virtual HRESULT BreakConnect(PIN_DIRECTION dir); - // virtual HRESULT CompleteConnect(PIN_DIRECTION direction,IPin *pReceivePin); - // virtual HRESULT EndOfStream(void); - // virtual HRESULT BeginFlush(void); - // virtual HRESULT EndFlush(void); - // virtual HRESULT NewSegment - // (REFERENCE_TIME tStart,REFERENCE_TIME tStop,double dRate); -#ifdef PERF - - // If you override this - ensure that you register all these ids - // as well as any of your own, - virtual void RegisterPerfId() { - m_idSkip = MSR_REGISTER(TEXT("Video Transform Skip frame")); - m_idFrameType = MSR_REGISTER(TEXT("Video transform frame type")); - m_idLate = MSR_REGISTER(TEXT("Video Transform Lateness")); - m_idTimeTillKey = MSR_REGISTER(TEXT("Video Transform Estd. time to next key")); - CTransformFilter::RegisterPerfId(); - } -#endif - - protected: - - // =========== QUALITY MANAGEMENT IMPLEMENTATION ======================== - // Frames are assumed to come in three types: - // Type 1: an AVI key frame or an MPEG I frame. - // This frame can be decoded with no history. - // Dropping this frame means that no further frame can be decoded - // until the next type 1 frame. - // Type 1 frames are sync points. - // Type 2: an AVI non-key frame or an MPEG P frame. - // This frame cannot be decoded unless the previous type 1 frame was - // decoded and all type 2 frames since have been decoded. - // Dropping this frame means that no further frame can be decoded - // until the next type 1 frame. - // Type 3: An MPEG B frame. - // This frame cannot be decoded unless the previous type 1 or 2 frame - // has been decoded AND the subsequent type 1 or 2 frame has also - // been decoded. (This requires decoding the frames out of sequence). - // Dropping this frame affects no other frames. This implementation - // does not allow for these. All non-sync-point frames are treated - // as being type 2. - // - // The spacing of frames of type 1 in a file is not guaranteed. There MUST - // be a type 1 frame at (well, near) the start of the file in order to start - // decoding at all. After that there could be one every half second or so, - // there could be one at the start of each scene (aka "cut", "shot") or - // there could be no more at all. - // If there is only a single type 1 frame then NO FRAMES CAN BE DROPPED - // without losing all the rest of the movie. There is no way to tell whether - // this is the case, so we find that we are in the gambling business. - // To try to improve the odds, we record the greatest interval between type 1s - // that we have seen and we bet on things being no worse than this in the - // future. - - // You can tell if it's a type 1 frame by calling IsSyncPoint(). - // there is no architected way to test for a type 3, so you should override - // the quality management here if you have B-frames. - - int m_nKeyFramePeriod; // the largest observed interval between type 1 frames - // 1 means every frame is type 1, 2 means every other. - - int m_nFramesSinceKeyFrame; // Used to count frames since the last type 1. - // becomes the new m_nKeyFramePeriod if greater. - - BOOL m_bSkipping; // we are skipping to the next type 1 frame - -#ifdef PERF - int m_idFrameType; // MSR id Frame type. 1=Key, 2="non-key" - int m_idSkip; // MSR id skipping - int m_idLate; // MSR id lateness - int m_idTimeTillKey; // MSR id for guessed time till next key frame. -#endif - - virtual HRESULT StartStreaming(); - - HRESULT AbortPlayback(HRESULT hr); // if something bad happens - - HRESULT Receive(IMediaSample *pSample); - - HRESULT AlterQuality(Quality q); - - BOOL ShouldSkipFrame(IMediaSample * pIn); - - int m_itrLate; // lateness from last Quality message - // (this overflows at 214 secs late). - int m_tDecodeStart; // timeGetTime when decode started. - int m_itrAvgDecode; // Average decode time in reference units. - - BOOL m_bNoSkip; // debug - no skipping. - - // We send an EC_QUALITY_CHANGE notification to the app if we have to degrade. - // We send one when we start degrading, not one for every frame, this means - // we track whether we've sent one yet. - BOOL m_bQualityChanged; - - // When non-zero, don't pass anything to renderer until next keyframe - // If there are few keys, give up and eventually draw something - int m_nWaitForKey; -}; diff --git a/plugins/gs/gsdx9/baseclasses/winctrl.cpp b/plugins/gs/gsdx9/baseclasses/winctrl.cpp deleted file mode 100644 index d96de70f33..0000000000 --- a/plugins/gs/gsdx9/baseclasses/winctrl.cpp +++ /dev/null @@ -1,2050 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinCtrl.cpp -// -// Desc: DirectShow base classes - implements video control interface class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -// The control interface methods require us to be connected - -#define CheckConnected(pin,code) \ -{ \ - if (pin == NULL) { \ - ASSERT(!TEXT("Pin not set")); \ - } else if (pin->IsConnected() == FALSE) { \ - return (code); \ - } \ -} - -// This checks to see whether the window has a drain. An application can in -// most environments set the owner/parent of windows so that they appear in -// a compound document context (for example). In this case, the application -// would probably like to be told of any keyboard/mouse messages. Therefore -// we pass these messages on untranslated, returning TRUE if we're successful - -BOOL WINAPI PossiblyEatMessage(HWND hwndDrain, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - if (hwndDrain != NULL && !InSendMessage()) - { - switch (uMsg) - { - case WM_CHAR: - case WM_DEADCHAR: - case WM_KEYDOWN: - case WM_KEYUP: - case WM_LBUTTONDBLCLK: - case WM_LBUTTONDOWN: - case WM_LBUTTONUP: - case WM_MBUTTONDBLCLK: - case WM_MBUTTONDOWN: - case WM_MBUTTONUP: - case WM_MOUSEACTIVATE: - case WM_MOUSEMOVE: - // If we pass this on we don't get any mouse clicks - //case WM_NCHITTEST: - case WM_NCLBUTTONDBLCLK: - case WM_NCLBUTTONDOWN: - case WM_NCLBUTTONUP: - case WM_NCMBUTTONDBLCLK: - case WM_NCMBUTTONDOWN: - case WM_NCMBUTTONUP: - case WM_NCMOUSEMOVE: - case WM_NCRBUTTONDBLCLK: - case WM_NCRBUTTONDOWN: - case WM_NCRBUTTONUP: - case WM_RBUTTONDBLCLK: - case WM_RBUTTONDOWN: - case WM_RBUTTONUP: - case WM_SYSCHAR: - case WM_SYSDEADCHAR: - case WM_SYSKEYDOWN: - case WM_SYSKEYUP: - - DbgLog((LOG_TRACE, 2, TEXT("Forwarding %x to drain"))); - PostMessage(hwndDrain, uMsg, wParam, lParam); - - return TRUE; - } - } - return FALSE; -} - - -// This class implements the IVideoWindow control functions (dual interface) -// we support a large number of properties and methods designed to allow the -// client (whether it be an automation controller or a C/C++ application) to -// set and get a number of window related properties such as it's position. -// We also support some methods that duplicate the properties but provide a -// more direct and efficient mechanism as many values may be changed in one - -CBaseControlWindow::CBaseControlWindow( - CBaseFilter *pFilter, // Owning filter - CCritSec *pInterfaceLock, // Locking object - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr) : // OLE return code - - CBaseVideoWindow(pName,pUnk), - m_pInterfaceLock(pInterfaceLock), - m_hwndOwner(NULL), - m_hwndDrain(NULL), - m_bAutoShow(TRUE), - m_pFilter(pFilter), - m_bCursorHidden(FALSE), - m_pPin(NULL) -{ - ASSERT(m_pFilter); - ASSERT(m_pInterfaceLock); - ASSERT(phr); - m_BorderColour = VIDEO_COLOUR; -} - - -// Set the title caption on the base window, we don't do any field checking -// as we really don't care what title they intend to have. We can always get -// it back again later with GetWindowText. The only other complication is to -// do the necessary string conversions between ANSI and OLE Unicode strings - -STDMETHODIMP CBaseControlWindow::put_Caption(BSTR strCaption) -{ - CheckPointer(strCaption,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); -#ifdef UNICODE - SetWindowText(m_hwnd, strCaption); -#else - CHAR Caption[CAPTION]; - - WideCharToMultiByte(CP_ACP,0,strCaption,-1,Caption,CAPTION,NULL,NULL); - SetWindowText(m_hwnd, Caption); -#endif - return NOERROR; -} - - -// Get the current base window title caption, once again we do no real field -// checking. We allocate a string for the window title to be filled in with -// which ensures the interface doesn't fiddle around with getting memory. A -// BSTR is a normal C string with the length at position (-1), we use the -// WriteBSTR helper function to create the caption to try and avoid OLE32 - -STDMETHODIMP CBaseControlWindow::get_Caption(BSTR *pstrCaption) -{ - CheckPointer(pstrCaption,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - WCHAR WideCaption[CAPTION]; - -#ifdef UNICODE - GetWindowText(m_hwnd,WideCaption,CAPTION); -#else - // Convert the ASCII caption to a UNICODE string - - TCHAR Caption[CAPTION]; - GetWindowText(m_hwnd,Caption,CAPTION); - MultiByteToWideChar(CP_ACP,0,Caption,-1,WideCaption,CAPTION); -#endif - return WriteBSTR(pstrCaption,WideCaption); -} - - -// Set the window style using GWL_EXSTYLE - -STDMETHODIMP CBaseControlWindow::put_WindowStyleEx(long WindowStyleEx) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Should we be taking off WS_EX_TOPMOST - - if (GetWindowLong(m_hwnd,GWL_EXSTYLE) & WS_EX_TOPMOST) { - if ((WindowStyleEx & WS_EX_TOPMOST) == 0) { - SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) FALSE,(LPARAM) 0); - } - } - - // Likewise should we be adding WS_EX_TOPMOST - - if (WindowStyleEx & WS_EX_TOPMOST) { - SendMessage(m_hwnd,m_ShowStageTop,(WPARAM) TRUE,(LPARAM) 0); - WindowStyleEx &= (~WS_EX_TOPMOST); - if (WindowStyleEx == 0) return NOERROR; - } - return DoSetWindowStyle(WindowStyleEx,GWL_EXSTYLE); -} - - -// Gets the current GWL_EXSTYLE base window style - -STDMETHODIMP CBaseControlWindow::get_WindowStyleEx(long *pWindowStyleEx) -{ - CheckPointer(pWindowStyleEx,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - return DoGetWindowStyle(pWindowStyleEx,GWL_EXSTYLE); -} - - -// Set the window style using GWL_STYLE - -STDMETHODIMP CBaseControlWindow::put_WindowStyle(long WindowStyle) -{ - // These styles cannot be changed dynamically - - if ((WindowStyle & WS_DISABLED) || - (WindowStyle & WS_ICONIC) || - (WindowStyle & WS_MAXIMIZE) || - (WindowStyle & WS_MINIMIZE) || - (WindowStyle & WS_HSCROLL) || - (WindowStyle & WS_VSCROLL)) { - - return E_INVALIDARG; - } - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - return DoSetWindowStyle(WindowStyle,GWL_STYLE); -} - - -// Get the current GWL_STYLE base window style - -STDMETHODIMP CBaseControlWindow::get_WindowStyle(long *pWindowStyle) -{ - CheckPointer(pWindowStyle,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - return DoGetWindowStyle(pWindowStyle,GWL_STYLE); -} - - -// Change the base window style or the extended styles depending on whether -// WindowLong is GWL_STYLE or GWL_EXSTYLE. We must call SetWindowPos to have -// the window displayed in it's new style after the change which is a little -// tricky if the window is not currently visible as we realise it offscreen. -// In most cases the client will call get_WindowStyle before they call this -// and then AND and OR in extra bit settings according to the requirements - -HRESULT CBaseControlWindow::DoSetWindowStyle(long Style,long WindowLong) -{ - RECT WindowRect; - - // Get the window's visibility before setting the style - BOOL bVisible = IsWindowVisible(m_hwnd); - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - // Set the new style flags for the window - SetWindowLong(m_hwnd,WindowLong,Style); - UINT WindowFlags = SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOACTIVATE; - WindowFlags |= SWP_NOZORDER | SWP_NOSIZE | SWP_NOMOVE; - - // Show the window again in the current position - - if (bVisible == TRUE) { - - SetWindowPos(m_hwnd, // Base window handle - HWND_TOP, // Just a place holder - 0,0,0,0, // Leave size and position - WindowFlags); // Just draw it again - - return NOERROR; - } - - // Move the window offscreen so the user doesn't see the changes - - MoveWindow((HWND) m_hwnd, // Base window handle - GetSystemMetrics(SM_CXSCREEN), // Current desktop width - GetSystemMetrics(SM_CYSCREEN), // Likewise it's height - WIDTH(&WindowRect), // Use the same width - HEIGHT(&WindowRect), // Keep height same to - TRUE); // May as well repaint - - // Now show the previously hidden window - - SetWindowPos(m_hwnd, // Base window handle - HWND_TOP, // Just a place holder - 0,0,0,0, // Leave size and position - WindowFlags); // Just draw it again - - ShowWindow(m_hwnd,SW_HIDE); - - if (GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - MoveWindow((HWND) m_hwnd, // Base window handle - WindowRect.left, // Existing x coordinate - WindowRect.top, // Existing y coordinate - WIDTH(&WindowRect), // Use the same width - HEIGHT(&WindowRect), // Keep height same to - TRUE); // May as well repaint - - return NOERROR; -} - - -// Get the current base window style (either GWL_STYLE or GWL_EXSTYLE) - -HRESULT CBaseControlWindow::DoGetWindowStyle(long *pStyle,long WindowLong) -{ - *pStyle = GetWindowLong(m_hwnd,WindowLong); - return NOERROR; -} - - -// Change the visibility of the base window, this takes the same parameters -// as the ShowWindow Win32 API does, so the client can have the window hidden -// or shown, minimised to an icon, or maximised to play in full screen mode -// We pass the request on to the base window to actually make the change - -STDMETHODIMP CBaseControlWindow::put_WindowState(long WindowState) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - DoShowWindow(WindowState); - return NOERROR; -} - - -// Get the current window state, this function returns a subset of the SW bit -// settings available in ShowWindow, if the window is visible then SW_SHOW is -// set, if it is hidden then the SW_HIDDEN is set, if it is either minimised -// or maximised then the SW_MINIMIZE or SW_MAXIMIZE is set respectively. The -// other SW bit settings are really set commands not readable output values - -STDMETHODIMP CBaseControlWindow::get_WindowState(long *pWindowState) -{ - CheckPointer(pWindowState,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - ASSERT(pWindowState); - *pWindowState = FALSE; - - // Is the window visible, a window is termed visible if it is somewhere on - // the current desktop even if it is completely obscured by other windows - // so the flag is a style for each window set with the WS_VISIBLE bit - - if (IsWindowVisible(m_hwnd) == TRUE) { - - // Is the base window iconic - if (IsIconic(m_hwnd) == TRUE) { - *pWindowState |= SW_MINIMIZE; - } - - // Has the window been maximised - else if (IsZoomed(m_hwnd) == TRUE) { - *pWindowState |= SW_MAXIMIZE; - } - - // Window is normal - else { - *pWindowState |= SW_SHOW; - } - - } else { - *pWindowState |= SW_HIDE; - } - return NOERROR; -} - - -// This makes sure that any palette we realise in the base window (through a -// media type or through the overlay interface) is done in the background and -// is therefore mapped to existing device entries rather than taking it over -// as it will do when we this window gets the keyboard focus. An application -// uses this to make sure it doesn't have it's palette removed by the window - -STDMETHODIMP CBaseControlWindow::put_BackgroundPalette(long BackgroundPalette) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cWindowLock(&m_WindowLock); - - // Check this is a valid automation boolean type - - if (BackgroundPalette != OATRUE) { - if (BackgroundPalette != OAFALSE) { - return E_INVALIDARG; - } - } - - // Make sure the window realises any palette it has again - - m_bBackground = (BackgroundPalette == OATRUE ? TRUE : FALSE); - PostMessage(m_hwnd,m_RealizePalette,0,0); - PaintWindow(FALSE); - - return NOERROR; -} - - -// This returns the current background realisation setting - -STDMETHODIMP -CBaseControlWindow::get_BackgroundPalette(long *pBackgroundPalette) -{ - CheckPointer(pBackgroundPalette,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cWindowLock(&m_WindowLock); - - // Get the current background palette setting - - *pBackgroundPalette = (m_bBackground == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// Change the visibility of the base window - -STDMETHODIMP CBaseControlWindow::put_Visible(long Visible) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Check this is a valid automation boolean type - - if (Visible != OATRUE) { - if (Visible != OAFALSE) { - return E_INVALIDARG; - } - } - - // Convert the boolean visibility into SW_SHOW and SW_HIDE - - INT Mode = (Visible == OATRUE ? SW_SHOWNORMAL : SW_HIDE); - DoShowWindow(Mode); - return NOERROR; -} - - -// Return OATRUE if the window is currently visible otherwise OAFALSE - -STDMETHODIMP CBaseControlWindow::get_Visible(long *pVisible) -{ - CheckPointer(pVisible,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // See if the base window has a WS_VISIBLE style - this will return TRUE - // even if the window is completely obscured by other desktop windows, we - // return FALSE if the window is not showing because of earlier calls - - BOOL Mode = IsWindowVisible(m_hwnd); - *pVisible = (Mode == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// Change the left position of the base window. This keeps the window width -// and height properties the same so it effectively shunts the window left or -// right accordingly - there is the Width property to change that dimension - -STDMETHODIMP CBaseControlWindow::put_Left(long Left) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Get the current window position in a RECT - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if (GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - WindowRect.bottom = WindowRect.bottom - WindowRect.top; - WindowRect.right = WindowRect.right - WindowRect.left; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - Left, // New left position - WindowRect.top, // Leave top alone - WindowRect.right, // The WIDTH (not right) - WindowRect.bottom, // The HEIGHT (not bottom) - WindowFlags); // Show window options - - if (bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window left position - -STDMETHODIMP CBaseControlWindow::get_Left(long *pLeft) -{ - CheckPointer(pLeft,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pLeft = WindowRect.left; - return NOERROR; -} - - -// Change the current width of the base window. This property complements the -// left position property so we must keep the left edge constant and expand or -// contract to the right, the alternative would be to change the left edge so -// keeping the right edge constant but this is maybe a little more intuitive - -STDMETHODIMP CBaseControlWindow::put_Width(long Width) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if (GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - WindowRect.bottom = WindowRect.bottom - WindowRect.top; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - // This seems to have a bug in that calling SetWindowPos on a window with - // just the width changing causes it to ignore the width that you pass in - // and sets it to a mimimum value of 110 pixels wide (Windows NT 3.51) - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Leave left alone - WindowRect.top, // Leave top alone - Width, // New WIDTH dimension - WindowRect.bottom, // The HEIGHT (not bottom) - WindowFlags); // Show window options - - if (bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window width - -STDMETHODIMP CBaseControlWindow::get_Width(long *pWidth) -{ - CheckPointer(pWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pWidth = WindowRect.right - WindowRect.left; - return NOERROR; -} - - -// This allows the client program to change the top position for the window in -// the same way that changing the left position does not affect the width of -// the image so changing the top position does not affect the window height - -STDMETHODIMP CBaseControlWindow::put_Top(long Top) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Get the current window position in a RECT - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if (GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - WindowRect.bottom = WindowRect.bottom - WindowRect.top; - WindowRect.right = WindowRect.right - WindowRect.left; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Leave left alone - Top, // New top position - WindowRect.right, // The WIDTH (not right) - WindowRect.bottom, // The HEIGHT (not bottom) - WindowFlags); // Show window flags - - if (bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window top position - -STDMETHODIMP CBaseControlWindow::get_Top(long *pTop) -{ - CheckPointer(pTop,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pTop = WindowRect.top; - return NOERROR; -} - - -// Change the height of the window, this complements the top property so when -// we change this we must keep the top position for the base window, as said -// before we could keep the bottom and grow upwards although this is perhaps -// a little more intuitive since we already have a top position property - -STDMETHODIMP CBaseControlWindow::put_Height(long Height) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - RECT WindowRect; - - // Adjust the coordinates ready for SetWindowPos, the window rectangle we - // get back from GetWindowRect is in left,top,right and bottom while the - // coordinates SetWindowPos wants are left,top,width and height values - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - if (GetParent(m_hwnd)) { - - MapWindowPoints(HWND_DESKTOP, GetParent(m_hwnd), (LPPOINT)&WindowRect, 2); - } - - WindowRect.right = WindowRect.right - WindowRect.left; - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Leave left alone - WindowRect.top, // Leave top alone - WindowRect.right, // The WIDTH (not right) - Height, // New height dimension - WindowFlags); // Show window flags - - if (bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// Return the current base window height - -STDMETHODIMP CBaseControlWindow::get_Height(long *pHeight) -{ - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - *pHeight = WindowRect.bottom - WindowRect.top; - return NOERROR; -} - - -// This can be called to change the owning window. Setting the owner is done -// through this function, however to make the window a true child window the -// style must also be set to WS_CHILD. After resetting the owner to NULL an -// application should also set the style to WS_OVERLAPPED | WS_CLIPCHILDREN. - -// We cannot lock the object here because the SetParent causes an interthread -// SendMessage to the owner window. If they are in GetState we will sit here -// incomplete with the critical section locked therefore blocking out source -// filter threads from accessing us. Because the source thread can't enter us -// it can't get buffers or call EndOfStream so the GetState will not complete - -STDMETHODIMP CBaseControlWindow::put_Owner(OAHWND Owner) -{ - // Check we are connected otherwise reject the call - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - m_hwndOwner = (HWND) Owner; - HWND hwndParent = m_hwndOwner; - - // Add or remove WS_CHILD as appropriate - - LONG Style = GetWindowLong(m_hwnd,GWL_STYLE); - if (Owner == NULL) { - Style &= (~WS_CHILD); - } else { - Style |= (WS_CHILD); - } - SetWindowLong(m_hwnd,GWL_STYLE,Style); - - // Don't call this with the filter locked - - SetParent(m_hwnd,hwndParent); - - PaintWindow(TRUE); - NOTE1("Changed parent %lx",hwndParent); - - return NOERROR; -} - - -// This complements the put_Owner to get the current owning window property -// we always return NOERROR although the returned window handle may be NULL -// to indicate no owning window (the desktop window doesn't qualify as one) -// If an application sets the owner we call SetParent, however that returns -// NULL until the WS_CHILD bit is set on, so we store the owner internally - -STDMETHODIMP CBaseControlWindow::get_Owner(OAHWND *Owner) -{ - CheckPointer(Owner,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *Owner = (OAHWND) m_hwndOwner; - return NOERROR; -} - - -// And renderer supporting IVideoWindow may have an HWND set who will get any -// keyboard and mouse messages we receive posted on to them. This is separate -// from setting an owning window. By separating the two, applications may get -// messages sent on even when they have set no owner (perhaps it's maximised) - -STDMETHODIMP CBaseControlWindow::put_MessageDrain(OAHWND Drain) -{ - // Check we are connected otherwise reject the call - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - m_hwndDrain = (HWND) Drain; - return NOERROR; -} - - -// Return the current message drain - -STDMETHODIMP CBaseControlWindow::get_MessageDrain(OAHWND *Drain) -{ - CheckPointer(Drain,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *Drain = (OAHWND) m_hwndDrain; - return NOERROR; -} - - -// This is called by the filter graph to inform us of a message we should know -// is being sent to our owning window. We have this because as a child window -// we do not get certain messages that are only sent to top level windows. We -// must see the palette changed/changing/query messages so that we know if we -// have the foreground palette or not. We pass the message on to our window -// using SendMessage - this will cause an interthread send message to occur - -STDMETHODIMP -CBaseControlWindow::NotifyOwnerMessage(OAHWND hwnd, // Window handle - long uMsg, // Message ID - LONG_PTR wParam, // Parameters - LONG_PTR lParam) // for message -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Only interested in these Windows messages - - switch (uMsg) { - - case WM_SYSCOLORCHANGE: - case WM_PALETTECHANGED: - case WM_PALETTEISCHANGING: - case WM_QUERYNEWPALETTE: - case WM_DEVMODECHANGE: - case WM_DISPLAYCHANGE: - case WM_ACTIVATEAPP: - - // If we do not have an owner then ignore - - if (m_hwndOwner == NULL) { - return NOERROR; - } - SendMessage(m_hwnd,uMsg,(WPARAM)wParam,(LPARAM)lParam); - break; - - // do NOT fwd WM_MOVE. the parameters are the location of the parent - // window, NOT what the renderer should be looking at. But we need - // to make sure the overlay is moved with the parent window, so we - // do this. - case WM_MOVE: - PostMessage(m_hwnd,WM_PAINT,0,0); - break; - } - return NOERROR; -} - - -// Allow an application to have us set the base window in the foreground. We -// have this because it is difficult for one thread to do do this to a window -// owned by another thread. We ask the base window class to do the real work - -STDMETHODIMP CBaseControlWindow::SetWindowForeground(long Focus) -{ - // Check this is a valid automation boolean type - - if (Focus != OATRUE) { - if (Focus != OAFALSE) { - return E_INVALIDARG; - } - } - - // We shouldn't lock as this sends a message - - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bFocus = (Focus == OATRUE ? TRUE : FALSE); - DoSetWindowForeground(bFocus); - - return NOERROR; -} - - -// This allows a client to set the complete window size and position in one -// atomic operation. The same affect can be had by changing each dimension -// in turn through their individual properties although some flashing will -// occur as each of them gets updated (they are better set at design time) - -STDMETHODIMP -CBaseControlWindow::SetWindowPosition(long Left,long Top,long Width,long Height) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - BOOL bSuccess; - - // Set the new size and position - UINT WindowFlags = SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE; - - ASSERT(IsWindow(m_hwnd)); - bSuccess = SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - Left, // Left position - Top, // Top position - Width, // Window width - Height, // Window height - WindowFlags); // Show window flags - ASSERT(bSuccess); -#ifdef DEBUG - DbgLog((LOG_TRACE, 1, TEXT("SWP failed error %d"), GetLastError())); -#endif - if (bSuccess == FALSE) { - return E_INVALIDARG; - } - return NOERROR; -} - - -// This complements the SetWindowPosition to return the current window place -// in device coordinates. As before the same information can be retrived by -// calling the property get functions individually but this is atomic and is -// therefore more suitable to a live environment rather than design time - -STDMETHODIMP -CBaseControlWindow::GetWindowPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) -{ - // Should check the pointers are not NULL - - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT WindowRect; - - // Get the current window coordinates - - EXECUTE_ASSERT(GetWindowRect(m_hwnd,&WindowRect)); - - // Convert the RECT into left,top,width and height values - - *pLeft = WindowRect.left; - *pTop = WindowRect.top; - *pWidth = WindowRect.right - WindowRect.left; - *pHeight = WindowRect.bottom - WindowRect.top; - - return NOERROR; -} - - -// When a window is maximised or iconic calling GetWindowPosition will return -// the current window position (likewise for the properties). However if the -// restored size (ie the size we'll return to when normally shown) is needed -// then this should be used. When in a normal position (neither iconic nor -// maximised) then this returns the same coordinates as GetWindowPosition - -STDMETHODIMP -CBaseControlWindow::GetRestorePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) -{ - // Should check the pointers are not NULL - - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Use GetWindowPlacement to find the restore position - - WINDOWPLACEMENT Place; - Place.length = sizeof(WINDOWPLACEMENT); - EXECUTE_ASSERT(GetWindowPlacement(m_hwnd,&Place)); - - RECT WorkArea; - - // We must take into account any task bar present - - if (SystemParametersInfo(SPI_GETWORKAREA,0,&WorkArea,FALSE) == TRUE) { - if (GetParent(m_hwnd) == NULL) { - Place.rcNormalPosition.top += WorkArea.top; - Place.rcNormalPosition.bottom += WorkArea.top; - Place.rcNormalPosition.left += WorkArea.left; - Place.rcNormalPosition.right += WorkArea.left; - } - } - - // Convert the RECT into left,top,width and height values - - *pLeft = Place.rcNormalPosition.left; - *pTop = Place.rcNormalPosition.top; - *pWidth = Place.rcNormalPosition.right - Place.rcNormalPosition.left; - *pHeight = Place.rcNormalPosition.bottom - Place.rcNormalPosition.top; - - return NOERROR; -} - - -// Return the current border colour, if we are playing something to a subset -// of the base window display there is an outside area exposed. The default -// action is to paint this colour in the Windows background colour (defined -// as value COLOR_WINDOW) We reset to this default when we're disconnected - -STDMETHODIMP CBaseControlWindow::get_BorderColor(long *Color) -{ - CheckPointer(Color,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *Color = (long) m_BorderColour; - return NOERROR; -} - - -// This can be called to set the current border colour - -STDMETHODIMP CBaseControlWindow::put_BorderColor(long Color) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Have the window repainted with the new border colour - - m_BorderColour = (COLORREF) Color; - PaintWindow(TRUE); - return NOERROR; -} - - -// Delegate fullscreen handling to plug in distributor - -STDMETHODIMP CBaseControlWindow::get_FullScreenMode(long *FullScreenMode) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CheckPointer(FullScreenMode,E_POINTER); - return E_NOTIMPL; -} - - -// Delegate fullscreen handling to plug in distributor - -STDMETHODIMP CBaseControlWindow::put_FullScreenMode(long FullScreenMode) -{ - return E_NOTIMPL; -} - - -// This sets the auto show property, this property causes the base window to -// be displayed whenever we change state. This allows an application to have -// to do nothing to have the window appear but still allow them to change the -// default behaviour if for example they want to keep it hidden for longer - -STDMETHODIMP CBaseControlWindow::put_AutoShow(long AutoShow) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Check this is a valid automation boolean type - - if (AutoShow != OATRUE) { - if (AutoShow != OAFALSE) { - return E_INVALIDARG; - } - } - - m_bAutoShow = (AutoShow == OATRUE ? TRUE : FALSE); - return NOERROR; -} - - -// This can be called to get the current auto show flag. The flag is updated -// when we connect and disconnect and through this interface all of which are -// controlled and serialised by means of the main renderer critical section - -STDMETHODIMP CBaseControlWindow::get_AutoShow(long *AutoShow) -{ - CheckPointer(AutoShow,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *AutoShow = (m_bAutoShow == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// Return the minimum ideal image size for the current video. This may differ -// to the actual video dimensions because we may be using DirectDraw hardware -// that has specific stretching requirements. For example the Cirrus Logic -// cards have a minimum stretch factor depending on the overlay surface size - -STDMETHODIMP -CBaseControlWindow::GetMinIdealImageSize(long *pWidth,long *pHeight) -{ - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - FILTER_STATE State; - - // Must not be stopped for this to work correctly - - m_pFilter->GetState(0,&State); - if (State == State_Stopped) { - return VFW_E_WRONG_STATE; - } - - RECT DefaultRect = GetDefaultRect(); - *pWidth = WIDTH(&DefaultRect); - *pHeight = HEIGHT(&DefaultRect); - return NOERROR; -} - - -// Return the maximum ideal image size for the current video. This may differ -// to the actual video dimensions because we may be using DirectDraw hardware -// that has specific stretching requirements. For example the Cirrus Logic -// cards have a maximum stretch factor depending on the overlay surface size - -STDMETHODIMP -CBaseControlWindow::GetMaxIdealImageSize(long *pWidth,long *pHeight) -{ - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - FILTER_STATE State; - - // Must not be stopped for this to work correctly - - m_pFilter->GetState(0,&State); - if (State == State_Stopped) { - return VFW_E_WRONG_STATE; - } - - RECT DefaultRect = GetDefaultRect(); - *pWidth = WIDTH(&DefaultRect); - *pHeight = HEIGHT(&DefaultRect); - return NOERROR; -} - - -// Allow an application to hide the cursor on our window - -STDMETHODIMP -CBaseControlWindow::HideCursor(long HideCursor) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - - // Check this is a valid automation boolean type - - if (HideCursor != OATRUE) { - if (HideCursor != OAFALSE) { - return E_INVALIDARG; - } - } - - m_bCursorHidden = (HideCursor == OATRUE ? TRUE : FALSE); - return NOERROR; -} - - -// Returns whether we have the cursor hidden or not - -STDMETHODIMP CBaseControlWindow::IsCursorHidden(long *CursorHidden) -{ - CheckPointer(CursorHidden,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - *CursorHidden = (m_bCursorHidden == TRUE ? OATRUE : OAFALSE); - return NOERROR; -} - - -// This class implements the IBasicVideo control functions (dual interface) -// we support a large number of properties and methods designed to allow the -// client (whether it be an automation controller or a C/C++ application) to -// set and get a number of video related properties such as the native video -// size. We support some methods that duplicate the properties but provide a -// more direct and efficient mechanism as many values may be changed in one - -CBaseControlVideo::CBaseControlVideo( - CBaseFilter *pFilter, // Owning filter - CCritSec *pInterfaceLock, // Locking object - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr) : // OLE return code - - CBaseBasicVideo(pName,pUnk), - m_pFilter(pFilter), - m_pInterfaceLock(pInterfaceLock), - m_pPin(NULL) -{ - ASSERT(m_pFilter); - ASSERT(m_pInterfaceLock); - ASSERT(phr); -} - -// Return an approximate average time per frame - -STDMETHODIMP CBaseControlVideo::get_AvgTimePerFrame(REFTIME *pAvgTimePerFrame) -{ - CheckPointer(pAvgTimePerFrame,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - COARefTime AvgTime(pVideoInfo->AvgTimePerFrame); - *pAvgTimePerFrame = (REFTIME) AvgTime; - - return NOERROR; -} - - -// Return an approximate bit rate for the video - -STDMETHODIMP CBaseControlVideo::get_BitRate(long *pBitRate) -{ - CheckPointer(pBitRate,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pBitRate = pVideoInfo->dwBitRate; - return NOERROR; -} - - -// Return an approximate bit error rate - -STDMETHODIMP CBaseControlVideo::get_BitErrorRate(long *pBitErrorRate) -{ - CheckPointer(pBitErrorRate,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pBitErrorRate = pVideoInfo->dwBitErrorRate; - return NOERROR; -} - - -// This returns the current video width - -STDMETHODIMP CBaseControlVideo::get_VideoWidth(long *pVideoWidth) -{ - CheckPointer(pVideoWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pVideoWidth = pVideoInfo->bmiHeader.biWidth; - return NOERROR; -} - - -// This returns the current video height - -STDMETHODIMP CBaseControlVideo::get_VideoHeight(long *pVideoHeight) -{ - CheckPointer(pVideoHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pVideoHeight = pVideoInfo->bmiHeader.biHeight; - return NOERROR; -} - - -// This returns the current palette the video is using as an array allocated -// by the user. To remain consistent we use PALETTEENTRY fields to return the -// colours in rather than RGBQUADs that multimedia decided to use. The memory -// is allocated by the user so we simple copy each in turn. We check that the -// number of entries requested and the start position offset are both valid -// If the number of entries evaluates to zero then we return an S_FALSE code - -STDMETHODIMP CBaseControlVideo::GetVideoPaletteEntries(long StartIndex, - long Entries, - long *pRetrieved, - long *pPalette) -{ - CheckPointer(pRetrieved,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - CMediaType MediaType; - - // Get the video format from the derived class - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - BITMAPINFOHEADER *pHeader = HEADER(pVideoInfo); - - // Is the current format palettised - - if (PALETTISED(pVideoInfo) == FALSE) { - *pRetrieved = 0; - return VFW_E_NO_PALETTE_AVAILABLE; - } - - // Do they just want to know how many are available - - if (pPalette == NULL) { - *pRetrieved = pHeader->biClrUsed; - return NOERROR; - } - - // Make sure the start position is a valid offset - - if (StartIndex >= (LONG) pHeader->biClrUsed || StartIndex < 0) { - *pRetrieved = 0; - return E_INVALIDARG; - } - - // Correct the number we can retrieve - - LONG Available = (LONG) pHeader->biClrUsed - StartIndex; - *pRetrieved = max(0,min(Available,Entries)); - if (*pRetrieved == 0) { - return S_FALSE; - } - - // Copy the palette entries to the output buffer - - PALETTEENTRY *pEntries = (PALETTEENTRY *) pPalette; - RGBQUAD *pColours = COLORS(pVideoInfo) + StartIndex; - - for (LONG Count = 0;Count < *pRetrieved;Count++) { - pEntries[Count].peRed = pColours[Count].rgbRed; - pEntries[Count].peGreen = pColours[Count].rgbGreen; - pEntries[Count].peBlue = pColours[Count].rgbBlue; - pEntries[Count].peFlags = 0; - } - return NOERROR; -} - - -// This returns the current video dimensions as a method rather than a number -// of individual property get calls. For the same reasons as said before we -// cannot access the renderer media type directly as the window object thread -// may be updating it since dynamic format changes may change these values - -STDMETHODIMP CBaseControlVideo::GetVideoSize(long *pWidth,long *pHeight) -{ - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - - // Get the video format from the derived class - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - *pWidth = pVideoInfo->bmiHeader.biWidth; - *pHeight = pVideoInfo->bmiHeader.biHeight; - return NOERROR; -} - - -// Set the source video rectangle as left,top,right and bottom coordinates -// rather than left,top,width and height as per OLE automation interfaces -// Then pass the rectangle on to the window object to set the source - -STDMETHODIMP -CBaseControlVideo::SetSourcePosition(long Left,long Top,long Width,long Height) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - SourceRect.left = Left; - SourceRect.top = Top; - SourceRect.right = Left + Width; - SourceRect.bottom = Top + Height; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the source rectangle in left,top,width and height rather than the -// left,top,right and bottom values that RECT uses (and which the window -// object returns through GetSourceRect) which requires a little work - -STDMETHODIMP -CBaseControlVideo::GetSourcePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) -{ - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT SourceRect; - - CAutoLock cInterfaceLock(m_pInterfaceLock); - GetSourceRect(&SourceRect); - - *pLeft = SourceRect.left; - *pTop = SourceRect.top; - *pWidth = WIDTH(&SourceRect); - *pHeight = HEIGHT(&SourceRect); - - return NOERROR; -} - - -// Set the video destination as left,top,right and bottom coordinates rather -// than the left,top,width and height uses as per OLE automation interfaces -// Then pass the rectangle on to the window object to set the destination - -STDMETHODIMP -CBaseControlVideo::SetDestinationPosition(long Left,long Top,long Width,long Height) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - DestinationRect.left = Left; - DestinationRect.top = Top; - DestinationRect.right = Left + Width; - DestinationRect.bottom = Top + Height; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the destination rectangle in left,top,width and height rather than -// the left,top,right and bottom values that RECT uses (and which the window -// object returns through GetDestinationRect) which requires a little work - -STDMETHODIMP -CBaseControlVideo::GetDestinationPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight) -{ - // Should check the pointers are not NULL - - CheckPointer(pLeft,E_POINTER); - CheckPointer(pTop,E_POINTER); - CheckPointer(pWidth,E_POINTER); - CheckPointer(pHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - RECT DestinationRect; - - CAutoLock cInterfaceLock(m_pInterfaceLock); - GetTargetRect(&DestinationRect); - - *pLeft = DestinationRect.left; - *pTop = DestinationRect.top; - *pWidth = WIDTH(&DestinationRect); - *pHeight = HEIGHT(&DestinationRect); - - return NOERROR; -} - - -// Set the source left position, the source rectangle we get back from the -// window object is a true rectangle in left,top,right and bottom positions -// so all we have to do is to update the left position and pass it back. We -// must keep the current width constant when we're updating this property - -STDMETHODIMP CBaseControlVideo::put_SourceLeft(long SourceLeft) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.right = SourceLeft + WIDTH(&SourceRect); - SourceRect.left = SourceLeft; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current left source video position - -STDMETHODIMP CBaseControlVideo::get_SourceLeft(long *pSourceLeft) -{ - CheckPointer(pSourceLeft,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceLeft = SourceRect.left; - return NOERROR; -} - - -// Set the source width, we get the current source rectangle and then update -// the right position to be the left position (thereby keeping it constant) -// plus the new source width we are passed in (it expands to the right) - -STDMETHODIMP CBaseControlVideo::put_SourceWidth(long SourceWidth) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.right = SourceRect.left + SourceWidth; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current source width - -STDMETHODIMP CBaseControlVideo::get_SourceWidth(long *pSourceWidth) -{ - CheckPointer(pSourceWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceWidth = WIDTH(&SourceRect); - return NOERROR; -} - - -// Set the source top position - changing this property does not affect the -// current source height. So changing this shunts the source rectangle up and -// down appropriately. Changing the height complements this functionality by -// keeping the top position constant and simply changing the source height - -STDMETHODIMP CBaseControlVideo::put_SourceTop(long SourceTop) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.bottom = SourceTop + HEIGHT(&SourceRect); - SourceRect.top = SourceTop; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current top position - -STDMETHODIMP CBaseControlVideo::get_SourceTop(long *pSourceTop) -{ - CheckPointer(pSourceTop,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceTop = SourceRect.top; - return NOERROR; -} - - -// Set the source height - -STDMETHODIMP CBaseControlVideo::put_SourceHeight(long SourceHeight) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - GetSourceRect(&SourceRect); - SourceRect.bottom = SourceRect.top + SourceHeight; - - // Check the source rectangle is valid - - HRESULT hr = CheckSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the source rectangle - - hr = SetSourceRect(&SourceRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the current source height - -STDMETHODIMP CBaseControlVideo::get_SourceHeight(long *pSourceHeight) -{ - CheckPointer(pSourceHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT SourceRect; - - GetSourceRect(&SourceRect); - *pSourceHeight = HEIGHT(&SourceRect); - return NOERROR; -} - - -// Set the target left position, the target rectangle we get back from the -// window object is a true rectangle in left,top,right and bottom positions -// so all we have to do is to update the left position and pass it back. We -// must keep the current width constant when we're updating this property - -STDMETHODIMP CBaseControlVideo::put_DestinationLeft(long DestinationLeft) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.right = DestinationLeft + WIDTH(&DestinationRect); - DestinationRect.left = DestinationLeft; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the left position for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationLeft(long *pDestinationLeft) -{ - CheckPointer(pDestinationLeft,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationLeft = DestinationRect.left; - return NOERROR; -} - - -// Set the destination width - -STDMETHODIMP CBaseControlVideo::put_DestinationWidth(long DestinationWidth) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.right = DestinationRect.left + DestinationWidth; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the width for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationWidth(long *pDestinationWidth) -{ - CheckPointer(pDestinationWidth,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationWidth = WIDTH(&DestinationRect); - return NOERROR; -} - - -// Set the target top position - changing this property does not affect the -// current target height. So changing this shunts the target rectangle up and -// down appropriately. Changing the height complements this functionality by -// keeping the top position constant and simply changing the target height - -STDMETHODIMP CBaseControlVideo::put_DestinationTop(long DestinationTop) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.bottom = DestinationTop + HEIGHT(&DestinationRect); - DestinationRect.top = DestinationTop; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the top position for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationTop(long *pDestinationTop) -{ - CheckPointer(pDestinationTop,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationTop = DestinationRect.top; - return NOERROR; -} - - -// Set the destination height - -STDMETHODIMP CBaseControlVideo::put_DestinationHeight(long DestinationHeight) -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - GetTargetRect(&DestinationRect); - DestinationRect.bottom = DestinationRect.top + DestinationHeight; - - // Check the target rectangle is valid - - HRESULT hr = CheckTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - - // Now set the new target rectangle - - hr = SetTargetRect(&DestinationRect); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return the height for the destination rectangle - -STDMETHODIMP CBaseControlVideo::get_DestinationHeight(long *pDestinationHeight) -{ - CheckPointer(pDestinationHeight,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - RECT DestinationRect; - - GetTargetRect(&DestinationRect); - *pDestinationHeight = HEIGHT(&DestinationRect); - return NOERROR; -} - - -// Reset the source rectangle to the full video dimensions - -STDMETHODIMP CBaseControlVideo::SetDefaultSourcePosition() -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - HRESULT hr = SetDefaultSourceRect(); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return S_OK if we're using the default source otherwise S_FALSE - -STDMETHODIMP CBaseControlVideo::IsUsingDefaultSource() -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - return IsDefaultSourceRect(); -} - - -// Reset the video renderer to use the entire playback area - -STDMETHODIMP CBaseControlVideo::SetDefaultDestinationPosition() -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - HRESULT hr = SetDefaultTargetRect(); - if (FAILED(hr)) { - return hr; - } - return OnUpdateRectangles(); -} - - -// Return S_OK if we're using the default target otherwise S_FALSE - -STDMETHODIMP CBaseControlVideo::IsUsingDefaultDestination() -{ - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - return IsDefaultTargetRect(); -} - - -// Return a copy of the current image in the video renderer - -STDMETHODIMP -CBaseControlVideo::GetCurrentImage(long *pBufferSize,long *pVideoImage) -{ - CheckPointer(pBufferSize,E_POINTER); - CheckConnected(m_pPin,VFW_E_NOT_CONNECTED); - CAutoLock cInterfaceLock(m_pInterfaceLock); - FILTER_STATE State; - - // Make sure we are in a paused state - - if (pVideoImage != NULL) { - m_pFilter->GetState(0,&State); - if (State != State_Paused) { - return VFW_E_NOT_PAUSED; - } - return GetStaticImage(pBufferSize,pVideoImage); - } - - // Just return the memory required - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - RECT SourceRect; - GetSourceRect(&SourceRect); - return GetImageSize(pVideoInfo,pBufferSize,&SourceRect); -} - - -// An application has two ways of using GetCurrentImage, one is to pass a real -// buffer which should be filled with the current image. The other is to pass -// a NULL buffer pointer which is interpreted as asking us to return how much -// memory is required for the image. The constraints for when the latter can -// be called are much looser. To calculate the memory required we synthesize -// a VIDEOINFO that takes into account the source rectangle that's being used - -HRESULT CBaseControlVideo::GetImageSize(VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - RECT *pSourceRect) -{ - NOTE("Entering GetImageSize"); - ASSERT(pSourceRect); - - // Check we have the correct input parameters - - if (pSourceRect == NULL || - pVideoInfo == NULL || - pBufferSize == NULL) { - - return E_UNEXPECTED; - } - - // Is the data format compatible - - if (pVideoInfo->bmiHeader.biCompression != BI_RGB) { - if (pVideoInfo->bmiHeader.biCompression != BI_BITFIELDS) { - return E_INVALIDARG; - } - } - - ASSERT(IsRectEmpty(pSourceRect) == FALSE); - - BITMAPINFOHEADER bih; - bih.biWidth = WIDTH(pSourceRect); - bih.biHeight = HEIGHT(pSourceRect); - bih.biBitCount = pVideoInfo->bmiHeader.biBitCount; - LONG Size = DIBSIZE(bih); - Size += GetBitmapFormatSize(HEADER(pVideoInfo)) - SIZE_PREHEADER; - *pBufferSize = Size; - - return NOERROR; -} - - -// Given an IMediaSample containing a linear buffer with an image and a type -// describing the bitmap make a rendering of the image into the output buffer -// This may be called by derived classes who render typical video images to -// handle the IBasicVideo GetCurrentImage method. The pVideoImage pointer may -// be NULL when passed to GetCurrentImage in which case GetImageSize will be -// called instead, which will just do the calculation of the memory required - -HRESULT CBaseControlVideo::CopyImage(IMediaSample *pMediaSample, - VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - BYTE *pVideoImage, - RECT *pSourceRect) -{ - NOTE("Entering CopyImage"); - ASSERT(pSourceRect); - BYTE *pCurrentImage; - - // Check we have an image to copy - - if (pMediaSample == NULL || pSourceRect == NULL || - pVideoInfo == NULL || pVideoImage == NULL || - pBufferSize == NULL) { - - return E_UNEXPECTED; - } - - // Is the data format compatible - - if (pVideoInfo->bmiHeader.biCompression != BI_RGB) { - if (pVideoInfo->bmiHeader.biCompression != BI_BITFIELDS) { - return E_INVALIDARG; - } - } - - ASSERT(IsRectEmpty(pSourceRect) == FALSE); - - BITMAPINFOHEADER bih; - bih.biWidth = WIDTH(pSourceRect); - bih.biHeight = HEIGHT(pSourceRect); - bih.biBitCount = pVideoInfo->bmiHeader.biBitCount; - LONG Size = GetBitmapFormatSize(HEADER(pVideoInfo)) - SIZE_PREHEADER; - LONG Total = Size + DIBSIZE(bih); - - // Make sure we have a large enough buffer - - if (*pBufferSize < Total) { - return E_OUTOFMEMORY; - } - - // Copy the BITMAPINFO - - CopyMemory((PVOID)pVideoImage, (PVOID)&pVideoInfo->bmiHeader, Size); - ((BITMAPINFOHEADER *)pVideoImage)->biWidth = WIDTH(pSourceRect); - ((BITMAPINFOHEADER *)pVideoImage)->biHeight = HEIGHT(pSourceRect); - ((BITMAPINFOHEADER *)pVideoImage)->biSizeImage = DIBSIZE(bih); - BYTE *pImageData = pVideoImage + Size; - - // Get the pointer to it's image data - - HRESULT hr = pMediaSample->GetPointer(&pCurrentImage); - if (FAILED(hr)) { - return hr; - } - - // Now we are ready to start copying the source scan lines - - LONG ScanLine = (pVideoInfo->bmiHeader.biBitCount / 8) * WIDTH(pSourceRect); - LONG LinesToSkip = pVideoInfo->bmiHeader.biHeight; - LinesToSkip -= pSourceRect->top + HEIGHT(pSourceRect); - pCurrentImage += LinesToSkip * DIBWIDTHBYTES(pVideoInfo->bmiHeader); - pCurrentImage += pSourceRect->left * (pVideoInfo->bmiHeader.biBitCount / 8); - - // Even money on this GP faulting sometime... - - for (LONG Line = 0;Line < HEIGHT(pSourceRect);Line++) { - CopyMemory((PVOID)pImageData, (PVOID)pCurrentImage, ScanLine); - pImageData += DIBWIDTHBYTES(*(BITMAPINFOHEADER *)pVideoImage); - pCurrentImage += DIBWIDTHBYTES(pVideoInfo->bmiHeader); - } - return NOERROR; -} - - -// Called when we change media types either during connection or dynamically -// We inform the filter graph and therefore the application that the video -// size may have changed, we don't bother looking to see if it really has as -// we leave that to the application - the dimensions are the event parameters - -HRESULT CBaseControlVideo::OnVideoSizeChange() -{ - // Get the video format from the derived class - - VIDEOINFOHEADER *pVideoInfo = GetVideoFormat(); - if (pVideoInfo == NULL) - return E_OUTOFMEMORY; - WORD Width = (WORD) pVideoInfo->bmiHeader.biWidth; - WORD Height = (WORD) pVideoInfo->bmiHeader.biHeight; - - return m_pFilter->NotifyEvent(EC_VIDEO_SIZE_CHANGED, - MAKELPARAM(Width,Height), - MAKEWPARAM(0,0)); -} - - -// Set the video source rectangle. We must check the source rectangle against -// the actual video dimensions otherwise when we come to draw the pictures we -// get access violations as GDI tries to touch data outside of the image data -// Although we store the rectangle in left, top, right and bottom coordinates -// instead of left, top, width and height as OLE uses we do take into account -// that the rectangle is used up to, but not including, the right column and -// bottom row of pixels, see the Win32 documentation on RECT for more details - -HRESULT CBaseControlVideo::CheckSourceRect(RECT *pSourceRect) -{ - CheckPointer(pSourceRect,E_POINTER); - LONG Width,Height; - GetVideoSize(&Width,&Height); - - // Check the coordinates are greater than zero - // and that the rectangle is valid (leftleft >= pSourceRect->right) || - (pSourceRect->left < 0) || - (pSourceRect->top >= pSourceRect->bottom) || - (pSourceRect->top < 0)) { - - return E_INVALIDARG; - } - - // Check the coordinates are less than the extents - - if ((pSourceRect->right > Width) || - (pSourceRect->bottom > Height)) { - - return E_INVALIDARG; - } - return NOERROR; -} - - -// Check the target rectangle has some valid coordinates, which amounts to -// little more than checking the destination rectangle isn't empty. Derived -// classes may call this when they have their SetTargetRect method called to -// check the rectangle validity, we do not update the rectangles passed in -// Although we store the rectangle in left, top, right and bottom coordinates -// instead of left, top, width and height as OLE uses we do take into account -// that the rectangle is used up to, but not including, the right column and -// bottom row of pixels, see the Win32 documentation on RECT for more details - -HRESULT CBaseControlVideo::CheckTargetRect(RECT *pTargetRect) -{ - // Check the pointer is valid - - if (pTargetRect == NULL) { - return E_POINTER; - } - - // These overflow the WIDTH and HEIGHT checks - - if (pTargetRect->left > pTargetRect->right || - pTargetRect->top > pTargetRect->bottom) { - return E_INVALIDARG; - } - - // Check the rectangle has valid coordinates - - if (WIDTH(pTargetRect) <= 0 || HEIGHT(pTargetRect) <= 0) { - return E_INVALIDARG; - } - - ASSERT(IsRectEmpty(pTargetRect) == FALSE); - return NOERROR; -} - diff --git a/plugins/gs/gsdx9/baseclasses/winctrl.h b/plugins/gs/gsdx9/baseclasses/winctrl.h deleted file mode 100644 index c3e18dae51..0000000000 --- a/plugins/gs/gsdx9/baseclasses/winctrl.h +++ /dev/null @@ -1,224 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinCtrl.h -// -// Desc: DirectShow base classes - defines classes for video control -// interfaces. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __WINCTRL__ -#define __WINCTRL__ - -#define ABSOL(x) (x < 0 ? -x : x) -#define NEGAT(x) (x > 0 ? -x : x) - -// Helper -BOOL WINAPI PossiblyEatMessage(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - -class CBaseControlWindow : public CBaseVideoWindow, public CBaseWindow -{ -protected: - - CBaseFilter *m_pFilter; // Pointer to owning media filter - CBasePin *m_pPin; // Controls media types for connection - CCritSec *m_pInterfaceLock; // Externally defined critical section - COLORREF m_BorderColour; // Current window border colour - BOOL m_bAutoShow; // What happens when the state changes - HWND m_hwndOwner; // Owner window that we optionally have - HWND m_hwndDrain; // HWND to post any messages received - BOOL m_bCursorHidden; // Should we hide the window cursor - -public: - - // Internal methods for other objects to get information out - - HRESULT DoSetWindowStyle(long Style,long WindowLong); - HRESULT DoGetWindowStyle(long *pStyle,long WindowLong); - BOOL IsAutoShowEnabled() { return m_bAutoShow; }; - COLORREF GetBorderColour() { return m_BorderColour; }; - HWND GetOwnerWindow() { return m_hwndOwner; }; - BOOL IsCursorHidden() { return m_bCursorHidden; }; - - inline BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) - { - return ::PossiblyEatMessage(m_hwndDrain, uMsg, wParam, lParam); - } - - // Derived classes must call this to set the pin the filter is using - // We don't have the pin passed in to the constructor (as we do with - // the CBaseFilter object) because filters typically create the - // pins dynamically when requested in CBaseFilter::GetPin. This can - // not be called from our constructor because is is a virtual method - - void SetControlWindowPin(CBasePin *pPin) { - m_pPin = pPin; - } - -public: - - CBaseControlWindow(CBaseFilter *pFilter, // Owning media filter - CCritSec *pInterfaceLock, // Locking object - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr); // OLE return code - - // These are the properties we support - - STDMETHODIMP put_Caption(BSTR strCaption); - STDMETHODIMP get_Caption(BSTR *pstrCaption); - STDMETHODIMP put_AutoShow(long AutoShow); - STDMETHODIMP get_AutoShow(long *AutoShow); - STDMETHODIMP put_WindowStyle(long WindowStyle); - STDMETHODIMP get_WindowStyle(long *pWindowStyle); - STDMETHODIMP put_WindowStyleEx(long WindowStyleEx); - STDMETHODIMP get_WindowStyleEx(long *pWindowStyleEx); - STDMETHODIMP put_WindowState(long WindowState); - STDMETHODIMP get_WindowState(long *pWindowState); - STDMETHODIMP put_BackgroundPalette(long BackgroundPalette); - STDMETHODIMP get_BackgroundPalette(long *pBackgroundPalette); - STDMETHODIMP put_Visible(long Visible); - STDMETHODIMP get_Visible(long *pVisible); - STDMETHODIMP put_Left(long Left); - STDMETHODIMP get_Left(long *pLeft); - STDMETHODIMP put_Width(long Width); - STDMETHODIMP get_Width(long *pWidth); - STDMETHODIMP put_Top(long Top); - STDMETHODIMP get_Top(long *pTop); - STDMETHODIMP put_Height(long Height); - STDMETHODIMP get_Height(long *pHeight); - STDMETHODIMP put_Owner(OAHWND Owner); - STDMETHODIMP get_Owner(OAHWND *Owner); - STDMETHODIMP put_MessageDrain(OAHWND Drain); - STDMETHODIMP get_MessageDrain(OAHWND *Drain); - STDMETHODIMP get_BorderColor(long *Color); - STDMETHODIMP put_BorderColor(long Color); - STDMETHODIMP get_FullScreenMode(long *FullScreenMode); - STDMETHODIMP put_FullScreenMode(long FullScreenMode); - - // And these are the methods - - STDMETHODIMP SetWindowForeground(long Focus); - STDMETHODIMP NotifyOwnerMessage(OAHWND hwnd,long uMsg,LONG_PTR wParam,LONG_PTR lParam); - STDMETHODIMP GetMinIdealImageSize(long *pWidth,long *pHeight); - STDMETHODIMP GetMaxIdealImageSize(long *pWidth,long *pHeight); - STDMETHODIMP SetWindowPosition(long Left,long Top,long Width,long Height); - STDMETHODIMP GetWindowPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP GetRestorePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP HideCursor(long HideCursor); - STDMETHODIMP IsCursorHidden(long *CursorHidden); -}; - -// This class implements the IBasicVideo interface - -class CBaseControlVideo : public CBaseBasicVideo -{ -protected: - - CBaseFilter *m_pFilter; // Pointer to owning media filter - CBasePin *m_pPin; // Controls media types for connection - CCritSec *m_pInterfaceLock; // Externally defined critical section - -public: - - // Derived classes must provide these for the implementation - - virtual HRESULT IsDefaultTargetRect() PURE; - virtual HRESULT SetDefaultTargetRect() PURE; - virtual HRESULT SetTargetRect(RECT *pTargetRect) PURE; - virtual HRESULT GetTargetRect(RECT *pTargetRect) PURE; - virtual HRESULT IsDefaultSourceRect() PURE; - virtual HRESULT SetDefaultSourceRect() PURE; - virtual HRESULT SetSourceRect(RECT *pSourceRect) PURE; - virtual HRESULT GetSourceRect(RECT *pSourceRect) PURE; - virtual HRESULT GetStaticImage(long *pBufferSize,long *pDIBImage) PURE; - - // Derived classes must override this to return a VIDEOINFO representing - // the video format. We cannot call IPin ConnectionMediaType to get this - // format because various filters dynamically change the type when using - // DirectDraw such that the format shows the position of the logical - // bitmap in a frame buffer surface, so the size might be returned as - // 1024x768 pixels instead of 320x240 which is the real video dimensions - - virtual VIDEOINFOHEADER *GetVideoFormat() PURE; - - // Helper functions for creating memory renderings of a DIB image - - HRESULT GetImageSize(VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - RECT *pSourceRect); - - HRESULT CopyImage(IMediaSample *pMediaSample, - VIDEOINFOHEADER *pVideoInfo, - LONG *pBufferSize, - BYTE *pVideoImage, - RECT *pSourceRect); - - // Override this if you want notifying when the rectangles change - virtual HRESULT OnUpdateRectangles() { return NOERROR; }; - virtual HRESULT OnVideoSizeChange(); - - // Derived classes must call this to set the pin the filter is using - // We don't have the pin passed in to the constructor (as we do with - // the CBaseFilter object) because filters typically create the - // pins dynamically when requested in CBaseFilter::GetPin. This can - // not be called from our constructor because is is a virtual method - - void SetControlVideoPin(CBasePin *pPin) { - m_pPin = pPin; - } - - // Helper methods for checking rectangles - virtual HRESULT CheckSourceRect(RECT *pSourceRect); - virtual HRESULT CheckTargetRect(RECT *pTargetRect); - -public: - - CBaseControlVideo(CBaseFilter *pFilter, // Owning media filter - CCritSec *pInterfaceLock, // Serialise interface - TCHAR *pName, // Object description - LPUNKNOWN pUnk, // Normal COM ownership - HRESULT *phr); // OLE return code - - // These are the properties we support - - STDMETHODIMP get_AvgTimePerFrame(REFTIME *pAvgTimePerFrame); - STDMETHODIMP get_BitRate(long *pBitRate); - STDMETHODIMP get_BitErrorRate(long *pBitErrorRate); - STDMETHODIMP get_VideoWidth(long *pVideoWidth); - STDMETHODIMP get_VideoHeight(long *pVideoHeight); - STDMETHODIMP put_SourceLeft(long SourceLeft); - STDMETHODIMP get_SourceLeft(long *pSourceLeft); - STDMETHODIMP put_SourceWidth(long SourceWidth); - STDMETHODIMP get_SourceWidth(long *pSourceWidth); - STDMETHODIMP put_SourceTop(long SourceTop); - STDMETHODIMP get_SourceTop(long *pSourceTop); - STDMETHODIMP put_SourceHeight(long SourceHeight); - STDMETHODIMP get_SourceHeight(long *pSourceHeight); - STDMETHODIMP put_DestinationLeft(long DestinationLeft); - STDMETHODIMP get_DestinationLeft(long *pDestinationLeft); - STDMETHODIMP put_DestinationWidth(long DestinationWidth); - STDMETHODIMP get_DestinationWidth(long *pDestinationWidth); - STDMETHODIMP put_DestinationTop(long DestinationTop); - STDMETHODIMP get_DestinationTop(long *pDestinationTop); - STDMETHODIMP put_DestinationHeight(long DestinationHeight); - STDMETHODIMP get_DestinationHeight(long *pDestinationHeight); - - // And these are the methods - - STDMETHODIMP GetVideoSize(long *pWidth,long *pHeight); - STDMETHODIMP SetSourcePosition(long Left,long Top,long Width,long Height); - STDMETHODIMP GetSourcePosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP GetVideoPaletteEntries(long StartIndex,long Entries,long *pRetrieved,long *pPalette); - STDMETHODIMP SetDefaultSourcePosition(); - STDMETHODIMP IsUsingDefaultSource(); - STDMETHODIMP SetDestinationPosition(long Left,long Top,long Width,long Height); - STDMETHODIMP GetDestinationPosition(long *pLeft,long *pTop,long *pWidth,long *pHeight); - STDMETHODIMP SetDefaultDestinationPosition(); - STDMETHODIMP IsUsingDefaultDestination(); - STDMETHODIMP GetCurrentImage(long *pBufferSize,long *pVideoImage); -}; - -#endif // __WINCTRL__ - diff --git a/plugins/gs/gsdx9/baseclasses/winutil.cpp b/plugins/gs/gsdx9/baseclasses/winutil.cpp deleted file mode 100644 index 1526828538..0000000000 --- a/plugins/gs/gsdx9/baseclasses/winutil.cpp +++ /dev/null @@ -1,2681 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinUtil.cpp -// -// Desc: DirectShow base classes - implements generic window handler class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include -#include -#include - -static UINT MsgDestroy; - -// Constructor - -CBaseWindow::CBaseWindow(BOOL bDoGetDC, bool bDoPostToDestroy) : - m_hInstance(g_hInst), - m_hwnd(NULL), - m_hdc(NULL), - m_bActivated(FALSE), - m_pClassName(NULL), - m_ClassStyles(0), - m_WindowStyles(0), - m_WindowStylesEx(0), - m_ShowStageMessage(0), - m_ShowStageTop(0), - m_MemoryDC(NULL), - m_hPalette(NULL), - m_bBackground(FALSE), -#ifdef DEBUG - m_bRealizing(FALSE), -#endif - m_bNoRealize(FALSE), - m_bDoPostToDestroy(bDoPostToDestroy) -{ - m_bDoGetDC = bDoGetDC; -} - - -// Prepare a window by spinning off a worker thread to do the creation and -// also poll the message input queue. We leave this to be called by derived -// classes because they might want to override methods like MessageLoop and -// InitialiseWindow, if we do this during construction they'll ALWAYS call -// this base class methods. We make the worker thread create the window so -// it owns it rather than the filter graph thread which is constructing us - -HRESULT CBaseWindow::PrepareWindow() -{ - if (m_hwnd) return NOERROR; - ASSERT(m_hwnd == NULL); - ASSERT(m_hdc == NULL); - - // Get the derived object's window and class styles - - m_pClassName = GetClassWindowStyles(&m_ClassStyles, - &m_WindowStyles, - &m_WindowStylesEx); - if (m_pClassName == NULL) { - return E_FAIL; - } - - // Register our special private messages - m_ShowStageMessage = RegisterWindowMessage(SHOWSTAGE); - - // RegisterWindowMessage() returns 0 if an error occurs. - if (0 == m_ShowStageMessage) { - return AmGetLastErrorToHResult(); - } - - m_ShowStageTop = RegisterWindowMessage(SHOWSTAGETOP); - if (0 == m_ShowStageTop) { - return AmGetLastErrorToHResult(); - } - - m_RealizePalette = RegisterWindowMessage(REALIZEPALETTE); - if (0 == m_RealizePalette) { - return AmGetLastErrorToHResult(); - } - - MsgDestroy = RegisterWindowMessage(TEXT("AM_DESTROY")); - if (0 == MsgDestroy) { - return AmGetLastErrorToHResult(); - } - - return DoCreateWindow(); -} - - -// Destructor just a placeholder so that we know it becomes virtual -// Derived classes MUST call DoneWithWindow in their destructors so -// that no messages arrive after the derived class constructor ends - -#ifdef DEBUG -CBaseWindow::~CBaseWindow() -{ - ASSERT(m_hwnd == NULL); - ASSERT(m_hdc == NULL); -} -#endif - - -// We use the sync worker event to have the window destroyed. All we do is -// signal the event and wait on the window thread handle. Trying to send it -// messages causes too many problems, furthermore to be on the safe side we -// just wait on the thread handle while it returns WAIT_TIMEOUT or there is -// a sent message to process on this thread. If the constructor failed to -// create the thread in the first place then the loop will get terminated - -HRESULT CBaseWindow::DoneWithWindow() -{ - if (!IsWindow(m_hwnd) || (GetWindowThreadProcessId(m_hwnd, NULL) != GetCurrentThreadId())) { - - if (IsWindow(m_hwnd)) { - - if (m_bDoPostToDestroy) { - - CAMEvent m_evDone; - - // We must post a message to destroy the window - // That way we can't be in the middle of processing a - // message posted to our window when we do go away - // Sending a message gives less synchronization. - PostMessage(m_hwnd, MsgDestroy, (WPARAM)(HANDLE)m_evDone, 0); - WaitDispatchingMessages(m_evDone, INFINITE); - } else { - SendMessage(m_hwnd, MsgDestroy, 0, 0); - } - } - - // - // This is not a leak, the window manager automatically free's - // hdc's that were got via GetDC, which is the case here. - // We set it to NULL so that we don't get any asserts later. - // - m_hdc = NULL; - - // - // We need to free this DC though because USER32 does not know - // anything about it. - // - if (m_MemoryDC) - { - EXECUTE_ASSERT(DeleteDC(m_MemoryDC)); - m_MemoryDC = NULL; - } - - // Reset the window variables - m_hwnd = NULL; - - return NOERROR; - } - const HWND hwnd = m_hwnd; - if (hwnd == NULL) { - return NOERROR; - } - - InactivateWindow(); - NOTE("Inactivated"); - - // Reset the window styles before destruction - - SetWindowLong(hwnd,GWL_STYLE,m_WindowStyles); - ASSERT(GetParent(hwnd) == NULL); - NOTE1("Reset window styles %d",m_WindowStyles); - - // UnintialiseWindow sets m_hwnd to NULL so save a copy - UninitialiseWindow(); - DbgLog((LOG_TRACE, 2, TEXT("Destroying 0x%8.8X"), hwnd)); - if (!DestroyWindow(hwnd)) { - DbgLog((LOG_TRACE, 0, TEXT("DestroyWindow %8.8X failed code %d"), - hwnd, GetLastError())); - DbgBreak(""); - } - - // Reset our state so we can be prepared again - - m_pClassName = NULL; - m_ClassStyles = 0; - m_WindowStyles = 0; - m_WindowStylesEx = 0; - m_ShowStageMessage = 0; - m_ShowStageTop = 0; - - return NOERROR; -} - - -// Called at the end to put the window in an inactive state. The pending list -// will always have been cleared by this time so event if the worker thread -// gets has been signaled and gets in to render something it will find both -// the state has been changed and that there are no available sample images -// Since we wait on the window thread to complete we don't lock the object - -HRESULT CBaseWindow::InactivateWindow() -{ - // Has the window been activated - if (m_bActivated == FALSE) { - return S_FALSE; - } - - m_bActivated = FALSE; - ShowWindow(m_hwnd,SW_HIDE); - return NOERROR; -} - - -HRESULT CBaseWindow::CompleteConnect() -{ - m_bActivated = FALSE; - return NOERROR; -} - -// This displays a normal window. We ask the base window class for default -// sizes which unless overriden will return DEFWIDTH and DEFHEIGHT. We go -// through a couple of extra hoops to get the client area the right size -// as the object specifies which accounts for the AdjustWindowRectEx calls -// We also DWORD align the left and top coordinates of the window here to -// maximise the chance of being able to use DCI/DirectDraw primary surface - -HRESULT CBaseWindow::ActivateWindow() -{ - // Has the window been sized and positioned already - - if (m_bActivated == TRUE || GetParent(m_hwnd) != NULL) { - - SetWindowPos(m_hwnd, // Our window handle - HWND_TOP, // Put it at the top - 0, 0, 0, 0, // Leave in current position - SWP_NOMOVE | // Don't change it's place - SWP_NOSIZE); // Change Z-order only - - m_bActivated = TRUE; - return S_FALSE; - } - - // Calculate the desired client rectangle - - RECT WindowRect, ClientRect = GetDefaultRect(); - GetWindowRect(m_hwnd,&WindowRect); - AdjustWindowRectEx(&ClientRect,GetWindowLong(m_hwnd,GWL_STYLE), - FALSE,GetWindowLong(m_hwnd,GWL_EXSTYLE)); - - // Align left and top edges on DWORD boundaries - - UINT WindowFlags = (SWP_NOACTIVATE | SWP_FRAMECHANGED); - WindowRect.left -= (WindowRect.left & 3); - WindowRect.top -= (WindowRect.top & 3); - - SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Align left edge - WindowRect.top, // And also top place - WIDTH(&ClientRect), // Horizontal size - HEIGHT(&ClientRect), // Vertical size - WindowFlags); // Don't show window - - m_bActivated = TRUE; - return NOERROR; -} - - -// This can be used to DWORD align the window for maximum performance - -HRESULT CBaseWindow::PerformanceAlignWindow() -{ - RECT ClientRect,WindowRect; - GetWindowRect(m_hwnd,&WindowRect); - ASSERT(m_bActivated == TRUE); - - // Don't do this if we're owned - - if (GetParent(m_hwnd)) { - return NOERROR; - } - - // Align left and top edges on DWORD boundaries - - GetClientRect(m_hwnd, &ClientRect); - MapWindowPoints(m_hwnd, HWND_DESKTOP, (LPPOINT) &ClientRect, 2); - WindowRect.left -= (ClientRect.left & 3); - WindowRect.top -= (ClientRect.top & 3); - UINT WindowFlags = (SWP_NOACTIVATE | SWP_NOSIZE); - - SetWindowPos(m_hwnd, // Window handle - HWND_TOP, // Put it at the top - WindowRect.left, // Align left edge - WindowRect.top, // And also top place - (int) 0,(int) 0, // Ignore these sizes - WindowFlags); // Don't show window - - return NOERROR; -} - - -// Install a palette into the base window - we may be called by a different -// thread to the one that owns the window. We have to be careful how we do -// the palette realisation as we could be a different thread to the window -// which would cause an inter thread send message. Therefore we realise the -// palette by sending it a special message but without the window locked - -HRESULT CBaseWindow::SetPalette(HPALETTE hPalette) -{ - // We must own the window lock during the change - { - CAutoLock cWindowLock(&m_WindowLock); - CAutoLock cPaletteLock(&m_PaletteLock); - ASSERT(hPalette); - m_hPalette = hPalette; - } - return SetPalette(); -} - - -HRESULT CBaseWindow::SetPalette() -{ - if (!m_bNoRealize) { - SendMessage(m_hwnd, m_RealizePalette, 0, 0); - return S_OK; - } else { - // Just select the palette - ASSERT(m_hdc); - ASSERT(m_MemoryDC); - - CAutoLock cPaletteLock(&m_PaletteLock); - SelectPalette(m_hdc,m_hPalette,m_bBackground); - SelectPalette(m_MemoryDC,m_hPalette,m_bBackground); - - return S_OK; - } -} - - -void CBaseWindow::UnsetPalette() -{ - CAutoLock cWindowLock(&m_WindowLock); - CAutoLock cPaletteLock(&m_PaletteLock); - - // Get a standard VGA colour palette - - HPALETTE hPalette = (HPALETTE) GetStockObject(DEFAULT_PALETTE); - ASSERT(hPalette); - - SelectPalette(GetWindowHDC(), hPalette, TRUE); - SelectPalette(GetMemoryHDC(), hPalette, TRUE); - - m_hPalette = NULL; -} - - -void CBaseWindow::LockPaletteLock() -{ - m_PaletteLock.Lock(); -} - - -void CBaseWindow::UnlockPaletteLock() -{ - m_PaletteLock.Unlock(); -} - - -// Realise our palettes in the window and device contexts - -HRESULT CBaseWindow::DoRealisePalette(BOOL bForceBackground) -{ - { - CAutoLock cPaletteLock(&m_PaletteLock); - - if (m_hPalette == NULL) { - return NOERROR; - } - - // Realize the palette on the window thread - ASSERT(m_hdc); - ASSERT(m_MemoryDC); - - SelectPalette(m_hdc,m_hPalette,m_bBackground || bForceBackground); - SelectPalette(m_MemoryDC,m_hPalette,m_bBackground); - } - - // If we grab a critical section here we can deadlock - // with the window thread because one of the side effects - // of RealizePalette is to send a WM_PALETTECHANGED message - // to every window in the system. In our handling - // of WM_PALETTECHANGED we used to grab this CS too. - // The really bad case is when our renderer calls DoRealisePalette() - // while we're in the middle of processing a palette change - // for another window. - // So don't hold the critical section while actually realising - // the palette. In any case USER is meant to manage palette - // handling - we shouldn't have to serialize everything as well - ASSERT(CritCheckOut(&m_WindowLock)); - ASSERT(CritCheckOut(&m_PaletteLock)); - - EXECUTE_ASSERT(RealizePalette(m_hdc) != GDI_ERROR); - EXECUTE_ASSERT(RealizePalette(m_MemoryDC) != GDI_ERROR); - - return (GdiFlush() == FALSE ? S_FALSE : S_OK); -} - - -// This is the global window procedure - -LRESULT CALLBACK WndProc(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam) // Other parameter -{ - - // Get the window long that holds our window object pointer - // If it is NULL then we are initialising the window in which - // case the object pointer has been passed in the window creation - // structure. IF we get any messages before WM_NCCREATE we will - // pass them to DefWindowProc. - - CBaseWindow *pBaseWindow = (CBaseWindow *)GetWindowLongPtr(hwnd,0); - if (pBaseWindow == NULL) { - - // Get the structure pointer from the create struct. - // We can only do this for WM_NCCREATE which should be one of - // the first messages we receive. Anything before this will - // have to be passed to DefWindowProc (i.e. WM_GETMINMAXINFO) - - // If the message is WM_NCCREATE we set our pBaseWindow pointer - // and will then place it in the window structure - - // turn off WS_EX_LAYOUTRTL style for quartz windows - if (uMsg == WM_NCCREATE) { - SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) & ~0x400000); - } - - if ((uMsg != WM_NCCREATE) - || (NULL == (pBaseWindow = *(CBaseWindow**) ((LPCREATESTRUCT)lParam)->lpCreateParams))) - { - return(DefWindowProc(hwnd, uMsg, wParam, lParam)); - } - - // Set the window LONG to be the object who created us -#ifdef DEBUG - SetLastError(0); // because of the way SetWindowLong works -#endif - LONG_PTR rc = SetWindowLongPtr(hwnd, (DWORD) 0, (LONG_PTR) pBaseWindow); -#ifdef DEBUG - if (0 == rc) { - // SetWindowLong MIGHT have failed. (Read the docs which admit - // that it is awkward to work out if you have had an error.) - LONG lasterror = GetLastError(); - ASSERT(0 == lasterror); - // If this is not the case we have not set the pBaseWindow pointer - // into the window structure and we will blow up. - } -#endif - - } - // See if this is the packet of death - if (uMsg == MsgDestroy && uMsg != 0) { - pBaseWindow->DoneWithWindow(); - if (pBaseWindow->m_bDoPostToDestroy) { - EXECUTE_ASSERT(SetEvent((HANDLE)wParam)); - } - return 0; - } - return pBaseWindow->OnReceiveMessage(hwnd,uMsg,wParam,lParam); -} - - -// When the window size changes we adjust our member variables that -// contain the dimensions of the client rectangle for our window so -// that we come to render an image we will know whether to stretch - -BOOL CBaseWindow::OnSize(LONG Width, LONG Height) -{ - m_Width = Width; - m_Height = Height; - return TRUE; -} - - -// This function handles the WM_CLOSE message - -BOOL CBaseWindow::OnClose() -{ - ShowWindow(m_hwnd,SW_HIDE); - return TRUE; -} - - -// This is called by the worker window thread when it receives a terminate -// message from the window object destructor to delete all the resources we -// allocated during initialisation. By the time the worker thread exits all -// processing will have been completed as the source filter disconnection -// flushes the image pending sample, therefore the GdiFlush should succeed - -HRESULT CBaseWindow::UninitialiseWindow() -{ - // Have we already cleaned up - - if (m_hwnd == NULL) { - ASSERT(m_hdc == NULL); - ASSERT(m_MemoryDC == NULL); - return NOERROR; - } - - // Release the window resources - - EXECUTE_ASSERT(GdiFlush()); - - if (m_hdc) - { - EXECUTE_ASSERT(ReleaseDC(m_hwnd,m_hdc)); - m_hdc = NULL; - } - - if (m_MemoryDC) - { - EXECUTE_ASSERT(DeleteDC(m_MemoryDC)); - m_MemoryDC = NULL; - } - - // Reset the window variables - m_hwnd = NULL; - - return NOERROR; -} - - -// This is called by the worker window thread after it has created the main -// window and it wants to initialise the rest of the owner objects window -// variables such as the device contexts. We execute this function with the -// critical section still locked. Nothing in this function must generate any -// SendMessage calls to the window because this is executing on the window -// thread so the message will never be processed and we will deadlock - -HRESULT CBaseWindow::InitialiseWindow(HWND hwnd) -{ - // Initialise the window variables - - ASSERT(IsWindow(hwnd)); - m_hwnd = hwnd; - - if (m_bDoGetDC) - { - EXECUTE_ASSERT(m_hdc = GetDC(hwnd)); - EXECUTE_ASSERT(m_MemoryDC = CreateCompatibleDC(m_hdc)); - - EXECUTE_ASSERT(SetStretchBltMode(m_hdc,COLORONCOLOR)); - EXECUTE_ASSERT(SetStretchBltMode(m_MemoryDC,COLORONCOLOR)); - } - - return NOERROR; -} - -HRESULT CBaseWindow::DoCreateWindow() -{ - WNDCLASS wndclass; // Used to register classes - BOOL bRegistered; // Is this class registered - HWND hwnd; // Handle to our window - - bRegistered = GetClassInfo(m_hInstance, // Module instance - m_pClassName, // Window class - &wndclass); // Info structure - - // if the window is to be used for drawing puposes and we are getting a DC - // for the entire lifetime of the window then changes the class style to do - // say so. If we don't set this flag then the DC comes from the cache and is - // really bad. - if (m_bDoGetDC) - { - m_ClassStyles |= CS_OWNDC; - } - - if (bRegistered == FALSE) { - - // Register the renderer window class - - wndclass.lpszClassName = m_pClassName; - wndclass.style = m_ClassStyles; - wndclass.lpfnWndProc = WndProc; - wndclass.cbClsExtra = 0; - wndclass.cbWndExtra = sizeof(CBaseWindow *); - wndclass.hInstance = m_hInstance; - wndclass.hIcon = NULL; - wndclass.hCursor = LoadCursor (NULL, IDC_ARROW); - wndclass.hbrBackground = (HBRUSH) NULL; - wndclass.lpszMenuName = NULL; - - RegisterClass(&wndclass); - } - - // Create the frame window. Pass the pBaseWindow information in the - // CreateStruct which allows our message handling loop to get hold of - // the pBaseWindow pointer. - - CBaseWindow *pBaseWindow = this; // The owner window object - hwnd = CreateWindowEx(m_WindowStylesEx, // Extended styles - m_pClassName, // Registered name - TEXT("ActiveMovie Window"), // Window title - m_WindowStyles, // Window styles - CW_USEDEFAULT, // Start x position - CW_USEDEFAULT, // Start y position - DEFWIDTH, // Window width - DEFHEIGHT, // Window height - NULL, // Parent handle - NULL, // Menu handle - m_hInstance, // Instance handle - &pBaseWindow); // Creation data - - // If we failed signal an error to the object constructor (based on the - // last Win32 error on this thread) then signal the constructor thread - // to continue, release the mutex to let others have a go and exit - - if (hwnd == NULL) { - DWORD Error = GetLastError(); - return AmHresultFromWin32(Error); - } - - // Check the window LONG is the object who created us - ASSERT(GetWindowLongPtr(hwnd, 0) == (LONG_PTR)this); - - // Initialise the window and then signal the constructor so that it can - // continue and then finally unlock the object's critical section. The - // window class is left registered even after we terminate the thread - // as we don't know when the last window has been closed. So we allow - // the operating system to free the class resources as appropriate - - InitialiseWindow(hwnd); - - DbgLog((LOG_TRACE, 2, TEXT("Created window class (%s) HWND(%8.8X)"), - m_pClassName, hwnd)); - - return S_OK; -} - - -// The base class provides some default handling and calls DefWindowProc - -LRESULT CBaseWindow::OnReceiveMessage(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam) // Other parameter -{ - ASSERT(IsWindow(hwnd)); - - if (PossiblyEatMessage(uMsg, wParam, lParam)) - return 0; - - // This is sent by the IVideoWindow SetWindowForeground method. If the - // window is invisible we will show it and make it topmost without the - // foreground focus. If the window is visible it will also be made the - // topmost window without the foreground focus. If wParam is TRUE then - // for both cases the window will be forced into the foreground focus - - if (uMsg == m_ShowStageMessage) { - - BOOL bVisible = IsWindowVisible(hwnd); - SetWindowPos(hwnd, HWND_TOP, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_SHOWWINDOW | - (bVisible ? SWP_NOACTIVATE : 0)); - - // Should we bring the window to the foreground - if (wParam == TRUE) { - SetForegroundWindow(hwnd); - } - return (LRESULT) 1; - } - - // When we go fullscreen we have to add the WS_EX_TOPMOST style to the - // video window so that it comes out above any task bar (this is more - // relevant to WindowsNT than Windows95). However the SetWindowPos call - // must be on the same thread as that which created the window. The - // wParam parameter can be TRUE or FALSE to set and reset the topmost - - if (uMsg == m_ShowStageTop) { - HWND HwndTop = (wParam == TRUE ? HWND_TOPMOST : HWND_NOTOPMOST); - BOOL bVisible = IsWindowVisible(hwnd); - SetWindowPos(hwnd, HwndTop, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | - (wParam == TRUE ? SWP_SHOWWINDOW : 0) | - (bVisible ? SWP_NOACTIVATE : 0)); - return (LRESULT) 1; - } - - // New palette stuff - if (uMsg == m_RealizePalette) { - ASSERT(m_hwnd == hwnd); - return OnPaletteChange(m_hwnd,WM_QUERYNEWPALETTE); - } - - switch (uMsg) { - - // Repaint the window if the system colours change - - case WM_SYSCOLORCHANGE: - - InvalidateRect(hwnd,NULL,FALSE); - return (LRESULT) 1; - - // Somebody has changed the palette - case WM_PALETTECHANGED: - - OnPaletteChange((HWND)wParam,uMsg); - return (LRESULT) 0; - - // We are about to receive the keyboard focus so we ask GDI to realise - // our logical palette again and hopefully it will be fully installed - // without any mapping having to be done during any picture rendering - - case WM_QUERYNEWPALETTE: - ASSERT(m_hwnd == hwnd); - return OnPaletteChange(m_hwnd,uMsg); - - // do NOT fwd WM_MOVE. the parameters are the location of the parent - // window, NOT what the renderer should be looking at. But we need - // to make sure the overlay is moved with the parent window, so we - // do this. - case WM_MOVE: - if (IsWindowVisible(m_hwnd)) { - PostMessage(m_hwnd,WM_PAINT,0,0); - } - break; - - // Store the width and height as useful base class members - - case WM_SIZE: - - OnSize(LOWORD(lParam), HIWORD(lParam)); - return (LRESULT) 0; - - // Intercept the WM_CLOSE messages to hide the window - - case WM_CLOSE: - - OnClose(); - return (LRESULT) 0; - } - return DefWindowProc(hwnd,uMsg,wParam,lParam); -} - - -// This handles the Windows palette change messages - if we do realise our -// palette then we return TRUE otherwise we return FALSE. If our window is -// foreground application then we should get first choice of colours in the -// system palette entries. We get best performance when our logical palette -// includes the standard VGA colours (at the beginning and end) otherwise -// GDI may have to map from our palette to the device palette while drawing - -LRESULT CBaseWindow::OnPaletteChange(HWND hwnd,UINT Message) -{ - // First check we are not changing the palette during closedown - - if (m_hwnd == NULL || hwnd == NULL) { - return (LRESULT) 0; - } - ASSERT(!m_bRealizing); - - // Should we realise our palette again - - if ((Message == WM_QUERYNEWPALETTE || hwnd != m_hwnd)) { - // It seems that even if we're invisible that we can get asked - // to realize our palette and this can cause really ugly side-effects - // Seems like there's another bug but this masks it a least for the - // shutting down case. - if (!IsWindowVisible(m_hwnd)) { - DbgLog((LOG_TRACE, 1, TEXT("Realizing when invisible!"))); - return (LRESULT) 0; - } - - // Avoid recursion with multiple graphs in the same app -#ifdef DEBUG - m_bRealizing = TRUE; -#endif - DoRealisePalette(Message != WM_QUERYNEWPALETTE); -#ifdef DEBUG - m_bRealizing = FALSE; -#endif - - // Should we redraw the window with the new palette - if (Message == WM_PALETTECHANGED) { - InvalidateRect(m_hwnd,NULL,FALSE); - } - } - - return (LRESULT) 1; -} - - -// Determine if the window exists. - -bool CBaseWindow::WindowExists() -{ - return !!IsWindow(m_hwnd); -} - - -// Return the default window rectangle - -RECT CBaseWindow::GetDefaultRect() -{ - RECT DefaultRect = {0,0,DEFWIDTH,DEFHEIGHT}; - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return DefaultRect; -} - - -// Return the current window width - -LONG CBaseWindow::GetWindowWidth() -{ - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return m_Width; -} - - -// Return the current window height - -LONG CBaseWindow::GetWindowHeight() -{ - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return m_Height; -} - - -// Return the window handle - -HWND CBaseWindow::GetWindowHWND() -{ - ASSERT(m_hwnd); - // ASSERT(m_hdc); - return m_hwnd; -} - - -// Return the window drawing device context - -HDC CBaseWindow::GetWindowHDC() -{ - ASSERT(m_hwnd); - ASSERT(m_hdc); - return m_hdc; -} - - -// Return the offscreen window drawing device context - -HDC CBaseWindow::GetMemoryHDC() -{ - ASSERT(m_hwnd); - ASSERT(m_MemoryDC); - return m_MemoryDC; -} - - -#ifdef DEBUG -HPALETTE CBaseWindow::GetPalette() -{ - // The palette lock should always be held when accessing - // m_hPalette. - ASSERT(CritCheckIn(&m_PaletteLock)); - return m_hPalette; -} -#endif // DEBUG - - -// This is available to clients who want to change the window visiblity. It's -// little more than an indirection to the Win32 ShowWindow although these is -// some benefit in going through here as this function may change sometime - -HRESULT CBaseWindow::DoShowWindow(LONG ShowCmd) -{ - ShowWindow(m_hwnd,ShowCmd); - return NOERROR; -} - - -// Generate a WM_PAINT message for the video window - -void CBaseWindow::PaintWindow(BOOL bErase) -{ - InvalidateRect(m_hwnd,NULL,bErase); -} - - -// Allow an application to have us set the video window in the foreground. We -// have this because it is difficult for one thread to do do this to a window -// owned by another thread. Rather than expose the message we use to execute -// the inter thread send message we provide the interface function. All we do -// is to SendMessage to the video window renderer thread with a WM_SHOWSTAGE - -void CBaseWindow::DoSetWindowForeground(BOOL bFocus) -{ - SendMessage(m_hwnd,m_ShowStageMessage,(WPARAM) bFocus,(LPARAM) 0); -} - - -// Constructor initialises the owning object pointer. Since we are a worker -// class for the main window object we have relatively few state variables to -// look after. We are given device context handles to use later on as well as -// the source and destination rectangles (but reset them here just in case) - -CDrawImage::CDrawImage(CBaseWindow *pBaseWindow) : - m_pBaseWindow(pBaseWindow), - m_hdc(NULL), - m_MemoryDC(NULL), - m_bStretch(FALSE), - m_pMediaType(NULL), - m_bUsingImageAllocator(FALSE) -{ - ASSERT(pBaseWindow); - ResetPaletteVersion(); - SetRectEmpty(&m_TargetRect); - SetRectEmpty(&m_SourceRect); - - m_perfidRenderTime = MSR_REGISTER(TEXT("Single Blt time")); -} - - -// Overlay the image time stamps on the picture. Access to this method is -// serialised by the caller. We display the sample start and end times on -// top of the video using TextOut on the device context we are handed. If -// there isn't enough room in the window for the times we don't show them - -void CDrawImage::DisplaySampleTimes(IMediaSample *pSample) -{ -#ifdef DEBUG - // - // Only allow the "annoying" time messages if the users has turned the - // logging "way up" - // - BOOL bAccept = DbgCheckModuleLevel(LOG_TRACE, 5); - if (bAccept == FALSE) { - return; - } -#endif - - TCHAR szTimes[TIMELENGTH]; // Time stamp strings - ASSERT(pSample); // Quick sanity check - RECT ClientRect; // Client window size - SIZE Size; // Size of text output - - // Get the time stamps and window size - - pSample->GetTime((REFERENCE_TIME*)&m_StartSample, (REFERENCE_TIME*)&m_EndSample); - HWND hwnd = m_pBaseWindow->GetWindowHWND(); - EXECUTE_ASSERT(GetClientRect(hwnd,&ClientRect)); - - // Format the sample time stamps - - (void)StringCchPrintf(szTimes, NUMELMS(szTimes), TEXT("%08d : %08d"), - m_StartSample.Millisecs(), - m_EndSample.Millisecs()); - - ASSERT(lstrlen(szTimes) < TIMELENGTH); - - // Put the times in the middle at the bottom of the window - - GetTextExtentPoint32(m_hdc,szTimes,lstrlen(szTimes),&Size); - INT XPos = ((ClientRect.right - ClientRect.left) - Size.cx) / 2; - INT YPos = ((ClientRect.bottom - ClientRect.top) - Size.cy) * 4 / 5; - - // Check the window is big enough to have sample times displayed - - if ((XPos > 0) && (YPos > 0)) { - TextOut(m_hdc,XPos,YPos,szTimes,lstrlen(szTimes)); - } -} - - -// This is called when the drawing code sees that the image has a down level -// palette cookie. We simply call the SetDIBColorTable Windows API with the -// palette that is found after the BITMAPINFOHEADER - we return no errors - -void CDrawImage::UpdateColourTable(HDC hdc,BITMAPINFOHEADER *pbmi) -{ - ASSERT(pbmi->biClrUsed); - RGBQUAD *pColourTable = (RGBQUAD *)(pbmi+1); - - // Set the new palette in the device context - - UINT uiReturn = SetDIBColorTable(hdc,(UINT) 0, - pbmi->biClrUsed, - pColourTable); - - // Should always succeed but check in debug builds - ASSERT(uiReturn == pbmi->biClrUsed); -} - - -// No source rectangle scaling is done by the base class - -RECT CDrawImage::ScaleSourceRect(const RECT *pSource) -{ - ASSERT(pSource); - return *pSource; -} - - -// This is called when the funky output pin uses our allocator. The samples we -// allocate are special because the memory is shared between us and GDI thus -// removing one copy when we ask for the image to be rendered. The source type -// information is in the main renderer m_mtIn field which is initialised when -// the media type is agreed in SetMediaType, the media type may be changed on -// the fly if, for example, the source filter needs to change the palette - -void CDrawImage::FastRender(IMediaSample *pMediaSample) -{ - BITMAPINFOHEADER *pbmi; // Image format data - DIBDATA *pDibData; // Stores DIB information - BYTE *pImage; // Pointer to image data - HBITMAP hOldBitmap; // Store the old bitmap - CImageSample *pSample; // Pointer to C++ object - - ASSERT(m_pMediaType); - - // From the untyped source format block get the VIDEOINFO and subsequently - // the BITMAPINFOHEADER structure. We can cast the IMediaSample interface - // to a CImageSample object so we can retrieve it's DIBSECTION details - - pbmi = HEADER(m_pMediaType->Format()); - pSample = (CImageSample *) pMediaSample; - pDibData = pSample->GetDIBData(); - hOldBitmap = (HBITMAP) SelectObject(m_MemoryDC,pDibData->hBitmap); - - // Get a pointer to the real image data - - HRESULT hr = pMediaSample->GetPointer(&pImage); - if (FAILED(hr)) { - return; - } - - // Do we need to update the colour table, we increment our palette cookie - // each time we get a dynamic format change. The sample palette cookie is - // stored in the DIBDATA structure so we try to keep the fields in sync - // By the time we get to draw the images the format change will be done - // so all we do is ask the renderer for what it's palette version is - - if (pDibData->PaletteVersion < GetPaletteVersion()) { - ASSERT(pbmi->biBitCount <= iPALETTE); - UpdateColourTable(m_MemoryDC,pbmi); - pDibData->PaletteVersion = GetPaletteVersion(); - } - - // This allows derived classes to change the source rectangle that we do - // the drawing with. For example a renderer may ask a codec to stretch - // the video from 320x240 to 640x480, in which case the source we see in - // here will still be 320x240, although the source we want to draw with - // should be scaled up to 640x480. The base class implementation of this - // method does nothing but return the same rectangle as we are passed in - - RECT SourceRect = ScaleSourceRect(&m_SourceRect); - - // Is the window the same size as the video - - if (m_bStretch == FALSE) { - - // Put the image straight into the window - - BitBlt( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - m_MemoryDC, // Source device context - SourceRect.left, // X source position - SourceRect.top, // Y source position - SRCCOPY); // Simple copy - - } else { - - // Stretch the image when copying to the window - - StretchBlt( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - m_MemoryDC, // Source device HDC - SourceRect.left, // X source position - SourceRect.top, // Y source position - SourceRect.right - SourceRect.left, // Source width - SourceRect.bottom - SourceRect.top, // Source height - SRCCOPY); // Simple copy - } - - // This displays the sample times over the top of the image. This used to - // draw the times into the offscreen device context however that actually - // writes the text into the image data buffer which may not be writable - - #ifdef DEBUG - DisplaySampleTimes(pMediaSample); - #endif - - // Put the old bitmap back into the device context so we don't leak - SelectObject(m_MemoryDC,hOldBitmap); -} - - -// This is called when there is a sample ready to be drawn, unfortunately the -// output pin was being rotten and didn't choose our super excellent shared -// memory DIB allocator so we have to do this slow render using boring old GDI -// SetDIBitsToDevice and StretchDIBits. The down side of using these GDI -// functions is that the image data has to be copied across from our address -// space into theirs before going to the screen (although in reality the cost -// is small because all they do is to map the buffer into their address space) - -void CDrawImage::SlowRender(IMediaSample *pMediaSample) -{ - // Get the BITMAPINFOHEADER for the connection - - ASSERT(m_pMediaType); - BITMAPINFOHEADER *pbmi = HEADER(m_pMediaType->Format()); - BYTE *pImage; - - // Get the image data buffer - - HRESULT hr = pMediaSample->GetPointer(&pImage); - if (FAILED(hr)) { - return; - } - - // This allows derived classes to change the source rectangle that we do - // the drawing with. For example a renderer may ask a codec to stretch - // the video from 320x240 to 640x480, in which case the source we see in - // here will still be 320x240, although the source we want to draw with - // should be scaled up to 640x480. The base class implementation of this - // method does nothing but return the same rectangle as we are passed in - - RECT SourceRect = ScaleSourceRect(&m_SourceRect); - - LONG lAdjustedSourceTop = SourceRect.top; - // if the origin of bitmap is bottom-left, adjust soruce_rect_top - // to be the bottom-left corner instead of the top-left. - if (pbmi->biHeight > 0) { - lAdjustedSourceTop = pbmi->biHeight - SourceRect.bottom; - } - // Is the window the same size as the video - - if (m_bStretch == FALSE) { - - // Put the image straight into the window - - SetDIBitsToDevice( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - SourceRect.left, // X source position - lAdjustedSourceTop, // Adjusted Y source position - (UINT) 0, // Start scan line - pbmi->biHeight, // Scan lines present - pImage, // Image data - (BITMAPINFO *) pbmi, // DIB header - DIB_RGB_COLORS); // Type of palette - - } else { - - // Stretch the image when copying to the window - - StretchDIBits( - (HDC) m_hdc, // Target device HDC - m_TargetRect.left, // X sink position - m_TargetRect.top, // Y sink position - m_TargetRect.right - m_TargetRect.left, // Destination width - m_TargetRect.bottom - m_TargetRect.top, // Destination height - SourceRect.left, // X source position - lAdjustedSourceTop, // Adjusted Y source position - SourceRect.right - SourceRect.left, // Source width - SourceRect.bottom - SourceRect.top, // Source height - pImage, // Image data - (BITMAPINFO *) pbmi, // DIB header - DIB_RGB_COLORS, // Type of palette - SRCCOPY); // Simple image copy - } - - // This shows the sample reference times over the top of the image which - // looks a little flickery. I tried using GdiSetBatchLimit and GdiFlush to - // control the screen updates but it doesn't quite work as expected and - // only partially reduces the flicker. I also tried using a memory context - // and combining the two in that before doing a final BitBlt operation to - // the screen, unfortunately this has considerable performance penalties - // and also means that this code is not executed when compiled retail - - #ifdef DEBUG - DisplaySampleTimes(pMediaSample); - #endif -} - - -// This is called with an IMediaSample interface on the image to be drawn. We -// decide on the drawing mechanism based on who's allocator we are using. We -// may be called when the window wants an image painted by WM_PAINT messages -// We can't realise the palette here because we have the renderer lock, any -// call to realise may cause an interthread send message to the window thread -// which may in turn be waiting to get the renderer lock before servicing it - -BOOL CDrawImage::DrawImage(IMediaSample *pMediaSample) -{ - ASSERT(m_hdc); - ASSERT(m_MemoryDC); - NotifyStartDraw(); - - // If the output pin used our allocator then the samples passed are in - // fact CVideoSample objects that contain CreateDIBSection data that we - // use to do faster image rendering, they may optionally also contain a - // DirectDraw surface pointer in which case we do not do the drawing - - if (m_bUsingImageAllocator == FALSE) { - SlowRender(pMediaSample); - EXECUTE_ASSERT(GdiFlush()); - NotifyEndDraw(); - return TRUE; - } - - // This is a DIBSECTION buffer - - FastRender(pMediaSample); - EXECUTE_ASSERT(GdiFlush()); - NotifyEndDraw(); - return TRUE; -} - - -BOOL CDrawImage::DrawVideoImageHere( - HDC hdc, - IMediaSample *pMediaSample, - LPRECT lprcSrc, - LPRECT lprcDst - ) -{ - ASSERT(m_pMediaType); - BITMAPINFOHEADER *pbmi = HEADER(m_pMediaType->Format()); - BYTE *pImage; - - // Get the image data buffer - - HRESULT hr = pMediaSample->GetPointer(&pImage); - if (FAILED(hr)) { - return FALSE; - } - - RECT SourceRect; - RECT TargetRect; - - if (lprcSrc) { - SourceRect = *lprcSrc; - } - else SourceRect = ScaleSourceRect(&m_SourceRect); - - if (lprcDst) { - TargetRect = *lprcDst; - } - else TargetRect = m_TargetRect; - - LONG lAdjustedSourceTop = SourceRect.top; - // if the origin of bitmap is bottom-left, adjust soruce_rect_top - // to be the bottom-left corner instead of the top-left. - if (pbmi->biHeight > 0) { - lAdjustedSourceTop = pbmi->biHeight - SourceRect.bottom; - } - - - // Stretch the image when copying to the DC - - BOOL bRet = (0 != StretchDIBits(hdc, - TargetRect.left, - TargetRect.top, - TargetRect.right - TargetRect.left, - TargetRect.bottom - TargetRect.top, - SourceRect.left, - lAdjustedSourceTop, - SourceRect.right - SourceRect.left, - SourceRect.bottom - SourceRect.top, - pImage, - (BITMAPINFO *)pbmi, - DIB_RGB_COLORS, - SRCCOPY)); - return bRet; -} - - -// This is called by the owning window object after it has created the window -// and it's drawing contexts. We are constructed with the base window we'll -// be drawing into so when given the notification we retrive the device HDCs -// to draw with. We cannot call these in our constructor as they are virtual - -void CDrawImage::SetDrawContext() -{ - m_MemoryDC = m_pBaseWindow->GetMemoryHDC(); - m_hdc = m_pBaseWindow->GetWindowHDC(); -} - - -// This is called to set the target rectangle in the video window, it will be -// called whenever a WM_SIZE message is retrieved from the message queue. We -// simply store the rectangle and use it later when we do the drawing calls - -void CDrawImage::SetTargetRect(RECT *pTargetRect) -{ - ASSERT(pTargetRect); - m_TargetRect = *pTargetRect; - SetStretchMode(); -} - - -// Return the current target rectangle - -void CDrawImage::GetTargetRect(RECT *pTargetRect) -{ - ASSERT(pTargetRect); - *pTargetRect = m_TargetRect; -} - - -// This is called when we want to change the section of the image to draw. We -// use this information in the drawing operation calls later on. We must also -// see if the source and destination rectangles have the same dimensions. If -// not we must stretch during the drawing rather than a direct pixel copy - -void CDrawImage::SetSourceRect(RECT *pSourceRect) -{ - ASSERT(pSourceRect); - m_SourceRect = *pSourceRect; - SetStretchMode(); -} - - -// Return the current source rectangle - -void CDrawImage::GetSourceRect(RECT *pSourceRect) -{ - ASSERT(pSourceRect); - *pSourceRect = m_SourceRect; -} - - -// This is called when either the source or destination rectanges change so we -// can update the stretch flag. If the rectangles don't match we stretch the -// video during the drawing otherwise we call the fast pixel copy functions -// NOTE the source and/or the destination rectangle may be completely empty - -void CDrawImage::SetStretchMode() -{ - // Calculate the overall rectangle dimensions - - LONG SourceWidth = m_SourceRect.right - m_SourceRect.left; - LONG SinkWidth = m_TargetRect.right - m_TargetRect.left; - LONG SourceHeight = m_SourceRect.bottom - m_SourceRect.top; - LONG SinkHeight = m_TargetRect.bottom - m_TargetRect.top; - - m_bStretch = TRUE; - if (SourceWidth == SinkWidth) { - if (SourceHeight == SinkHeight) { - m_bStretch = FALSE; - } - } -} - - -// Tell us whose allocator we are using. This should be called with TRUE if -// the filter agrees to use an allocator based around the CImageAllocator -// SDK base class - whose image buffers are made through CreateDIBSection. -// Otherwise this should be called with FALSE and we will draw the images -// using SetDIBitsToDevice and StretchDIBitsToDevice. None of these calls -// can handle buffers which have non zero strides (like DirectDraw uses) - -void CDrawImage::NotifyAllocator(BOOL bUsingImageAllocator) -{ - m_bUsingImageAllocator = bUsingImageAllocator; -} - - -// Are we using the image DIBSECTION allocator - -BOOL CDrawImage::UsingImageAllocator() -{ - return m_bUsingImageAllocator; -} - - -// We need the media type of the connection so that we can get the BITMAPINFO -// from it. We use that in the calls to draw the image such as StretchDIBits -// and also when updating the colour table held in shared memory DIBSECTIONs - -void CDrawImage::NotifyMediaType(CMediaType *pMediaType) -{ - m_pMediaType = pMediaType; -} - - -// We store in this object a cookie maintaining the current palette version. -// Each time a palettised format is changed we increment this value so that -// when we come to draw the images we look at the colour table value they -// have and if less than the current we know to update it. This version is -// only needed and indeed used when working with shared memory DIBSECTIONs - -LONG CDrawImage::GetPaletteVersion() -{ - return m_PaletteVersion; -} - - -// Resets the current palette version number - -void CDrawImage::ResetPaletteVersion() -{ - m_PaletteVersion = PALETTE_VERSION; -} - - -// Increment the current palette version - -void CDrawImage::IncrementPaletteVersion() -{ - m_PaletteVersion++; -} - - -// Constructor must initialise the base allocator. Each sample we create has a -// palette version cookie on board. When the source filter changes the palette -// during streaming the window object increments an internal cookie counter it -// keeps as well. When it comes to render the samples it looks at the cookie -// values and if they don't match then it knows to update the sample's colour -// table. However we always create samples with a cookie of PALETTE_VERSION -// If there have been multiple format changes and we disconnect and reconnect -// thereby causing the samples to be reallocated we will create them with a -// cookie much lower than the current version, this isn't a problem since it -// will be seen by the window object and the versions will then be updated - -CImageAllocator::CImageAllocator(CBaseFilter *pFilter, - TCHAR *pName, - HRESULT *phr) : - CBaseAllocator(pName,NULL,phr,TRUE,TRUE), - m_pFilter(pFilter) -{ - ASSERT(phr); - ASSERT(pFilter); -} - - -// Check our DIB buffers have been released - -#ifdef DEBUG -CImageAllocator::~CImageAllocator() -{ - ASSERT(m_bCommitted == FALSE); -} -#endif - - -// Called from destructor and also from base class to free resources. We work -// our way through the list of media samples deleting the DIBSECTION created -// for each. All samples should be back in our list so there is no chance a -// filter is still using one to write on the display or hold on a pending list - -void CImageAllocator::Free() -{ - ASSERT(m_lAllocated == m_lFree.GetCount()); - EXECUTE_ASSERT(GdiFlush()); - CImageSample *pSample; - DIBDATA *pDibData; - - while (m_lFree.GetCount() != 0) { - pSample = (CImageSample *) m_lFree.RemoveHead(); - pDibData = pSample->GetDIBData(); - EXECUTE_ASSERT(DeleteObject(pDibData->hBitmap)); - EXECUTE_ASSERT(CloseHandle(pDibData->hMapping)); - delete pSample; - } - - m_lAllocated = 0; -} - - -// Prepare the allocator by checking all the input parameters - -STDMETHODIMP CImageAllocator::CheckSizes(ALLOCATOR_PROPERTIES *pRequest) -{ - // Check we have a valid connection - - if (m_pMediaType == NULL) { - return VFW_E_NOT_CONNECTED; - } - - // NOTE We always create a DIB section with the source format type which - // may contain a source palette. When we do the BitBlt drawing operation - // the target display device may contain a different palette (we may not - // have the focus) in which case GDI will do after the palette mapping - - VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *) m_pMediaType->Format(); - - // When we call CreateDIBSection it implicitly maps only enough memory - // for the image as defined by thee BITMAPINFOHEADER. If the user asks - // for an image smaller than this then we reject the call, if they ask - // for an image larger than this then we return what they can have - - if ((DWORD) pRequest->cbBuffer < pVideoInfo->bmiHeader.biSizeImage) { - return E_INVALIDARG; - } - - // Reject buffer prefixes - - if (pRequest->cbPrefix > 0) { - return E_INVALIDARG; - } - - pRequest->cbBuffer = pVideoInfo->bmiHeader.biSizeImage; - return NOERROR; -} - - -// Agree the number of media sample buffers and their sizes. The base class -// this allocator is derived from allows samples to be aligned only on byte -// boundaries NOTE the buffers are not allocated until the Commit call - -STDMETHODIMP CImageAllocator::SetProperties( - ALLOCATOR_PROPERTIES * pRequest, - ALLOCATOR_PROPERTIES * pActual) -{ - ALLOCATOR_PROPERTIES Adjusted = *pRequest; - - // Check the parameters fit with the current connection - - HRESULT hr = CheckSizes(&Adjusted); - if (FAILED(hr)) { - return hr; - } - return CBaseAllocator::SetProperties(&Adjusted, pActual); -} - - -// Commit the memory by allocating the agreed number of media samples. For -// each sample we are committed to creating we have a CImageSample object -// that we use to manage it's resources. This is initialised with a DIBDATA -// structure that contains amongst other things the GDI DIBSECTION handle -// We will access the renderer media type during this so we must have locked -// (to prevent the format changing for example). The class overrides Commit -// and Decommit to do this locking (base class Commit in turn calls Alloc) - -HRESULT CImageAllocator::Alloc(void) -{ - ASSERT(m_pMediaType); - CImageSample *pSample; - DIBDATA DibData; - - // Check the base allocator says it's ok to continue - - HRESULT hr = CBaseAllocator::Alloc(); - if (FAILED(hr)) { - return hr; - } - - // We create a new memory mapped object although we don't map it into our - // address space because GDI does that in CreateDIBSection. It is possible - // that we run out of resources before creating all the samples in which - // case the available sample list is left with those already created - - ASSERT(m_lAllocated == 0); - while (m_lAllocated < m_lCount) { - - // Create and initialise a shared memory GDI buffer - - HRESULT hr = CreateDIB(m_lSize,DibData); - if (FAILED(hr)) { - return hr; - } - - // Create the sample object and pass it the DIBDATA - - pSample = CreateImageSample(DibData.pBase,m_lSize); - if (pSample == NULL) { - EXECUTE_ASSERT(DeleteObject(DibData.hBitmap)); - EXECUTE_ASSERT(CloseHandle(DibData.hMapping)); - return E_OUTOFMEMORY; - } - - // Add the completed sample to the available list - - pSample->SetDIBData(&DibData); - m_lFree.Add(pSample); - m_lAllocated++; - } - return NOERROR; -} - - -// We have a virtual method that allocates the samples so that a derived class -// may override it and allocate more specialised sample objects. So long as it -// derives its samples from CImageSample then all this code will still work ok - -CImageSample *CImageAllocator::CreateImageSample(LPBYTE pData,LONG Length) -{ - HRESULT hr = NOERROR; - CImageSample *pSample; - - // Allocate the new sample and check the return codes - - pSample = new CImageSample((CBaseAllocator *) this, // Base class - NAME("Video sample"), // DEBUG name - (HRESULT *) &hr, // Return code - (LPBYTE) pData, // DIB address - (LONG) Length); // Size of DIB - - if (pSample == NULL || FAILED(hr)) { - delete pSample; - return NULL; - } - return pSample; -} - - -// This function allocates a shared memory block for use by the source filter -// generating DIBs for us to render. The memory block is created in shared -// memory so that GDI doesn't have to copy the memory when we do a BitBlt - -HRESULT CImageAllocator::CreateDIB(LONG InSize,DIBDATA &DibData) -{ - BITMAPINFO *pbmi; // Format information for pin - BYTE *pBase; // Pointer to the actual image - HANDLE hMapping; // Handle to mapped object - HBITMAP hBitmap; // DIB section bitmap handle - - // Create a file mapping object and map into our address space - - hMapping = CreateFileMapping(hMEMORY, // Use system page file - NULL, // No security attributes - PAGE_READWRITE, // Full access to memory - (DWORD) 0, // Less than 4Gb in size - InSize, // Size of buffer - NULL); // No name to section - if (hMapping == NULL) { - DWORD Error = GetLastError(); - return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, Error); - } - - // NOTE We always create a DIB section with the source format type which - // may contain a source palette. When we do the BitBlt drawing operation - // the target display device may contain a different palette (we may not - // have the focus) in which case GDI will do after the palette mapping - - pbmi = (BITMAPINFO *) HEADER(m_pMediaType->Format()); - if (m_pMediaType == NULL) { - DbgBreak("Invalid media type"); - } - - hBitmap = CreateDIBSection((HDC) NULL, // NO device context - pbmi, // Format information - DIB_RGB_COLORS, // Use the palette - (VOID **) &pBase, // Pointer to image data - hMapping, // Mapped memory handle - (DWORD) 0); // Offset into memory - - if (hBitmap == NULL || pBase == NULL) { - EXECUTE_ASSERT(CloseHandle(hMapping)); - DWORD Error = GetLastError(); - return MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, Error); - } - - // Initialise the DIB information structure - - DibData.hBitmap = hBitmap; - DibData.hMapping = hMapping; - DibData.pBase = pBase; - DibData.PaletteVersion = PALETTE_VERSION; - GetObject(hBitmap,sizeof(DIBSECTION),(VOID *)&DibData.DibSection); - - return NOERROR; -} - - -// We use the media type during the DIBSECTION creation - -void CImageAllocator::NotifyMediaType(CMediaType *pMediaType) -{ - m_pMediaType = pMediaType; -} - - -// Overriden to increment the owning object's reference count - -STDMETHODIMP_(ULONG) CImageAllocator::NonDelegatingAddRef() -{ - return m_pFilter->AddRef(); -} - - -// Overriden to decrement the owning object's reference count - -STDMETHODIMP_(ULONG) CImageAllocator::NonDelegatingRelease() -{ - return m_pFilter->Release(); -} - - -// If you derive a class from CMediaSample that has to transport specialised -// member variables and entry points then there are three alternate solutions -// The first is to create a memory buffer larger than actually required by the -// sample and store your information either at the beginning of it or at the -// end, the former being moderately safer allowing for misbehaving transform -// filters. You then adjust the buffer address when you create the base media -// sample. This has the disadvantage of breaking up the memory allocated to -// the samples into separate blocks. The second solution is to implement a -// class derived from CMediaSample and support additional interface(s) that -// convey your private data. This means defining a custom interface. The final -// alternative is to create a class that inherits from CMediaSample and adds -// the private data structures, when you get an IMediaSample in your Receive() -// call check to see if your allocator is being used, and if it is then cast -// the IMediaSample into one of your objects. Additional checks can be made -// to ensure the sample's this pointer is known to be one of your own objects - -CImageSample::CImageSample(CBaseAllocator *pAllocator, - TCHAR *pName, - HRESULT *phr, - LPBYTE pBuffer, - LONG length) : - CMediaSample(pName,pAllocator,phr,pBuffer,length), - m_bInit(FALSE) -{ - ASSERT(pAllocator); - ASSERT(pBuffer); -} - - -// Set the shared memory DIB information - -void CImageSample::SetDIBData(DIBDATA *pDibData) -{ - ASSERT(pDibData); - m_DibData = *pDibData; - m_bInit = TRUE; -} - - -// Retrieve the shared memory DIB data - -DIBDATA *CImageSample::GetDIBData() -{ - ASSERT(m_bInit == TRUE); - return &m_DibData; -} - - -// This class handles the creation of a palette. It is fairly specialist and -// is intended to simplify palette management for video renderer filters. It -// is for this reason that the constructor requires three other objects with -// which it interacts, namely a base media filter, a base window and a base -// drawing object although the base window or the draw object may be NULL to -// ignore that part of us. We try not to create and install palettes unless -// absolutely necessary as they typically require WM_PALETTECHANGED messages -// to be sent to every window thread in the system which is very expensive - -CImagePalette::CImagePalette(CBaseFilter *pBaseFilter, - CBaseWindow *pBaseWindow, - CDrawImage *pDrawImage) : - m_pBaseWindow(pBaseWindow), - m_pFilter(pBaseFilter), - m_pDrawImage(pDrawImage), - m_hPalette(NULL) -{ - ASSERT(m_pFilter); -} - - -// Destructor - -#ifdef DEBUG -CImagePalette::~CImagePalette() -{ - ASSERT(m_hPalette == NULL); -} -#endif - - -// We allow dynamic format changes of the palette but rather than change the -// palette every time we call this to work out whether an update is required. -// If the original type didn't use a palette and the new one does (or vica -// versa) then we return TRUE. If neither formats use a palette we'll return -// FALSE. If both formats use a palette we compare their colours and return -// FALSE if they match. This therefore short circuits palette creation unless -// absolutely necessary since installing palettes is an expensive operation - -BOOL CImagePalette::ShouldUpdate(const VIDEOINFOHEADER *pNewInfo, - const VIDEOINFOHEADER *pOldInfo) -{ - // We may not have a current format yet - - if (pOldInfo == NULL) { - return TRUE; - } - - // Do both formats not require a palette - - if (ContainsPalette(pNewInfo) == FALSE) { - if (ContainsPalette(pOldInfo) == FALSE) { - return FALSE; - } - } - - // Compare the colours to see if they match - - DWORD VideoEntries = pNewInfo->bmiHeader.biClrUsed; - if (ContainsPalette(pNewInfo) == TRUE) - if (ContainsPalette(pOldInfo) == TRUE) - if (pOldInfo->bmiHeader.biClrUsed == VideoEntries) - if (pOldInfo->bmiHeader.biClrUsed > 0) - if (memcmp((PVOID) GetBitmapPalette(pNewInfo), - (PVOID) GetBitmapPalette(pOldInfo), - VideoEntries * sizeof(RGBQUAD)) == 0) { - - return FALSE; - } - return TRUE; -} - - -// This is normally called when the input pin type is set to install a palette -// We will typically be called from two different places. The first is when we -// have negotiated a palettised media type after connection, the other is when -// we receive a new type during processing with an updated palette in which -// case we must remove and release the resources held by the current palette - -// We can be passed an optional device name if we wish to prepare a palette -// for a specific monitor on a multi monitor system - -HRESULT CImagePalette::PreparePalette(const CMediaType *pmtNew, - const CMediaType *pmtOld, - LPSTR szDevice) -{ - const VIDEOINFOHEADER *pNewInfo = (VIDEOINFOHEADER *) pmtNew->Format(); - const VIDEOINFOHEADER *pOldInfo = (VIDEOINFOHEADER *) pmtOld->Format(); - ASSERT(pNewInfo); - - // This is an performance optimisation, when we get a media type we check - // to see if the format requires a palette change. If either we need one - // when previously we didn't or vica versa then this returns TRUE, if we - // previously needed a palette and we do now it compares their colours - - if (ShouldUpdate(pNewInfo,pOldInfo) == FALSE) { - NOTE("No update needed"); - return S_FALSE; - } - - // We must notify the filter graph that the application may have changed - // the palette although in practice we don't bother checking to see if it - // is really different. If it tries to get the palette either the window - // or renderer lock will ensure it doesn't get in until we are finished - - RemovePalette(); - m_pFilter->NotifyEvent(EC_PALETTE_CHANGED,0,0); - - // Do we need a palette for the new format - - if (ContainsPalette(pNewInfo) == FALSE) { - NOTE("New has no palette"); - return S_FALSE; - } - - if (m_pBaseWindow) { - m_pBaseWindow->LockPaletteLock(); - } - - // If we're changing the palette on the fly then we increment our palette - // cookie which is compared against the cookie also stored in all of our - // DIBSECTION media samples. If they don't match when we come to draw it - // then we know the sample is out of date and we'll update it's palette - - NOTE("Making new colour palette"); - m_hPalette = MakePalette(pNewInfo, szDevice); - ASSERT(m_hPalette != NULL); - - if (m_pBaseWindow) { - m_pBaseWindow->UnlockPaletteLock(); - } - - // The window in which the new palette is to be realised may be a NULL - // pointer to signal that no window is in use, if so we don't call it - // Some filters just want to use this object to create/manage palettes - - if (m_pBaseWindow) m_pBaseWindow->SetPalette(m_hPalette); - - // This is the only time where we need access to the draw object to say - // to it that a new palette will be arriving on a sample real soon. The - // constructor may take a NULL pointer in which case we don't call this - - if (m_pDrawImage) m_pDrawImage->IncrementPaletteVersion(); - return NOERROR; -} - - -// Helper function to copy a palette out of any kind of VIDEOINFO (ie it may -// be YUV or true colour) into a palettised VIDEOINFO. We use this changing -// palettes on DirectDraw samples as a source filter can attach a palette to -// any buffer (eg YUV) and hand it back. We make a new palette out of that -// format and then copy the palette colours into the current connection type - -HRESULT CImagePalette::CopyPalette(const CMediaType *pSrc,CMediaType *pDest) -{ - // Reset the destination palette before starting - - VIDEOINFOHEADER *pDestInfo = (VIDEOINFOHEADER *) pDest->Format(); - pDestInfo->bmiHeader.biClrUsed = 0; - pDestInfo->bmiHeader.biClrImportant = 0; - - // Does the destination have a palette - - if (PALETTISED(pDestInfo) == FALSE) { - NOTE("No destination palette"); - return S_FALSE; - } - - // Does the source contain a palette - - const VIDEOINFOHEADER *pSrcInfo = (VIDEOINFOHEADER *) pSrc->Format(); - if (ContainsPalette(pSrcInfo) == FALSE) { - NOTE("No source palette"); - return S_FALSE; - } - - // The number of colours may be zero filled - - DWORD PaletteEntries = pSrcInfo->bmiHeader.biClrUsed; - if (PaletteEntries == 0) { - DWORD Maximum = (1 << pSrcInfo->bmiHeader.biBitCount); - NOTE1("Setting maximum colours (%d)",Maximum); - PaletteEntries = Maximum; - } - - // Make sure the destination has enough room for the palette - - ASSERT(pSrcInfo->bmiHeader.biClrUsed <= iPALETTE_COLORS); - ASSERT(pSrcInfo->bmiHeader.biClrImportant <= PaletteEntries); - ASSERT(COLORS(pDestInfo) == GetBitmapPalette(pDestInfo)); - pDestInfo->bmiHeader.biClrUsed = PaletteEntries; - pDestInfo->bmiHeader.biClrImportant = pSrcInfo->bmiHeader.biClrImportant; - ULONG BitmapSize = GetBitmapFormatSize(HEADER(pSrcInfo)); - - if (pDest->FormatLength() < BitmapSize) { - NOTE("Reallocating destination"); - pDest->ReallocFormatBuffer(BitmapSize); - } - - // Now copy the palette colours across - - CopyMemory((PVOID) COLORS(pDestInfo), - (PVOID) GetBitmapPalette(pSrcInfo), - PaletteEntries * sizeof(RGBQUAD)); - - return NOERROR; -} - - -// This is normally called when the palette is changed (typically during a -// dynamic format change) to remove any palette we previously installed. We -// replace it (if necessary) in the video window with a standard VGA palette -// that should always be available even if this is a true colour display - -HRESULT CImagePalette::RemovePalette() -{ - if (m_pBaseWindow) { - m_pBaseWindow->LockPaletteLock(); - } - - // Do we have a palette to remove - - if (m_hPalette != NULL) { - - if (m_pBaseWindow) { - // Make sure that the window's palette handle matches - // our palette handle. - ASSERT(m_hPalette == m_pBaseWindow->GetPalette()); - - m_pBaseWindow->UnsetPalette(); - } - - EXECUTE_ASSERT(DeleteObject(m_hPalette)); - m_hPalette = NULL; - } - - if (m_pBaseWindow) { - m_pBaseWindow->UnlockPaletteLock(); - } - - return NOERROR; -} - - -// Called to create a palette for the object, the data structure used by GDI -// to describe a palette is a LOGPALETTE, this includes a variable number of -// PALETTEENTRY fields which are the colours, we have to convert the RGBQUAD -// colour fields we are handed in a BITMAPINFO from the media type into these -// This handles extraction of palettes from true colour and YUV media formats - -// We can be passed an optional device name if we wish to prepare a palette -// for a specific monitor on a multi monitor system - -HPALETTE CImagePalette::MakePalette(const VIDEOINFOHEADER *pVideoInfo, LPSTR szDevice) -{ - ASSERT(ContainsPalette(pVideoInfo) == TRUE); - ASSERT(pVideoInfo->bmiHeader.biClrUsed <= iPALETTE_COLORS); - BITMAPINFOHEADER *pHeader = HEADER(pVideoInfo); - - const RGBQUAD *pColours; // Pointer to the palette - LOGPALETTE *lp; // Used to create a palette - HPALETTE hPalette; // Logical palette object - - lp = (LOGPALETTE *) new BYTE[sizeof(LOGPALETTE) + SIZE_PALETTE]; - if (lp == NULL) { - return NULL; - } - - // Unfortunately for some hare brained reason a GDI palette entry (a - // PALETTEENTRY structure) is different to a palette entry from a DIB - // format (a RGBQUAD structure) so we have to do the field conversion - // The VIDEOINFO containing the palette may be a true colour type so - // we use GetBitmapPalette to skip over any bit fields if they exist - - lp->palVersion = PALVERSION; - lp->palNumEntries = (USHORT) pHeader->biClrUsed; - if (lp->palNumEntries == 0) lp->palNumEntries = (1 << pHeader->biBitCount); - pColours = GetBitmapPalette(pVideoInfo); - - for (DWORD dwCount = 0;dwCount < lp->palNumEntries;dwCount++) { - lp->palPalEntry[dwCount].peRed = pColours[dwCount].rgbRed; - lp->palPalEntry[dwCount].peGreen = pColours[dwCount].rgbGreen; - lp->palPalEntry[dwCount].peBlue = pColours[dwCount].rgbBlue; - lp->palPalEntry[dwCount].peFlags = 0; - } - - MakeIdentityPalette(lp->palPalEntry, lp->palNumEntries, szDevice); - - // Create a logical palette - - hPalette = CreatePalette(lp); - ASSERT(hPalette != NULL); - delete[] lp; - return hPalette; -} - - -// GDI does a fair job of compressing the palette entries you give it, so for -// example if you have five entries with an RGB colour (0,0,0) it will remove -// all but one of them. When you subsequently draw an image it will map from -// your logical palette to the compressed device palette. This function looks -// to see if it is trying to be an identity palette and if so sets the flags -// field in the PALETTEENTRYs so they remain expanded to boost performance - -// We can be passed an optional device name if we wish to prepare a palette -// for a specific monitor on a multi monitor system - -HRESULT CImagePalette::MakeIdentityPalette(PALETTEENTRY *pEntry,INT iColours, LPSTR szDevice) -{ - PALETTEENTRY SystemEntries[10]; // System palette entries - BOOL bIdentityPalette = TRUE; // Is an identity palette - ASSERT(iColours <= iPALETTE_COLORS); // Should have a palette - const int PalLoCount = 10; // First ten reserved colours - const int PalHiStart = 246; // Last VGA palette entries - - // Does this have the full colour range - - if (iColours < 10) { - return S_FALSE; - } - - // Apparently some displays have odd numbers of system colours - - // Get a DC on the right monitor - it's ugly, but this is the way you have - // to do it - HDC hdc; - if (szDevice == NULL || lstrcmpiA(szDevice, "DISPLAY") == 0) - hdc = CreateDCA("DISPLAY", NULL, NULL, NULL); - else - hdc = CreateDCA(NULL, szDevice, NULL, NULL); - if (NULL == hdc) { - return E_OUTOFMEMORY; - } - INT Reserved = GetDeviceCaps(hdc,NUMRESERVED); - if (Reserved != 20) { - DeleteDC(hdc); - return S_FALSE; - } - - // Compare our palette against the first ten system entries. The reason I - // don't do a memory compare between our two arrays of colours is because - // I am not sure what will be in the flags fields for the system entries - - UINT Result = GetSystemPaletteEntries(hdc,0,PalLoCount,SystemEntries); - UINT Count; - for (Count = 0;Count < Result;Count++) { - if (SystemEntries[Count].peRed != pEntry[Count].peRed || - SystemEntries[Count].peGreen != pEntry[Count].peGreen || - SystemEntries[Count].peBlue != pEntry[Count].peBlue) { - bIdentityPalette = FALSE; - } - } - - // And likewise compare against the last ten entries - - Result = GetSystemPaletteEntries(hdc,PalHiStart,PalLoCount,SystemEntries); - for (Count = 0;Count < Result;Count++) { - if (INT(Count) + PalHiStart < iColours) { - if (SystemEntries[Count].peRed != pEntry[PalHiStart + Count].peRed || - SystemEntries[Count].peGreen != pEntry[PalHiStart + Count].peGreen || - SystemEntries[Count].peBlue != pEntry[PalHiStart + Count].peBlue) { - bIdentityPalette = FALSE; - } - } - } - - // If not an identity palette then return S_FALSE - - DeleteDC(hdc); - if (bIdentityPalette == FALSE) { - return S_FALSE; - } - - // Set the non VGA entries so that GDI doesn't map them - - for (Count = PalLoCount;INT(Count) < min(PalHiStart,iColours);Count++) { - pEntry[Count].peFlags = PC_NOCOLLAPSE; - } - return NOERROR; -} - - -// Constructor initialises the VIDEOINFO we keep storing the current display -// format. The format can be changed at any time, to reset the format held -// by us call the RefreshDisplayType directly (it's a public method). Since -// more than one thread will typically call us (ie window threads resetting -// the type and source threads in the type checking methods) we have a lock - -CImageDisplay::CImageDisplay() -{ - RefreshDisplayType(NULL); -} - - - -// This initialises the format we hold which contains the display device type -// We do a conversion on the display device type in here so that when we start -// type checking input formats we can assume that certain fields have been set -// correctly, an example is when we make the 16 bit mask fields explicit. This -// is normally called when we receive WM_DEVMODECHANGED device change messages - -// The optional szDeviceName parameter tells us which monitor we are interested -// in for a multi monitor system - -HRESULT CImageDisplay::RefreshDisplayType(LPSTR szDeviceName) -{ - CAutoLock cDisplayLock(this); - - // Set the preferred format type - - ZeroMemory((PVOID)&m_Display,sizeof(VIDEOINFOHEADER)+sizeof(TRUECOLORINFO)); - m_Display.bmiHeader.biSize = sizeof(BITMAPINFOHEADER); - m_Display.bmiHeader.biBitCount = FALSE; - - // Get the bit depth of a device compatible bitmap - - // get caps of whichever monitor they are interested in (multi monitor) - HDC hdcDisplay; - // it's ugly, but this is the way you have to do it - if (szDeviceName == NULL || lstrcmpiA(szDeviceName, "DISPLAY") == 0) - hdcDisplay = CreateDCA("DISPLAY", NULL, NULL, NULL); - else - hdcDisplay = CreateDCA(NULL, szDeviceName, NULL, NULL); - if (hdcDisplay == NULL) { - ASSERT(FALSE); - DbgLog((LOG_ERROR,1,TEXT("ACK! Can't get a DC for %hs"), - szDeviceName ? szDeviceName : "")); - return E_FAIL; - } else { - DbgLog((LOG_TRACE,3,TEXT("Created a DC for %s"), - szDeviceName ? szDeviceName : "")); - } - HBITMAP hbm = CreateCompatibleBitmap(hdcDisplay,1,1); - if ( hbm ) - { - GetDIBits(hdcDisplay,hbm,0,1,NULL,(BITMAPINFO *)&m_Display.bmiHeader,DIB_RGB_COLORS); - - // This call will get the colour table or the proper bitfields - GetDIBits(hdcDisplay,hbm,0,1,NULL,(BITMAPINFO *)&m_Display.bmiHeader,DIB_RGB_COLORS); - DeleteObject(hbm); - } - DeleteDC(hdcDisplay); - - // Complete the display type initialisation - - ASSERT(CheckHeaderValidity(&m_Display)); - UpdateFormat(&m_Display); - DbgLog((LOG_TRACE,3,TEXT("New DISPLAY bit depth =%d"), - m_Display.bmiHeader.biBitCount)); - return NOERROR; -} - - -// We assume throughout this code that any bitfields masks are allowed no -// more than eight bits to store a colour component. This checks that the -// bit count assumption is enforced and also makes sure that all the bits -// set are contiguous. We return a boolean TRUE if the field checks out ok - -BOOL CImageDisplay::CheckBitFields(const VIDEOINFO *pInput) -{ - DWORD *pBitFields = (DWORD *) BITMASKS(pInput); - - for (INT iColour = iRED;iColour <= iBLUE;iColour++) { - - // First of all work out how many bits are set - - DWORD SetBits = CountSetBits(pBitFields[iColour]); - if (SetBits > iMAXBITS || SetBits == 0) { - NOTE1("Bit fields for component %d invalid",iColour); - return FALSE; - } - - // Next work out the number of zero bits prefix - DWORD PrefixBits = CountPrefixBits(pBitFields[iColour]); - - // This is going to see if all the bits set are contiguous (as they - // should be). We know how much to shift them right by from the - // count of prefix bits. The number of bits set defines a mask, we - // invert this (ones complement) and AND it with the shifted bit - // fields. If the result is NON zero then there are bit(s) sticking - // out the left hand end which means they are not contiguous - - DWORD TestField = pBitFields[iColour] >> PrefixBits; - DWORD Mask = ULONG_MAX << SetBits; - if (TestField & Mask) { - NOTE1("Bit fields for component %d not contiguous",iColour); - return FALSE; - } - } - return TRUE; -} - - -// This counts the number of bits set in the input field - -DWORD CImageDisplay::CountSetBits(DWORD Field) -{ - // This is a relatively well known bit counting algorithm - - DWORD Count = 0; - DWORD init = Field; - - // Until the input is exhausted, count the number of bits - - while (init) { - init = init & (init - 1); // Turn off the bottommost bit - Count++; - } - return Count; -} - - -// This counts the number of zero bits upto the first one set NOTE the input -// field should have been previously checked to ensure there is at least one -// set although if we don't find one set we return the impossible value 32 - -DWORD CImageDisplay::CountPrefixBits(DWORD Field) -{ - DWORD Mask = 1; - DWORD Count = 0; - - while (TRUE) { - if (Field & Mask) { - return Count; - } - Count++; - - ASSERT(Mask != 0x80000000); - if (Mask == 0x80000000) { - return Count; - } - Mask <<= 1; - } -} - - -// This is called to check the BITMAPINFOHEADER for the input type. There are -// many implicit dependancies between the fields in a header structure which -// if we validate now make for easier manipulation in subsequent handling. We -// also check that the BITMAPINFOHEADER matches it's specification such that -// fields likes the number of planes is one, that it's structure size is set -// correctly and that the bitmap dimensions have not been set as negative - -BOOL CImageDisplay::CheckHeaderValidity(const VIDEOINFO *pInput) -{ - // Check the bitmap width and height are not negative. - - if (pInput->bmiHeader.biWidth <= 0 || - pInput->bmiHeader.biHeight <= 0) { - NOTE("Invalid bitmap dimensions"); - return FALSE; - } - - // Check the compression is either BI_RGB or BI_BITFIELDS - - if (pInput->bmiHeader.biCompression != BI_RGB) { - if (pInput->bmiHeader.biCompression != BI_BITFIELDS) { - NOTE("Invalid compression format"); - return FALSE; - } - } - - // If BI_BITFIELDS compression format check the colour depth - - if (pInput->bmiHeader.biCompression == BI_BITFIELDS) { - if (pInput->bmiHeader.biBitCount != 16) { - if (pInput->bmiHeader.biBitCount != 32) { - NOTE("BI_BITFIELDS not 16/32 bit depth"); - return FALSE; - } - } - } - - // Check the assumptions about the layout of the bit fields - - if (pInput->bmiHeader.biCompression == BI_BITFIELDS) { - if (CheckBitFields(pInput) == FALSE) { - NOTE("Bit fields are not valid"); - return FALSE; - } - } - - // Are the number of planes equal to one - - if (pInput->bmiHeader.biPlanes != 1) { - NOTE("Number of planes not one"); - return FALSE; - } - - // Check the image size is consistent (it can be zero) - - if (pInput->bmiHeader.biSizeImage != GetBitmapSize(&pInput->bmiHeader)) { - if (pInput->bmiHeader.biSizeImage) { - NOTE("Image size incorrectly set"); - return FALSE; - } - } - - // Check the size of the structure - - if (pInput->bmiHeader.biSize != sizeof(BITMAPINFOHEADER)) { - NOTE("Size of BITMAPINFOHEADER wrong"); - return FALSE; - } - return CheckPaletteHeader(pInput); -} - - -// This runs a few simple tests against the palette fields in the input to -// see if it looks vaguely correct. The tests look at the number of palette -// colours present, the number considered important and the biCompression -// field which should always be BI_RGB as no other formats are meaningful - -BOOL CImageDisplay::CheckPaletteHeader(const VIDEOINFO *pInput) -{ - // The checks here are for palettised videos only - - if (PALETTISED(pInput) == FALSE) { - if (pInput->bmiHeader.biClrUsed) { - NOTE("Invalid palette entries"); - return FALSE; - } - return TRUE; - } - - // Compression type of BI_BITFIELDS is meaningless for palette video - - if (pInput->bmiHeader.biCompression != BI_RGB) { - NOTE("Palettised video must be BI_RGB"); - return FALSE; - } - - // Check the number of palette colours is correct - - if (pInput->bmiHeader.biClrUsed > PALETTE_ENTRIES(pInput)) { - NOTE("Too many colours in palette"); - return FALSE; - } - - // The number of important colours shouldn't exceed the number used - - if (pInput->bmiHeader.biClrImportant > pInput->bmiHeader.biClrUsed) { - NOTE("Too many important colours"); - return FALSE; - } - return TRUE; -} - - -// Return the format of the video display - -const VIDEOINFO *CImageDisplay::GetDisplayFormat() -{ - return &m_Display; -} - - -// Return TRUE if the display uses a palette - -BOOL CImageDisplay::IsPalettised() -{ - return PALETTISED(&m_Display); -} - - -// Return the bit depth of the current display setting - -WORD CImageDisplay::GetDisplayDepth() -{ - return m_Display.bmiHeader.biBitCount; -} - - -// Initialise the optional fields in a VIDEOINFO. These are mainly to do with -// the source and destination rectangles and palette information such as the -// number of colours present. It simplifies our code just a little if we don't -// have to keep checking for all the different valid permutations in a header -// every time we want to do anything with it (an example would be creating a -// palette). We set the base class media type before calling this function so -// that the media types between the pins match after a connection is made - -HRESULT CImageDisplay::UpdateFormat(VIDEOINFO *pVideoInfo) -{ - ASSERT(pVideoInfo); - - BITMAPINFOHEADER *pbmi = HEADER(pVideoInfo); - SetRectEmpty(&pVideoInfo->rcSource); - SetRectEmpty(&pVideoInfo->rcTarget); - - // Set the number of colours explicitly - - if (PALETTISED(pVideoInfo)) { - if (pVideoInfo->bmiHeader.biClrUsed == 0) { - pVideoInfo->bmiHeader.biClrUsed = PALETTE_ENTRIES(pVideoInfo); - } - } - - // The number of important colours shouldn't exceed the number used, on - // some displays the number of important colours is not initialised when - // retrieving the display type so we set the colours used correctly - - if (pVideoInfo->bmiHeader.biClrImportant > pVideoInfo->bmiHeader.biClrUsed) { - pVideoInfo->bmiHeader.biClrImportant = PALETTE_ENTRIES(pVideoInfo); - } - - // Change the image size field to be explicit - - if (pVideoInfo->bmiHeader.biSizeImage == 0) { - pVideoInfo->bmiHeader.biSizeImage = GetBitmapSize(&pVideoInfo->bmiHeader); - } - return NOERROR; -} - - -// Lots of video rendering filters want code to check proposed formats are ok -// This checks the VIDEOINFO we are passed as a media type. If the media type -// is a valid media type then we return NOERROR otherwise E_INVALIDARG. Note -// however we only accept formats that can be easily displayed in the display -// so if we are on a 16 bit device we will not accept 24 bit images. The one -// complexity is that most displays draw 8 bit palettised images efficiently -// Also if the input format is less colour bits per pixel then we also accept - -HRESULT CImageDisplay::CheckVideoType(const VIDEOINFO *pInput) -{ - // First of all check the VIDEOINFOHEADER looks correct - - if (CheckHeaderValidity(pInput) == FALSE) { - return E_INVALIDARG; - } - - // Virtually all devices support palettised images efficiently - - if (m_Display.bmiHeader.biBitCount == pInput->bmiHeader.biBitCount) { - if (PALETTISED(pInput) == TRUE) { - ASSERT(PALETTISED(&m_Display) == TRUE); - NOTE("(Video) Type connection ACCEPTED"); - return NOERROR; - } - } - - - // Is the display depth greater than the input format - - if (m_Display.bmiHeader.biBitCount > pInput->bmiHeader.biBitCount) { - NOTE("(Video) Mismatch agreed"); - return NOERROR; - } - - // Is the display depth less than the input format - - if (m_Display.bmiHeader.biBitCount < pInput->bmiHeader.biBitCount) { - NOTE("(Video) Format mismatch"); - return E_INVALIDARG; - } - - - // Both input and display formats are either BI_RGB or BI_BITFIELDS - - ASSERT(m_Display.bmiHeader.biBitCount == pInput->bmiHeader.biBitCount); - ASSERT(PALETTISED(pInput) == FALSE); - ASSERT(PALETTISED(&m_Display) == FALSE); - - // BI_RGB 16 bit representation is implicitly RGB555, and likewise BI_RGB - // 24 bit representation is RGB888. So we initialise a pointer to the bit - // fields they really mean and check against the display device format - // This is only going to be called when both formats are equal bits pixel - - const DWORD *pInputMask = GetBitMasks(pInput); - const DWORD *pDisplayMask = GetBitMasks((VIDEOINFO *)&m_Display); - - if (pInputMask[iRED] != pDisplayMask[iRED] || - pInputMask[iGREEN] != pDisplayMask[iGREEN] || - pInputMask[iBLUE] != pDisplayMask[iBLUE]) { - - NOTE("(Video) Bit field mismatch"); - return E_INVALIDARG; - } - - NOTE("(Video) Type connection ACCEPTED"); - return NOERROR; -} - - -// Return the bit masks for the true colour VIDEOINFO provided - -const DWORD *CImageDisplay::GetBitMasks(const VIDEOINFO *pVideoInfo) -{ - static const DWORD FailMasks[] = {0,0,0}; - - if (pVideoInfo->bmiHeader.biCompression == BI_BITFIELDS) { - return BITMASKS(pVideoInfo); - } - - ASSERT(pVideoInfo->bmiHeader.biCompression == BI_RGB); - - switch (pVideoInfo->bmiHeader.biBitCount) { - case 16: return bits555; - case 24: return bits888; - case 32: return bits888; - default: return FailMasks; - } -} - - -// Check to see if we can support media type pmtIn as proposed by the output -// pin - We first check that the major media type is video and also identify -// the media sub type. Then we thoroughly check the VIDEOINFO type provided -// As well as the contained VIDEOINFO being correct the major type must be -// video, the subtype a recognised video format and the type GUID correct - -HRESULT CImageDisplay::CheckMediaType(const CMediaType *pmtIn) -{ - // Does this have a VIDEOINFOHEADER format block - - const GUID *pFormatType = pmtIn->FormatType(); - if (*pFormatType != FORMAT_VideoInfo) { - NOTE("Format GUID not a VIDEOINFOHEADER"); - return E_INVALIDARG; - } - ASSERT(pmtIn->Format()); - - // Check the format looks reasonably ok - - ULONG Length = pmtIn->FormatLength(); - if (Length < SIZE_VIDEOHEADER) { - NOTE("Format smaller than a VIDEOHEADER"); - return E_FAIL; - } - - VIDEOINFO *pInput = (VIDEOINFO *) pmtIn->Format(); - - // Check the major type is MEDIATYPE_Video - - const GUID *pMajorType = pmtIn->Type(); - if (*pMajorType != MEDIATYPE_Video) { - NOTE("Major type not MEDIATYPE_Video"); - return E_INVALIDARG; - } - - // Check we can identify the media subtype - - const GUID *pSubType = pmtIn->Subtype(); - if (GetBitCount(pSubType) == USHRT_MAX) { - NOTE("Invalid video media subtype"); - return E_INVALIDARG; - } - return CheckVideoType(pInput); -} - - -// Given a video format described by a VIDEOINFO structure we return the mask -// that is used to obtain the range of acceptable colours for this type, for -// example, the mask for a 24 bit true colour format is 0xFF in all cases. A -// 16 bit 5:6:5 display format uses 0xF8, 0xFC and 0xF8, therefore given any -// RGB triplets we can AND them with these fields to find one that is valid - -BOOL CImageDisplay::GetColourMask(DWORD *pMaskRed, - DWORD *pMaskGreen, - DWORD *pMaskBlue) -{ - CAutoLock cDisplayLock(this); - *pMaskRed = 0xFF; - *pMaskGreen = 0xFF; - *pMaskBlue = 0xFF; - - // If this format is palettised then it doesn't have bit fields - - if (m_Display.bmiHeader.biBitCount < 16) { - return FALSE; - } - - // If this is a 24 bit true colour display then it can handle all the - // possible colour component ranges described by a byte. It is never - // allowed for a 24 bit colour depth image to have BI_BITFIELDS set - - if (m_Display.bmiHeader.biBitCount == 24) { - ASSERT(m_Display.bmiHeader.biCompression == BI_RGB); - return TRUE; - } - - // Calculate the mask based on the format's bit fields - - const DWORD *pBitFields = (DWORD *) GetBitMasks((VIDEOINFO *)&m_Display); - DWORD *pOutputMask[] = { pMaskRed, pMaskGreen, pMaskBlue }; - - // We know from earlier testing that there are no more than iMAXBITS - // bits set in the mask and that they are all contiguous. All that - // therefore remains is to shift them into the correct position - - for (INT iColour = iRED;iColour <= iBLUE;iColour++) { - - // This works out how many bits there are and where they live - - DWORD PrefixBits = CountPrefixBits(pBitFields[iColour]); - DWORD SetBits = CountSetBits(pBitFields[iColour]); - - // The first shift moves the bit field so that it is right justified - // in the DWORD, after which we then shift it back left which then - // puts the leading bit in the bytes most significant bit position - - *(pOutputMask[iColour]) = pBitFields[iColour] >> PrefixBits; - *(pOutputMask[iColour]) <<= (iMAXBITS - SetBits); - } - return TRUE; -} - - -/* Helper to convert to VIDEOINFOHEADER2 -*/ -STDAPI ConvertVideoInfoToVideoInfo2(AM_MEDIA_TYPE *pmt) -{ - ASSERT(pmt->formattype == FORMAT_VideoInfo); - VIDEOINFO *pVideoInfo = (VIDEOINFO *)pmt->pbFormat; - PVOID pvNew = CoTaskMemAlloc(pmt->cbFormat + sizeof(VIDEOINFOHEADER2) - - sizeof(VIDEOINFOHEADER)); - if (pvNew == NULL) { - return E_OUTOFMEMORY; - } - CopyMemory(pvNew, pmt->pbFormat, FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader)); - ZeroMemory((PBYTE)pvNew + FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader), - sizeof(VIDEOINFOHEADER2) - sizeof(VIDEOINFOHEADER)); - CopyMemory((PBYTE)pvNew + FIELD_OFFSET(VIDEOINFOHEADER2, bmiHeader), - pmt->pbFormat + FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader), - pmt->cbFormat - FIELD_OFFSET(VIDEOINFOHEADER, bmiHeader)); - VIDEOINFOHEADER2 *pVideoInfo2 = (VIDEOINFOHEADER2 *)pvNew; - pVideoInfo2->dwPictAspectRatioX = (DWORD)pVideoInfo2->bmiHeader.biWidth; - pVideoInfo2->dwPictAspectRatioY = (DWORD)pVideoInfo2->bmiHeader.biHeight; - pmt->formattype = FORMAT_VideoInfo2; - CoTaskMemFree(pmt->pbFormat); - pmt->pbFormat = (PBYTE)pvNew; - pmt->cbFormat += sizeof(VIDEOINFOHEADER2) - sizeof(VIDEOINFOHEADER); - return S_OK; -} diff --git a/plugins/gs/gsdx9/baseclasses/winutil.h b/plugins/gs/gsdx9/baseclasses/winutil.h deleted file mode 100644 index ffe3024e1e..0000000000 --- a/plugins/gs/gsdx9/baseclasses/winutil.h +++ /dev/null @@ -1,413 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WinUtil.h -// -// Desc: DirectShow base classes - defines generic handler classes. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -// Make sure that you call PrepareWindow to initialise the window after -// the object has been constructed. It is a separate method so that -// derived classes can override useful methods like MessageLoop. Also -// any derived class must call DoneWithWindow in its destructor. If it -// doesn't a message may be retrieved and call a derived class member -// function while a thread is executing the base class destructor code - -#ifndef __WINUTIL__ -#define __WINUTIL__ - -const int DEFWIDTH = 320; // Initial window width -const int DEFHEIGHT = 240; // Initial window height -const int CAPTION = 256; // Maximum length of caption -const int TIMELENGTH = 50; // Maximum length of times -const int PROFILESTR = 128; // Normal profile string -const WORD PALVERSION = 0x300; // GDI palette version -const LONG PALETTE_VERSION = (LONG) 1; // Initial palette version -const COLORREF VIDEO_COLOUR = 0; // Defaults to black background -const HANDLE hMEMORY = (HANDLE) (-1); // Says to open as memory file - -#define WIDTH(x) ((*(x)).right - (*(x)).left) -#define HEIGHT(x) ((*(x)).bottom - (*(x)).top) -#define SHOWSTAGE TEXT("WM_SHOWSTAGE") -#define SHOWSTAGETOP TEXT("WM_SHOWSTAGETOP") -#define REALIZEPALETTE TEXT("WM_REALIZEPALETTE") - -class AM_NOVTABLE CBaseWindow -{ -protected: - - HINSTANCE m_hInstance; // Global module instance handle - HWND m_hwnd; // Handle for our window - HDC m_hdc; // Device context for the window - LONG m_Width; // Client window width - LONG m_Height; // Client window height - BOOL m_bActivated; // Has the window been activated - LPTSTR m_pClassName; // Static string holding class name - DWORD m_ClassStyles; // Passed in to our constructor - DWORD m_WindowStyles; // Likewise the initial window styles - DWORD m_WindowStylesEx; // And the extended window styles - UINT m_ShowStageMessage; // Have the window shown with focus - UINT m_ShowStageTop; // Makes the window WS_EX_TOPMOST - UINT m_RealizePalette; // Makes us realize our new palette - HDC m_MemoryDC; // Used for fast BitBlt operations - HPALETTE m_hPalette; // Handle to any palette we may have - BYTE m_bNoRealize; // Don't realize palette now - BYTE m_bBackground; // Should we realise in background - BYTE m_bRealizing; // already realizing the palette - CCritSec m_WindowLock; // Serialise window object access - BOOL m_bDoGetDC; // Should this window get a DC - bool m_bDoPostToDestroy; // Use PostMessage to destroy - CCritSec m_PaletteLock; // This lock protects m_hPalette. - // It should be held anytime the - // program use the value of m_hPalette. - - // Maps windows message procedure into C++ methods - friend LRESULT CALLBACK WndProc(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam); // Other parameter - - virtual LRESULT OnPaletteChange(HWND hwnd, UINT Message); - -public: - - CBaseWindow(BOOL bDoGetDC = TRUE, bool bPostToDestroy = false); - -#ifdef DEBUG - virtual ~CBaseWindow(); -#endif - - virtual HRESULT DoneWithWindow(); - virtual HRESULT PrepareWindow(); - virtual HRESULT InactivateWindow(); - virtual HRESULT ActivateWindow(); - virtual BOOL OnSize(LONG Width, LONG Height); - virtual BOOL OnClose(); - virtual RECT GetDefaultRect(); - virtual HRESULT UninitialiseWindow(); - virtual HRESULT InitialiseWindow(HWND hwnd); - - HRESULT CompleteConnect(); - HRESULT DoCreateWindow(); - - HRESULT PerformanceAlignWindow(); - HRESULT DoShowWindow(LONG ShowCmd); - void PaintWindow(BOOL bErase); - void DoSetWindowForeground(BOOL bFocus); - virtual HRESULT SetPalette(HPALETTE hPalette); - void SetRealize(BOOL bRealize) - { - m_bNoRealize = !bRealize; - } - - // Jump over to the window thread to set the current palette - HRESULT SetPalette(); - void UnsetPalette(void); - virtual HRESULT DoRealisePalette(BOOL bForceBackground = FALSE); - - void LockPaletteLock(); - void UnlockPaletteLock(); - - virtual BOOL PossiblyEatMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) - { return FALSE; }; - - // Access our window information - - bool WindowExists(); - LONG GetWindowWidth(); - LONG GetWindowHeight(); - HWND GetWindowHWND(); - HDC GetMemoryHDC(); - HDC GetWindowHDC(); - - #ifdef DEBUG - HPALETTE GetPalette(); - #endif // DEBUG - - // This is the window procedure the derived object should override - - virtual LRESULT OnReceiveMessage(HWND hwnd, // Window handle - UINT uMsg, // Message ID - WPARAM wParam, // First parameter - LPARAM lParam); // Other parameter - - // Must be overriden to return class and window styles - - virtual LPTSTR GetClassWindowStyles( - DWORD *pClassStyles, // Class styles - DWORD *pWindowStyles, // Window styles - DWORD *pWindowStylesEx) PURE; // Extended styles -}; - - -// This helper class is entirely subservient to the owning CBaseWindow object -// All this object does is to split out the actual drawing operation from the -// main object (because it was becoming too large). We have a number of entry -// points to set things like the draw device contexts, to implement the actual -// drawing and to set the destination rectangle in the client window. We have -// no critical section locking in this class because we are used exclusively -// by the owning window object which looks after serialising calls into us - -// If you want to use this class make sure you call NotifyAllocator once the -// allocate has been agreed, also call NotifyMediaType with a pointer to a -// NON stack based CMediaType once that has been set (we keep a pointer to -// the original rather than taking a copy). When the palette changes call -// IncrementPaletteVersion (easiest thing to do is to also call this method -// in the SetMediaType method most filters implement). Finally before you -// start rendering anything call SetDrawContext so that we can get the HDCs -// for drawing from the CBaseWindow object we are given during construction - -class CDrawImage -{ -protected: - - CBaseWindow *m_pBaseWindow; // Owning video window object - CRefTime m_StartSample; // Start time for the current sample - CRefTime m_EndSample; // And likewise it's end sample time - HDC m_hdc; // Main window device context - HDC m_MemoryDC; // Offscreen draw device context - RECT m_TargetRect; // Target destination rectangle - RECT m_SourceRect; // Source image rectangle - BOOL m_bStretch; // Do we have to stretch the images - BOOL m_bUsingImageAllocator; // Are the samples shared DIBSECTIONs - CMediaType *m_pMediaType; // Pointer to the current format - int m_perfidRenderTime; // Time taken to render an image - LONG m_PaletteVersion; // Current palette version cookie - - // Draw the video images in the window - - void SlowRender(IMediaSample *pMediaSample); - void FastRender(IMediaSample *pMediaSample); - void DisplaySampleTimes(IMediaSample *pSample); - void UpdateColourTable(HDC hdc,BITMAPINFOHEADER *pbmi); - void SetStretchMode(); - -public: - - // Used to control the image drawing - - CDrawImage(CBaseWindow *pBaseWindow); - BOOL DrawImage(IMediaSample *pMediaSample); - BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, - LPRECT lprcSrc, LPRECT lprcDst); - void SetDrawContext(); - void SetTargetRect(RECT *pTargetRect); - void SetSourceRect(RECT *pSourceRect); - void GetTargetRect(RECT *pTargetRect); - void GetSourceRect(RECT *pSourceRect); - virtual RECT ScaleSourceRect(const RECT *pSource); - - // Handle updating palettes as they change - - LONG GetPaletteVersion(); - void ResetPaletteVersion(); - void IncrementPaletteVersion(); - - // Tell us media types and allocator assignments - - void NotifyAllocator(BOOL bUsingImageAllocator); - void NotifyMediaType(CMediaType *pMediaType); - BOOL UsingImageAllocator(); - - // Called when we are about to draw an image - - void NotifyStartDraw() { - MSR_START(m_perfidRenderTime); - }; - - // Called when we complete an image rendering - - void NotifyEndDraw() { - MSR_STOP(m_perfidRenderTime); - }; -}; - - -// This is the structure used to keep information about each GDI DIB. All the -// samples we create from our allocator will have a DIBSECTION allocated to -// them. When we receive the sample we know we can BitBlt straight to an HDC - -typedef struct tagDIBDATA { - - LONG PaletteVersion; // Current palette version in use - DIBSECTION DibSection; // Details of DIB section allocated - HBITMAP hBitmap; // Handle to bitmap for drawing - HANDLE hMapping; // Handle to shared memory block - BYTE *pBase; // Pointer to base memory address - -} DIBDATA; - - -// This class inherits from CMediaSample and uses all of it's methods but it -// overrides the constructor to initialise itself with the DIBDATA structure -// When we come to render an IMediaSample we will know if we are using our own -// allocator, and if we are, we can cast the IMediaSample to a pointer to one -// of these are retrieve the DIB section information and hence the HBITMAP - -class CImageSample : public CMediaSample -{ -protected: - - DIBDATA m_DibData; // Information about the DIBSECTION - BOOL m_bInit; // Is the DIB information setup - -public: - - // Constructor - - CImageSample(CBaseAllocator *pAllocator, - TCHAR *pName, - HRESULT *phr, - LPBYTE pBuffer, - LONG length); - - // Maintain the DIB/DirectDraw state - - void SetDIBData(DIBDATA *pDibData); - DIBDATA *GetDIBData(); -}; - - -// This is an allocator based on the abstract CBaseAllocator base class that -// allocates sample buffers in shared memory. The number and size of these -// are determined when the output pin calls Prepare on us. The shared memory -// blocks are used in subsequent calls to GDI CreateDIBSection, once that -// has been done the output pin can fill the buffers with data which will -// then be handed to GDI through BitBlt calls and thereby remove one copy - -class CImageAllocator : public CBaseAllocator -{ -protected: - - CBaseFilter *m_pFilter; // Delegate reference counts to - CMediaType *m_pMediaType; // Pointer to the current format - - // Used to create and delete samples - - HRESULT Alloc(); - void Free(); - - // Manage the shared DIBSECTION and DCI/DirectDraw buffers - - HRESULT CreateDIB(LONG InSize,DIBDATA &DibData); - STDMETHODIMP CheckSizes(ALLOCATOR_PROPERTIES *pRequest); - virtual CImageSample *CreateImageSample(LPBYTE pData,LONG Length); - -public: - - // Constructor and destructor - - CImageAllocator(CBaseFilter *pFilter,TCHAR *pName,HRESULT *phr); -#ifdef DEBUG - ~CImageAllocator(); -#endif - - STDMETHODIMP_(ULONG) NonDelegatingAddRef(); - STDMETHODIMP_(ULONG) NonDelegatingRelease(); - void NotifyMediaType(CMediaType *pMediaType); - - // Agree the number of buffers to be used and their size - - STDMETHODIMP SetProperties( - ALLOCATOR_PROPERTIES *pRequest, - ALLOCATOR_PROPERTIES *pActual); -}; - - -// This class is a fairly specialised helper class for image renderers that -// have to create and manage palettes. The CBaseWindow class looks after -// realising palettes once they have been installed. This class can be used -// to create the palette handles from a media format (which must contain a -// VIDEOINFO structure in the format block). We try to make the palette an -// identity palette to maximise performance and also only change palettes -// if actually required to (we compare palette colours before updating). -// All the methods are virtual so that they can be overriden if so required - -class CImagePalette -{ -protected: - - CBaseWindow *m_pBaseWindow; // Window to realise palette in - CBaseFilter *m_pFilter; // Media filter to send events - CDrawImage *m_pDrawImage; // Object who will be drawing - HPALETTE m_hPalette; // The palette handle we own - -public: - - CImagePalette(CBaseFilter *pBaseFilter, - CBaseWindow *pBaseWindow, - CDrawImage *pDrawImage); - -#ifdef DEBUG - virtual ~CImagePalette(); -#endif - - static HPALETTE MakePalette(const VIDEOINFOHEADER *pVideoInfo, LPSTR szDevice); - HRESULT RemovePalette(); - static HRESULT MakeIdentityPalette(PALETTEENTRY *pEntry,INT iColours, LPSTR szDevice); - HRESULT CopyPalette(const CMediaType *pSrc,CMediaType *pDest); - BOOL ShouldUpdate(const VIDEOINFOHEADER *pNewInfo,const VIDEOINFOHEADER *pOldInfo); - HRESULT PreparePalette(const CMediaType *pmtNew,const CMediaType *pmtOld,LPSTR szDevice); - - BOOL DrawVideoImageHere(HDC hdc, IMediaSample *pMediaSample, LPRECT lprcSrc, LPRECT lprcDst) - { - return m_pDrawImage->DrawVideoImageHere(hdc, pMediaSample, lprcSrc,lprcDst); - } -}; - - -// Another helper class really for video based renderers. Most such renderers -// need to know what the display format is to some degree or another. This -// class initialises itself with the display format. The format can be asked -// for through GetDisplayFormat and various other accessor functions. If a -// filter detects a display format change (perhaps it gets a WM_DEVMODECHANGE -// message then it can call RefreshDisplayType to reset that format). Also -// many video renderers will want to check formats as they are proposed by -// source filters. This class provides methods to check formats and only -// accept those video formats that can be efficiently drawn using GDI calls - -class CImageDisplay : public CCritSec -{ -protected: - - // This holds the display format; biSize should not be too big, so we can - // safely use the VIDEOINFO structure - VIDEOINFO m_Display; - - static DWORD CountSetBits(const DWORD Field); - static DWORD CountPrefixBits(const DWORD Field); - static BOOL CheckBitFields(const VIDEOINFO *pInput); - -public: - - // Constructor and destructor - - CImageDisplay(); - - // Used to manage BITMAPINFOHEADERs and the display format - - const VIDEOINFO *GetDisplayFormat(); - HRESULT RefreshDisplayType(LPSTR szDeviceName); - static BOOL CheckHeaderValidity(const VIDEOINFO *pInput); - static BOOL CheckPaletteHeader(const VIDEOINFO *pInput); - BOOL IsPalettised(); - WORD GetDisplayDepth(); - - // Provide simple video format type checking - - HRESULT CheckMediaType(const CMediaType *pmtIn); - HRESULT CheckVideoType(const VIDEOINFO *pInput); - HRESULT UpdateFormat(VIDEOINFO *pVideoInfo); - const DWORD *GetBitMasks(const VIDEOINFO *pVideoInfo); - - BOOL GetColourMask(DWORD *pMaskRed, - DWORD *pMaskGreen, - DWORD *pMaskBlue); -}; - -// Convert a FORMAT_VideoInfo to FORMAT_VideoInfo2 -STDAPI ConvertVideoInfoToVideoInfo2(AM_MEDIA_TYPE *pmt); - -#endif // __WINUTIL__ - diff --git a/plugins/gs/gsdx9/baseclasses/wxdebug.cpp b/plugins/gs/gsdx9/baseclasses/wxdebug.cpp deleted file mode 100644 index f730d1c57f..0000000000 --- a/plugins/gs/gsdx9/baseclasses/wxdebug.cpp +++ /dev/null @@ -1,1420 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXDebug.cpp -// -// Desc: DirectShow base classes - implements ActiveX system debugging -// facilities. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#define _WINDLL - -#include -#include -#include - -#ifdef DEBUG -#ifdef UNICODE -#ifndef _UNICODE -#define _UNICODE -#endif // _UNICODE -#endif // UNICODE -#endif // DEBUG - -#ifdef DEBUG - -// The Win32 wsprintf() function writes a maximum of 1024 characters to it's output buffer. -// See the documentation for wsprintf()'s lpOut parameter for more information. -const INT iDEBUGINFO = 1024; // Used to format strings - -/* For every module and executable we store a debugging level for each of - the five categories (eg LOG_ERROR and LOG_TIMING). This makes it easy - to isolate and debug individual modules without seeing everybody elses - spurious debug output. The keys are stored in the registry under the - HKEY_LOCAL_MACHINE\SOFTWARE\Debug\\ key values - NOTE these must be in the same order as their enumeration definition */ - -TCHAR *pKeyNames[] = { - TEXT("TIMING"), // Timing and performance measurements - TEXT("TRACE"), // General step point call tracing - TEXT("MEMORY"), // Memory and object allocation/destruction - TEXT("LOCKING"), // Locking/unlocking of critical sections - TEXT("ERROR"), // Debug error notification - TEXT("CUSTOM1"), - TEXT("CUSTOM2"), - TEXT("CUSTOM3"), - TEXT("CUSTOM4"), - TEXT("CUSTOM5") - }; - -const TCHAR CAutoTrace::_szEntering[] = TEXT("->: %s"); -const TCHAR CAutoTrace::_szLeaving[] = TEXT("<-: %s"); - -const INT iMAXLEVELS = NUMELMS(pKeyNames); // Maximum debug categories - -HINSTANCE m_hInst; // Module instance handle -TCHAR m_ModuleName[iDEBUGINFO]; // Cut down module name -DWORD m_Levels[iMAXLEVELS]; // Debug level per category -CRITICAL_SECTION m_CSDebug; // Controls access to list -DWORD m_dwNextCookie; // Next active object ID -ObjectDesc *pListHead = NULL; // First active object -DWORD m_dwObjectCount; // Active object count -BOOL m_bInit = FALSE; // Have we been initialised -HANDLE m_hOutput = INVALID_HANDLE_VALUE; // Optional output written here -DWORD dwWaitTimeout = INFINITE; // Default timeout value -DWORD dwTimeOffset; // Time of first DbgLog call -bool g_fUseKASSERT = false; // don't create messagebox -bool g_fDbgInDllEntryPoint = false; -bool g_fAutoRefreshLevels = false; - -const TCHAR *pBaseKey = TEXT("SOFTWARE\\Debug"); -const TCHAR *pGlobalKey = TEXT("GLOBAL"); -static CHAR *pUnknownName = "UNKNOWN"; - -TCHAR *TimeoutName = TEXT("TIMEOUT"); - -/* This sets the instance handle that the debug library uses to find - the module's file name from the Win32 GetModuleFileName function */ - -void WINAPI DbgInitialise(HINSTANCE hInst) -{ - InitializeCriticalSection(&m_CSDebug); - m_bInit = TRUE; - - m_hInst = hInst; - DbgInitModuleName(); - if (GetProfileInt(m_ModuleName, TEXT("BreakOnLoad"), 0)) - DebugBreak(); - DbgInitModuleSettings(false); - DbgInitGlobalSettings(true); - dwTimeOffset = timeGetTime(); -} - - -/* This is called to clear up any resources the debug library uses - at the - moment we delete our critical section and the object list. The values we - retrieve from the registry are all done during initialisation but we don't - go looking for update notifications while we are running, if the values - are changed then the application has to be restarted to pick them up */ - -void WINAPI DbgTerminate() -{ - if (m_hOutput != INVALID_HANDLE_VALUE) { - EXECUTE_ASSERT(CloseHandle(m_hOutput)); - m_hOutput = INVALID_HANDLE_VALUE; - } - DeleteCriticalSection(&m_CSDebug); - m_bInit = FALSE; -} - - -/* This is called by DbgInitLogLevels to read the debug settings - for each logging category for this module from the registry */ - -void WINAPI DbgInitKeyLevels(HKEY hKey, bool fTakeMax) -{ - LONG lReturn; // Create key return value - LONG lKeyPos; // Current key category - DWORD dwKeySize; // Size of the key value - DWORD dwKeyType; // Receives it's type - DWORD dwKeyValue; // This fields value - - /* Try and read a value for each key position in turn */ - for (lKeyPos = 0;lKeyPos < iMAXLEVELS;lKeyPos++) { - - dwKeySize = sizeof(DWORD); - lReturn = RegQueryValueEx( - hKey, // Handle to an open key - pKeyNames[lKeyPos], // Subkey name derivation - NULL, // Reserved field - &dwKeyType, // Returns the field type - (LPBYTE) &dwKeyValue, // Returns the field's value - &dwKeySize ); // Number of bytes transferred - - /* If either the key was not available or it was not a DWORD value - then we ensure only the high priority debug logging is output - but we try and update the field to a zero filled DWORD value */ - - if (lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD) { - - dwKeyValue = 0; - lReturn = RegSetValueEx( - hKey, // Handle of an open key - pKeyNames[lKeyPos], // Address of subkey name - (DWORD) 0, // Reserved field - REG_DWORD, // Type of the key field - (PBYTE) &dwKeyValue, // Value for the field - sizeof(DWORD)); // Size of the field buffer - - if (lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not create subkey %s"),pKeyNames[lKeyPos])); - dwKeyValue = 0; - } - } - if(fTakeMax) - { - m_Levels[lKeyPos] = max(dwKeyValue,m_Levels[lKeyPos]); - } - else - { - if((m_Levels[lKeyPos] & LOG_FORCIBLY_SET) == 0) { - m_Levels[lKeyPos] = dwKeyValue; - } - } - } - - /* Read the timeout value for catching hangs */ - dwKeySize = sizeof(DWORD); - lReturn = RegQueryValueEx( - hKey, // Handle to an open key - TimeoutName, // Subkey name derivation - NULL, // Reserved field - &dwKeyType, // Returns the field type - (LPBYTE) &dwWaitTimeout, // Returns the field's value - &dwKeySize ); // Number of bytes transferred - - /* If either the key was not available or it was not a DWORD value - then we ensure only the high priority debug logging is output - but we try and update the field to a zero filled DWORD value */ - - if (lReturn != ERROR_SUCCESS || dwKeyType != REG_DWORD) { - - dwWaitTimeout = INFINITE; - lReturn = RegSetValueEx( - hKey, // Handle of an open key - TimeoutName, // Address of subkey name - (DWORD) 0, // Reserved field - REG_DWORD, // Type of the key field - (PBYTE) &dwWaitTimeout, // Value for the field - sizeof(DWORD)); // Size of the field buffer - - if (lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not create subkey %s"),TimeoutName)); - dwWaitTimeout = INFINITE; - } - } -} - -void WINAPI DbgOutString(LPCTSTR psz) -{ - if (m_hOutput != INVALID_HANDLE_VALUE) { - UINT cb = lstrlen(psz); - DWORD dw; -#ifdef UNICODE - CHAR szDest[2048]; - WideCharToMultiByte(CP_ACP, 0, psz, -1, szDest, NUMELMS(szDest), 0, 0); - WriteFile (m_hOutput, szDest, cb, &dw, NULL); -#else - WriteFile (m_hOutput, psz, cb, &dw, NULL); -#endif - } else { - OutputDebugString (psz); - } -} - -/* Called by DbgInitGlobalSettings to setup alternate logging destinations - */ - -void WINAPI DbgInitLogTo ( - HKEY hKey) -{ - LONG lReturn; - DWORD dwKeyType; - DWORD dwKeySize; - TCHAR szFile[MAX_PATH] = {0}; - static const TCHAR cszKey[] = TEXT("LogToFile"); - - dwKeySize = MAX_PATH; - lReturn = RegQueryValueEx( - hKey, // Handle to an open key - cszKey, // Subkey name derivation - NULL, // Reserved field - &dwKeyType, // Returns the field type - (LPBYTE) szFile, // Returns the field's value - &dwKeySize); // Number of bytes transferred - - // create an empty key if it does not already exist - // - if (lReturn != ERROR_SUCCESS || dwKeyType != REG_SZ) - { - dwKeySize = sizeof(TCHAR); - lReturn = RegSetValueEx( - hKey, // Handle of an open key - cszKey, // Address of subkey name - (DWORD) 0, // Reserved field - REG_SZ, // Type of the key field - (PBYTE)szFile, // Value for the field - dwKeySize); // Size of the field buffer - } - - // if an output-to was specified. try to open it. - // - if (m_hOutput != INVALID_HANDLE_VALUE) { - EXECUTE_ASSERT(CloseHandle (m_hOutput)); - m_hOutput = INVALID_HANDLE_VALUE; - } - if (szFile[0] != 0) - { - if (!lstrcmpi(szFile, TEXT("Console"))) { - m_hOutput = GetStdHandle (STD_OUTPUT_HANDLE); - if (m_hOutput == INVALID_HANDLE_VALUE) { - AllocConsole (); - m_hOutput = GetStdHandle (STD_OUTPUT_HANDLE); - } - SetConsoleTitle (TEXT("ActiveX Debug Output")); - } else if (szFile[0] && - lstrcmpi(szFile, TEXT("Debug")) && - lstrcmpi(szFile, TEXT("Debugger")) && - lstrcmpi(szFile, TEXT("Deb"))) - { - m_hOutput = CreateFile(szFile, GENERIC_WRITE, - FILE_SHARE_READ, - NULL, OPEN_ALWAYS, - FILE_ATTRIBUTE_NORMAL, - NULL); - if (INVALID_HANDLE_VALUE != m_hOutput) - { - static const TCHAR cszBar[] = TEXT("\r\n\r\n=====DbgInitialize()=====\r\n\r\n"); - SetFilePointer (m_hOutput, 0, NULL, FILE_END); - DbgOutString (cszBar); - } - } - } -} - - - -/* This is called by DbgInitLogLevels to read the global debug settings for - each logging category for this module from the registry. Normally each - module has it's own values set for it's different debug categories but - setting the global SOFTWARE\Debug\Global applies them to ALL modules */ - -void WINAPI DbgInitGlobalSettings(bool fTakeMax) -{ - LONG lReturn; // Create key return value - TCHAR szInfo[iDEBUGINFO]; // Constructs key names - HKEY hGlobalKey; // Global override key - - /* Construct the global base key name */ - (void)StringCchPrintf(szInfo,NUMELMS(szInfo),TEXT("%s\\%s"),pBaseKey,pGlobalKey); - - /* Create or open the key for this module */ - lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE, // Handle of an open key - szInfo, // Address of subkey name - (DWORD) 0, // Reserved value - NULL, // Address of class name - (DWORD) 0, // Special options flags - KEY_ALL_ACCESS, // Desired security access - NULL, // Key security descriptor - &hGlobalKey, // Opened handle buffer - NULL); // What really happened - - if (lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not access GLOBAL module key"))); - return; - } - - DbgInitKeyLevels(hGlobalKey, fTakeMax); - RegCloseKey(hGlobalKey); -} - - -/* This sets the debugging log levels for the different categories. We start - by opening (or creating if not already available) the SOFTWARE\Debug key - that all these settings live under. We then look at the global values - set under SOFTWARE\Debug\Global which apply on top of the individual - module settings. We then load the individual module registry settings */ - -void WINAPI DbgInitModuleSettings(bool fTakeMax) -{ - LONG lReturn; // Create key return value - TCHAR szInfo[iDEBUGINFO]; // Constructs key names - HKEY hModuleKey; // Module key handle - - /* Construct the base key name */ - (void)StringCchPrintf(szInfo,NUMELMS(szInfo), TEXT("%s\\%s"),pBaseKey,m_ModuleName); - - /* Create or open the key for this module */ - lReturn = RegCreateKeyEx(HKEY_LOCAL_MACHINE, // Handle of an open key - szInfo, // Address of subkey name - (DWORD) 0, // Reserved value - NULL, // Address of class name - (DWORD) 0, // Special options flags - KEY_ALL_ACCESS, // Desired security access - NULL, // Key security descriptor - &hModuleKey, // Opened handle buffer - NULL); // What really happened - - if (lReturn != ERROR_SUCCESS) { - DbgLog((LOG_ERROR,0,TEXT("Could not access module key"))); - return; - } - - DbgInitLogTo(hModuleKey); - DbgInitKeyLevels(hModuleKey, fTakeMax); - RegCloseKey(hModuleKey); -} - - -/* Initialise the module file name */ - -void WINAPI DbgInitModuleName() -{ - TCHAR FullName[iDEBUGINFO]; // Load the full path and module name - TCHAR *pName; // Searches from the end for a backslash - - GetModuleFileName(m_hInst,FullName,iDEBUGINFO); - pName = _tcsrchr(FullName,'\\'); - if (pName == NULL) { - pName = FullName; - } else { - pName++; - } - (void)StringCchCopy(m_ModuleName,NUMELMS(m_ModuleName), pName); -} - -struct MsgBoxMsg -{ - HWND hwnd; - TCHAR *szTitle; - TCHAR *szMessage; - DWORD dwFlags; - INT iResult; -}; - -// -// create a thread to call MessageBox(). calling MessageBox() on -// random threads at bad times can confuse the host (eg IE). -// -DWORD WINAPI MsgBoxThread( - LPVOID lpParameter // thread data - ) -{ - MsgBoxMsg *pmsg = (MsgBoxMsg *)lpParameter; - pmsg->iResult = MessageBox( - pmsg->hwnd, - pmsg->szTitle, - pmsg->szMessage, - pmsg->dwFlags); - - return 0; -} - -INT MessageBoxOtherThread( - HWND hwnd, - TCHAR *szTitle, - TCHAR *szMessage, - DWORD dwFlags) -{ - if(g_fDbgInDllEntryPoint) - { - // can't wait on another thread because we have the loader - // lock held in the dll entry point. - return MessageBox(hwnd, szTitle, szMessage, dwFlags); - } - else - { - MsgBoxMsg msg = {hwnd, szTitle, szMessage, dwFlags, 0}; - DWORD dwid; - HANDLE hThread = CreateThread( - 0, // security - 0, // stack size - MsgBoxThread, - (void *)&msg, // arg - 0, // flags - &dwid); - if(hThread) - { - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - return msg.iResult; - } - - // break into debugger on failure. - return IDCANCEL; - } -} - -/* Displays a message box if the condition evaluated to FALSE */ - -void WINAPI DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine) -{ - if(g_fUseKASSERT) - { - DbgKernelAssert(pCondition, pFileName, iLine); - } - else - { - - TCHAR szInfo[iDEBUGINFO]; - - (void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("%s \nAt line %d of %s\nContinue? (Cancel to debug)"), - pCondition, iLine, pFileName); - - INT MsgId = MessageBoxOtherThread(NULL,szInfo,TEXT("ASSERT Failed"), - MB_SYSTEMMODAL | - MB_ICONHAND | - MB_YESNOCANCEL | - MB_SETFOREGROUND); - switch (MsgId) - { - case IDNO: /* Kill the application */ - - FatalAppExit(FALSE, TEXT("Application terminated")); - break; - - case IDCANCEL: /* Break into the debugger */ - - DebugBreak(); - break; - - case IDYES: /* Ignore assertion continue execution */ - break; - } - } -} - -/* Displays a message box at a break point */ - -void WINAPI DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine) -{ - if(g_fUseKASSERT) - { - DbgKernelAssert(pCondition, pFileName, iLine); - } - else - { - TCHAR szInfo[iDEBUGINFO]; - - (void)StringCchPrintf(szInfo, NUMELMS(szInfo), TEXT("%s \nAt line %d of %s\nContinue? (Cancel to debug)"), - pCondition, iLine, pFileName); - - INT MsgId = MessageBoxOtherThread(NULL,szInfo,TEXT("Hard coded break point"), - MB_SYSTEMMODAL | - MB_ICONHAND | - MB_YESNOCANCEL | - MB_SETFOREGROUND); - switch (MsgId) - { - case IDNO: /* Kill the application */ - - FatalAppExit(FALSE, TEXT("Application terminated")); - break; - - case IDCANCEL: /* Break into the debugger */ - - DebugBreak(); - break; - - case IDYES: /* Ignore break point continue execution */ - break; - } - } -} - -void WINAPI DbgBreakPoint(const TCHAR *pFileName,INT iLine,const TCHAR* szFormatString,...) -{ - // A debug break point message can have at most 2000 characters if - // ANSI or UNICODE characters are being used. A debug break point message - // can have between 1000 and 2000 double byte characters in it. If a - // particular message needs more characters, then the value of this constant - // should be increased. - const DWORD MAX_BREAK_POINT_MESSAGE_SIZE = 2000; - - TCHAR szBreakPointMessage[MAX_BREAK_POINT_MESSAGE_SIZE]; - - const DWORD MAX_CHARS_IN_BREAK_POINT_MESSAGE = sizeof(szBreakPointMessage) / sizeof(TCHAR); - - va_list va; - va_start( va, szFormatString ); - - HRESULT hr = StringCchVPrintf( szBreakPointMessage, MAX_CHARS_IN_BREAK_POINT_MESSAGE, szFormatString, va ); - - va_end(va); - - if( S_OK != hr ) { - DbgBreak( "ERROR in DbgBreakPoint(). The variable length debug message could not be displayed because _vsnprintf() failed." ); - return; - } - - ::DbgBreakPoint( szBreakPointMessage, pFileName, iLine ); -} - - -/* When we initialised the library we stored in the m_Levels array the current - debug output level for this module for each of the five categories. When - some debug logging is sent to us it can be sent with a combination of the - categories (if it is applicable to many for example) in which case we map - the type's categories into their current debug levels and see if any of - them can be accepted. The function looks at each bit position in turn from - the input type field and then compares it's debug level with the modules. - - A level of 0 means that output is always sent to the debugger. This is - due to producing output if the input level is <= m_Levels. -*/ - - -BOOL WINAPI DbgCheckModuleLevel(DWORD Type,DWORD Level) -{ - if(g_fAutoRefreshLevels) - { - // re-read the registry every second. We cannot use RegNotify() to - // notice registry changes because it's not available on win9x. - static DWORD g_dwLastRefresh = 0; - DWORD dwTime = timeGetTime(); - if(dwTime - g_dwLastRefresh > 1000) { - g_dwLastRefresh = dwTime; - - // there's a race condition: multiple threads could update the - // values. plus read and write not synchronized. no harm - // though. - DbgInitModuleSettings(false); - } - } - - - DWORD Mask = 0x01; - - // If no valid bits are set return FALSE - if ((Type & ((1<m_szName = szObjectName; - pObject->m_wszName = wszObjectName; - pObject->m_dwCookie = ++m_dwNextCookie; - pObject->m_pNext = pListHead; - - pListHead = pObject; - m_dwObjectCount++; - - DWORD ObjectCookie = pObject->m_dwCookie; - ASSERT(ObjectCookie); - - if(wszObjectName) { - DbgLog((LOG_MEMORY,2,TEXT("Object created %d (%ls) %d Active"), - pObject->m_dwCookie, wszObjectName, m_dwObjectCount)); - } else { - DbgLog((LOG_MEMORY,2,TEXT("Object created %d (%hs) %d Active"), - pObject->m_dwCookie, szObjectName, m_dwObjectCount)); - } - - LeaveCriticalSection(&m_CSDebug); - return ObjectCookie; -} - - -/* This is called by the CBaseObject destructor when an object is about to be - destroyed, we are passed the cookie we returned during construction that - identifies this object. We scan the object list for a matching cookie and - remove the object if successful. We also update the active object count */ - -BOOL WINAPI DbgRegisterObjectDestruction(DWORD dwCookie) -{ - /* Grab the list critical section */ - EnterCriticalSection(&m_CSDebug); - - ObjectDesc *pObject = pListHead; - ObjectDesc *pPrevious = NULL; - - /* Scan the object list looking for a cookie match */ - - while (pObject) { - if (pObject->m_dwCookie == dwCookie) { - break; - } - pPrevious = pObject; - pObject = pObject->m_pNext; - } - - if (pObject == NULL) { - DbgBreak("Apparently destroying a bogus object"); - LeaveCriticalSection(&m_CSDebug); - return FALSE; - } - - /* Is the object at the head of the list */ - - if (pPrevious == NULL) { - pListHead = pObject->m_pNext; - } else { - pPrevious->m_pNext = pObject->m_pNext; - } - - /* Delete the object and update the housekeeping information */ - - m_dwObjectCount--; - - if(pObject->m_wszName) { - DbgLog((LOG_MEMORY,2,TEXT("Object destroyed %d (%ls) %d Active"), - pObject->m_dwCookie, pObject->m_wszName, m_dwObjectCount)); - } else { - DbgLog((LOG_MEMORY,2,TEXT("Object destroyed %d (%hs) %d Active"), - pObject->m_dwCookie, pObject->m_szName, m_dwObjectCount)); - } - - delete pObject; - LeaveCriticalSection(&m_CSDebug); - return TRUE; -} - - -/* This runs through the active object list displaying their details */ - -void WINAPI DbgDumpObjectRegister() -{ - TCHAR szInfo[iDEBUGINFO]; - - /* Grab the list critical section */ - - EnterCriticalSection(&m_CSDebug); - ObjectDesc *pObject = pListHead; - - /* Scan the object list displaying the name and cookie */ - - DbgLog((LOG_MEMORY,2,TEXT(""))); - DbgLog((LOG_MEMORY,2,TEXT(" ID Object Description"))); - DbgLog((LOG_MEMORY,2,TEXT(""))); - - while (pObject) { - if(pObject->m_wszName) { - #ifdef UNICODE - LPCTSTR FORMAT_STRING = TEXT("%5d (%8x) %30s"); - #else - LPCTSTR FORMAT_STRING = TEXT("%5d (%8x) %30S"); - #endif - - (void)StringCchPrintf(szInfo,NUMELMS(szInfo), FORMAT_STRING, pObject->m_dwCookie, &pObject, pObject->m_wszName); - - } else { - #ifdef UNICODE - LPCTSTR FORMAT_STRING = TEXT("%5d (%8x) %30S"); - #else - LPCTSTR FORMAT_STRING = TEXT("%5d (%8x) %30s"); - #endif - - (void)StringCchPrintf(szInfo,NUMELMS(szInfo),FORMAT_STRING,pObject->m_dwCookie, &pObject, pObject->m_szName); - } - DbgLog((LOG_MEMORY,2,szInfo)); - pObject = pObject->m_pNext; - } - - (void)StringCchPrintf(szInfo,NUMELMS(szInfo),TEXT("Total object count %5d"),m_dwObjectCount); - DbgLog((LOG_MEMORY,2,TEXT(""))); - DbgLog((LOG_MEMORY,1,szInfo)); - LeaveCriticalSection(&m_CSDebug); -} - -/* Debug infinite wait stuff */ -DWORD WINAPI DbgWaitForSingleObject(HANDLE h) -{ - DWORD dwWaitResult; - do { - dwWaitResult = WaitForSingleObject(h, dwWaitTimeout); - ASSERT(dwWaitResult == WAIT_OBJECT_0); - } while (dwWaitResult == WAIT_TIMEOUT); - return dwWaitResult; -} -DWORD WINAPI DbgWaitForMultipleObjects(DWORD nCount, - CONST HANDLE *lpHandles, - BOOL bWaitAll) -{ - DWORD dwWaitResult; - do { - dwWaitResult = WaitForMultipleObjects(nCount, - lpHandles, - bWaitAll, - dwWaitTimeout); - ASSERT((DWORD)(dwWaitResult - WAIT_OBJECT_0) < MAXIMUM_WAIT_OBJECTS); - } while (dwWaitResult == WAIT_TIMEOUT); - return dwWaitResult; -} - -void WINAPI DbgSetWaitTimeout(DWORD dwTimeout) -{ - dwWaitTimeout = dwTimeout; -} - -#endif /* DEBUG */ - -#ifdef _OBJBASE_H_ - - /* Stuff for printing out our GUID names */ - - GUID_STRING_ENTRY g_GuidNames[] = { - #define OUR_GUID_ENTRY(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ - { #name, { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } } }, - #include - }; - - CGuidNameList GuidNames; - int g_cGuidNames = sizeof(g_GuidNames) / sizeof(g_GuidNames[0]); - - char *CGuidNameList::operator [] (const GUID &guid) - { - for (int i = 0; i < g_cGuidNames; i++) { - if (g_GuidNames[i].guid == guid) { - return g_GuidNames[i].szName; - } - } - if (guid == GUID_NULL) { - return "GUID_NULL"; - } - - // !!! add something to print FOURCC guids? - - // shouldn't this print the hex CLSID? - return "Unknown GUID Name"; - } - -#endif /* _OBJBASE_H_ */ - -/* CDisp class - display our data types */ - -// clashes with REFERENCE_TIME -CDisp::CDisp(LONGLONG ll, int Format) -{ - // note: this could be combined with CDisp(LONGLONG) by - // introducing a default format of CDISP_REFTIME - LARGE_INTEGER li; - li.QuadPart = ll; - switch (Format) { - case CDISP_DEC: - { - TCHAR temp[20]; - int pos=20; - temp[--pos] = 0; - int digit; - // always output at least one digit - do { - // Get the rightmost digit - we only need the low word - digit = li.LowPart % 10; - li.QuadPart /= 10; - temp[--pos] = (TCHAR) digit+L'0'; - } while (li.QuadPart); - (void)StringCchPrintf(m_String, NUMELMS(m_String), TEXT("%s"), temp+pos); - break; - } - case CDISP_HEX: - default: - (void)StringCchPrintf(m_String, NUMELMS(m_String), TEXT("0x%X%8.8X"), li.HighPart, li.LowPart); - } -}; - -CDisp::CDisp(REFCLSID clsid) -{ - WCHAR strClass[CHARS_IN_GUID+1]; - StringFromGUID2(clsid, strClass, sizeof(strClass) / sizeof(strClass[0])); - ASSERT(sizeof(m_String)/sizeof(m_String[0]) >= CHARS_IN_GUID+1); - #ifdef UNICODE - (void)StringCchPrintf(m_String, NUMELMS(m_String), TEXT("%s"), strClass); - #else - (void)StringCchPrintf(m_String, NUMELMS(m_String), TEXT("%S"), strClass); - #endif -}; - -#ifdef __STREAMS__ -/* Display stuff */ -CDisp::CDisp(CRefTime llTime) -{ - LPTSTR lpsz = m_String; - size_t len = NUMELMS(m_String); - LONGLONG llDiv; - if (llTime < 0) { - llTime = -llTime; - (void)StringCchPrintf(lpsz, len, TEXT("-")); - size_t t = lstrlen(lpsz); - lpsz += t; - len -= t; - } - llDiv = (LONGLONG)24 * 3600 * 10000000; - if (llTime >= llDiv) { - (void)StringCchPrintf(lpsz, len, TEXT("%d days "), (LONG)(llTime / llDiv)); - size_t t = lstrlen(lpsz); - lpsz += t; - len -= t; - llTime = llTime % llDiv; - } - llDiv = (LONGLONG)3600 * 10000000; - if (llTime >= llDiv) { - (void)StringCchPrintf(lpsz, len, TEXT("%d hrs "), (LONG)(llTime / llDiv)); - size_t t = lstrlen(lpsz); - lpsz += t; - len -= t; - llTime = llTime % llDiv; - } - llDiv = (LONGLONG)60 * 10000000; - if (llTime >= llDiv) { - (void)StringCchPrintf(lpsz, len, TEXT("%d mins "), (LONG)(llTime / llDiv)); - size_t t = lstrlen(lpsz); - lpsz += t; - len -= t; - llTime = llTime % llDiv; - } - (void)StringCchPrintf(lpsz, len, TEXT("%d.%3.3d sec"), - (LONG)llTime / 10000000, - (LONG)((llTime % 10000000) / 10000)); -}; - -#endif // __STREAMS__ - - -/* Display pin */ -CDisp::CDisp(IPin *pPin) -{ - PIN_INFO pi; - TCHAR str[MAX_PIN_NAME]; - CLSID clsid; - - if (pPin) { - pPin->QueryPinInfo(&pi); - pi.pFilter->GetClassID(&clsid); - QueryPinInfoReleaseFilter(pi); - #ifndef UNICODE - WideCharToMultiByte(GetACP(), 0, pi.achName, lstrlenW(pi.achName) + 1, - str, MAX_PIN_NAME, NULL, NULL); - #else - (void)StringCchCopy(str, NUMELMS(str), pi.achName); - #endif - } else { - (void)StringCchCopy(str, NUMELMS(str), TEXT("NULL IPin")); - } - - size_t len = lstrlen(str)+64; - m_pString = (PTCHAR) new TCHAR[len]; - if (!m_pString) { - return; - } - - #ifdef UNICODE - LPCTSTR FORMAT_STRING = TEXT("%S(%s)"); - #else - LPCTSTR FORMAT_STRING = TEXT("%s(%s)"); - #endif - - (void)StringCchPrintf(m_pString, len, FORMAT_STRING, GuidNames[clsid], str); -} - -/* Display filter or pin */ -CDisp::CDisp(IUnknown *pUnk) -{ - IBaseFilter *pf; - HRESULT hr = pUnk->QueryInterface(IID_IBaseFilter, (void **)&pf); - if(SUCCEEDED(hr)) - { - FILTER_INFO fi; - hr = pf->QueryFilterInfo(&fi); - if(SUCCEEDED(hr)) - { - QueryFilterInfoReleaseGraph(fi); - - size_t len = lstrlenW(fi.achName) + 1; - m_pString = new TCHAR[len]; - if(m_pString) - { - #ifdef UNICODE - LPCTSTR FORMAT_STRING = TEXT("%s"); - #else - LPCTSTR FORMAT_STRING = TEXT("%S"); - #endif - - (void)StringCchPrintf(m_pString, len, FORMAT_STRING, fi.achName); - } - } - - pf->Release(); - - return; - } - - IPin *pp; - hr = pUnk->QueryInterface(IID_IPin, (void **)&pp); - if(SUCCEEDED(hr)) - { - CDisp::CDisp(pp); - pp->Release(); - return; - } -} - - -CDisp::~CDisp() -{ -} - -CDispBasic::~CDispBasic() -{ - if (m_pString != m_String) { - delete [] m_pString; - } -} - -CDisp::CDisp(double d) -{ -#ifdef DEBUG - (void)StringCchPrintf(m_String, NUMELMS(m_String), TEXT("%.16g"), d); -#else - (void)StringCchPrintf(m_String, NUMELMS(m_String), TEXT("%d.%03d"), (int) d, (int) ((d - (int) d) * 1000)); -#endif -} - - -/* If built for debug this will display the media type details. We convert the - major and subtypes into strings and also ask the base classes for a string - description of the subtype, so MEDIASUBTYPE_RGB565 becomes RGB 565 16 bit - We also display the fields in the BITMAPINFOHEADER structure, this should - succeed as we do not accept input types unless the format is big enough */ - -#ifdef DEBUG -void WINAPI DisplayType(LPTSTR label, const AM_MEDIA_TYPE *pmtIn) -{ - - /* Dump the GUID types and a short description */ - - DbgLog((LOG_TRACE,5,TEXT(""))); - DbgLog((LOG_TRACE,2,TEXT("%s M type %hs S type %hs"), label, - GuidNames[pmtIn->majortype], - GuidNames[pmtIn->subtype])); - DbgLog((LOG_TRACE,5,TEXT("Subtype description %s"),GetSubtypeName(&pmtIn->subtype))); - - /* Dump the generic media types */ - - if (pmtIn->bTemporalCompression) { - DbgLog((LOG_TRACE,5,TEXT("Temporally compressed"))); - } else { - DbgLog((LOG_TRACE,5,TEXT("Not temporally compressed"))); - } - - if (pmtIn->bFixedSizeSamples) { - DbgLog((LOG_TRACE,5,TEXT("Sample size %d"),pmtIn->lSampleSize)); - } else { - DbgLog((LOG_TRACE,5,TEXT("Variable size samples"))); - } - - if (pmtIn->formattype == FORMAT_VideoInfo) { - /* Dump the contents of the BITMAPINFOHEADER structure */ - BITMAPINFOHEADER *pbmi = HEADER(pmtIn->pbFormat); - VIDEOINFOHEADER *pVideoInfo = (VIDEOINFOHEADER *)pmtIn->pbFormat; - - DbgLog((LOG_TRACE,5,TEXT("Source rectangle (Left %d Top %d Right %d Bottom %d)"), - pVideoInfo->rcSource.left, - pVideoInfo->rcSource.top, - pVideoInfo->rcSource.right, - pVideoInfo->rcSource.bottom)); - - DbgLog((LOG_TRACE,5,TEXT("Target rectangle (Left %d Top %d Right %d Bottom %d)"), - pVideoInfo->rcTarget.left, - pVideoInfo->rcTarget.top, - pVideoInfo->rcTarget.right, - pVideoInfo->rcTarget.bottom)); - - DbgLog((LOG_TRACE,5,TEXT("Size of BITMAPINFO structure %d"),pbmi->biSize)); - if (pbmi->biCompression < 256) { - DbgLog((LOG_TRACE,2,TEXT("%dx%dx%d bit (%d)"), - pbmi->biWidth, pbmi->biHeight, - pbmi->biBitCount, pbmi->biCompression)); - } else { - DbgLog((LOG_TRACE,2,TEXT("%dx%dx%d bit '%4.4hs'"), - pbmi->biWidth, pbmi->biHeight, - pbmi->biBitCount, &pbmi->biCompression)); - } - - DbgLog((LOG_TRACE,2,TEXT("Image size %d"),pbmi->biSizeImage)); - DbgLog((LOG_TRACE,5,TEXT("Planes %d"),pbmi->biPlanes)); - DbgLog((LOG_TRACE,5,TEXT("X Pels per metre %d"),pbmi->biXPelsPerMeter)); - DbgLog((LOG_TRACE,5,TEXT("Y Pels per metre %d"),pbmi->biYPelsPerMeter)); - DbgLog((LOG_TRACE,5,TEXT("Colours used %d"),pbmi->biClrUsed)); - - } else if (pmtIn->majortype == MEDIATYPE_Audio) { - DbgLog((LOG_TRACE,2,TEXT(" Format type %hs"), - GuidNames[pmtIn->formattype])); - DbgLog((LOG_TRACE,2,TEXT(" Subtype %hs"), - GuidNames[pmtIn->subtype])); - - if ((pmtIn->subtype != MEDIASUBTYPE_MPEG1Packet) - && (pmtIn->cbFormat >= sizeof(PCMWAVEFORMAT))) - { - /* Dump the contents of the WAVEFORMATEX type-specific format structure */ - - WAVEFORMATEX *pwfx = (WAVEFORMATEX *) pmtIn->pbFormat; - DbgLog((LOG_TRACE,2,TEXT("wFormatTag %u"), pwfx->wFormatTag)); - DbgLog((LOG_TRACE,2,TEXT("nChannels %u"), pwfx->nChannels)); - DbgLog((LOG_TRACE,2,TEXT("nSamplesPerSec %lu"), pwfx->nSamplesPerSec)); - DbgLog((LOG_TRACE,2,TEXT("nAvgBytesPerSec %lu"), pwfx->nAvgBytesPerSec)); - DbgLog((LOG_TRACE,2,TEXT("nBlockAlign %u"), pwfx->nBlockAlign)); - DbgLog((LOG_TRACE,2,TEXT("wBitsPerSample %u"), pwfx->wBitsPerSample)); - - /* PCM uses a WAVEFORMAT and does not have the extra size field */ - - if (pmtIn->cbFormat >= sizeof(WAVEFORMATEX)) { - DbgLog((LOG_TRACE,2,TEXT("cbSize %u"), pwfx->cbSize)); - } - } else { - } - - } else { - DbgLog((LOG_TRACE,2,TEXT(" Format type %hs"), - GuidNames[pmtIn->formattype])); - // !!!! should add code to dump wave format, others - } -} - - -void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel) -{ - if( !pGraph ) - { - return; - } - - IEnumFilters *pFilters; - - DbgLog((LOG_TRACE,dwLevel,TEXT("DumpGraph [%x]"), pGraph)); - - if (FAILED(pGraph->EnumFilters(&pFilters))) { - DbgLog((LOG_TRACE,dwLevel,TEXT("EnumFilters failed!"))); - } - - IBaseFilter *pFilter; - ULONG n; - while (pFilters->Next(1, &pFilter, &n) == S_OK) { - FILTER_INFO info; - - if (FAILED(pFilter->QueryFilterInfo(&info))) { - DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] -- failed QueryFilterInfo"), pFilter)); - } else { - QueryFilterInfoReleaseGraph(info); - - // !!! should QueryVendorInfo here! - - DbgLog((LOG_TRACE,dwLevel,TEXT(" Filter [%x] '%ls'"), pFilter, info.achName)); - - IEnumPins *pins; - - if (FAILED(pFilter->EnumPins(&pins))) { - DbgLog((LOG_TRACE,dwLevel,TEXT("EnumPins failed!"))); - } else { - - IPin *pPin; - while (pins->Next(1, &pPin, &n) == S_OK) { - PIN_INFO info; - - if (FAILED(pPin->QueryPinInfo(&info))) { - DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] -- failed QueryPinInfo"), pPin)); - } else { - QueryPinInfoReleaseFilter(info); - - IPin *pPinConnected = NULL; - - HRESULT hr = pPin->ConnectedTo(&pPinConnected); - - if (pPinConnected) { - DbgLog((LOG_TRACE,dwLevel,TEXT(" Pin [%x] '%ls' [%sput]") - TEXT(" Connected to pin [%x]"), - pPin, info.achName, - info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"), - pPinConnected)); - - pPinConnected->Release(); - - // perhaps we should really dump the type both ways as a sanity - // check? - if (info.dir == PINDIR_OUTPUT) { - AM_MEDIA_TYPE mt; - - hr = pPin->ConnectionMediaType(&mt); - - if (SUCCEEDED(hr)) { - DisplayType(TEXT("Connection type"), &mt); - - FreeMediaType(mt); - } - } - } else { - DbgLog((LOG_TRACE,dwLevel, - TEXT(" Pin [%x] '%ls' [%sput]"), - pPin, info.achName, - info.dir == PINDIR_INPUT ? TEXT("In") : TEXT("Out"))); - - } - } - - pPin->Release(); - - } - - pins->Release(); - } - - } - - pFilter->Release(); - } - - pFilters->Release(); - -} - -#endif - diff --git a/plugins/gs/gsdx9/baseclasses/wxdebug.h b/plugins/gs/gsdx9/baseclasses/wxdebug.h deleted file mode 100644 index 4c967addaf..0000000000 --- a/plugins/gs/gsdx9/baseclasses/wxdebug.h +++ /dev/null @@ -1,393 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXDebug.h -// -// Desc: DirectShow base classes - provides debugging facilities. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __WXDEBUG__ -#define __WXDEBUG__ - -// This library provides fairly straight forward debugging functionality, this -// is split into two main sections. The first is assertion handling, there are -// three types of assertions provided here. The most commonly used one is the -// ASSERT(condition) macro which will pop up a message box including the file -// and line number if the condition evaluates to FALSE. Then there is the -// EXECUTE_ASSERT macro which is the same as ASSERT except the condition will -// still be executed in NON debug builds. The final type of assertion is the -// KASSERT macro which is more suitable for pure (perhaps kernel) filters as -// the condition is printed onto the debugger rather than in a message box. -// -// The other part of the debug module facilties is general purpose logging. -// This is accessed by calling DbgLog(). The function takes a type and level -// field which define the type of informational string you are presenting and -// it's relative importance. The type field can be a combination (one or more) -// of LOG_TIMING, LOG_TRACE, LOG_MEMORY, LOG_LOCKING and LOG_ERROR. The level -// is a DWORD value where zero defines highest important. Use of zero as the -// debug logging level is to be encouraged ONLY for major errors or events as -// they will ALWAYS be displayed on the debugger. Other debug output has it's -// level matched against the current debug output level stored in the registry -// for this module and if less than the current setting it will be displayed. -// -// Each module or executable has it's own debug output level for each of the -// five types. These are read in when the DbgInitialise function is called -// for DLLs linking to STRMBASE.LIB this is done automatically when the DLL -// is loaded, executables must call it explicitely with the module instance -// handle given to them through the WINMAIN entry point. An executable must -// also call DbgTerminate when they have finished to clean up the resources -// the debug library uses, once again this is done automatically for DLLs - -// These are the five different categories of logging information - -enum { LOG_TIMING = 0x01, // Timing and performance measurements - LOG_TRACE = 0x02, // General step point call tracing - LOG_MEMORY = 0x04, // Memory and object allocation/destruction - LOG_LOCKING = 0x08, // Locking/unlocking of critical sections - LOG_ERROR = 0x10, // Debug error notification - LOG_CUSTOM1 = 0x20, - LOG_CUSTOM2 = 0x40, - LOG_CUSTOM3 = 0x80, - LOG_CUSTOM4 = 0x100, - LOG_CUSTOM5 = 0x200, -}; - -#define LOG_FORCIBLY_SET 0x80000000 - -enum { CDISP_HEX = 0x01, - CDISP_DEC = 0x02}; - -// For each object created derived from CBaseObject (in debug builds) we -// create a descriptor that holds it's name (statically allocated memory) -// and a cookie we assign it. We keep a list of all the active objects -// we have registered so that we can dump a list of remaining objects - -typedef struct tag_ObjectDesc { - const CHAR *m_szName; - const WCHAR *m_wszName; - DWORD m_dwCookie; - tag_ObjectDesc *m_pNext; -} ObjectDesc; - -#define DLLIMPORT __declspec(dllimport) -#define DLLEXPORT __declspec(dllexport) - -#ifdef DEBUG - - #define NAME(x) TEXT(x) - - // These are used internally by the debug library (PRIVATE) - - void WINAPI DbgInitKeyLevels(HKEY hKey, bool fTakeMax); - void WINAPI DbgInitGlobalSettings(bool fTakeMax); - void WINAPI DbgInitModuleSettings(bool fTakeMax); - void WINAPI DbgInitModuleName(); - DWORD WINAPI DbgRegisterObjectCreation( - const CHAR *szObjectName, const WCHAR *wszObjectName); - - BOOL WINAPI DbgRegisterObjectDestruction(DWORD dwCookie); - - // These are the PUBLIC entry points - - BOOL WINAPI DbgCheckModuleLevel(DWORD Type,DWORD Level); - void WINAPI DbgSetModuleLevel(DWORD Type,DWORD Level); - void WINAPI DbgSetAutoRefreshLevels(bool fAuto); - - // Initialise the library with the module handle - - void WINAPI DbgInitialise(HINSTANCE hInst); - void WINAPI DbgTerminate(); - - void WINAPI DbgDumpObjectRegister(); - - // Display error and logging to the user - - void WINAPI DbgAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine); - void WINAPI DbgBreakPoint(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine); - void WINAPI DbgBreakPoint(const TCHAR *pFileName,INT iLine,const TCHAR* szFormatString,...); - - void WINAPI DbgKernelAssert(const TCHAR *pCondition,const TCHAR *pFileName,INT iLine); - void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const TCHAR *pFormat,...); -#ifdef UNICODE - void WINAPI DbgLogInfo(DWORD Type,DWORD Level,const CHAR *pFormat,...); - void WINAPI DbgAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine); - void WINAPI DbgBreakPoint(const CHAR *pCondition,const CHAR *pFileName,INT iLine); - void WINAPI DbgKernelAssert(const CHAR *pCondition,const CHAR *pFileName,INT iLine); -#endif - void WINAPI DbgOutString(LPCTSTR psz); - - // Debug infinite wait stuff - DWORD WINAPI DbgWaitForSingleObject(HANDLE h); - DWORD WINAPI DbgWaitForMultipleObjects(DWORD nCount, - CONST HANDLE *lpHandles, - BOOL bWaitAll); - void WINAPI DbgSetWaitTimeout(DWORD dwTimeout); - -#ifdef __strmif_h__ - // Display a media type: Terse at level 2, verbose at level 5 - void WINAPI DisplayType(LPTSTR label, const AM_MEDIA_TYPE *pmtIn); - - // Dump lots of information about a filter graph - void WINAPI DumpGraph(IFilterGraph *pGraph, DWORD dwLevel); -#endif - - #define KASSERT(_x_) if (!(_x_)) \ - DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__) - - // Break on the debugger without putting up a message box - // message goes to debugger instead - - #define KDbgBreak(_x_) \ - DbgKernelAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__) - - // We chose a common name for our ASSERT macro, MFC also uses this name - // So long as the implementation evaluates the condition and handles it - // then we will be ok. Rather than override the behaviour expected we - // will leave whatever first defines ASSERT as the handler (i.e. MFC) - #ifndef ASSERT - #define ASSERT(_x_) if (!(_x_)) \ - DbgAssert(TEXT(#_x_),TEXT(__FILE__),__LINE__) - #endif - - #define DbgAssertAligned( _ptr_, _alignment_ ) ASSERT( ((DWORD_PTR) (_ptr_)) % (_alignment_) == 0) - - // Put up a message box informing the user of a halt - // condition in the program - - #define DbgBreak(_x_) \ - DbgBreakPoint(TEXT(#_x_),TEXT(__FILE__),__LINE__) - - #define EXECUTE_ASSERT(_x_) ASSERT(_x_) - #define DbgLog(_x_) DbgLogInfo _x_ - // MFC style trace macros - - #define NOTE(_x_) DbgLog((LOG_TRACE,5,TEXT(_x_))) - #define NOTE1(_x_,a) DbgLog((LOG_TRACE,5,TEXT(_x_),a)) - #define NOTE2(_x_,a,b) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b)) - #define NOTE3(_x_,a,b,c) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c)) - #define NOTE4(_x_,a,b,c,d) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d)) - #define NOTE5(_x_,a,b,c,d,e) DbgLog((LOG_TRACE,5,TEXT(_x_),a,b,c,d,e)) - -#else - - // Retail builds make public debug functions inert - WARNING the source - // files do not define or build any of the entry points in debug builds - // (public entry points compile to nothing) so if you go trying to call - // any of the private entry points in your source they won't compile - - #define NAME(_x_) ((TCHAR *) NULL) - - #define DbgInitialise(hInst) - #define DbgTerminate() - #define DbgLog(_x_) 0 - #define DbgOutString(psz) - #define DbgAssertAligned( _ptr_, _alignment_ ) 0 - - #define DbgRegisterObjectCreation(pObjectName) - #define DbgRegisterObjectDestruction(dwCookie) - #define DbgDumpObjectRegister() - - #define DbgCheckModuleLevel(Type,Level) - #define DbgSetModuleLevel(Type,Level) - #define DbgSetAutoRefreshLevels(fAuto) - - #define DbgWaitForSingleObject(h) WaitForSingleObject(h, INFINITE) - #define DbgWaitForMultipleObjects(nCount, lpHandles, bWaitAll) \ - WaitForMultipleObjects(nCount, lpHandles, bWaitAll, INFINITE) - #define DbgSetWaitTimeout(dwTimeout) - - #define KDbgBreak(_x_) - #define DbgBreak(_x_) - - #define KASSERT(_x_) ((void)0) - #ifndef ASSERT - #define ASSERT(_x_) ((void)0) - #endif - #define EXECUTE_ASSERT(_x_) ((void)(_x_)) - - // MFC style trace macros - - #define NOTE(_x_) ((void)0) - #define NOTE1(_x_,a) ((void)0) - #define NOTE2(_x_,a,b) ((void)0) - #define NOTE3(_x_,a,b,c) ((void)0) - #define NOTE4(_x_,a,b,c,d) ((void)0) - #define NOTE5(_x_,a,b,c,d,e) ((void)0) - - #define DisplayType(label, pmtIn) ((void)0) - #define DumpGraph(pGraph, label) ((void)0) -#endif - - -// Checks a pointer which should be non NULL - can be used as follows. - -#define CheckPointer(p,ret) {if((p)==NULL) return (ret);} - -// HRESULT Foo(VOID *pBar) -// { -// CheckPointer(pBar,E_INVALIDARG) -// } -// -// Or if the function returns a boolean -// -// BOOL Foo(VOID *pBar) -// { -// CheckPointer(pBar,FALSE) -// } - -// These validate pointers when symbol VFWROBUST is defined -// This will normally be defined in debug not retail builds - -#ifdef DEBUG - #define VFWROBUST -#endif - -#ifdef VFWROBUST - - #define ValidateReadPtr(p,cb) \ - {if(IsBadReadPtr((PVOID)p,cb) == TRUE) \ - DbgBreak("Invalid read pointer");} - - #define ValidateWritePtr(p,cb) \ - {if(IsBadWritePtr((PVOID)p,cb) == TRUE) \ - DbgBreak("Invalid write pointer");} - - #define ValidateReadWritePtr(p,cb) \ - {ValidateReadPtr(p,cb) ValidateWritePtr(p,cb)} - - #define ValidateStringPtr(p) \ - {if(IsBadStringPtr((LPCTSTR)p,INFINITE) == TRUE) \ - DbgBreak("Invalid string pointer");} - - #define ValidateStringPtrA(p) \ - {if(IsBadStringPtrA((LPCSTR)p,INFINITE) == TRUE) \ - DbgBreak("Invalid ANSI string pointer");} - - #define ValidateStringPtrW(p) \ - {if(IsBadStringPtrW((LPCWSTR)p,INFINITE) == TRUE) \ - DbgBreak("Invalid UNICODE string pointer");} - -#else - #define ValidateReadPtr(p,cb) 0 - #define ValidateWritePtr(p,cb) 0 - #define ValidateReadWritePtr(p,cb) 0 - #define ValidateStringPtr(p) 0 - #define ValidateStringPtrA(p) 0 - #define ValidateStringPtrW(p) 0 -#endif - - -#ifdef _OBJBASE_H_ - - // Outputting GUID names. If you want to include the name - // associated with a GUID (eg CLSID_...) then - // - // GuidNames[yourGUID] - // - // Returns the name defined in uuids.h as a string - - typedef struct { - CHAR *szName; - GUID guid; - } GUID_STRING_ENTRY; - - class CGuidNameList { - public: - CHAR *operator [] (const GUID& guid); - }; - - extern CGuidNameList GuidNames; - -#endif - -#ifndef REMIND - // REMIND macro - generates warning as reminder to complete coding - // (eg) usage: - // - // #pragma message (REMIND("Add automation support")) - - - #define QUOTE(x) #x - #define QQUOTE(y) QUOTE(y) - #define REMIND(str) __FILE__ "(" QQUOTE(__LINE__) ") : " str -#endif - -// Method to display objects in a useful format -// -// eg If you want to display a LONGLONG ll in a debug string do (eg) -// -// DbgLog((LOG_TRACE, n, TEXT("Value is %s"), (LPCTSTR)CDisp(ll, CDISP_HEX))); - - -class CDispBasic -{ -public: - CDispBasic() { m_pString = m_String; }; - ~CDispBasic(); -protected: - PTCHAR m_pString; // normally points to m_String... unless too much data - TCHAR m_String[50]; -}; -class CDisp : public CDispBasic -{ -public: - CDisp(LONGLONG ll, int Format = CDISP_HEX); // Display a LONGLONG in CDISP_HEX or CDISP_DEC form - CDisp(REFCLSID clsid); // Display a GUID - CDisp(double d); // Display a floating point number -#ifdef __strmif_h__ -#ifdef __STREAMS__ - CDisp(CRefTime t); // Display a Reference Time -#endif - CDisp(IPin *pPin); // Display a pin as {filter clsid}(pin name) - CDisp(IUnknown *pUnk); // Display a filter or pin -#endif // __strmif_h__ - ~CDisp(); - - // Implement cast to (LPCTSTR) as parameter to logger - operator LPCTSTR() - { - return (LPCTSTR)m_pString; - }; -}; - - -#if defined(DEBUG) -class CAutoTrace -{ -private: - const TCHAR* _szBlkName; - const int _level; - static const TCHAR _szEntering[]; - static const TCHAR _szLeaving[]; -public: - CAutoTrace(const TCHAR* szBlkName, const int level = 15) - : _szBlkName(szBlkName), _level(level) - {DbgLog((LOG_TRACE, _level, _szEntering, _szBlkName));} - - ~CAutoTrace() - {DbgLog((LOG_TRACE, _level, _szLeaving, _szBlkName));} -}; - -#if defined (__FUNCTION__) - -#define AMTRACEFN() CAutoTrace __trace(TEXT(__FUNCTION__)) -#define AMTRACE(_x_) CAutoTrace __trace(TEXT(__FUNCTION__)) - -#else - -#define AMTRACE(_x_) CAutoTrace __trace _x_ -#define AMTRACEFN() - -#endif - -#else - -#define AMTRACE(_x_) -#define AMTRACEFN() - -#endif - -#endif // __WXDEBUG__ - - diff --git a/plugins/gs/gsdx9/baseclasses/wxlist.cpp b/plugins/gs/gsdx9/baseclasses/wxlist.cpp deleted file mode 100644 index e44a813616..0000000000 --- a/plugins/gs/gsdx9/baseclasses/wxlist.cpp +++ /dev/null @@ -1,885 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXList.cpp -// -// Desc: DirectShow base classes - implements a non-MFC based generic list -// template class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* A generic list of pointers to objects. - Objectives: avoid using MFC libraries in ndm kernel mode and - provide a really useful list type. - - The class is thread safe in that separate threads may add and - delete items in the list concurrently although the application - must ensure that constructor and destructor access is suitably - synchronised. - - The list name must not conflict with MFC classes as an - application may use both - - The nodes form a doubly linked, NULL terminated chain with an anchor - block (the list object per se) holding pointers to the first and last - nodes and a count of the nodes. - There is a node cache to reduce the allocation and freeing overhead. - It optionally (determined at construction time) has an Event which is - set whenever the list becomes non-empty and reset whenever it becomes - empty. - It optionally (determined at construction time) has a Critical Section - which is entered during the important part of each operation. (About - all you can do outside it is some parameter checking). - - The node cache is a repository of nodes that are NOT in the list to speed - up storage allocation. Each list has its own cache to reduce locking and - serialising. The list accesses are serialised anyway for a given list - a - common cache would mean that we would have to separately serialise access - of all lists within the cache. Because the cache only stores nodes that are - not in the list, releasing the cache does not release any list nodes. This - means that list nodes can be copied or rechained from one list to another - without danger of creating a dangling reference if the original cache goes - away. - - Questionable design decisions: - 1. Retaining the warts for compatibility - 2. Keeping an element count -i.e. counting whenever we do anything - instead of only when we want the count. - 3. Making the chain pointers NULL terminated. If the list object - itself looks just like a node and the list is kept as a ring then - it reduces the number of special cases. All inserts look the same. -*/ - - -#include - -/* set cursor to the position of each element of list in turn */ -#define INTERNALTRAVERSELIST(list, cursor) \ -for ( cursor = (list).GetHeadPositionI() \ - ; cursor!=NULL \ - ; cursor = (list).Next(cursor) \ - ) - - -/* set cursor to the position of each element of list in turn - in reverse order -*/ -#define INTERNALREVERSETRAVERSELIST(list, cursor) \ -for ( cursor = (list).GetTailPositionI() \ - ; cursor!=NULL \ - ; cursor = (list).Prev(cursor) \ - ) - -/* Constructor calls a separate initialisation function that - creates a node cache, optionally creates a lock object - and optionally creates a signaling object. - - By default we create a locking object, a DEFAULTCACHE sized - cache but no event object so the list cannot be used in calls - to WaitForSingleObject -*/ -CBaseList::CBaseList(TCHAR *pName, // Descriptive list name - INT iItems) : // Node cache size -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(iItems) -{ -} // constructor - -CBaseList::CBaseList(TCHAR *pName) : // Descriptive list name -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(DEFAULTCACHE) -{ -} // constructor - -#ifdef UNICODE -CBaseList::CBaseList(CHAR *pName, // Descriptive list name - INT iItems) : // Node cache size -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(iItems) -{ -} // constructor - -CBaseList::CBaseList(CHAR *pName) : // Descriptive list name -#ifdef DEBUG - CBaseObject(pName), -#endif - m_pFirst(NULL), - m_pLast(NULL), - m_Count(0), - m_Cache(DEFAULTCACHE) -{ -} // constructor - -#endif - -/* The destructor enumerates all the node objects in the list and - in the cache deleting each in turn. We do not do any processing - on the objects that the list holds (i.e. points to) so if they - represent interfaces for example the creator of the list should - ensure that each of them is released before deleting us -*/ -CBaseList::~CBaseList() -{ - /* Delete all our list nodes */ - - RemoveAll(); - -} // destructor - -/* Remove all the nodes from the list but don't do anything - with the objects that each node looks after (this is the - responsibility of the creator). - Aa a last act we reset the signalling event - (if available) to indicate to clients that the list - does not have any entries in it. -*/ -void CBaseList::RemoveAll() -{ - /* Free up all the CNode objects NOTE we don't bother putting the - deleted nodes into the cache as this method is only really called - in serious times of change such as when we are being deleted at - which point the cache will be deleted anway */ - - CNode *pn = m_pFirst; - while (pn) { - CNode *op = pn; - pn = pn->Next(); - delete op; - } - - /* Reset the object count and the list pointers */ - - m_Count = 0; - m_pFirst = m_pLast = NULL; - -} // RemoveAll - - - -/* Return a position enumerator for the entire list. - A position enumerator is a pointer to a node object cast to a - transparent type so all we do is return the head/tail node - pointer in the list. - WARNING because the position is a pointer to a node there is - an implicit assumption for users a the list class that after - deleting an object from the list that any other position - enumerators that you have may be invalid (since the node - may be gone). -*/ -WXLIST_POSITION CBaseList::GetHeadPositionI() const -{ - return (WXLIST_POSITION) m_pFirst; -} // GetHeadPosition - - - -WXLIST_POSITION CBaseList::GetTailPositionI() const -{ - return (WXLIST_POSITION) m_pLast; -} // GetTailPosition - - - -/* Get the number of objects in the list, - Get the lock before accessing the count. - Locking may not be entirely necessary but it has the side effect - of making sure that all operations are complete before we get it. - So for example if a list is being added to this list then that - will have completed in full before we continue rather than seeing - an intermediate albeit valid state -*/ -int CBaseList::GetCountI() const -{ - return m_Count; -} // GetCount - - - -/* Return the object at rp, update rp to the next object from - the list or NULL if you have moved over the last object. - You may still call this function once we return NULL but - we will continue to return a NULL position value -*/ -void *CBaseList::GetNextI(WXLIST_POSITION& rp) const -{ - /* have we reached the end of the list */ - - if (rp == NULL) { - return NULL; - } - - /* Lock the object before continuing */ - - void *pObject; - - /* Copy the original position then step on */ - - CNode *pn = (CNode *) rp; - ASSERT(pn != NULL); - rp = (WXLIST_POSITION) pn->Next(); - - /* Get the object at the original position from the list */ - - pObject = pn->GetData(); - // ASSERT(pObject != NULL); // NULL pointers in the list are allowed. - return pObject; -} //GetNext - - - -/* Return the object at p. - Asking for the object at NULL ASSERTs then returns NULL - The object is NOT locked. The list is not being changed - in any way. If another thread is busy deleting the object - then locking would only result in a change from one bad - behaviour to another. -*/ -void *CBaseList::GetI(WXLIST_POSITION p) const -{ - if (p == NULL) { - return NULL; - } - - CNode * pn = (CNode *) p; - void *pObject = pn->GetData(); - // ASSERT(pObject != NULL); // NULL pointers in the list are allowed. - return pObject; -} //Get - - - -/* Return the first position in the list which holds the given pointer. - Return NULL if it's not found. -*/ -WXLIST_POSITION CBaseList::FindI( void * pObj) const -{ - WXLIST_POSITION pn; - INTERNALTRAVERSELIST(*this, pn){ - if (GetI(pn)==pObj) { - return pn; - } - } - return NULL; -} // Find - - - -/* Remove the first node in the list (deletes the pointer to its object - from the list, does not free the object itself). - Return the pointer to its object or NULL if empty -*/ -void *CBaseList::RemoveHeadI() -{ - /* All we do is get the head position and ask for that to be deleted. - We could special case this since some of the code path checking - in Remove() is redundant as we know there is no previous - node for example but it seems to gain little over the - added complexity - */ - - return RemoveI((WXLIST_POSITION)m_pFirst); -} // RemoveHead - - - -/* Remove the last node in the list (deletes the pointer to its object - from the list, does not free the object itself). - Return the pointer to its object or NULL if empty -*/ -void *CBaseList::RemoveTailI() -{ - /* All we do is get the tail position and ask for that to be deleted. - We could special case this since some of the code path checking - in Remove() is redundant as we know there is no previous - node for example but it seems to gain little over the - added complexity - */ - - return RemoveI((WXLIST_POSITION)m_pLast); -} // RemoveTail - - - -/* Remove the pointer to the object in this position from the list. - Deal with all the chain pointers - Return a pointer to the object removed from the list. - The node object that is freed as a result - of this operation is added to the node cache where - it can be used again. - Remove(NULL) is a harmless no-op - but probably is a wart. -*/ -void *CBaseList::RemoveI(WXLIST_POSITION pos) -{ - /* Lock the critical section before continuing */ - - // ASSERT (pos!=NULL); // Removing NULL is to be harmless! - if (pos==NULL) return NULL; - - - CNode *pCurrent = (CNode *) pos; - ASSERT(pCurrent != NULL); - - /* Update the previous node */ - - CNode *pNode = pCurrent->Prev(); - if (pNode == NULL) { - m_pFirst = pCurrent->Next(); - } else { - pNode->SetNext(pCurrent->Next()); - } - - /* Update the following node */ - - pNode = pCurrent->Next(); - if (pNode == NULL) { - m_pLast = pCurrent->Prev(); - } else { - pNode->SetPrev(pCurrent->Prev()); - } - - /* Get the object this node was looking after */ - - void *pObject = pCurrent->GetData(); - - // ASSERT(pObject != NULL); // NULL pointers in the list are allowed. - - /* Try and add the node object to the cache - - a NULL return code from the cache means we ran out of room. - The cache size is fixed by a constructor argument when the - list is created and defaults to DEFAULTCACHE. - This means that the cache will have room for this many - node objects. So if you have a list of media samples - and you know there will never be more than five active at - any given time of them for example then override the default - constructor - */ - - m_Cache.AddToCache(pCurrent); - - /* If the list is empty then reset the list event */ - - --m_Count; - ASSERT(m_Count >= 0); - return pObject; -} // Remove - - - -/* Add this object to the tail end of our list - Return the new tail position. -*/ - -WXLIST_POSITION CBaseList::AddTailI(void *pObject) -{ - /* Lock the critical section before continuing */ - - CNode *pNode; - // ASSERT(pObject); // NULL pointers in the list are allowed. - - /* If there is a node objects in the cache then use - that otherwise we will have to create a new one */ - - pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObject); - pNode->SetNext(NULL); - pNode->SetPrev(m_pLast); - - if (m_pLast == NULL) { - m_pFirst = pNode; - } else { - m_pLast->SetNext(pNode); - } - - /* Set the new last node pointer and also increment the number - of list entries, the critical section is unlocked when we - exit the function - */ - - m_pLast = pNode; - ++m_Count; - - return (WXLIST_POSITION) pNode; -} // AddTail(object) - - - -/* Add this object to the head end of our list - Return the new head position. -*/ -WXLIST_POSITION CBaseList::AddHeadI(void *pObject) -{ - CNode *pNode; - // ASSERT(pObject); // NULL pointers in the list are allowed. - - /* If there is a node objects in the cache then use - that otherwise we will have to create a new one */ - - pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObject); - - /* chain it in (set four pointers) */ - pNode->SetPrev(NULL); - pNode->SetNext(m_pFirst); - - if (m_pFirst == NULL) { - m_pLast = pNode; - } else { - m_pFirst->SetPrev(pNode); - } - m_pFirst = pNode; - - ++m_Count; - - return (WXLIST_POSITION) pNode; -} // AddHead(object) - - - -/* Add all the elements in *pList to the tail of this list. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some elements may have been added. -*/ -BOOL CBaseList::AddTail(CBaseList *pList) -{ - /* lock the object before starting then enumerate - each entry in the source list and add them one by one to - our list (while still holding the object lock) - Lock the other list too. - */ - WXLIST_POSITION pos = pList->GetHeadPositionI(); - - while (pos) { - if (NULL == AddTailI(pList->GetNextI(pos))) { - return FALSE; - } - } - return TRUE; -} // AddTail(list) - - - -/* Add all the elements in *pList to the head of this list. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some elements may have been added. -*/ -BOOL CBaseList::AddHead(CBaseList *pList) -{ - /* lock the object before starting then enumerate - each entry in the source list and add them one by one to - our list (while still holding the object lock) - Lock the other list too. - - To avoid reversing the list, traverse it backwards. - */ - - WXLIST_POSITION pos; - - INTERNALREVERSETRAVERSELIST(*pList, pos) { - if (NULL== AddHeadI(pList->GetI(pos))){ - return FALSE; - } - } - return TRUE; -} // AddHead(list) - - - -/* Add the object after position p - p is still valid after the operation. - AddAfter(NULL,x) adds x to the start - same as AddHead - Return the position of the new object, NULL if it failed -*/ -WXLIST_POSITION CBaseList::AddAfterI(WXLIST_POSITION pos, void * pObj) -{ - if (pos==NULL) - return AddHeadI(pObj); - - /* As someone else might be furkling with the list - - Lock the critical section before continuing - */ - CNode *pAfter = (CNode *) pos; - ASSERT(pAfter != NULL); - if (pAfter==m_pLast) - return AddTailI(pObj); - - /* set pnode to point to a new node, preferably from the cache */ - - CNode *pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObj); - - /* It is to be added to the middle of the list - there is a before - and after node. Chain it after pAfter, before pBefore. - */ - CNode * pBefore = pAfter->Next(); - ASSERT(pBefore != NULL); - - /* chain it in (set four pointers) */ - pNode->SetPrev(pAfter); - pNode->SetNext(pBefore); - pBefore->SetPrev(pNode); - pAfter->SetNext(pNode); - - ++m_Count; - - return (WXLIST_POSITION) pNode; - -} // AddAfter(object) - - - -BOOL CBaseList::AddAfter(WXLIST_POSITION p, CBaseList *pList) -{ - WXLIST_POSITION pos; - INTERNALTRAVERSELIST(*pList, pos) { - /* p follows along the elements being added */ - p = AddAfterI(p, pList->GetI(pos)); - if (p==NULL) return FALSE; - } - return TRUE; -} // AddAfter(list) - - - -/* Mirror images: - Add the element or list after position p. - p is still valid after the operation. - AddBefore(NULL,x) adds x to the end - same as AddTail -*/ -WXLIST_POSITION CBaseList::AddBeforeI(WXLIST_POSITION pos, void * pObj) -{ - if (pos==NULL) - return AddTailI(pObj); - - /* set pnode to point to a new node, preferably from the cache */ - - CNode *pBefore = (CNode *) pos; - ASSERT(pBefore != NULL); - if (pBefore==m_pFirst) - return AddHeadI(pObj); - - CNode * pNode = (CNode *) m_Cache.RemoveFromCache(); - if (pNode == NULL) { - pNode = new CNode; - } - - /* Check we have a valid object */ - - if (pNode == NULL) { - return NULL; - } - - /* Initialise all the CNode object - just in case it came from the cache - */ - - pNode->SetData(pObj); - - /* It is to be added to the middle of the list - there is a before - and after node. Chain it after pAfter, before pBefore. - */ - - CNode * pAfter = pBefore->Prev(); - ASSERT(pAfter != NULL); - - /* chain it in (set four pointers) */ - pNode->SetPrev(pAfter); - pNode->SetNext(pBefore); - pBefore->SetPrev(pNode); - pAfter->SetNext(pNode); - - ++m_Count; - - return (WXLIST_POSITION) pNode; - -} // Addbefore(object) - - - -BOOL CBaseList::AddBefore(WXLIST_POSITION p, CBaseList *pList) -{ - WXLIST_POSITION pos; - INTERNALREVERSETRAVERSELIST(*pList, pos) { - /* p follows along the elements being added */ - p = AddBeforeI(p, pList->GetI(pos)); - if (p==NULL) return FALSE; - } - return TRUE; -} // AddBefore(list) - - - -/* Split *this after position p in *this - Retain as *this the tail portion of the original *this - Add the head portion to the tail end of *pList - Return TRUE if it all worked, FALSE if it didn't. - - e.g. - foo->MoveToTail(foo->GetHeadPosition(), bar); - moves one element from the head of foo to the tail of bar - foo->MoveToTail(NULL, bar); - is a no-op - foo->MoveToTail(foo->GetTailPosition, bar); - concatenates foo onto the end of bar and empties foo. - - A better, except excessively long name might be - MoveElementsFromHeadThroughPositionToOtherTail -*/ -BOOL CBaseList::MoveToTail - (WXLIST_POSITION pos, CBaseList *pList) -{ - /* Algorithm: - Note that the elements (including their order) in the concatenation - of *pList to the head of *this is invariant. - 1. Count elements to be moved - 2. Join *pList onto the head of this to make one long chain - 3. Set first/Last pointers in *this and *pList - 4. Break the chain at the new place - 5. Adjust counts - 6. Set/Reset any events - */ - - if (pos==NULL) return TRUE; // no-op. Eliminates special cases later. - - - /* Make cMove the number of nodes to move */ - CNode * p = (CNode *)pos; - int cMove = 0; // number of nodes to move - while(p!=NULL) { - p = p->Prev(); - ++cMove; - } - - - /* Join the two chains together */ - if (pList->m_pLast!=NULL) - pList->m_pLast->SetNext(m_pFirst); - if (m_pFirst!=NULL) - m_pFirst->SetPrev(pList->m_pLast); - - - /* set first and last pointers */ - p = (CNode *)pos; - - if (pList->m_pFirst==NULL) - pList->m_pFirst = m_pFirst; - m_pFirst = p->Next(); - if (m_pFirst==NULL) - m_pLast = NULL; - pList->m_pLast = p; - - - /* Break the chain after p to create the new pieces */ - if (m_pFirst!=NULL) - m_pFirst->SetPrev(NULL); - p->SetNext(NULL); - - - /* Adjust the counts */ - m_Count -= cMove; - pList->m_Count += cMove; - - return TRUE; - -} // MoveToTail - - - -/* Mirror image of MoveToTail: - Split *this before position p in *this. - Retain in *this the head portion of the original *this - Add the tail portion to the start (i.e. head) of *pList - Return TRUE if it all worked, FALSE if it didn't. - - e.g. - foo->MoveToHead(foo->GetTailPosition(), bar); - moves one element from the tail of foo to the head of bar - foo->MoveToHead(NULL, bar); - is a no-op - foo->MoveToHead(foo->GetHeadPosition, bar); - concatenates foo onto the start of bar and empties foo. -*/ -BOOL CBaseList::MoveToHead - (WXLIST_POSITION pos, CBaseList *pList) -{ - - /* See the comments on the algorithm in MoveToTail */ - - if (pos==NULL) return TRUE; // no-op. Eliminates special cases later. - - /* Make cMove the number of nodes to move */ - CNode * p = (CNode *)pos; - int cMove = 0; // number of nodes to move - while(p!=NULL) { - p = p->Next(); - ++cMove; - } - - - /* Join the two chains together */ - if (pList->m_pFirst!=NULL) - pList->m_pFirst->SetPrev(m_pLast); - if (m_pLast!=NULL) - m_pLast->SetNext(pList->m_pFirst); - - - /* set first and last pointers */ - p = (CNode *)pos; - - - if (pList->m_pLast==NULL) - pList->m_pLast = m_pLast; - - m_pLast = p->Prev(); - if (m_pLast==NULL) - m_pFirst = NULL; - pList->m_pFirst = p; - - - /* Break the chain after p to create the new pieces */ - if (m_pLast!=NULL) - m_pLast->SetNext(NULL); - p->SetPrev(NULL); - - - /* Adjust the counts */ - m_Count -= cMove; - pList->m_Count += cMove; - - return TRUE; - -} // MoveToHead - - - -/* Reverse the order of the [pointers to] objects in *this -*/ -void CBaseList::Reverse() -{ - /* algorithm: - The obvious booby trap is that you flip pointers around and lose - addressability to the node that you are going to process next. - The easy way to avoid this is do do one chain at a time. - - Run along the forward chain, - For each node, set the reverse pointer to the one ahead of us. - The reverse chain is now a copy of the old forward chain, including - the NULL termination. - - Run along the reverse chain (i.e. old forward chain again) - For each node set the forward pointer of the node ahead to point back - to the one we're standing on. - The first node needs special treatment, - it's new forward pointer is NULL. - Finally set the First/Last pointers - - */ - CNode * p; - - // Yes we COULD use a traverse, but it would look funny! - p = m_pFirst; - while (p!=NULL) { - CNode * q; - q = p->Next(); - p->SetNext(p->Prev()); - p->SetPrev(q); - p = q; - } - - p = m_pFirst; - m_pFirst = m_pLast; - m_pLast = p; - - -#if 0 // old version - - if (m_pFirst==NULL) return; // empty list - if (m_pFirst->Next()==NULL) return; // single node list - - - /* run along forward chain */ - for ( p = m_pFirst - ; p!=NULL - ; p = p->Next() - ){ - p->SetPrev(p->Next()); - } - - - /* special case first element */ - m_pFirst->SetNext(NULL); // fix the old first element - - - /* run along new reverse chain i.e. old forward chain again */ - for ( p = m_pFirst // start at the old first element - ; p->Prev()!=NULL // while there's a node still to be set - ; p = p->Prev() // work in the same direction as before - ){ - p->Prev()->SetNext(p); - } - - - /* fix forward and reverse pointers - - the triple XOR swap would work but all the casts look hideous */ - p = m_pFirst; - m_pFirst = m_pLast; - m_pLast = p; -#endif - -} // Reverse diff --git a/plugins/gs/gsdx9/baseclasses/wxlist.h b/plugins/gs/gsdx9/baseclasses/wxlist.h deleted file mode 100644 index 3c268c3258..0000000000 --- a/plugins/gs/gsdx9/baseclasses/wxlist.h +++ /dev/null @@ -1,543 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXList.h -// -// Desc: DirectShow base classes - defines a non-MFC generic template list -// class. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -/* A generic list of pointers to objects. - No storage management or copying is done on the objects pointed to. - Objectives: avoid using MFC libraries in ndm kernel mode and - provide a really useful list type. - - The class is thread safe in that separate threads may add and - delete items in the list concurrently although the application - must ensure that constructor and destructor access is suitably - synchronised. An application can cause deadlock with operations - which use two lists by simultaneously calling - list1->Operation(list2) and list2->Operation(list1). So don't! - - The names must not conflict with MFC classes as an application - may use both. - */ - -#ifndef __WXLIST__ -#define __WXLIST__ - - /* A POSITION represents (in some fashion that's opaque) a cursor - on the list that can be set to identify any element. NULL is - a valid value and several operations regard NULL as the position - "one step off the end of the list". (In an n element list there - are n+1 places to insert and NULL is that "n+1-th" value). - The POSITION of an element in the list is only invalidated if - that element is deleted. Move operations may mean that what - was a valid POSITION in one list is now a valid POSITION in - a different list. - - Some operations which at first sight are illegal are allowed as - harmless no-ops. For instance RemoveHead is legal on an empty - list and it returns NULL. This allows an atomic way to test if - there is an element there, and if so, get it. The two operations - AddTail and RemoveHead thus implement a MONITOR (See Hoare's paper). - - Single element operations return POSITIONs, non-NULL means it worked. - whole list operations return a BOOL. TRUE means it all worked. - - This definition is the same as the POSITION type for MFCs, so we must - avoid defining it twice. - */ -struct __WXLIST_POSITION { int unused; }; -typedef __WXLIST_POSITION* WXLIST_POSITION; - -const int DEFAULTCACHE = 10; /* Default node object cache size */ - -/* A class representing one node in a list. - Each node knows a pointer to it's adjacent nodes and also a pointer - to the object that it looks after. - All of these pointers can be retrieved or set through member functions. -*/ -class CBaseList -#ifdef DEBUG - : public CBaseObject -#endif -{ - /* Making these classes inherit from CBaseObject does nothing - functionally but it allows us to check there are no memory - leaks in debug builds. - */ - -public: - -#ifdef DEBUG - class CNode : public CBaseObject { -#else - class CNode { -#endif - - CNode *m_pPrev; /* Previous node in the list */ - CNode *m_pNext; /* Next node in the list */ - void *m_pObject; /* Pointer to the object */ - - public: - - /* Constructor - initialise the object's pointers */ - CNode() -#ifdef DEBUG - : CBaseObject(NAME("List node")) -#endif - { - }; - - - /* Return the previous node before this one */ - CNode *Prev() const { return m_pPrev; }; - - - /* Return the next node after this one */ - CNode *Next() const { return m_pNext; }; - - - /* Set the previous node before this one */ - void SetPrev(CNode *p) { m_pPrev = p; }; - - - /* Set the next node after this one */ - void SetNext(CNode *p) { m_pNext = p; }; - - - /* Get the pointer to the object for this node */ - void *GetData() const { return m_pObject; }; - - - /* Set the pointer to the object for this node */ - void SetData(void *p) { m_pObject = p; }; - }; - - class CNodeCache - { - public: - CNodeCache(INT iCacheSize) : m_iCacheSize(iCacheSize), - m_pHead(NULL), - m_iUsed(0) - {}; - ~CNodeCache() { - CNode *pNode = m_pHead; - while (pNode) { - CNode *pCurrent = pNode; - pNode = pNode->Next(); - delete pCurrent; - } - }; - void AddToCache(CNode *pNode) - { - if (m_iUsed < m_iCacheSize) { - pNode->SetNext(m_pHead); - m_pHead = pNode; - m_iUsed++; - } else { - delete pNode; - } - }; - CNode *RemoveFromCache() - { - CNode *pNode = m_pHead; - if (pNode != NULL) { - m_pHead = pNode->Next(); - m_iUsed--; - ASSERT(m_iUsed >= 0); - } else { - ASSERT(m_iUsed == 0); - } - return pNode; - }; - private: - INT m_iCacheSize; - INT m_iUsed; - CNode *m_pHead; - }; - -protected: - - CNode* m_pFirst; /* Pointer to first node in the list */ - CNode* m_pLast; /* Pointer to the last node in the list */ - LONG m_Count; /* Number of nodes currently in the list */ - -private: - - CNodeCache m_Cache; /* Cache of unused node pointers */ - -private: - - /* These override the default copy constructor and assignment - operator for all list classes. They are in the private class - declaration section so that anybody trying to pass a list - object by value will generate a compile time error of - "cannot access the private member function". If these were - not here then the compiler will create default constructors - and assignment operators which when executed first take a - copy of all member variables and then during destruction - delete them all. This must not be done for any heap - allocated data. - */ - CBaseList(const CBaseList &refList); - CBaseList &operator=(const CBaseList &refList); - -public: - - CBaseList(TCHAR *pName, - INT iItems); - - CBaseList(TCHAR *pName); -#ifdef UNICODE - CBaseList(CHAR *pName, - INT iItems); - - CBaseList(CHAR *pName); -#endif - ~CBaseList(); - - /* Remove all the nodes from *this i.e. make the list empty */ - void RemoveAll(); - - - /* Return a cursor which identifies the first element of *this */ - WXLIST_POSITION GetHeadPositionI() const; - - - /* Return a cursor which identifies the last element of *this */ - WXLIST_POSITION GetTailPositionI() const; - - - /* Return the number of objects in *this */ - int GetCountI() const; - -protected: - /* Return the pointer to the object at rp, - Update rp to the next node in *this - but make it NULL if it was at the end of *this. - This is a wart retained for backwards compatibility. - GetPrev is not implemented. - Use Next, Prev and Get separately. - */ - void *GetNextI(WXLIST_POSITION& rp) const; - - - /* Return a pointer to the object at p - Asking for the object at NULL will return NULL harmlessly. - */ - void *GetI(WXLIST_POSITION p) const; - -public: - /* return the next / prev position in *this - return NULL when going past the end/start. - Next(NULL) is same as GetHeadPosition() - Prev(NULL) is same as GetTailPosition() - An n element list therefore behaves like a n+1 element - cycle with NULL at the start/end. - - !!WARNING!! - This handling of NULL is DIFFERENT from GetNext. - - Some reasons are: - 1. For a list of n items there are n+1 positions to insert - These are conveniently encoded as the n POSITIONs and NULL. - 2. If you are keeping a list sorted (fairly common) and you - search forward for an element to insert before and don't - find it you finish up with NULL as the element before which - to insert. You then want that NULL to be a valid WXLIST_POSITION - so that you can insert before it and you want that insertion - point to mean the (n+1)-th one that doesn't have a WXLIST_POSITION. - (symmetrically if you are working backwards through the list). - 3. It simplifies the algebra which the methods generate. - e.g. AddBefore(p,x) is identical to AddAfter(Prev(p),x) - in ALL cases. All the other arguments probably are reflections - of the algebraic point. - */ - WXLIST_POSITION Next(WXLIST_POSITION pos) const - { - if (pos == NULL) { - return (WXLIST_POSITION) m_pFirst; - } - CNode *pn = (CNode *) pos; - return (WXLIST_POSITION) pn->Next(); - } //Next - - // See Next - WXLIST_POSITION Prev(WXLIST_POSITION pos) const - { - if (pos == NULL) { - return (WXLIST_POSITION) m_pLast; - } - CNode *pn = (CNode *) pos; - return (WXLIST_POSITION) pn->Prev(); - } //Prev - - - /* Return the first position in *this which holds the given - pointer. Return NULL if the pointer was not not found. - */ -protected: - WXLIST_POSITION FindI( void * pObj) const; - - /* Remove the first node in *this (deletes the pointer to its - object from the list, does not free the object itself). - Return the pointer to its object. - If *this was already empty it will harmlessly return NULL. - */ - void *RemoveHeadI(); - - - /* Remove the last node in *this (deletes the pointer to its - object from the list, does not free the object itself). - Return the pointer to its object. - If *this was already empty it will harmlessly return NULL. - */ - void *RemoveTailI(); - - - /* Remove the node identified by p from the list (deletes the pointer - to its object from the list, does not free the object itself). - Asking to Remove the object at NULL will harmlessly return NULL. - Return the pointer to the object removed. - */ - void *RemoveI(WXLIST_POSITION p); - - /* Add single object *pObj to become a new last element of the list. - Return the new tail position, NULL if it fails. - If you are adding a COM objects, you might want AddRef it first. - Other existing POSITIONs in *this are still valid - */ - WXLIST_POSITION AddTailI(void * pObj); -public: - - - /* Add all the elements in *pList to the tail of *this. - This duplicates all the nodes in *pList (i.e. duplicates - all its pointers to objects). It does not duplicate the objects. - If you are adding a list of pointers to a COM object into the list - it's a good idea to AddRef them all it when you AddTail it. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some elements may have been added. - Existing POSITIONs in *this are still valid - - If you actually want to MOVE the elements, use MoveToTail instead. - */ - BOOL AddTail(CBaseList *pList); - - - /* Mirror images of AddHead: */ - - /* Add single object to become a new first element of the list. - Return the new head position, NULL if it fails. - Existing POSITIONs in *this are still valid - */ -protected: - WXLIST_POSITION AddHeadI(void * pObj); -public: - - /* Add all the elements in *pList to the head of *this. - Same warnings apply as for AddTail. - Return TRUE if it all worked, FALSE if it didn't. - If it fails some of the objects may have been added. - - If you actually want to MOVE the elements, use MoveToHead instead. - */ - BOOL AddHead(CBaseList *pList); - - - /* Add the object *pObj to *this after position p in *this. - AddAfter(NULL,x) adds x to the start - equivalent to AddHead - Return the position of the object added, NULL if it failed. - Existing POSITIONs in *this are undisturbed, including p. - */ -protected: - WXLIST_POSITION AddAfterI(WXLIST_POSITION p, void * pObj); -public: - - /* Add the list *pList to *this after position p in *this - AddAfter(NULL,x) adds x to the start - equivalent to AddHead - Return TRUE if it all worked, FALSE if it didn't. - If it fails, some of the objects may be added - Existing POSITIONs in *this are undisturbed, including p. - */ - BOOL AddAfter(WXLIST_POSITION p, CBaseList *pList); - - - /* Mirror images: - Add the object *pObj to this-List after position p in *this. - AddBefore(NULL,x) adds x to the end - equivalent to AddTail - Return the position of the new object, NULL if it fails - Existing POSITIONs in *this are undisturbed, including p. - */ - protected: - WXLIST_POSITION AddBeforeI(WXLIST_POSITION p, void * pObj); - public: - - /* Add the list *pList to *this before position p in *this - AddAfter(NULL,x) adds x to the start - equivalent to AddHead - Return TRUE if it all worked, FALSE if it didn't. - If it fails, some of the objects may be added - Existing POSITIONs in *this are undisturbed, including p. - */ - BOOL AddBefore(WXLIST_POSITION p, CBaseList *pList); - - - /* Note that AddAfter(p,x) is equivalent to AddBefore(Next(p),x) - even in cases where p is NULL or Next(p) is NULL. - Similarly for mirror images etc. - This may make it easier to argue about programs. - */ - - - - /* The following operations do not copy any elements. - They move existing blocks of elements around by switching pointers. - They are fairly efficient for long lists as for short lists. - (Alas, the Count slows things down). - - They split the list into two parts. - One part remains as the original list, the other part - is appended to the second list. There are eight possible - variations: - Split the list {after/before} a given element - keep the {head/tail} portion in the original list - append the rest to the {head/tail} of the new list. - - Since After is strictly equivalent to Before Next - we are not in serious need of the Before/After variants. - That leaves only four. - - If you are processing a list left to right and dumping - the bits that you have processed into another list as - you go, the Tail/Tail variant gives the most natural result. - If you are processing in reverse order, Head/Head is best. - - By using NULL positions and empty lists judiciously either - of the other two can be built up in two operations. - - The definition of NULL (see Next/Prev etc) means that - degenerate cases include - "move all elements to new list" - "Split a list into two lists" - "Concatenate two lists" - (and quite a few no-ops) - - !!WARNING!! The type checking won't buy you much if you get list - positions muddled up - e.g. use a WXLIST_POSITION that's in a different - list and see what a mess you get! - */ - - /* Split *this after position p in *this - Retain as *this the tail portion of the original *this - Add the head portion to the tail end of *pList - Return TRUE if it all worked, FALSE if it didn't. - - e.g. - foo->MoveToTail(foo->GetHeadPosition(), bar); - moves one element from the head of foo to the tail of bar - foo->MoveToTail(NULL, bar); - is a no-op, returns NULL - foo->MoveToTail(foo->GetTailPosition, bar); - concatenates foo onto the end of bar and empties foo. - - A better, except excessively long name might be - MoveElementsFromHeadThroughPositionToOtherTail - */ - BOOL MoveToTail(WXLIST_POSITION pos, CBaseList *pList); - - - /* Mirror image: - Split *this before position p in *this. - Retain in *this the head portion of the original *this - Add the tail portion to the start (i.e. head) of *pList - - e.g. - foo->MoveToHead(foo->GetTailPosition(), bar); - moves one element from the tail of foo to the head of bar - foo->MoveToHead(NULL, bar); - is a no-op, returns NULL - foo->MoveToHead(foo->GetHeadPosition, bar); - concatenates foo onto the start of bar and empties foo. - */ - BOOL MoveToHead(WXLIST_POSITION pos, CBaseList *pList); - - - /* Reverse the order of the [pointers to] objects in *this - */ - void Reverse(); - - - /* set cursor to the position of each element of list in turn */ - #define TRAVERSELIST(list, cursor) \ - for ( cursor = (list).GetHeadPosition() \ - ; cursor!=NULL \ - ; cursor = (list).Next(cursor) \ - ) - - - /* set cursor to the position of each element of list in turn - in reverse order - */ - #define REVERSETRAVERSELIST(list, cursor) \ - for ( cursor = (list).GetTailPosition() \ - ; cursor!=NULL \ - ; cursor = (list).Prev(cursor) \ - ) - -}; // end of class declaration - -template class CGenericList : public CBaseList -{ -public: - CGenericList(TCHAR *pName, - INT iItems, - BOOL bLock = TRUE, - BOOL bAlert = FALSE) : - CBaseList(pName, iItems) { - UNREFERENCED_PARAMETER(bAlert); - UNREFERENCED_PARAMETER(bLock); - }; - CGenericList(TCHAR *pName) : - CBaseList(pName) { - }; - - WXLIST_POSITION GetHeadPosition() const { return (WXLIST_POSITION)m_pFirst; } - WXLIST_POSITION GetTailPosition() const { return (WXLIST_POSITION)m_pLast; } - int GetCount() const { return m_Count; } - - OBJECT *GetNext(WXLIST_POSITION& rp) const { return (OBJECT *) GetNextI(rp); } - - OBJECT *Get(WXLIST_POSITION p) const { return (OBJECT *) GetI(p); } - OBJECT *GetHead() const { return Get(GetHeadPosition()); } - - OBJECT *RemoveHead() { return (OBJECT *) RemoveHeadI(); } - - OBJECT *RemoveTail() { return (OBJECT *) RemoveTailI(); } - - OBJECT *Remove(WXLIST_POSITION p) { return (OBJECT *) RemoveI(p); } - WXLIST_POSITION AddBefore(WXLIST_POSITION p, OBJECT * pObj) { return AddBeforeI(p, pObj); } - WXLIST_POSITION AddAfter(WXLIST_POSITION p, OBJECT * pObj) { return AddAfterI(p, pObj); } - WXLIST_POSITION AddHead(OBJECT * pObj) { return AddHeadI(pObj); } - WXLIST_POSITION AddTail(OBJECT * pObj) { return AddTailI(pObj); } - BOOL AddTail(CGenericList *pList) - { return CBaseList::AddTail((CBaseList *) pList); } - BOOL AddHead(CGenericList *pList) - { return CBaseList::AddHead((CBaseList *) pList); } - BOOL AddAfter(WXLIST_POSITION p, CGenericList *pList) - { return CBaseList::AddAfter(p, (CBaseList *) pList); }; - BOOL AddBefore(WXLIST_POSITION p, CGenericList *pList) - { return CBaseList::AddBefore(p, (CBaseList *) pList); }; - WXLIST_POSITION Find( OBJECT * pObj) const { return FindI(pObj); } -}; // end of class declaration - - - -/* These define the standard list types */ - -typedef CGenericList CBaseObjectList; -typedef CGenericList CBaseInterfaceList; - -#endif /* __WXLIST__ */ - diff --git a/plugins/gs/gsdx9/baseclasses/wxutil.cpp b/plugins/gs/gsdx9/baseclasses/wxutil.cpp deleted file mode 100644 index fe363fd6d9..0000000000 --- a/plugins/gs/gsdx9/baseclasses/wxutil.cpp +++ /dev/null @@ -1,1240 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXUtil.cpp -// -// Desc: DirectShow base classes - implements helper classes for building -// multimedia filters. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#include - -// -// Declare function from largeint.h we need so that PPC can build -// - -// -// Enlarged integer divide - 64-bits / 32-bits > 32-bits -// - -#ifndef _X86_ - -#define LLtoU64(x) (*(unsigned __int64*)(void*)(&(x))) - -__inline -ULONG -WINAPI -EnlargedUnsignedDivide ( - IN ULARGE_INTEGER Dividend, - IN ULONG Divisor, - IN PULONG Remainder - ) -{ - // return remainder if necessary - if (Remainder != NULL) - *Remainder = (ULONG)(LLtoU64(Dividend) % Divisor); - return (ULONG)(LLtoU64(Dividend) / Divisor); -} - -#else -__inline -ULONG -WINAPI -EnlargedUnsignedDivide ( - IN ULARGE_INTEGER Dividend, - IN ULONG Divisor, - IN PULONG Remainder - ) -{ - ULONG ulResult; - _asm { - mov eax,Dividend.LowPart - mov edx,Dividend.HighPart - mov ecx,Remainder - div Divisor - or ecx,ecx - jz short label - mov [ecx],edx -label: - mov ulResult,eax - } - return ulResult; -} -#endif - -// --- CAMEvent ----------------------- -CAMEvent::CAMEvent(BOOL fManualReset) -{ - m_hEvent = CreateEvent(NULL, fManualReset, FALSE, NULL); -} - -CAMEvent::~CAMEvent() -{ - if (m_hEvent) { - EXECUTE_ASSERT(CloseHandle(m_hEvent)); - } -} - - -// --- CAMMsgEvent ----------------------- -// One routine. The rest is handled in CAMEvent - -BOOL CAMMsgEvent::WaitMsg(DWORD dwTimeout) -{ - // wait for the event to be signalled, or for the - // timeout (in MS) to expire. allow SENT messages - // to be processed while we wait - DWORD dwWait; - DWORD dwStartTime; - - // set the waiting period. - DWORD dwWaitTime = dwTimeout; - - // the timeout will eventually run down as we iterate - // processing messages. grab the start time so that - // we can calculate elapsed times. - if (dwWaitTime != INFINITE) { - dwStartTime = timeGetTime(); - } - - do { - dwWait = MsgWaitForMultipleObjects(1,&m_hEvent,FALSE, dwWaitTime, QS_SENDMESSAGE); - if (dwWait == WAIT_OBJECT_0 + 1) { - MSG Message; - PeekMessage(&Message,NULL,0,0,PM_NOREMOVE); - - // If we have an explicit length of time to wait calculate - // the next wake up point - which might be now. - // If dwTimeout is INFINITE, it stays INFINITE - if (dwWaitTime != INFINITE) { - - DWORD dwElapsed = timeGetTime()-dwStartTime; - - dwWaitTime = - (dwElapsed >= dwTimeout) - ? 0 // wake up with WAIT_TIMEOUT - : dwTimeout-dwElapsed; - } - } - } while (dwWait == WAIT_OBJECT_0 + 1); - - // return TRUE if we woke on the event handle, - // FALSE if we timed out. - return (dwWait == WAIT_OBJECT_0); -} - -// --- CAMThread ---------------------- - - -CAMThread::CAMThread() - : m_EventSend(TRUE) // must be manual-reset for CheckRequest() -{ - m_hThread = NULL; -} - -CAMThread::~CAMThread() { - Close(); -} - - -// when the thread starts, it calls this function. We unwrap the 'this' -//pointer and call ThreadProc. -DWORD WINAPI -CAMThread::InitialThreadProc(LPVOID pv) -{ - HRESULT hrCoInit = CAMThread::CoInitializeHelper(); - if(FAILED(hrCoInit)) { - DbgLog((LOG_ERROR, 1, TEXT("CoInitializeEx failed."))); - } - - CAMThread * pThread = (CAMThread *) pv; - - HRESULT hr = pThread->ThreadProc(); - - if(SUCCEEDED(hrCoInit)) { - CoUninitialize(); - } - - return hr; -} - -BOOL -CAMThread::Create() -{ - DWORD threadid; - - CAutoLock lock(&m_AccessLock); - - if (ThreadExists()) { - return FALSE; - } - - m_hThread = CreateThread( - NULL, - 0, - CAMThread::InitialThreadProc, - this, - 0, - &threadid); - - if (!m_hThread) { - return FALSE; - } - - return TRUE; -} - -DWORD -CAMThread::CallWorker(DWORD dwParam) -{ - // lock access to the worker thread for scope of this object - CAutoLock lock(&m_AccessLock); - - if (!ThreadExists()) { - return (DWORD) E_FAIL; - } - - // set the parameter - m_dwParam = dwParam; - - // signal the worker thread - m_EventSend.Set(); - - // wait for the completion to be signalled - m_EventComplete.Wait(); - - // done - this is the thread's return value - return m_dwReturnVal; -} - -// Wait for a request from the client -DWORD -CAMThread::GetRequest() -{ - m_EventSend.Wait(); - return m_dwParam; -} - -// is there a request? -BOOL -CAMThread::CheckRequest(DWORD * pParam) -{ - if (!m_EventSend.Check()) { - return FALSE; - } else { - if (pParam) { - *pParam = m_dwParam; - } - return TRUE; - } -} - -// reply to the request -void -CAMThread::Reply(DWORD dw) -{ - m_dwReturnVal = dw; - - // The request is now complete so CheckRequest should fail from - // now on - // - // This event should be reset BEFORE we signal the client or - // the client may Set it before we reset it and we'll then - // reset it (!) - - m_EventSend.Reset(); - - // Tell the client we're finished - - m_EventComplete.Set(); -} - -HRESULT CAMThread::CoInitializeHelper() -{ - // call CoInitializeEx and tell OLE not to create a window (this - // thread probably won't dispatch messages and will hang on - // broadcast msgs o/w). - // - // If CoInitEx is not available, threads that don't call CoCreate - // aren't affected. Threads that do will have to handle the - // failure. Perhaps we should fall back to CoInitialize and risk - // hanging? - // - - // older versions of ole32.dll don't have CoInitializeEx - - HRESULT hr = E_FAIL; - HINSTANCE hOle = GetModuleHandle(TEXT("ole32.dll")); - if(hOle) - { - typedef HRESULT (STDAPICALLTYPE *PCoInitializeEx)( - LPVOID pvReserved, DWORD dwCoInit); - PCoInitializeEx pCoInitializeEx = - (PCoInitializeEx)(GetProcAddress(hOle, "CoInitializeEx")); - if(pCoInitializeEx) - { - hr = (*pCoInitializeEx)(0, COINIT_DISABLE_OLE1DDE ); - } - } - else - { - // caller must load ole32.dll - DbgBreak("couldn't locate ole32.dll"); - } - - return hr; -} - - -// destructor for CMsgThread - cleans up any messages left in the -// queue when the thread exited -CMsgThread::~CMsgThread() -{ - if (m_hThread != NULL) { - WaitForSingleObject(m_hThread, INFINITE); - EXECUTE_ASSERT(CloseHandle(m_hThread)); - } - - WXLIST_POSITION pos = m_ThreadQueue.GetHeadPosition(); - while (pos) { - CMsg * pMsg = m_ThreadQueue.GetNext(pos); - delete pMsg; - } - m_ThreadQueue.RemoveAll(); - - if (m_hSem != NULL) { - EXECUTE_ASSERT(CloseHandle(m_hSem)); - } -} - -BOOL -CMsgThread::CreateThread( - ) -{ - m_hSem = CreateSemaphore(NULL, 0, 0x7FFFFFFF, NULL); - if (m_hSem == NULL) { - return FALSE; - } - - m_hThread = ::CreateThread(NULL, 0, DefaultThreadProc, - (LPVOID)this, 0, &m_ThreadId); - return m_hThread != NULL; -} - - -// This is the threads message pump. Here we get and dispatch messages to -// clients thread proc until the client refuses to process a message. -// The client returns a non-zero value to stop the message pump, this -// value becomes the threads exit code. - -DWORD WINAPI -CMsgThread::DefaultThreadProc( - LPVOID lpParam - ) -{ - CMsgThread *lpThis = (CMsgThread *)lpParam; - CMsg msg; - LRESULT lResult; - - // !!! - CoInitialize(NULL); - - // allow a derived class to handle thread startup - lpThis->OnThreadInit(); - - do { - lpThis->GetThreadMsg(&msg); - lResult = lpThis->ThreadMessageProc(msg.uMsg,msg.dwFlags, - msg.lpParam, msg.pEvent); - } while (lResult == 0L); - - // !!! - CoUninitialize(); - - return (DWORD)lResult; -} - - -// Block until the next message is placed on the list m_ThreadQueue. -// copies the message to the message pointed to by *pmsg -void -CMsgThread::GetThreadMsg(CMsg *msg) -{ - CMsg * pmsg = NULL; - - // keep trying until a message appears - while (TRUE) { - { - CAutoLock lck(&m_Lock); - pmsg = m_ThreadQueue.RemoveHead(); - if (pmsg == NULL) { - m_lWaiting++; - } else { - break; - } - } - // the semaphore will be signalled when it is non-empty - WaitForSingleObject(m_hSem, INFINITE); - } - // copy fields to caller's CMsg - *msg = *pmsg; - - // this CMsg was allocated by the 'new' in PutThreadMsg - delete pmsg; - -} - - -// NOTE: as we need to use the same binaries on Win95 as on NT this code should -// be compiled WITHOUT unicode being defined. Otherwise we will not pick up -// these internal routines and the binary will not run on Win95. - -#ifndef UNICODE -// Windows 95 doesn't implement this, so we provide an implementation. -// LPWSTR -// WINAPI -// lstrcpyWInternal( -// LPWSTR lpString1, -// LPCWSTR lpString2 -// ) -// { -// LPWSTR lpReturn = lpString1; -// while (*lpString1++ = *lpString2++); -// -// return lpReturn; -// } - -// Windows 95 doesn't implement this, so we provide an implementation. -LPWSTR -WINAPI -lstrcpynWInternal( - LPWSTR lpString1, - LPCWSTR lpString2, - int iMaxLength - ) -{ - ASSERT(iMaxLength); - LPWSTR lpReturn = lpString1; - if (iMaxLength) { - while (--iMaxLength && (*lpString1++ = *lpString2++)); - - // If we ran out of room (which will be the case if - // iMaxLength is now 0) we still need to terminate the - // string. - if (!iMaxLength) *lpString1 = L'\0'; - } - return lpReturn; -} - -int -WINAPI -lstrcmpWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) -{ - do { - WCHAR c1 = *lpString1; - WCHAR c2 = *lpString2; - if (c1 != c2) - return (int) c1 - (int) c2; - } while (*lpString1++ && *lpString2++); - return 0; -} - - -int -WINAPI -lstrcmpiWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) -{ - do { - WCHAR c1 = *lpString1; - WCHAR c2 = *lpString2; - if (c1 >= L'A' && c1 <= L'Z') - c1 -= (WCHAR) (L'A' - L'a'); - if (c2 >= L'A' && c2 <= L'Z') - c2 -= (WCHAR) (L'A' - L'a'); - - if (c1 != c2) - return (int) c1 - (int) c2; - } while (*lpString1++ && *lpString2++); - - return 0; -} - - -int -WINAPI -lstrlenWInternal( - LPCWSTR lpString - ) -{ - int i = -1; - while (*(lpString+(++i))) - ; - return i; -} - - -// int WINAPIV wsprintfWInternal(LPWSTR wszOut, LPCWSTR pszFmt, ...) -// { -// char fmt[256]; // !!! -// char ach[256]; // !!! -// int i; -// -// va_list va; -// va_start(va, pszFmt); -// WideCharToMultiByte(GetACP(), 0, pszFmt, -1, fmt, 256, NULL, NULL); -// (void)StringCchVPrintf(ach, NUMELMS(ach), fmt, va); -// i = lstrlenA(ach); -// va_end(va); -// -// MultiByteToWideChar(CP_ACP, 0, ach, -1, wszOut, i+1); -// -// return i; -// } -#else - -// need to provide the implementations in unicode for non-unicode -// builds linking with the unicode strmbase.lib -//LPWSTR WINAPI lstrcpyWInternal( -// LPWSTR lpString1, -// LPCWSTR lpString2 -// ) -//{ -// return lstrcpyW(lpString1, lpString2); -//} - -LPWSTR WINAPI lstrcpynWInternal( - LPWSTR lpString1, - LPCWSTR lpString2, - int iMaxLength - ) -{ - return lstrcpynW(lpString1, lpString2, iMaxLength); -} - -int WINAPI lstrcmpWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) -{ - return lstrcmpW(lpString1, lpString2); -} - - -int WINAPI lstrcmpiWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ) -{ - return lstrcmpiW(lpString1, lpString2); -} - - -int WINAPI lstrlenWInternal( - LPCWSTR lpString - ) -{ - return lstrlenW(lpString); -} - - -//int WINAPIV wsprintfWInternal( -// LPWSTR wszOut, LPCWSTR pszFmt, ...) -//{ -// va_list va; -// va_start(va, pszFmt); -// int i = wvsprintfW(wszOut, pszFmt, va); -// va_end(va); -// return i; -//} -#endif - - -// Helper function - convert int to WSTR -void WINAPI IntToWstr(int i, LPWSTR wstr, size_t len) -{ -#ifdef UNICODE - (void)StringCchPrintf(wstr, len, L"%d", i); -#else - TCHAR temp[32]; - (void)StringCchPrintf(temp, NUMELMS(temp), "%d", i); - MultiByteToWideChar(CP_ACP, 0, temp, -1, wstr, int(len) ); -#endif -} // IntToWstr - - -#if 0 -void * memchrInternal(const void *pv, int c, size_t sz) -{ - BYTE *pb = (BYTE *) pv; - while (sz--) { - if (*pb == c) - return (void *) pb; - pb++; - } - return NULL; -} -#endif - - -#define MEMORY_ALIGNMENT 4 -#define MEMORY_ALIGNMENT_LOG2 2 -#define MEMORY_ALIGNMENT_MASK MEMORY_ALIGNMENT - 1 - -void * __stdcall memmoveInternal(void * dst, const void * src, size_t count) -{ - void * ret = dst; - -#ifdef _X86_ - if (dst <= src || (char *)dst >= ((char *)src + count)) { - - /* - * Non-Overlapping Buffers - * copy from lower addresses to higher addresses - */ - _asm { - mov esi,src - mov edi,dst - mov ecx,count - cld - mov edx,ecx - and edx,MEMORY_ALIGNMENT_MASK - shr ecx,MEMORY_ALIGNMENT_LOG2 - rep movsd - or ecx,edx - jz memmove_done - rep movsb -memmove_done: - } - } - else { - - /* - * Overlapping Buffers - * copy from higher addresses to lower addresses - */ - _asm { - mov esi,src - mov edi,dst - mov ecx,count - std - add esi,ecx - add edi,ecx - dec esi - dec edi - rep movsb - cld - } - } -#else - MoveMemory(dst, src, count); -#endif - - return ret; -} - -/* Arithmetic functions to help with time format conversions -*/ - -#ifdef _M_ALPHA -// work around bug in version 12.00.8385 of the alpha compiler where -// UInt32x32To64 sign-extends its arguments (?) -#undef UInt32x32To64 -#define UInt32x32To64(a, b) (((ULONGLONG)((ULONG)(a)) & 0xffffffff) * ((ULONGLONG)((ULONG)(b)) & 0xffffffff)) -#endif - -/* Compute (a * b + d) / c */ -LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG d) -{ - /* Compute the absolute values to avoid signed arithmetic problems */ - ULARGE_INTEGER ua, ub; - DWORDLONG uc; - - ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a); - ub.QuadPart = (DWORDLONG)(b >= 0 ? b : -b); - uc = (DWORDLONG)(c >= 0 ? c : -c); - BOOL bSign = (a < 0) ^ (b < 0); - - /* Do long multiplication */ - ULARGE_INTEGER p[2]; - p[0].QuadPart = UInt32x32To64(ua.LowPart, ub.LowPart); - - /* This next computation cannot overflow into p[1].HighPart because - the max number we can compute here is: - - (2 ** 32 - 1) * (2 ** 32 - 1) + // ua.LowPart * ub.LowPart - (2 ** 32) * (2 ** 31) * (2 ** 32 - 1) * 2 // x.LowPart * y.HighPart * 2 - - == 2 ** 96 - 2 ** 64 + (2 ** 64 - 2 ** 33 + 1) - == 2 ** 96 - 2 ** 33 + 1 - < 2 ** 96 - */ - - ULARGE_INTEGER x; - x.QuadPart = UInt32x32To64(ua.LowPart, ub.HighPart) + - UInt32x32To64(ua.HighPart, ub.LowPart) + - p[0].HighPart; - p[0].HighPart = x.LowPart; - p[1].QuadPart = UInt32x32To64(ua.HighPart, ub.HighPart) + x.HighPart; - - if (d != 0) { - ULARGE_INTEGER ud[2]; - if (bSign) { - ud[0].QuadPart = (DWORDLONG)(-d); - if (d > 0) { - /* -d < 0 */ - ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1; - } else { - ud[1].QuadPart = (DWORDLONG)0; - } - } else { - ud[0].QuadPart = (DWORDLONG)d; - if (d < 0) { - ud[1].QuadPart = (DWORDLONG)(LONGLONG)-1; - } else { - ud[1].QuadPart = (DWORDLONG)0; - } - } - /* Now do extended addition */ - ULARGE_INTEGER uliTotal; - - /* Add ls DWORDs */ - uliTotal.QuadPart = (DWORDLONG)ud[0].LowPart + p[0].LowPart; - p[0].LowPart = uliTotal.LowPart; - - /* Propagate carry */ - uliTotal.LowPart = uliTotal.HighPart; - uliTotal.HighPart = 0; - - /* Add 2nd most ls DWORDs */ - uliTotal.QuadPart += (DWORDLONG)ud[0].HighPart + p[0].HighPart; - p[0].HighPart = uliTotal.LowPart; - - /* Propagate carry */ - uliTotal.LowPart = uliTotal.HighPart; - uliTotal.HighPart = 0; - - /* Add MS DWORDLONGs - no carry expected */ - p[1].QuadPart += ud[1].QuadPart + uliTotal.QuadPart; - - /* Now see if we got a sign change from the addition */ - if ((LONG)p[1].HighPart < 0) { - bSign = !bSign; - - /* Negate the current value (ugh!) */ - p[0].QuadPart = ~p[0].QuadPart; - p[1].QuadPart = ~p[1].QuadPart; - p[0].QuadPart += 1; - p[1].QuadPart += (p[0].QuadPart == 0); - } - } - - /* Now for the division */ - if (c < 0) { - bSign = !bSign; - } - - - /* This will catch c == 0 and overflow */ - if (uc <= p[1].QuadPart) { - return bSign ? (LONGLONG)0x8000000000000000 : - (LONGLONG)0x7FFFFFFFFFFFFFFF; - } - - DWORDLONG ullResult; - - /* Do the division */ - /* If the dividend is a DWORD_LONG use the compiler */ - if (p[1].QuadPart == 0) { - ullResult = p[0].QuadPart / uc; - return bSign ? -(LONGLONG)ullResult : (LONGLONG)ullResult; - } - - /* If the divisor is a DWORD then its simpler */ - ULARGE_INTEGER ulic; - ulic.QuadPart = uc; - if (ulic.HighPart == 0) { - ULARGE_INTEGER uliDividend; - ULARGE_INTEGER uliResult; - DWORD dwDivisor = (DWORD)uc; - // ASSERT(p[1].HighPart == 0 && p[1].LowPart < dwDivisor); - uliDividend.HighPart = p[1].LowPart; - uliDividend.LowPart = p[0].HighPart; -#ifndef USE_LARGEINT - uliResult.HighPart = (DWORD)(uliDividend.QuadPart / dwDivisor); - p[0].HighPart = (DWORD)(uliDividend.QuadPart % dwDivisor); - uliResult.LowPart = 0; - uliResult.QuadPart = p[0].QuadPart / dwDivisor + uliResult.QuadPart; -#else - /* NOTE - this routine will take exceptions if - the result does not fit in a DWORD - */ - if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) { - uliResult.HighPart = EnlargedUnsignedDivide( - uliDividend, - dwDivisor, - &p[0].HighPart); - } else { - uliResult.HighPart = 0; - } - uliResult.LowPart = EnlargedUnsignedDivide( - p[0], - dwDivisor, - NULL); -#endif - return bSign ? -(LONGLONG)uliResult.QuadPart : - (LONGLONG)uliResult.QuadPart; - } - - - ullResult = 0; - - /* OK - do long division */ - for (int i = 0; i < 64; i++) { - ullResult <<= 1; - - /* Shift 128 bit p left 1 */ - p[1].QuadPart <<= 1; - if ((p[0].HighPart & 0x80000000) != 0) { - p[1].LowPart++; - } - p[0].QuadPart <<= 1; - - /* Compare */ - if (uc <= p[1].QuadPart) { - p[1].QuadPart -= uc; - ullResult += 1; - } - } - - return bSign ? - (LONGLONG)ullResult : (LONGLONG)ullResult; -} - -LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG d) -{ - ULARGE_INTEGER ua; - DWORD ub; - DWORD uc; - - /* Compute the absolute values to avoid signed arithmetic problems */ - ua.QuadPart = (DWORDLONG)(a >= 0 ? a : -a); - ub = (DWORD)(b >= 0 ? b : -b); - uc = (DWORD)(c >= 0 ? c : -c); - BOOL bSign = (a < 0) ^ (b < 0); - - /* Do long multiplication */ - ULARGE_INTEGER p0; - DWORD p1; - p0.QuadPart = UInt32x32To64(ua.LowPart, ub); - - if (ua.HighPart != 0) { - ULARGE_INTEGER x; - x.QuadPart = UInt32x32To64(ua.HighPart, ub) + p0.HighPart; - p0.HighPart = x.LowPart; - p1 = x.HighPart; - } else { - p1 = 0; - } - - if (d != 0) { - ULARGE_INTEGER ud0; - DWORD ud1; - - if (bSign) { - // - // Cast d to LONGLONG first otherwise -0x80000000 sign extends - // incorrectly - // - ud0.QuadPart = (DWORDLONG)(-(LONGLONG)d); - if (d > 0) { - /* -d < 0 */ - ud1 = (DWORD)-1; - } else { - ud1 = (DWORD)0; - } - } else { - ud0.QuadPart = (DWORDLONG)d; - if (d < 0) { - ud1 = (DWORD)-1; - } else { - ud1 = (DWORD)0; - } - } - /* Now do extended addition */ - ULARGE_INTEGER uliTotal; - - /* Add ls DWORDs */ - uliTotal.QuadPart = (DWORDLONG)ud0.LowPart + p0.LowPart; - p0.LowPart = uliTotal.LowPart; - - /* Propagate carry */ - uliTotal.LowPart = uliTotal.HighPart; - uliTotal.HighPart = 0; - - /* Add 2nd most ls DWORDs */ - uliTotal.QuadPart += (DWORDLONG)ud0.HighPart + p0.HighPart; - p0.HighPart = uliTotal.LowPart; - - /* Add MS DWORDLONGs - no carry expected */ - p1 += ud1 + uliTotal.HighPart; - - /* Now see if we got a sign change from the addition */ - if ((LONG)p1 < 0) { - bSign = !bSign; - - /* Negate the current value (ugh!) */ - p0.QuadPart = ~p0.QuadPart; - p1 = ~p1; - p0.QuadPart += 1; - p1 += (p0.QuadPart == 0); - } - } - - /* Now for the division */ - if (c < 0) { - bSign = !bSign; - } - - - /* This will catch c == 0 and overflow */ - if (uc <= p1) { - return bSign ? (LONGLONG)0x8000000000000000 : - (LONGLONG)0x7FFFFFFFFFFFFFFF; - } - - /* Do the division */ - - /* If the divisor is a DWORD then its simpler */ - ULARGE_INTEGER uliDividend; - ULARGE_INTEGER uliResult; - DWORD dwDivisor = uc; - uliDividend.HighPart = p1; - uliDividend.LowPart = p0.HighPart; - /* NOTE - this routine will take exceptions if - the result does not fit in a DWORD - */ - if (uliDividend.QuadPart >= (DWORDLONG)dwDivisor) { - uliResult.HighPart = EnlargedUnsignedDivide( - uliDividend, - dwDivisor, - &p0.HighPart); - } else { - uliResult.HighPart = 0; - } - uliResult.LowPart = EnlargedUnsignedDivide( - p0, - dwDivisor, - NULL); - return bSign ? -(LONGLONG)uliResult.QuadPart : - (LONGLONG)uliResult.QuadPart; -} - -#ifdef DEBUG -/******************************Public*Routine******************************\ -* Debug CCritSec helpers -* -* We provide debug versions of the Constructor, destructor, Lock and Unlock -* routines. The debug code tracks who owns each critical section by -* maintaining a depth count. -* -* History: -* -\**************************************************************************/ - -CCritSec::CCritSec() -{ - InitializeCriticalSection(&m_CritSec); - m_currentOwner = m_lockCount = 0; - m_fTrace = FALSE; -} - -CCritSec::~CCritSec() -{ - DeleteCriticalSection(&m_CritSec); -} - -void CCritSec::Lock() -{ - UINT tracelevel=3; - DWORD us = GetCurrentThreadId(); - DWORD currentOwner = m_currentOwner; - if (currentOwner && (currentOwner != us)) { - // already owned, but not by us - if (m_fTrace) { - DbgLog((LOG_LOCKING, 2, TEXT("Thread %d about to wait for lock %x owned by %d"), - GetCurrentThreadId(), &m_CritSec, currentOwner)); - tracelevel=2; - // if we saw the message about waiting for the critical - // section we ensure we see the message when we get the - // critical section - } - } - EnterCriticalSection(&m_CritSec); - if (0 == m_lockCount++) { - // we now own it for the first time. Set owner information - m_currentOwner = us; - - if (m_fTrace) { - DbgLog((LOG_LOCKING, tracelevel, TEXT("Thread %d now owns lock %x"), m_currentOwner, &m_CritSec)); - } - } -} - -void CCritSec::Unlock() { - if (0 == --m_lockCount) { - // about to be unowned - if (m_fTrace) { - DbgLog((LOG_LOCKING, 3, TEXT("Thread %d releasing lock %x"), m_currentOwner, &m_CritSec)); - } - - m_currentOwner = 0; - } - LeaveCriticalSection(&m_CritSec); -} - -void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace) -{ - pcCrit->m_fTrace = fTrace; -} - -BOOL WINAPI CritCheckIn(CCritSec * pcCrit) -{ - return (GetCurrentThreadId() == pcCrit->m_currentOwner); -} - -BOOL WINAPI CritCheckIn(const CCritSec * pcCrit) -{ - return (GetCurrentThreadId() == pcCrit->m_currentOwner); -} - -BOOL WINAPI CritCheckOut(CCritSec * pcCrit) -{ - return (GetCurrentThreadId() != pcCrit->m_currentOwner); -} - -BOOL WINAPI CritCheckOut(const CCritSec * pcCrit) -{ - return (GetCurrentThreadId() != pcCrit->m_currentOwner); -} -#endif - - -STDAPI WriteBSTR(BSTR *pstrDest, LPCWSTR szSrc) -{ - *pstrDest = SysAllocString( szSrc ); - if( !(*pstrDest) ) return E_OUTOFMEMORY; - return NOERROR; -} - - -STDAPI FreeBSTR(BSTR* pstr) -{ - if( *pstr == NULL ) return S_FALSE; - SysFreeString( *pstr ); - return NOERROR; -} - - -// Return a wide string - allocating memory for it -// Returns: -// S_OK - no error -// E_POINTER - ppszReturn == NULL -// E_OUTOFMEMORY - can't allocate memory for returned string -STDAPI AMGetWideString(LPCWSTR psz, LPWSTR *ppszReturn) -{ - CheckPointer(ppszReturn, E_POINTER); - ValidateReadWritePtr(ppszReturn, sizeof(LPWSTR)); - DWORD nameLen = sizeof(WCHAR) * (lstrlenW(psz)+1); - *ppszReturn = (LPWSTR)CoTaskMemAlloc(nameLen); - if (*ppszReturn == NULL) { - return E_OUTOFMEMORY; - } - CopyMemory(*ppszReturn, psz, nameLen); - return NOERROR; -} - -// Waits for the HANDLE hObject. While waiting messages sent -// to windows on our thread by SendMessage will be processed. -// Using this function to do waits and mutual exclusion -// avoids some deadlocks in objects with windows. -// Return codes are the same as for WaitForSingleObject -DWORD WINAPI WaitDispatchingMessages( - HANDLE hObject, - DWORD dwWait, - HWND hwnd, - UINT uMsg, - HANDLE hEvent) -{ - BOOL bPeeked = FALSE; - DWORD dwResult; - DWORD dwStart; - DWORD dwThreadPriority; - - static UINT uMsgId = 0; - - HANDLE hObjects[2] = { hObject, hEvent }; - if (dwWait != INFINITE && dwWait != 0) { - dwStart = GetTickCount(); - } - for (; ; ) { - DWORD nCount = NULL != hEvent ? 2 : 1; - - // Minimize the chance of actually dispatching any messages - // by seeing if we can lock immediately. - dwResult = WaitForMultipleObjects(nCount, hObjects, FALSE, 0); - if (dwResult < WAIT_OBJECT_0 + nCount) { - break; - } - - DWORD dwTimeOut = dwWait; - if (dwTimeOut > 10) { - dwTimeOut = 10; - } - dwResult = MsgWaitForMultipleObjects( - nCount, - hObjects, - FALSE, - dwTimeOut, - hwnd == NULL ? QS_SENDMESSAGE : - QS_SENDMESSAGE + QS_POSTMESSAGE); - if (dwResult == WAIT_OBJECT_0 + nCount || - dwResult == WAIT_TIMEOUT && dwTimeOut != dwWait) { - MSG msg; - if (hwnd != NULL) { - while (PeekMessage(&msg, hwnd, uMsg, uMsg, PM_REMOVE)) { - DispatchMessage(&msg); - } - } - // Do this anyway - the previous peek doesn't flush out the - // messages - PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE); - - if (dwWait != INFINITE && dwWait != 0) { - DWORD dwNow = GetTickCount(); - - // Working with differences handles wrap-around - DWORD dwDiff = dwNow - dwStart; - if (dwDiff > dwWait) { - dwWait = 0; - } else { - dwWait -= dwDiff; - } - dwStart = dwNow; - } - if (!bPeeked) { - // Raise our priority to prevent our message queue - // building up - dwThreadPriority = GetThreadPriority(GetCurrentThread()); - if (dwThreadPriority < THREAD_PRIORITY_HIGHEST) { - SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST); - } - bPeeked = TRUE; - } - } else { - break; - } - } - if (bPeeked) { - SetThreadPriority(GetCurrentThread(), dwThreadPriority); - if (HIWORD(GetQueueStatus(QS_POSTMESSAGE)) & QS_POSTMESSAGE) { - if (uMsgId == 0) { - uMsgId = RegisterWindowMessage(TEXT("AMUnblock")); - } - if (uMsgId != 0) { - MSG msg; - // Remove old ones - while (PeekMessage(&msg, (HWND)-1, uMsgId, uMsgId, PM_REMOVE)) { - } - } - PostThreadMessage(GetCurrentThreadId(), uMsgId, 0, 0); - } - } - return dwResult; -} - -HRESULT AmGetLastErrorToHResult() -{ - DWORD dwLastError = GetLastError(); - if(dwLastError != 0) - { - return HRESULT_FROM_WIN32(dwLastError); - } - else - { - return E_FAIL; - } -} - -IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp) -{ - if (lp != NULL) - lp->AddRef(); - if (*pp) - (*pp)->Release(); - *pp = lp; - return lp; -} - -/****************************************************************************** - -CompatibleTimeSetEvent - - CompatibleTimeSetEvent() sets the TIME_KILL_SYNCHRONOUS flag before calling -timeSetEvent() if the current operating system supports it. TIME_KILL_SYNCHRONOUS -is supported on Windows XP and later operating systems. - -Parameters: -- The same parameters as timeSetEvent(). See timeSetEvent()'s documentation in -the Platform SDK for more information. - -Return Value: -- The same return value as timeSetEvent(). See timeSetEvent()'s documentation in -the Platform SDK for more information. - -******************************************************************************/ -MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent ) -{ - #if WINVER >= 0x0501 - { - static bool fCheckedVersion = false; - static bool fTimeKillSynchronousFlagAvailable = false; - - if( !fCheckedVersion ) { - fTimeKillSynchronousFlagAvailable = TimeKillSynchronousFlagAvailable(); - fCheckedVersion = true; - } - - if( fTimeKillSynchronousFlagAvailable ) { - fuEvent = fuEvent | TIME_KILL_SYNCHRONOUS; - } - } - #endif // WINVER >= 0x0501 - - return timeSetEvent( uDelay, uResolution, lpTimeProc, dwUser, fuEvent ); -} - -bool TimeKillSynchronousFlagAvailable( void ) -{ - OSVERSIONINFO osverinfo; - - osverinfo.dwOSVersionInfoSize = sizeof(osverinfo); - - if( GetVersionEx( &osverinfo ) ) { - - // Windows XP's major version is 5 and its' minor version is 1. - // timeSetEvent() started supporting the TIME_KILL_SYNCHRONOUS flag - // in Windows XP. - if( (osverinfo.dwMajorVersion > 5) || - ( (osverinfo.dwMajorVersion == 5) && (osverinfo.dwMinorVersion >= 1) ) ) { - return true; - } - } - - return false; -} diff --git a/plugins/gs/gsdx9/baseclasses/wxutil.h b/plugins/gs/gsdx9/baseclasses/wxutil.h deleted file mode 100644 index 9cf4ef5cdd..0000000000 --- a/plugins/gs/gsdx9/baseclasses/wxutil.h +++ /dev/null @@ -1,540 +0,0 @@ -//------------------------------------------------------------------------------ -// File: WXUtil.h -// -// Desc: DirectShow base classes - defines helper classes and functions for -// building multimedia filters. -// -// Copyright (c) Microsoft Corporation. All rights reserved. -//------------------------------------------------------------------------------ - - -#ifndef __WXUTIL__ -#define __WXUTIL__ - -// eliminate spurious "statement has no effect" warnings. -#pragma warning(disable: 4705) - -// wrapper for whatever critical section we have -class CCritSec { - - // make copy constructor and assignment operator inaccessible - - CCritSec(const CCritSec &refCritSec); - CCritSec &operator=(const CCritSec &refCritSec); - - CRITICAL_SECTION m_CritSec; - -#ifdef DEBUG -public: - DWORD m_currentOwner; - DWORD m_lockCount; - BOOL m_fTrace; // Trace this one -public: - CCritSec(); - ~CCritSec(); - void Lock(); - void Unlock(); -#else - -public: - CCritSec() { - InitializeCriticalSection(&m_CritSec); - }; - - ~CCritSec() { - DeleteCriticalSection(&m_CritSec); - }; - - void Lock() { - EnterCriticalSection(&m_CritSec); - }; - - void Unlock() { - LeaveCriticalSection(&m_CritSec); - }; -#endif -}; - -// -// To make deadlocks easier to track it is useful to insert in the -// code an assertion that says whether we own a critical section or -// not. We make the routines that do the checking globals to avoid -// having different numbers of member functions in the debug and -// retail class implementations of CCritSec. In addition we provide -// a routine that allows usage of specific critical sections to be -// traced. This is NOT on by default - there are far too many. -// - -#ifdef DEBUG - BOOL WINAPI CritCheckIn(CCritSec * pcCrit); - BOOL WINAPI CritCheckIn(const CCritSec * pcCrit); - BOOL WINAPI CritCheckOut(CCritSec * pcCrit); - BOOL WINAPI CritCheckOut(const CCritSec * pcCrit); - void WINAPI DbgLockTrace(CCritSec * pcCrit, BOOL fTrace); -#else - #define CritCheckIn(x) TRUE - #define CritCheckOut(x) TRUE - #define DbgLockTrace(pc, fT) -#endif - - -// locks a critical section, and unlocks it automatically -// when the lock goes out of scope -class CAutoLock { - - // make copy constructor and assignment operator inaccessible - - CAutoLock(const CAutoLock &refAutoLock); - CAutoLock &operator=(const CAutoLock &refAutoLock); - -protected: - CCritSec * m_pLock; - -public: - CAutoLock(CCritSec * plock) - { - m_pLock = plock; - m_pLock->Lock(); - }; - - ~CAutoLock() { - m_pLock->Unlock(); - }; -}; - - - -// wrapper for event objects -class CAMEvent -{ - - // make copy constructor and assignment operator inaccessible - - CAMEvent(const CAMEvent &refEvent); - CAMEvent &operator=(const CAMEvent &refEvent); - -protected: - HANDLE m_hEvent; -public: - CAMEvent(BOOL fManualReset = FALSE); - ~CAMEvent(); - - // Cast to HANDLE - we don't support this as an lvalue - operator HANDLE () const { return m_hEvent; }; - - void Set() {EXECUTE_ASSERT(SetEvent(m_hEvent));}; - BOOL Wait(DWORD dwTimeout = INFINITE) { - return (WaitForSingleObject(m_hEvent, dwTimeout) == WAIT_OBJECT_0); - }; - void Reset() { ResetEvent(m_hEvent); }; - BOOL Check() { return Wait(0); }; -}; - - -// wrapper for event objects that do message processing -// This adds ONE method to the CAMEvent object to allow sent -// messages to be processed while waiting - -class CAMMsgEvent : public CAMEvent -{ - -public: - - // Allow SEND messages to be processed while waiting - BOOL WaitMsg(DWORD dwTimeout = INFINITE); -}; - -// old name supported for the time being -#define CTimeoutEvent CAMEvent - -// support for a worker thread - -// simple thread class supports creation of worker thread, synchronization -// and communication. Can be derived to simplify parameter passing -class AM_NOVTABLE CAMThread { - - // make copy constructor and assignment operator inaccessible - - CAMThread(const CAMThread &refThread); - CAMThread &operator=(const CAMThread &refThread); - - CAMEvent m_EventSend; - CAMEvent m_EventComplete; - - DWORD m_dwParam; - DWORD m_dwReturnVal; - -protected: - HANDLE m_hThread; - - // thread will run this function on startup - // must be supplied by derived class - virtual DWORD ThreadProc() = 0; - -public: - CAMThread(); - virtual ~CAMThread(); - - CCritSec m_AccessLock; // locks access by client threads - CCritSec m_WorkerLock; // locks access to shared objects - - // thread initially runs this. param is actually 'this'. function - // just gets this and calls ThreadProc - static DWORD WINAPI InitialThreadProc(LPVOID pv); - - // start thread running - error if already running - BOOL Create(); - - // signal the thread, and block for a response - // - DWORD CallWorker(DWORD); - - // accessor thread calls this when done with thread (having told thread - // to exit) - void Close() { - #pragma warning( push ) - // C4312: 'type cast' : conversion from 'LONG' to 'PVOID' of greater size - // - // This code works correctly on 32-bit and 64-bit systems. - #pragma warning( disable : 4312 ) - HANDLE hThread = (HANDLE)InterlockedExchangePointer(&m_hThread, 0); - #pragma warning( pop ) - - if (hThread) { - WaitForSingleObject(hThread, INFINITE); - CloseHandle(hThread); - } - }; - - // ThreadExists - // Return TRUE if the thread exists. FALSE otherwise - BOOL ThreadExists(void) const - { - if (m_hThread == 0) { - return FALSE; - } else { - return TRUE; - } - } - - // wait for the next request - DWORD GetRequest(); - - // is there a request? - BOOL CheckRequest(DWORD * pParam); - - // reply to the request - void Reply(DWORD); - - // If you want to do WaitForMultipleObjects you'll need to include - // this handle in your wait list or you won't be responsive - HANDLE GetRequestHandle() const { return m_EventSend; }; - - // Find out what the request was - DWORD GetRequestParam() const { return m_dwParam; }; - - // call CoInitializeEx (COINIT_DISABLE_OLE1DDE) if - // available. S_FALSE means it's not available. - static HRESULT CoInitializeHelper(); -}; - - -// CQueue -// -// Implements a simple Queue ADT. The queue contains a finite number of -// objects, access to which is controlled by a semaphore. The semaphore -// is created with an initial count (N). Each time an object is added -// a call to WaitForSingleObject is made on the semaphore's handle. When -// this function returns a slot has been reserved in the queue for the new -// object. If no slots are available the function blocks until one becomes -// available. Each time an object is removed from the queue ReleaseSemaphore -// is called on the semaphore's handle, thus freeing a slot in the queue. -// If no objects are present in the queue the function blocks until an -// object has been added. - -#define DEFAULT_QUEUESIZE 2 - -template class CQueue { -private: - HANDLE hSemPut; // Semaphore controlling queue "putting" - HANDLE hSemGet; // Semaphore controlling queue "getting" - CRITICAL_SECTION CritSect; // Thread seriallization - int nMax; // Max objects allowed in queue - int iNextPut; // Array index of next "PutMsg" - int iNextGet; // Array index of next "GetMsg" - T *QueueObjects; // Array of objects (ptr's to void) - - void Initialize(int n) { - iNextPut = iNextGet = 0; - nMax = n; - InitializeCriticalSection(&CritSect); - hSemPut = CreateSemaphore(NULL, n, n, NULL); - hSemGet = CreateSemaphore(NULL, 0, n, NULL); - QueueObjects = new T[n]; - } - - -public: - CQueue(int n) { - Initialize(n); - } - - CQueue() { - Initialize(DEFAULT_QUEUESIZE); - } - - ~CQueue() { - delete [] QueueObjects; - DeleteCriticalSection(&CritSect); - CloseHandle(hSemPut); - CloseHandle(hSemGet); - } - - T GetQueueObject() { - int iSlot; - T Object; - LONG lPrevious; - - // Wait for someone to put something on our queue, returns straight - // away is there is already an object on the queue. - // - WaitForSingleObject(hSemGet, INFINITE); - - EnterCriticalSection(&CritSect); - iSlot = iNextGet++ % nMax; - Object = QueueObjects[iSlot]; - LeaveCriticalSection(&CritSect); - - // Release anyone waiting to put an object onto our queue as there - // is now space available in the queue. - // - ReleaseSemaphore(hSemPut, 1L, &lPrevious); - return Object; - } - - void PutQueueObject(T Object) { - int iSlot; - LONG lPrevious; - - // Wait for someone to get something from our queue, returns straight - // away is there is already an empty slot on the queue. - // - WaitForSingleObject(hSemPut, INFINITE); - - EnterCriticalSection(&CritSect); - iSlot = iNextPut++ % nMax; - QueueObjects[iSlot] = Object; - LeaveCriticalSection(&CritSect); - - // Release anyone waiting to remove an object from our queue as there - // is now an object available to be removed. - // - ReleaseSemaphore(hSemGet, 1L, &lPrevious); - } -}; - -// miscellaneous string conversion functions -// NOTE: as we need to use the same binaries on Win95 as on NT this code should -// be compiled WITHOUT unicode being defined. Otherwise we will not pick up -// these internal routines and the binary will not run on Win95. - -// int WINAPIV wsprintfWInternal(LPWSTR, LPCWSTR, ...); - -//LPWSTR -//WINAPI -//lstrcpyWInternal( -// LPWSTR lpString1, -// LPCWSTR lpString2 -// ); -LPWSTR -WINAPI -lstrcpynWInternal( - LPWSTR lpString1, - LPCWSTR lpString2, - int iMaxLength - ); -int -WINAPI -lstrcmpWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ); -int -WINAPI -lstrcmpiWInternal( - LPCWSTR lpString1, - LPCWSTR lpString2 - ); -int -WINAPI -lstrlenWInternal( - LPCWSTR lpString - ); - -#ifndef UNICODE -#define wsprintfW wsprintfWInternal -#define lstrcpyW lstrcpyWInternal -#define lstrcpynW lstrcpynWInternal -#define lstrcmpW lstrcmpWInternal -#define lstrcmpiW lstrcmpiWInternal -#define lstrlenW lstrlenWInternal -#endif - -extern "C" -void * __stdcall memmoveInternal(void *, const void *, size_t); - -inline void * __cdecl memchrInternal(const void *buf, int chr, size_t cnt) -{ -#ifdef _X86_ - void *pRet = NULL; - - _asm { - cld // make sure we get the direction right - mov ecx, cnt // num of bytes to scan - mov edi, buf // pointer byte stream - mov eax, chr // byte to scan for - repne scasb // look for the byte in the byte stream - jnz exit_memchr // Z flag set if byte found - dec edi // scasb always increments edi even when it - // finds the required byte - mov pRet, edi -exit_memchr: - } - return pRet; - -#else - while ( cnt && (*(unsigned char *)buf != (unsigned char)chr) ) { - buf = (unsigned char *)buf + 1; - cnt--; - } - - return(cnt ? (void *)buf : NULL); -#endif -} - -void WINAPI IntToWstr(int i, LPWSTR wstr, size_t len); - -#define WstrToInt(sz) _wtoi(sz) -#define atoiW(sz) _wtoi(sz) -#define atoiA(sz) atoi(sz) - -// These are available to help managing bitmap VIDEOINFOHEADER media structures - -extern const DWORD bits555[3]; -extern const DWORD bits565[3]; -extern const DWORD bits888[3]; - -// These help convert between VIDEOINFOHEADER and BITMAPINFO structures - -STDAPI_(const GUID) GetTrueColorType(const BITMAPINFOHEADER *pbmiHeader); -STDAPI_(const GUID) GetBitmapSubtype(const BITMAPINFOHEADER *pbmiHeader); -STDAPI_(WORD) GetBitCount(const GUID *pSubtype); - -// strmbase.lib implements this for compatibility with people who -// managed to link to this directly. we don't want to advertise it. -// -// STDAPI_(/* T */ CHAR *) GetSubtypeName(const GUID *pSubtype); - -STDAPI_(CHAR *) GetSubtypeNameA(const GUID *pSubtype); -STDAPI_(WCHAR *) GetSubtypeNameW(const GUID *pSubtype); - -#ifdef UNICODE -#define GetSubtypeName GetSubtypeNameW -#else -#define GetSubtypeName GetSubtypeNameA -#endif - -STDAPI_(LONG) GetBitmapFormatSize(const BITMAPINFOHEADER *pHeader); -STDAPI_(DWORD) GetBitmapSize(const BITMAPINFOHEADER *pHeader); -STDAPI_(BOOL) ContainsPalette(const VIDEOINFOHEADER *pVideoInfo); -STDAPI_(const RGBQUAD *) GetBitmapPalette(const VIDEOINFOHEADER *pVideoInfo); - - -// Compares two interfaces and returns TRUE if they are on the same object -BOOL WINAPI IsEqualObject(IUnknown *pFirst, IUnknown *pSecond); - -// This is for comparing pins -#define EqualPins(pPin1, pPin2) IsEqualObject(pPin1, pPin2) - - -// Arithmetic helper functions - -// Compute (a * b + rnd) / c -LONGLONG WINAPI llMulDiv(LONGLONG a, LONGLONG b, LONGLONG c, LONGLONG rnd); -LONGLONG WINAPI Int64x32Div32(LONGLONG a, LONG b, LONG c, LONG rnd); - - -// Avoids us dyna-linking to SysAllocString to copy BSTR strings -STDAPI WriteBSTR(BSTR * pstrDest, LPCWSTR szSrc); -STDAPI FreeBSTR(BSTR* pstr); - -// Return a wide string - allocating memory for it -// Returns: -// S_OK - no error -// E_POINTER - ppszReturn == NULL -// E_OUTOFMEMORY - can't allocate memory for returned string -STDAPI AMGetWideString(LPCWSTR pszString, LPWSTR *ppszReturn); - -// Special wait for objects owning windows -DWORD WINAPI WaitDispatchingMessages( - HANDLE hObject, - DWORD dwWait, - HWND hwnd = NULL, - UINT uMsg = 0, - HANDLE hEvent = NULL); - -// HRESULT_FROM_WIN32 converts ERROR_SUCCESS to a success code, but in -// our use of HRESULT_FROM_WIN32, it typically means a function failed -// to call SetLastError(), and we still want a failure code. -// -#define AmHresultFromWin32(x) (MAKE_HRESULT(SEVERITY_ERROR, FACILITY_WIN32, x)) - -// call GetLastError and return an HRESULT value that will fail the -// SUCCEEDED() macro. -HRESULT AmGetLastErrorToHResult(void); - -// duplicate of ATL's CComPtr to avoid linker conflicts. - -IUnknown* QzAtlComPtrAssign(IUnknown** pp, IUnknown* lp); - -template -class QzCComPtr -{ -public: - typedef T _PtrClass; - QzCComPtr() {p=NULL;} - QzCComPtr(T* lp) - { - if ((p = lp) != NULL) - p->AddRef(); - } - QzCComPtr(const QzCComPtr& lp) - { - if ((p = lp.p) != NULL) - p->AddRef(); - } - ~QzCComPtr() {if (p) p->Release();} - void Release() {if (p) p->Release(); p=NULL;} - operator T*() {return (T*)p;} - T& operator*() {ASSERT(p!=NULL); return *p; } - //The assert on operator& usually indicates a bug. If this is really - //what is needed, however, take the address of the p member explicitly. - T** operator&() { ASSERT(p==NULL); return &p; } - T* operator->() { ASSERT(p!=NULL); return p; } - T* operator=(T* lp){return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp);} - T* operator=(const QzCComPtr& lp) - { - return (T*)QzAtlComPtrAssign((IUnknown**)&p, lp.p); - } -#if _MSC_VER>1020 - bool operator!(){return (p == NULL);} -#else - BOOL operator!(){return (p == NULL) ? TRUE : FALSE;} -#endif - T* p; -}; - -MMRESULT CompatibleTimeSetEvent( UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent ); -bool TimeKillSynchronousFlagAvailable( void ); - -#endif /* __WXUTIL__ */ diff --git a/plugins/gs/gsdx9/res/GSdx9.rc2 b/plugins/gs/gsdx9/res/GSdx9.rc2 deleted file mode 100644 index 9e684f60a1..0000000000 --- a/plugins/gs/gsdx9/res/GSdx9.rc2 +++ /dev/null @@ -1,37 +0,0 @@ -// -// GSdx9.RC2 - resources Microsoft Visual C++ does not edit directly -// - -#ifdef APSTUDIO_INVOKED -#error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// Add manually edited resources here... - -IDR_PS11_TFX000 RCDATA "res\\ps11_tfx000.psh" -IDR_PS11_TFX010 RCDATA "res\\ps11_tfx010.psh" -IDR_PS11_TFX011 RCDATA "res\\ps11_tfx011.psh" -IDR_PS11_TFX1x0 RCDATA "res\\ps11_tfx1x0.psh" -IDR_PS11_TFX1x1 RCDATA "res\\ps11_tfx1x1.psh" -IDR_PS11_TFX200 RCDATA "res\\ps11_tfx200.psh" -IDR_PS11_TFX210 RCDATA "res\\ps11_tfx210.psh" -IDR_PS11_TFX211 RCDATA "res\\ps11_tfx211.psh" -IDR_PS11_TFX300 RCDATA "res\\ps11_tfx300.psh" -IDR_PS11_TFX310 RCDATA "res\\ps11_tfx310.psh" -IDR_PS11_TFX311 RCDATA "res\\ps11_tfx311.psh" -IDR_PS11_TFX4xx RCDATA "res\\ps11_tfx4xx.psh" -IDR_PS11_EN11 RCDATA "res\\ps11_en11.psh" -IDR_PS11_EN01 RCDATA "res\\ps11_en01.psh" -IDR_PS11_EN10 RCDATA "res\\ps11_en10.psh" -IDR_PS11_EN00 RCDATA "res\\ps11_en00.psh" -IDR_PS14_EN11 RCDATA "res\\ps14_en11.psh" -IDR_PS14_EN01 RCDATA "res\\ps14_en01.psh" -IDR_PS14_EN10 RCDATA "res\\ps14_en10.psh" -IDR_PS14_EN00 RCDATA "res\\ps14_en00.psh" -IDR_HLSL_TFX RCDATA "res\\hlsl_tfx.fx" -IDR_HLSL_MERGE RCDATA "res\\hlsl_merge.fx" -IDR_HLSL_RB RCDATA "res\\hlsl_rb.fx" - -///////////////////////////////////////////////////////////////////////////// diff --git a/plugins/gs/gsdx9/res/hlsl_merge.fx b/plugins/gs/gsdx9/res/hlsl_merge.fx deleted file mode 100644 index bc8cc8c1f1..0000000000 --- a/plugins/gs/gsdx9/res/hlsl_merge.fx +++ /dev/null @@ -1,101 +0,0 @@ - -sampler RAO1 : register(s0); -sampler RAO2 : register(s1); - -float4 Params1 : register(c0); - -#define BGColor (Params1.rgb) -#define ALP (Params1.a) - -float4 Params2 : register(c1); - -#define AMOD (Params2[0] >= 0) -#define EN1 (Params2[1]) -#define EN2 (Params2[2]) -#define MMOD (Params2[3] >= 0) - -float4 Params3 : register(c2); - -#define AEM (Params3[0]) -#define TA0 (Params3[1]) -#define TA1 (Params3[2]) -#define SLBG (Params3[3] >= 0) - -float4 Merge(float4 Color1 : COLOR, float4 Color2 : COLOR) : COLOR -{ - float a = EN1 * (MMOD ? ALP : Color1.a); - float4 c = lerp(Color2, Color1, a); - // c.a = AMOD ? Color2.a : Color1.a; // not used - c.rgba = c.bgra; - return c; -} - -// 16 - -float4 CorrectTexColor16(float4 TexColor : COLOR) -{ - float A = AEM * !any(TexColor.rgb) * TA0; - TexColor.a = (TexColor.a < 1.0) ? A : TA1; // < 0.5 ? - return TexColor; -} - -float4 Sample16RAO1(float2 Tex : TEXCOORD0) : COLOR -{ - return EN1 * CorrectTexColor16(tex2D(RAO1, Tex)); -} - -float4 Sample16RAO2(float2 Tex : TEXCOORD0) : COLOR -{ - return SLBG ? float4(BGColor, 0) : (EN2 * CorrectTexColor16(tex2D(RAO2, Tex))); -} - -float4 main0(float2 Tex1 : TEXCOORD0, float2 Tex2 : TEXCOORD1) : COLOR -{ - float4 Color1 = Sample16RAO1(Tex1); - float4 Color2 = Sample16RAO2(Tex2); - return Merge(Color1, Color2); -} - -// 24 - -float4 CorrectTexColor24(float4 TexColor : COLOR) -{ - TexColor.a = AEM * !any(TexColor.rgb) * TA0; - return TexColor; -} - -float4 Sample24RAO1(float2 Tex : TEXCOORD0) : COLOR -{ - return EN1 * CorrectTexColor24(tex2D(RAO1, Tex)); -} - -float4 Sample24RAO2(float2 Tex : TEXCOORD0) : COLOR -{ - return SLBG ? float4(BGColor, 0) : (EN2 * CorrectTexColor24(tex2D(RAO2, Tex))); -} - -float4 main1(float2 Tex1 : TEXCOORD0, float2 Tex2 : TEXCOORD1) : COLOR -{ - float4 Color1 = Sample24RAO1(Tex1); - float4 Color2 = Sample24RAO2(Tex2); - return Merge(Color1, Color2); -} - -// 32 - -float4 SampleRAO1(float2 Tex : TEXCOORD0) : COLOR -{ - return EN1 * tex2D(RAO1, Tex); -} - -float4 SampleRAO2(float2 Tex : TEXCOORD0) : COLOR -{ - return SLBG ? float4(BGColor, 0) : (EN2 * tex2D(RAO2, Tex)); -} - -float4 main2(float2 Tex1 : TEXCOORD0, float2 Tex2 : TEXCOORD1) : COLOR -{ - float4 Color1 = SampleRAO1(Tex1); - float4 Color2 = SampleRAO2(Tex2); - return Merge(Color1, Color2); -} diff --git a/plugins/gs/gsdx9/res/hlsl_rb.fx b/plugins/gs/gsdx9/res/hlsl_rb.fx deleted file mode 100644 index 5ea33849ef..0000000000 --- a/plugins/gs/gsdx9/res/hlsl_rb.fx +++ /dev/null @@ -1,8 +0,0 @@ -sampler Texture : register(s0); - -float4 main(float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, Tex); - c.rgba = c.bgra; - return c; -} diff --git a/plugins/gs/gsdx9/res/hlsl_tfx.fx b/plugins/gs/gsdx9/res/hlsl_tfx.fx deleted file mode 100644 index af950de69c..0000000000 --- a/plugins/gs/gsdx9/res/hlsl_tfx.fx +++ /dev/null @@ -1,379 +0,0 @@ - -sampler Texture : register(s0); -sampler1D Palette : register(s1); - -float4 Params0 : register(c0); - -#define bTCC (Params0[0] >= 0) -#define fRT (Params0[1]) -#define TA0 (Params0[2]) -#define TA1 (Params0[3]) - -float2 W_H : register(c1); -float2 RW_RH : register(c2); -float2 RW_ZERO : register(c3); -float2 ZERO_RH : register(c4); - -// -// texture sampling -// - -float4 SampleTexture_32(in float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, Tex); - c.a *= fRT; - return c; -} - -float4 SampleTexture_24(in float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, Tex); - c.a = TA0; - // c.a *= fRT; // premultiplied - return c; -} - -float4 SampleTexture_24AEM(in float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, Tex); - c.a = any(c.rgb) ? TA0 : 0; - // c.a *= fRT; // premultiplied - return c; -} - -float4 SampleTexture_16(in float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, Tex); - c.a = c.a != 0 ? TA1 : TA0; - // c.a *= fRT; // premultiplied - return c; -} - -float4 SampleTexture_16AEM(in float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex2D(Texture, Tex); - c.a = c.a != 0 ? TA1 : any(c.rgb) ? TA0 : 0; - // c.a *= fRT; // premultiplied - return c; -} - -static const float s_palerr = 0.001/256; - -float4 SampleTexture_8P_pt(in float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex1D(Palette, tex2D(Texture, Tex).x - s_palerr); - // c.a *= fRT; // premultiplied - return c; -} - -float4 SampleTexture_8P_ln(in float2 Tex : TEXCOORD0) : COLOR -{ - Tex -= 0.5*RW_RH; // ? - float4 c00 = tex1D(Palette, tex2D(Texture, Tex).x - s_palerr); - float4 c01 = tex1D(Palette, tex2D(Texture, Tex + RW_ZERO).x - s_palerr); - float4 c10 = tex1D(Palette, tex2D(Texture, Tex + ZERO_RH).x - s_palerr); - float4 c11 = tex1D(Palette, tex2D(Texture, Tex + RW_RH).x - s_palerr); - float2 dd = frac(Tex * W_H); - float4 c = lerp(lerp(c00, c01, dd.x), lerp(c10, c11, dd.x), dd.y); - c.a *= fRT; - return c; -} - -float4 SampleTexture_8HP_pt(in float2 Tex : TEXCOORD0) : COLOR -{ - float4 c = tex1D(Palette, tex2D(Texture, Tex).a - s_palerr); - c.a *= fRT; - return c; -} - -float4 SampleTexture_8HP_ln(in float2 Tex : TEXCOORD0) : COLOR -{ - Tex -= 0.5*RW_RH; // ? - float4 c00 = tex1D(Palette, tex2D(Texture, Tex).a - s_palerr); - float4 c01 = tex1D(Palette, tex2D(Texture, Tex + RW_ZERO).a - s_palerr); - float4 c10 = tex1D(Palette, tex2D(Texture, Tex + ZERO_RH).a - s_palerr); - float4 c11 = tex1D(Palette, tex2D(Texture, Tex + RW_RH).a - s_palerr); - float2 dd = frac(Tex * W_H); - float4 c = lerp(lerp(c00, c01, dd.x), lerp(c10, c11, dd.x), dd.y); - c.a *= fRT; - return c; -} - -// -// fog -// - -float4 ApplyFog(in float4 Diff : COLOR, in float4 Fog : COLOR) : COLOR -{ - Diff = saturate(Diff); - Diff.rgb = lerp(Fog.rgb, Diff.rgb, Fog.a); - return Diff; -} - -// -// tfx -// - -float4 tfx0(float4 Diff, float4 TexColor) : COLOR -{ - Diff *= 2; - Diff.rgb *= TexColor.rgb; - if(bTCC) Diff.a *= TexColor.a; - return Diff; -} - -float4 tfx1(float4 Diff, float4 TexColor) : COLOR -{ - Diff = TexColor; - return Diff; -} - -float4 tfx2(float4 Diff, float4 TexColor) : COLOR -{ - Diff.rgb *= TexColor.rgb * 2; - Diff.rgb += Diff.a; - if(bTCC) Diff.a = Diff.a * 2 + TexColor.a; - return Diff; -} - -float4 tfx3(float4 Diff, float4 TexColor) : COLOR -{ - Diff.rgb *= TexColor.rgb * 2; - Diff.rgb += Diff.a; - if(bTCC) Diff.a = TexColor.a; - return Diff; -} - -// -// main tfx 32 -// - -float4 main_tfx0_32(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_32(Tex)), Fog); -} - -float4 main_tfx1_32(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_32(Tex)), Fog); -} - -float4 main_tfx2_32(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_32(Tex)), Fog); -} - -float4 main_tfx3_32(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_32(Tex)), Fog); -} - -// -// main tfx 24 -// - -float4 main_tfx0_24(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_24(Tex)), Fog); -} - -float4 main_tfx1_24(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_24(Tex)), Fog); -} - -float4 main_tfx2_24(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_24(Tex)), Fog); -} - -float4 main_tfx3_24(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_24(Tex)), Fog); -} - -// -// main tfx 24 AEM -// - -float4 main_tfx0_24AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_24AEM(Tex)), Fog); -} - -float4 main_tfx1_24AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_24AEM(Tex)), Fog); -} - -float4 main_tfx2_24AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_24AEM(Tex)), Fog); -} - -float4 main_tfx3_24AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_24AEM(Tex)), Fog); -} - -// -// main tfx 16 -// - -float4 main_tfx0_16(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_16(Tex)), Fog); -} - -float4 main_tfx1_16(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_16(Tex)), Fog); -} - -float4 main_tfx2_16(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_16(Tex)), Fog); -} - -float4 main_tfx3_16(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_16(Tex)), Fog); -} - -// -// main tfx 16 AEM -// - -float4 main_tfx0_16AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_16AEM(Tex)), Fog); -} - -float4 main_tfx1_16AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_16AEM(Tex)), Fog); -} - -float4 main_tfx2_16AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_16AEM(Tex)), Fog); -} - -float4 main_tfx3_16AEM(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_16AEM(Tex)), Fog); -} - -// -// main tfx 8P pt -// - -float4 main_tfx0_8P_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_8P_pt(Tex)), Fog); -} - -float4 main_tfx1_8P_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_8P_pt(Tex)), Fog); -} - -float4 main_tfx2_8P_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_8P_pt(Tex)), Fog); -} - -float4 main_tfx3_8P_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_8P_pt(Tex)), Fog); -} - -// -// main tfx 8P ln -// - -float4 main_tfx0_8P_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_8P_ln(Tex)), Fog); -} - -float4 main_tfx1_8P_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_8P_ln(Tex)), Fog); -} - -float4 main_tfx2_8P_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_8P_ln(Tex)), Fog); -} - -float4 main_tfx3_8P_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_8P_ln(Tex)), Fog); -} - -// -// main tfx 8HP pt -// - -float4 main_tfx0_8HP_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_8HP_pt(Tex)), Fog); -} - -float4 main_tfx1_8HP_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_8HP_pt(Tex)), Fog); -} - -float4 main_tfx2_8HP_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_8HP_pt(Tex)), Fog); -} - -float4 main_tfx3_8HP_pt(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_8HP_pt(Tex)), Fog); -} - -// -// main tfx 8HP ln -// - -float4 main_tfx0_8HP_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx0(Diff, SampleTexture_8HP_ln(Tex)), Fog); -} - -float4 main_tfx1_8HP_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx1(Diff, SampleTexture_8HP_ln(Tex)), Fog); -} - -float4 main_tfx2_8HP_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx2(Diff, SampleTexture_8HP_ln(Tex)), Fog); -} - -float4 main_tfx3_8HP_ln(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(tfx3(Diff, SampleTexture_8HP_ln(Tex)), Fog); -} - -// -// main notfx -// - -float4 main_notfx(float4 Diff : COLOR0, float4 Fog : COLOR1, float2 Tex : TEXCOORD0) : COLOR -{ - return ApplyFog(Diff, Fog); -} - -// -// main 8P -> 32 -// - -float4 main_8PTo32(float4 Diff : COLOR0, float2 Tex : TEXCOORD0) : COLOR -{ - return tex1D(Palette, tex2D(Texture, Tex).x - s_palerr); -} diff --git a/plugins/gs/gsdx9/res/logo1.bmp b/plugins/gs/gsdx9/res/logo1.bmp deleted file mode 100644 index 24cfdbeea8..0000000000 Binary files a/plugins/gs/gsdx9/res/logo1.bmp and /dev/null differ diff --git a/plugins/gs/gsdx9/res/ps11_en00.psh b/plugins/gs/gsdx9/res/ps11_en00.psh deleted file mode 100644 index 8de5108833..0000000000 --- a/plugins/gs/gsdx9/res/ps11_en00.psh +++ /dev/null @@ -1,11 +0,0 @@ -; FRAME_n -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_1 - -tex t2 - -mov r0, t2 diff --git a/plugins/gs/gsdx9/res/ps11_en01.psh b/plugins/gs/gsdx9/res/ps11_en01.psh deleted file mode 100644 index d3b2c9230d..0000000000 --- a/plugins/gs/gsdx9/res/ps11_en01.psh +++ /dev/null @@ -1,12 +0,0 @@ -; RAO2 -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_1 - -tex t1 - -mov r0, c2 -cnd r0, r0.a, c0, t1 diff --git a/plugins/gs/gsdx9/res/ps11_en10.psh b/plugins/gs/gsdx9/res/ps11_en10.psh deleted file mode 100644 index d60e80f681..0000000000 --- a/plugins/gs/gsdx9/res/ps11_en10.psh +++ /dev/null @@ -1,17 +0,0 @@ -; RAO1 -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_1 - -tex t0 - -mov r0, c1 -cnd r0.a, r0.a, c0, t0 -mul r0, t0, r0.a - - - - diff --git a/plugins/gs/gsdx9/res/ps11_en11.psh b/plugins/gs/gsdx9/res/ps11_en11.psh deleted file mode 100644 index 7a2c05d8ef..0000000000 --- a/plugins/gs/gsdx9/res/ps11_en11.psh +++ /dev/null @@ -1,19 +0,0 @@ -; RAO1 + RAO2 -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_1 - -tex t0 -tex t1 - -mov r1, t0 -mov r0, c1 -cnd r1.a, r0.a, c0, r1 - -mov r0, c2 -cnd r0.rgb, r0.a, c0, t1 - -lrp r0, r1.a, r1, r0 diff --git a/plugins/gs/gsdx9/res/ps11_tfx000.psh b/plugins/gs/gsdx9/res/ps11_tfx000.psh deleted file mode 100644 index 4ee69557b2..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx000.psh +++ /dev/null @@ -1,13 +0,0 @@ -; TFX = 0 (MODULATE) | TCC = 0 -; Rv = Rt * Rf -; Gv = Gt * Gf -; Bv = Bt * Bf -; Av = Af - -ps_1_1 - -tex t0 - -mul_x2 r0.rgb, v0, t0 -mov_x2 r0.a, v0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx010.psh b/plugins/gs/gsdx9/res/ps11_tfx010.psh deleted file mode 100644 index fac89d175c..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx010.psh +++ /dev/null @@ -1,13 +0,0 @@ -; TFX = 0 (MODULATE) | TCC = 1 | At = 0.0 - 2.0 -; Rv = Rt * Rf -; Gv = Gt * Gf -; Bv = Bt * Bf -; Av = At * Af - -ps_1_1 - -tex t0 - -mul_x2 r0.rgb, v0, t0 -mul_x4 r0.a, v0, t0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx011.psh b/plugins/gs/gsdx9/res/ps11_tfx011.psh deleted file mode 100644 index aaaf8d6a13..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx011.psh +++ /dev/null @@ -1,13 +0,0 @@ -; TFX = 0 (MODULATE) | TCC = 1 | At = 0.0 - 1.0 -; Rv = Rt * Rf -; Gv = Gt * Gf -; Bv = Bt * Bf -; Av = At * Af - -ps_1_1 - -tex t0 - -mul_x2 r0.rgb, v0, t0 -mul_x2 r0.a, v0, t0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx1x0.psh b/plugins/gs/gsdx9/res/ps11_tfx1x0.psh deleted file mode 100644 index 4faac00638..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx1x0.psh +++ /dev/null @@ -1,13 +0,0 @@ -; TFX = 1 (DECAL) | TCC = x | At = 0.0 - 2.0 -; Rv = Rt -; Gv = Gt -; Bv = Bt -; Av = At - -ps_1_1 - -tex t0 - -mov r0.rgb, t0 -mov_x2 r0.a, t0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx1x1.psh b/plugins/gs/gsdx9/res/ps11_tfx1x1.psh deleted file mode 100644 index 00304947f0..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx1x1.psh +++ /dev/null @@ -1,13 +0,0 @@ -; TFX = 1 (DECAL) | TCC = x | At = 0.0 - 1.0 -; Rv = Rt -; Gv = Gt -; Bv = Bt -; Av = At - -ps_1_1 - -tex t0 - -mov r0, t0 -lrp r0.rgb, v1.a, r0, v1 - diff --git a/plugins/gs/gsdx9/res/ps11_tfx200.psh b/plugins/gs/gsdx9/res/ps11_tfx200.psh deleted file mode 100644 index 062581c5ec..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx200.psh +++ /dev/null @@ -1,14 +0,0 @@ -; TFX = 2 (HIGHLIGHT) | TCC = 0 -; Rv = Rt * Rf + Af -; Gv = Gt * Gf + Af -; Bv = Bt * Bf + Af -; Av = Af - -ps_1_1 - -tex t0 - -mov_x2 r1, t0 -mad r0.rgb, v0, r1, v0.a -mov_x2 r0.a, v0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx210.psh b/plugins/gs/gsdx9/res/ps11_tfx210.psh deleted file mode 100644 index b962a8808d..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx210.psh +++ /dev/null @@ -1,14 +0,0 @@ -; TFX = 2 (HIGHLIGHT) | TCC = 1 | At = 0.0 - 2.0 -; Rv = Rt * Rf + Af -; Gv = Gt * Gf + Af -; Bv = Bt * Bf + Af -; Av = At + Af - -ps_1_1 - -tex t0 - -mov_x2 r1, t0 -mad r0.rgb, v0, r1, v0.a -add_x2 r0.a, v0, t0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx211.psh b/plugins/gs/gsdx9/res/ps11_tfx211.psh deleted file mode 100644 index 61eb5c9cb5..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx211.psh +++ /dev/null @@ -1,15 +0,0 @@ -; TFX = 2 (HIGHLIGHT) | TCC = 1 | At = 0.0 - 1.0 -; Rv = Rt * Rf + Af -; Gv = Gt * Gf + Af -; Bv = Bt * Bf + Af -; Av = At + Af - -ps_1_1 - -tex t0 - -mov_x2 r1, t0 -mad r0.rgb, v0, r1, v0.a -mov_x2 r1, v0 -add r0.a, r1, t0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx300.psh b/plugins/gs/gsdx9/res/ps11_tfx300.psh deleted file mode 100644 index 1b5f67d375..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx300.psh +++ /dev/null @@ -1,14 +0,0 @@ -; TFX = 3 (HIGHLIGHT) | TCC = 0 -; Rv = Rt * Rf + Af -; Gv = Gt * Gf + Af -; Bv = Bt * Bf + Af -; Av = Af - -ps_1_1 - -tex t0 - -mov_x2 r1, t0 -mad r0.rgb, v0, r1, v0.a -mov_x2 r0.a, v0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx310.psh b/plugins/gs/gsdx9/res/ps11_tfx310.psh deleted file mode 100644 index c776e7b0e4..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx310.psh +++ /dev/null @@ -1,14 +0,0 @@ -; TFX = 3 (HIGHLIGHT) | TCC = 1 | At = 0.0 - 2.0 -; Rv = Rt * Rf + Af -; Gv = Gt * Gf + Af -; Bv = Bt * Bf + Af -; Av = At - -ps_1_1 - -tex t0 - -mov_x2 r1, t0 -mad r0.rgb, v0, r1, v0.a -mov_x2 r0.a, t0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx311.psh b/plugins/gs/gsdx9/res/ps11_tfx311.psh deleted file mode 100644 index 4a264aa4c5..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx311.psh +++ /dev/null @@ -1,14 +0,0 @@ -; TFX = 3 (HIGHLIGHT) | TCC = 1 | At = 0.0 - 1.0 -; Rv = Rt * Rf + Af -; Gv = Gt * Gf + Af -; Bv = Bt * Bf + Af -; Av = At - -ps_1_1 - -tex t0 - -mov_x2 r1, t0 -mad r0.rgb, v0, r1, v0.a -mov r0.a, t0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps11_tfx4xx.psh b/plugins/gs/gsdx9/res/ps11_tfx4xx.psh deleted file mode 100644 index 74ccf1b9fc..0000000000 --- a/plugins/gs/gsdx9/res/ps11_tfx4xx.psh +++ /dev/null @@ -1,4 +0,0 @@ -ps_1_1 - -mov r0, v0 -lrp r0.rgb, v1.a, r0, v1 diff --git a/plugins/gs/gsdx9/res/ps14_en00.psh b/plugins/gs/gsdx9/res/ps14_en00.psh deleted file mode 100644 index 706b67ead3..0000000000 --- a/plugins/gs/gsdx9/res/ps14_en00.psh +++ /dev/null @@ -1,13 +0,0 @@ -; FRAME_n -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_4 - -texld r2, t2 - -mov r0.ga, r2 -mov r0.b, r2.r -mov r0.r, r2.b diff --git a/plugins/gs/gsdx9/res/ps14_en01.psh b/plugins/gs/gsdx9/res/ps14_en01.psh deleted file mode 100644 index c23756a12f..0000000000 --- a/plugins/gs/gsdx9/res/ps14_en01.psh +++ /dev/null @@ -1,16 +0,0 @@ -; RAO2 -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_4 - -texld r1, t1 - -mov r0, c2 -cnd r1, r0.a, c0, r1 - -mov r0.ga, r1 -mov r0.b, r1.r -mov r0.r, r1.b diff --git a/plugins/gs/gsdx9/res/ps14_en10.psh b/plugins/gs/gsdx9/res/ps14_en10.psh deleted file mode 100644 index 6616208e07..0000000000 --- a/plugins/gs/gsdx9/res/ps14_en10.psh +++ /dev/null @@ -1,20 +0,0 @@ -; RAO1 -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_4 - -texld r0, t0 -mov r1, r0 // FIXME - -mov r0, c1 -cnd r0.a, r0.a, c0, r1 -mul r2, r1, r0.a - -mov r0.ga, r2 -mov r0.b, r2.r -mov r0.r, r2.b - - diff --git a/plugins/gs/gsdx9/res/ps14_en11.psh b/plugins/gs/gsdx9/res/ps14_en11.psh deleted file mode 100644 index 299d47f462..0000000000 --- a/plugins/gs/gsdx9/res/ps14_en11.psh +++ /dev/null @@ -1,23 +0,0 @@ -; RAO1 + RAO2 -; c0.rgb = BGCOLOR -; c0.a = ALP -; c1.a = MMOD -; c2.a = SLBG - -ps_1_4 - -texld r0, t0 -texld r1, t1 - -mov r2, c1 -cnd r0.a, r2.a, c0, r0 - -mov r2, c2 -cnd r1.rgb, r2.a, c0, r1 - -lrp r2, r0.a, r0, r1 - -mov r0.ga, r2 -mov r0.b, r2.r -mov r0.r, r2.b - diff --git a/plugins/gs/gsdx9/resource.h b/plugins/gs/gsdx9/resource.h deleted file mode 100644 index a84766a233..0000000000 --- a/plugins/gs/gsdx9/resource.h +++ /dev/null @@ -1,55 +0,0 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Visual C++ generated include file. -// Used by GSdx9.rc -// -#define IDC_CHECK1 2001 -#define IDR_PS11_TFX000 2001 -#define IDC_CHECK2 2002 -#define IDR_PS11_TFX010 2002 -#define IDC_CHECK3 2003 -#define IDR_PS11_TFX011 2003 -#define IDD_CONFIG 2004 -#define IDR_PS11_TFX1x0 2004 -#define IDC_CHECK5 2004 -#define IDR_PS11_TFX1x1 2005 -#define IDR_PS11_TFX200 2006 -#define IDC_COMBO1 2006 -#define IDR_PS11_TFX210 2007 -#define IDR_PS11_TFX211 2008 -#define IDC_COMBO3 2008 -#define IDR_PS11_TFX300 2009 -#define IDC_COMBO4 2009 -#define IDR_PS11_TFX310 2010 -#define IDC_EDIT1 2010 -#define IDR_PS11_TFX311 2011 -#define IDC_BUTTON1 2011 -#define IDR_PS11_TFX4xx 2012 -#define IDC_BUTTON2 2012 -#define IDR_PS11_EN11 2013 -#define IDC_CUSTOM1 2013 -#define IDR_PS11_EN01 2014 -#define IDC_CHECK4 2014 -#define IDR_PS11_EN10 2015 -#define IDC_COMBO2 2015 -#define IDR_PS11_EN00 2016 -#define IDR_HLSL_TFX 2017 -#define IDR_HLSL_MERGE 2018 -#define IDD_CAPTURE 2018 -#define IDR_PS14_EN11 2019 -#define IDR_PS14_EN01 2020 -#define IDR_PS14_EN10 2021 -#define IDR_PS14_EN00 2022 -#define IDR_HLSL_RB 2023 -#define IDB_BITMAP1 2024 -#define IDB_LOGO1 2024 - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 2025 -#define _APS_NEXT_COMMAND_VALUE 32771 -#define _APS_NEXT_CONTROL_VALUE 2016 -#define _APS_NEXT_SYMED_VALUE 2000 -#endif -#endif diff --git a/plugins/gs/gsdx9/stdafx.cpp b/plugins/gs/gsdx9/stdafx.cpp deleted file mode 100644 index 35050994b9..0000000000 --- a/plugins/gs/gsdx9/stdafx.cpp +++ /dev/null @@ -1,7 +0,0 @@ -// stdafx.cpp : source file that includes just the standard includes -// GSdx9.pch will be the pre-compiled header -// stdafx.obj will contain the pre-compiled type information - -#include "stdafx.h" - - diff --git a/plugins/gs/gsdx9/stdafx.h b/plugins/gs/gsdx9/stdafx.h deleted file mode 100644 index 478fe9785e..0000000000 --- a/plugins/gs/gsdx9/stdafx.h +++ /dev/null @@ -1,95 +0,0 @@ -// stdafx.h : include file for standard system include files, -// or project specific include files that are used frequently, but -// are changed infrequently - -#pragma once - -#pragma warning(disable: 4996) - -#ifndef VC_EXTRALEAN -#define VC_EXTRALEAN // Exclude rarely-used stuff from Windows headers -#endif - -// Modify the following defines if you have to target a platform prior to the ones specified below. -// Refer to MSDN for the latest info on corresponding values for different platforms. -#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. -#define WINVER 0x0510 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. -#endif - -#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. -#define _WIN32_WINNT 0x0400 // Change this to the appropriate value to target Windows 2000 or later. -#endif - -#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. -#define _WIN32_WINDOWS 0x0410 // Change this to the appropriate value to target Windows Me or later. -#endif - -#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. -#define _WIN32_IE 0x0400 // Change this to the appropriate value to target IE 5.0 or later. -#endif - -#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit - -#include // MFC core and standard components -#include // MFC extensions -/* -#ifndef _AFX_NO_OLE_SUPPORT -#include // MFC OLE classes -#include // MFC OLE dialog classes -#include // MFC Automation classes -#endif // _AFX_NO_OLE_SUPPORT - -#ifndef _AFX_NO_DB_SUPPORT -#include // MFC ODBC database classes -#endif // _AFX_NO_DB_SUPPORT - -#include // MFC support for Internet Explorer 4 Common Controls -*/ -#ifndef _AFX_NO_AFXCMN_SUPPORT -#include // MFC support for Windows Common Controls -#endif // _AFX_NO_AFXCMN_SUPPORT - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef _OPENMP -#include -#endif - -#define countof(a) (sizeof(a)/sizeof(a[0])) - -#define EXPORT_C extern "C" __declspec(dllexport) void __stdcall -#define EXPORT_C_(type) extern "C" __declspec(dllexport) type __stdcall - -#define QI(i) (riid == __uuidof(i)) ? GetInterface((i*)this, ppv) : - -#define BeginEnumSysDev(clsid, pMoniker) \ - {CComPtr pDevEnum4$##clsid; \ - pDevEnum4$##clsid.CoCreateInstance(CLSID_SystemDeviceEnum); \ - CComPtr pClassEnum4$##clsid; \ - if(SUCCEEDED(pDevEnum4$##clsid->CreateClassEnumerator(clsid, &pClassEnum4$##clsid, 0)) \ - && pClassEnum4$##clsid) \ - { \ - for(CComPtr pMoniker; pClassEnum4$##clsid->Next(1, &pMoniker, 0) == S_OK; pMoniker = NULL) \ - { \ - -#define EndEnumSysDev }}} - -#pragma warning(disable : 4995 4324) - -#ifndef RESTRICT - #ifdef __INTEL_COMPILER - #define RESTRICT restrict - #elif _MSC_VER >= 1400 - #define RESTRICT __restrict - #else - #define RESTRICT - #endif -#endif \ No newline at end of file diff --git a/plugins/gs/gsdx9/x86-32.asm b/plugins/gs/gsdx9/x86-32.asm deleted file mode 100644 index 4e945c43e0..0000000000 --- a/plugins/gs/gsdx9/x86-32.asm +++ /dev/null @@ -1,1335 +0,0 @@ - - .686 - .model flat - .mmx - .xmm - - .const - - __uvmin DD 0d01502f9r ; -1e+010 - __uvmax DD 0501502f9r ; +1e+010 - - .code - -; -; memsetd -; - -@memsetd@12 proc public - - push edi - - mov edi, ecx - mov eax, edx - mov ecx, [esp+4+4] - cld - rep stosd - - pop edi - - ret 4 - -@memsetd@12 endp - -; -; SaturateColor -; - -@SaturateColor_sse2@4 proc public - - pxor xmm0, xmm0 - movdqa xmm1, [ecx] - packssdw xmm1, xmm0 - packuswb xmm1, xmm0 - punpcklbw xmm1, xmm0 - punpcklwd xmm1, xmm0 - movdqa [ecx], xmm1 - - ret - -@SaturateColor_sse2@4 endp - -@SaturateColor_asm@4 proc public - - push esi - - mov esi, ecx - - xor eax, eax - mov edx, 000000ffh - - mov ecx, [esi] - cmp ecx, eax - cmovl ecx, eax - cmp ecx, edx - cmovg ecx, edx - mov [esi], ecx - - mov ecx, [esi+4] - cmp ecx, eax - cmovl ecx, eax - cmp ecx, edx - cmovg ecx, edx - mov [esi+4], ecx - - mov ecx, [esi+8] - cmp ecx, eax - cmovl ecx, eax - cmp ecx, edx - cmovg ecx, edx - mov [esi+8], ecx - - mov ecx, [esi+12] - cmp ecx, eax - cmovl ecx, eax - cmp ecx, edx - cmovg ecx, edx - mov [esi+12], ecx - - pop esi - - ret - -@SaturateColor_asm@4 endp - -; -; swizzling -; - -punpck macro op, sd0, sd2, s1, s3, d1, d3 - - movdqa @CatStr(xmm, %d1), @CatStr(xmm, %sd0) - pshufd @CatStr(xmm, %d3), @CatStr(xmm, %sd2), 0e4h - - @CatStr(punpckl, op) @CatStr(xmm, %sd0), @CatStr(xmm, %s1) - @CatStr(punpckh, op) @CatStr(xmm, %d1), @CatStr(xmm, %s1) - @CatStr(punpckl, op) @CatStr(xmm, %sd2), @CatStr(xmm, %s3) - @CatStr(punpckh, op) @CatStr(xmm, %d3), @CatStr(xmm, %s3) - - endm - -punpcknb macro - - movdqa xmm4, xmm0 - pshufd xmm5, xmm1, 0e4h - - psllq xmm1, 4 - psrlq xmm4, 4 - - movdqa xmm6, xmm7 - pand xmm0, xmm7 - pandn xmm6, xmm1 - por xmm0, xmm6 - - movdqa xmm6, xmm7 - pand xmm4, xmm7 - pandn xmm6, xmm5 - por xmm4, xmm6 - - movdqa xmm1, xmm4 - - movdqa xmm4, xmm2 - pshufd xmm5, xmm3, 0e4h - - psllq xmm3, 4 - psrlq xmm4, 4 - - movdqa xmm6, xmm7 - pand xmm2, xmm7 - pandn xmm6, xmm3 - por xmm2, xmm6 - - movdqa xmm6, xmm7 - pand xmm4, xmm7 - pandn xmm6, xmm5 - por xmm4, xmm6 - - movdqa xmm3, xmm4 - - punpck bw, 0, 2, 1, 3, 4, 6 - - endm - -; -; unSwizzleBlock32 -; - -@unSwizzleBlock32_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - lea eax, [ebx*2] - add eax, ebx - - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm2, [ecx+16*2] - movdqa xmm3, [ecx+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - movdqa [edx], xmm0 - movdqa [edx+16], xmm2 - movdqa [edx+ebx], xmm4 - movdqa [edx+ebx+16], xmm6 - - movdqa xmm0, [ecx+16*4] - movdqa xmm1, [ecx+16*5] - movdqa xmm2, [ecx+16*6] - movdqa xmm3, [ecx+16*7] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - movdqa [edx+ebx*2], xmm0 - movdqa [edx+ebx*2+16], xmm2 - movdqa [edx+eax], xmm4 - movdqa [edx+eax+16], xmm6 - - lea edx, [edx+ebx*4] - - movdqa xmm0, [ecx+16*8] - movdqa xmm1, [ecx+16*9] - movdqa xmm2, [ecx+16*10] - movdqa xmm3, [ecx+16*11] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - movdqa [edx], xmm0 - movdqa [edx+16], xmm2 - movdqa [edx+ebx], xmm4 - movdqa [edx+ebx+16], xmm6 - - movdqa xmm0, [ecx+16*12] - movdqa xmm1, [ecx+16*13] - movdqa xmm2, [ecx+16*14] - movdqa xmm3, [ecx+16*15] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - movdqa [edx+ebx*2], xmm0 - movdqa [edx+ebx*2+16], xmm2 - movdqa [edx+eax], xmm4 - movdqa [edx+eax+16], xmm6 - - pop ebx - - ret 4 - -@unSwizzleBlock32_sse2@12 endp - -; -; unSwizzleBlock16 -; - -@unSwizzleBlock16_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 4 - - align 16 -@@: - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm2, [ecx+16*2] - movdqa xmm3, [ecx+16*3] - - punpck wd, 0, 2, 1, 3, 4, 6 - punpck dq, 0, 4, 2, 6, 1, 3 - punpck wd, 0, 4, 1, 3, 2, 6 - - movdqa [edx], xmm0 - movdqa [edx+16], xmm2 - movdqa [edx+ebx], xmm4 - movdqa [edx+ebx+16], xmm6 - - add ecx, 64 - lea edx, [edx+ebx*2] - - dec eax - jnz @B - - pop ebx - - ret 4 - -@unSwizzleBlock16_sse2@12 endp - -; -; unSwizzleBlock8 -; - -@unSwizzleBlock8_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 2 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm4, [ecx+16*2] - movdqa xmm5, [ecx+16*3] - - punpck bw, 0, 4, 1, 5, 2, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 2, 4, 6, 1, 3 - - pshufd xmm1, xmm1, 0b1h - pshufd xmm3, xmm3, 0b1h - - movdqa [edx], xmm0 - movdqa [edx+ebx], xmm2 - lea edx, [edx+ebx*2] - - movdqa [edx], xmm1 - movdqa [edx+ebx], xmm3 - lea edx, [edx+ebx*2] - - ; col 1, 3 - - movdqa xmm0, [ecx+16*4] - movdqa xmm1, [ecx+16*5] - movdqa xmm4, [ecx+16*6] - movdqa xmm5, [ecx+16*7] - - punpck bw, 0, 4, 1, 5, 2, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 2, 4, 6, 1, 3 - - pshufd xmm0, xmm0, 0b1h - pshufd xmm2, xmm2, 0b1h - - movdqa [edx], xmm0 - movdqa [edx+ebx], xmm2 - lea edx, [edx+ebx*2] - - movdqa [edx], xmm1 - movdqa [edx+ebx], xmm3 - lea edx, [edx+ebx*2] - - add ecx, 128 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@unSwizzleBlock8_sse2@12 endp - -; -; unSwizzleBlock4 -; - -@unSwizzleBlock4_sse2@12 proc public - - push ebx - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - mov ebx, [esp+4+4] - mov eax, 2 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm4, [ecx+16*2] - movdqa xmm3, [ecx+16*3] - - punpck dq, 0, 4, 1, 3, 2, 6 - punpck dq, 0, 2, 4, 6, 1, 3 - punpcknb - punpck bw, 0, 2, 4, 6, 1, 3 - punpck wd, 0, 2, 1, 3, 4, 6 - - pshufd xmm0, xmm0, 0d8h - pshufd xmm2, xmm2, 0d8h - pshufd xmm4, xmm4, 0d8h - pshufd xmm6, xmm6, 0d8h - - punpck qdq, 0, 2, 4, 6, 1, 3 - - pshuflw xmm1, xmm1, 0b1h - pshuflw xmm3, xmm3, 0b1h - pshufhw xmm1, xmm1, 0b1h - pshufhw xmm3, xmm3, 0b1h - - movdqa [edx], xmm0 - movdqa [edx+ebx], xmm2 - lea edx, [edx+ebx*2] - - movdqa [edx], xmm1 - movdqa [edx+ebx], xmm3 - lea edx, [edx+ebx*2] - - ; col 1, 3 - - movdqa xmm0, [ecx+16*4] - movdqa xmm1, [ecx+16*5] - movdqa xmm4, [ecx+16*6] - movdqa xmm3, [ecx+16*7] - - punpck dq, 0, 4, 1, 3, 2, 6 - punpck dq, 0, 2, 4, 6, 1, 3 - punpcknb - punpck bw, 0, 2, 4, 6, 1, 3 - punpck wd, 0, 2, 1, 3, 4, 6 - - pshufd xmm0, xmm0, 0d8h - pshufd xmm2, xmm2, 0d8h - pshufd xmm4, xmm4, 0d8h - pshufd xmm6, xmm6, 0d8h - - punpck qdq, 0, 2, 4, 6, 1, 3 - - pshuflw xmm0, xmm0, 0b1h - pshuflw xmm2, xmm2, 0b1h - pshufhw xmm0, xmm0, 0b1h - pshufhw xmm2, xmm2, 0b1h - - movdqa [edx], xmm0 - movdqa [edx+ebx], xmm2 - lea edx, [edx+ebx*2] - - movdqa [edx], xmm1 - movdqa [edx+ebx], xmm3 - lea edx, [edx+ebx*2] - - add ecx, 128 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@unSwizzleBlock4_sse2@12 endp - -; -; unSwizzleBlock8HP -; - -@unSwizzleBlock8HP_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 4 - - align 16 -@@: - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm2, [ecx+16*2] - movdqa xmm3, [ecx+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - psrld xmm0, 24 - psrld xmm2, 24 - psrld xmm4, 24 - psrld xmm6, 24 - - packssdw xmm0, xmm2 - packssdw xmm4, xmm6 - packuswb xmm0, xmm4 - - movlps qword ptr [edx], xmm0 - movhps qword ptr [edx+ebx], xmm0 - - add ecx, 64 - lea edx, [edx+ebx*2] - - dec eax - jnz @B - - pop ebx - - ret 4 - -@unSwizzleBlock8HP_sse2@12 endp - -; -; unSwizzleBlock4HLP -; - -@unSwizzleBlock4HLP_sse2@12 proc public - - push ebx - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - mov ebx, [esp+4+4] - mov eax, 4 - - align 16 -@@: - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm2, [ecx+16*2] - movdqa xmm3, [ecx+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - psrld xmm0, 24 - psrld xmm2, 24 - psrld xmm4, 24 - psrld xmm6, 24 - - packssdw xmm0, xmm2 - packssdw xmm4, xmm6 - packuswb xmm0, xmm4 - - pand xmm0, xmm7 - - movlps qword ptr [edx], xmm0 - movhps qword ptr [edx+ebx], xmm0 - - add ecx, 64 - lea edx, [edx+ebx*2] - - dec eax - jnz @B - - pop ebx - - ret 4 - -@unSwizzleBlock4HLP_sse2@12 endp - -; -; unSwizzleBlock4HHP -; - -@unSwizzleBlock4HHP_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 4 - - align 16 -@@: - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm2, [ecx+16*2] - movdqa xmm3, [ecx+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - psrld xmm0, 28 - psrld xmm2, 28 - psrld xmm4, 28 - psrld xmm6, 28 - - packssdw xmm0, xmm2 - packssdw xmm4, xmm6 - packuswb xmm0, xmm4 - - movlps qword ptr [edx], xmm0 - movhps qword ptr [edx+ebx], xmm0 - - add ecx, 64 - lea edx, [edx+ebx*2] - - dec eax - jnz @B - - pop ebx - - ret 4 - -@unSwizzleBlock4HHP_sse2@12 endp - -; -; unSwizzleBlock4P -; - -@unSwizzleBlock4P_sse2@12 proc public - - push esi - push edi - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - mov esi, [esp+4+8] - lea edi, [esi*2] - add edi, esi - - ; col 0 - - movdqa xmm0, [ecx+16*0] - movdqa xmm1, [ecx+16*1] - movdqa xmm2, [ecx+16*2] - movdqa xmm3, [ecx+16*3] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm7 - pandn xmm1, xmm0 - pand xmm0, xmm7 - pshufd xmm1, xmm1, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm2 - pand xmm2, xmm7 - pshufd xmm3, xmm3, 0b1h - psrlq xmm3, 4 - - movdqa [edx], xmm0 - movdqa [edx+16], xmm2 - movdqa [edx+esi*2], xmm1 - movdqa [edx+esi*2+16], xmm3 - - movdqa xmm1, xmm7 - pandn xmm1, xmm4 - pand xmm4, xmm7 - pshufd xmm1, xmm1, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm6 - pand xmm6, xmm7 - pshufd xmm3, xmm3, 0b1h - psrlq xmm3, 4 - - movdqa [edx+esi], xmm4 - movdqa [edx+esi+16], xmm6 - movdqa [edx+edi], xmm1 - movdqa [edx+edi+16], xmm3 - - lea edx, [edx+esi*4] - - ; col 1 - - movdqa xmm0, [ecx+16*4] - movdqa xmm1, [ecx+16*5] - movdqa xmm2, [ecx+16*6] - movdqa xmm3, [ecx+16*7] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm7 - pandn xmm1, xmm0 - pand xmm0, xmm7 - pshufd xmm0, xmm0, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm2 - pand xmm2, xmm7 - pshufd xmm2, xmm2, 0b1h - psrlq xmm3, 4 - - movdqa [edx], xmm0 - movdqa [edx+16], xmm2 - movdqa [edx+esi*2], xmm1 - movdqa [edx+esi*2+16], xmm3 - - movdqa xmm1, xmm7 - pandn xmm1, xmm4 - pand xmm4, xmm7 - pshufd xmm4, xmm4, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm6 - pand xmm6, xmm7 - pshufd xmm6, xmm6, 0b1h - psrlq xmm3, 4 - - movdqa [edx+esi], xmm4 - movdqa [edx+esi+16], xmm6 - movdqa [edx+edi], xmm1 - movdqa [edx+edi+16], xmm3 - - lea edx, [edx+esi*4] - - ; col 2 - - movdqa xmm0, [ecx+16*8] - movdqa xmm1, [ecx+16*9] - movdqa xmm2, [ecx+16*10] - movdqa xmm3, [ecx+16*11] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm7 - pandn xmm1, xmm0 - pand xmm0, xmm7 - pshufd xmm1, xmm1, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm2 - pand xmm2, xmm7 - pshufd xmm3, xmm3, 0b1h - psrlq xmm3, 4 - - movdqa [edx], xmm0 - movdqa [edx+16], xmm2 - movdqa [edx+esi*2], xmm1 - movdqa [edx+esi*2+16], xmm3 - - movdqa xmm1, xmm7 - pandn xmm1, xmm4 - pand xmm4, xmm7 - pshufd xmm1, xmm1, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm6 - pand xmm6, xmm7 - pshufd xmm3, xmm3, 0b1h - psrlq xmm3, 4 - - movdqa [edx+esi], xmm4 - movdqa [edx+esi+16], xmm6 - movdqa [edx+edi], xmm1 - movdqa [edx+edi+16], xmm3 - - lea edx, [edx+esi*4] - - ; col 3 - - movdqa xmm0, [ecx+16*12] - movdqa xmm1, [ecx+16*13] - movdqa xmm2, [ecx+16*14] - movdqa xmm3, [ecx+16*15] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm7 - pandn xmm1, xmm0 - pand xmm0, xmm7 - pshufd xmm0, xmm0, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm2 - pand xmm2, xmm7 - pshufd xmm2, xmm2, 0b1h - psrlq xmm3, 4 - - movdqa [edx], xmm0 - movdqa [edx+16], xmm2 - movdqa [edx+esi*2], xmm1 - movdqa [edx+esi*2+16], xmm3 - - movdqa xmm1, xmm7 - pandn xmm1, xmm4 - pand xmm4, xmm7 - pshufd xmm4, xmm4, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm7 - pandn xmm3, xmm6 - pand xmm6, xmm7 - pshufd xmm6, xmm6, 0b1h - psrlq xmm3, 4 - - movdqa [edx+esi], xmm4 - movdqa [edx+esi+16], xmm6 - movdqa [edx+edi], xmm1 - movdqa [edx+edi+16], xmm3 - - ; lea edx, [edx+esi*4] - - pop edi - pop esi - - ret 4 - -@unSwizzleBlock4P_sse2@12 endp - -; -; swizzling -; - -; -; SwizzleBlock32 -; - -@SwizzleBlock32_sse2@16 proc public - - - push esi - push edi - - mov edi, ecx - mov esi, edx - mov edx, [esp+4+8] - mov ecx, 4 - - mov eax, [esp+8+8] - cmp eax, 0ffffffffh - jnz SwizzleBlock32_sse2@WM - - align 16 -@@: - movdqa xmm0, [esi] - movdqa xmm4, [esi+16] - movdqa xmm1, [esi+edx] - movdqa xmm5, [esi+edx+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa [edi+16*0], xmm0 - movdqa [edi+16*1], xmm2 - movdqa [edi+16*2], xmm4 - movdqa [edi+16*3], xmm6 - - lea esi, [esi+edx*2] - add edi, 64 - - dec ecx - jnz @B - - pop edi - pop esi - - ret 8 - -SwizzleBlock32_sse2@WM: - - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - align 16 -@@: - movdqa xmm0, [esi] - movdqa xmm4, [esi+16] - movdqa xmm1, [esi+edx] - movdqa xmm5, [esi+edx+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa xmm3, xmm7 - pshufd xmm5, xmm7, 0e4h - - pandn xmm3, [edi+16*0] - pand xmm0, xmm7 - por xmm0, xmm3 - movdqa [edi+16*0], xmm0 - - pandn xmm5, [edi+16*1] - pand xmm2, xmm7 - por xmm2, xmm5 - movdqa [edi+16*1], xmm2 - - movdqa xmm3, xmm7 - pshufd xmm5, xmm7, 0e4h - - pandn xmm3, [edi+16*2] - pand xmm4, xmm7 - por xmm4, xmm3 - movdqa [edi+16*2], xmm4 - - pandn xmm5, [edi+16*3] - pand xmm6, xmm7 - por xmm6, xmm5 - movdqa [edi+16*3], xmm6 - - lea esi, [esi+edx*2] - add edi, 64 - - dec ecx - jnz @B - - pop edi - pop esi - - ret 8 - -@SwizzleBlock32_sse2@16 endp - -; -; SwizzleBlock16 -; - -@SwizzleBlock16_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 4 - - align 16 -@@: - movdqa xmm0, [edx] - movdqa xmm1, [edx+16] - movdqa xmm2, [edx+ebx] - movdqa xmm3, [edx+ebx+16] - - punpck wd, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 5 - - movdqa [ecx+16*0], xmm0 - movdqa [ecx+16*1], xmm1 - movdqa [ecx+16*2], xmm4 - movdqa [ecx+16*3], xmm5 - - lea edx, [edx+ebx*2] - add ecx, 64 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@SwizzleBlock16_sse2@12 endp - -; -; SwizzleBlock8 -; - -@SwizzleBlock8_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 2 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [edx] - movdqa xmm2, [edx+ebx] - lea edx, [edx+ebx*2] - - pshufd xmm1, [edx], 0b1h - pshufd xmm3, [edx+ebx], 0b1h - lea edx, [edx+ebx*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [ecx+16*0], xmm0 - movdqa [ecx+16*1], xmm4 - movdqa [ecx+16*2], xmm1 - movdqa [ecx+16*3], xmm5 - - ; col 1, 3 - - pshufd xmm0, [edx], 0b1h - pshufd xmm2, [edx+ebx], 0b1h - lea edx, [edx+ebx*2] - - movdqa xmm1, [edx] - movdqa xmm3, [edx+ebx] - lea edx, [edx+ebx*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [ecx+16*4], xmm0 - movdqa [ecx+16*5], xmm4 - movdqa [ecx+16*6], xmm1 - movdqa [ecx+16*7], xmm5 - - add ecx, 128 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@SwizzleBlock8_sse2@12 endp - -; -; SwizzleBlock4 -; - -@SwizzleBlock4_sse2@12 proc public - - push ebx - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - mov ebx, [esp+4+4] - mov eax, 2 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [edx] - movdqa xmm2, [edx+ebx] - lea edx, [edx+ebx*2] - - movdqa xmm1, [edx] - movdqa xmm3, [edx+ebx] - lea edx, [edx+ebx*2] - - pshuflw xmm1, xmm1, 0b1h - pshuflw xmm3, xmm3, 0b1h - pshufhw xmm1, xmm1, 0b1h - pshufhw xmm3, xmm3, 0b1h - - punpcknb - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [ecx+16*0], xmm0 - movdqa [ecx+16*1], xmm1 - movdqa [ecx+16*2], xmm4 - movdqa [ecx+16*3], xmm3 - - ; col 1, 3 - - movdqa xmm0, [edx] - movdqa xmm2, [edx+ebx] - lea edx, [edx+ebx*2] - - movdqa xmm1, [edx] - movdqa xmm3, [edx+ebx] - lea edx, [edx+ebx*2] - - pshuflw xmm0, xmm0, 0b1h - pshuflw xmm2, xmm2, 0b1h - pshufhw xmm0, xmm0, 0b1h - pshufhw xmm2, xmm2, 0b1h - - punpcknb - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [ecx+16*4], xmm0 - movdqa [ecx+16*5], xmm1 - movdqa [ecx+16*6], xmm4 - movdqa [ecx+16*7], xmm3 - - add ecx, 128 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@SwizzleBlock4_sse2@12 endp - -; -; swizzling with unaligned reads -; - -; -; SwizzleBlock32u -; - -@SwizzleBlock32u_sse2@16 proc public - - push esi - push edi - - mov edi, ecx - mov esi, edx - mov edx, [esp+4+8] - mov ecx, 4 - - mov eax, [esp+8+8] - cmp eax, 0ffffffffh - jnz SwizzleBlock32u_sse2@WM - - align 16 -@@: - movdqu xmm0, [esi] - movdqu xmm4, [esi+16] - movdqu xmm1, [esi+edx] - movdqu xmm5, [esi+edx+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa [edi+16*0], xmm0 - movdqa [edi+16*1], xmm2 - movdqa [edi+16*2], xmm4 - movdqa [edi+16*3], xmm6 - - lea esi, [esi+edx*2] - add edi, 64 - - dec ecx - jnz @B - - pop edi - pop esi - - ret 8 - -SwizzleBlock32u_sse2@WM: - - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - align 16 -@@: - movdqu xmm0, [esi] - movdqu xmm4, [esi+16] - movdqu xmm1, [esi+edx] - movdqu xmm5, [esi+edx+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa xmm3, xmm7 - pshufd xmm5, xmm7, 0e4h - - pandn xmm3, [edi+16*0] - pand xmm0, xmm7 - por xmm0, xmm3 - movdqa [edi+16*0], xmm0 - - pandn xmm5, [edi+16*1] - pand xmm2, xmm7 - por xmm2, xmm5 - movdqa [edi+16*1], xmm2 - - movdqa xmm3, xmm7 - pshufd xmm5, xmm7, 0e4h - - pandn xmm3, [edi+16*2] - pand xmm4, xmm7 - por xmm4, xmm3 - movdqa [edi+16*2], xmm4 - - pandn xmm5, [edi+16*3] - pand xmm6, xmm7 - por xmm6, xmm5 - movdqa [edi+16*3], xmm6 - - lea esi, [esi+edx*2] - add edi, 64 - - dec ecx - jnz @B - - pop edi - pop esi - - ret 8 - -@SwizzleBlock32u_sse2@16 endp - -; -; SwizzleBlock16u -; - -@SwizzleBlock16u_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 4 - - align 16 -@@: - movdqu xmm0, [edx] - movdqu xmm1, [edx+16] - movdqu xmm2, [edx+ebx] - movdqu xmm3, [edx+ebx+16] - - punpck wd, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 5 - - movdqa [ecx+16*0], xmm0 - movdqa [ecx+16*1], xmm1 - movdqa [ecx+16*2], xmm4 - movdqa [ecx+16*3], xmm5 - - lea edx, [edx+ebx*2] - add ecx, 64 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@SwizzleBlock16u_sse2@12 endp - -; -; SwizzleBlock8u -; - -@SwizzleBlock8u_sse2@12 proc public - - push ebx - - mov ebx, [esp+4+4] - mov eax, 2 - - align 16 -@@: - ; col 0, 2 - - movdqu xmm0, [edx] - movdqu xmm2, [edx+ebx] - lea edx, [edx+ebx*2] - - movdqu xmm1, [edx] - movdqu xmm3, [edx+ebx] - pshufd xmm1, xmm1, 0b1h - pshufd xmm3, xmm3, 0b1h - lea edx, [edx+ebx*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [ecx+16*0], xmm0 - movdqa [ecx+16*1], xmm4 - movdqa [ecx+16*2], xmm1 - movdqa [ecx+16*3], xmm5 - - ; col 1, 3 - - movdqu xmm0, [edx] - movdqu xmm2, [edx+ebx] - pshufd xmm0, xmm0, 0b1h - pshufd xmm2, xmm2, 0b1h - lea edx, [edx+ebx*2] - - movdqu xmm1, [edx] - movdqu xmm3, [edx+ebx] - lea edx, [edx+ebx*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [ecx+16*4], xmm0 - movdqa [ecx+16*5], xmm4 - movdqa [ecx+16*6], xmm1 - movdqa [ecx+16*7], xmm5 - - add ecx, 128 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@SwizzleBlock8u_sse2@12 endp - -; -; SwizzleBlock4u -; - -@SwizzleBlock4u_sse2@12 proc public - - push ebx - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - mov ebx, [esp+4+4] - mov eax, 2 - - align 16 -@@: - ; col 0, 2 - - movdqu xmm0, [edx] - movdqu xmm2, [edx+ebx] - lea edx, [edx+ebx*2] - - movdqu xmm1, [edx] - movdqu xmm3, [edx+ebx] - lea edx, [edx+ebx*2] - - pshuflw xmm1, xmm1, 0b1h - pshuflw xmm3, xmm3, 0b1h - pshufhw xmm1, xmm1, 0b1h - pshufhw xmm3, xmm3, 0b1h - - punpcknb - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [ecx+16*0], xmm0 - movdqa [ecx+16*1], xmm1 - movdqa [ecx+16*2], xmm4 - movdqa [ecx+16*3], xmm3 - - ; col 1, 3 - - movdqu xmm0, [edx] - movdqu xmm2, [edx+ebx] - lea edx, [edx+ebx*2] - - movdqu xmm1, [edx] - movdqu xmm3, [edx+ebx] - lea edx, [edx+ebx*2] - - pshuflw xmm0, xmm0, 0b1h - pshuflw xmm2, xmm2, 0b1h - pshufhw xmm0, xmm0, 0b1h - pshufhw xmm2, xmm2, 0b1h - - punpcknb - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [ecx+16*4], xmm0 - movdqa [ecx+16*5], xmm1 - movdqa [ecx+16*6], xmm4 - movdqa [ecx+16*7], xmm3 - - add ecx, 128 - - dec eax - jnz @B - - pop ebx - - ret 4 - -@SwizzleBlock4u_sse2@12 endp - - end \ No newline at end of file diff --git a/plugins/gs/gsdx9/x86-64.asm b/plugins/gs/gsdx9/x86-64.asm deleted file mode 100644 index ed4a9ea6fb..0000000000 --- a/plugins/gs/gsdx9/x86-64.asm +++ /dev/null @@ -1,1418 +0,0 @@ - - .const - - __uvmin DD 0d01502f9r ; -1e+010 - __uvmax DD 0501502f9r ; +1e+010 - - .code - -; -; memsetd -; - -memsetd proc public - - push rdi - - mov rdi, rcx - mov eax, edx - mov rcx, r8 - cld - rep stosd - - pop rdi - - ret - -memsetd endp - -; -; SaturateColor -; - -SaturateColor_amd64 proc public - - pxor xmm0, xmm0 - movdqa xmm1, [rcx] - packssdw xmm1, xmm0 - packuswb xmm1, xmm0 - punpcklbw xmm1, xmm0 - punpcklwd xmm1, xmm0 - movdqa [rcx], xmm1 - - ret - -SaturateColor_amd64 endp - -; -; swizzling -; - -punpck macro op, sd0, sd2, s1, s3, d1, d3 - - movdqa @CatStr(xmm, %d1), @CatStr(xmm, %sd0) - pshufd @CatStr(xmm, %d3), @CatStr(xmm, %sd2), 0e4h - - @CatStr(punpckl, op) @CatStr(xmm, %sd0), @CatStr(xmm, %s1) - @CatStr(punpckh, op) @CatStr(xmm, %d1), @CatStr(xmm, %s1) - @CatStr(punpckl, op) @CatStr(xmm, %sd2), @CatStr(xmm, %s3) - @CatStr(punpckh, op) @CatStr(xmm, %d3), @CatStr(xmm, %s3) - - endm - -punpck2 macro op, sd0, sd2, sd4, sd6, s1, s3, s5, s7, d1, d3, d5, d7 - - movdqa @CatStr(xmm, %d1), @CatStr(xmm, %sd0) - pshufd @CatStr(xmm, %d3), @CatStr(xmm, %sd2), 0e4h - movdqa @CatStr(xmm, %d5), @CatStr(xmm, %sd4) - pshufd @CatStr(xmm, %d7), @CatStr(xmm, %sd6), 0e4h - - @CatStr(punpckl, op) @CatStr(xmm, %sd0), @CatStr(xmm, %s1) - @CatStr(punpckh, op) @CatStr(xmm, %d1), @CatStr(xmm, %s1) - @CatStr(punpckl, op) @CatStr(xmm, %sd2), @CatStr(xmm, %s3) - @CatStr(punpckh, op) @CatStr(xmm, %d3), @CatStr(xmm, %s3) - @CatStr(punpckl, op) @CatStr(xmm, %sd4), @CatStr(xmm, %s5) - @CatStr(punpckh, op) @CatStr(xmm, %d5), @CatStr(xmm, %s5) - @CatStr(punpckl, op) @CatStr(xmm, %sd6), @CatStr(xmm, %s7) - @CatStr(punpckh, op) @CatStr(xmm, %d7), @CatStr(xmm, %s7) - - endm - -punpcknbl macro - - movdqa xmm4, xmm0 - pshufd xmm5, xmm1, 0e4h - - psllq xmm1, 4 - psrlq xmm4, 4 - - movdqa xmm6, xmm7 - pand xmm0, xmm7 - pandn xmm6, xmm1 - por xmm0, xmm6 - - movdqa xmm6, xmm7 - pand xmm4, xmm7 - pandn xmm6, xmm5 - por xmm4, xmm6 - - movdqa xmm1, xmm4 - - movdqa xmm4, xmm2 - pshufd xmm5, xmm3, 0e4h - - psllq xmm3, 4 - psrlq xmm4, 4 - - movdqa xmm6, xmm7 - pand xmm2, xmm7 - pandn xmm6, xmm3 - por xmm2, xmm6 - - movdqa xmm6, xmm7 - pand xmm4, xmm7 - pandn xmm6, xmm5 - por xmm4, xmm6 - - movdqa xmm3, xmm4 - - punpck bw, 0, 2, 1, 3, 4, 6 - - endm - -punpcknbh macro - - movdqa xmm12, xmm8 - pshufd xmm13, xmm9, 0e4h - - psllq xmm9, 4 - psrlq xmm12, 4 - - movdqa xmm14, xmm15 - pand xmm8, xmm15 - pandn xmm14, xmm9 - por xmm8, xmm14 - - movdqa xmm14, xmm15 - pand xmm12, xmm15 - pandn xmm14, xmm13 - por xmm12, xmm14 - - movdqa xmm9, xmm12 - - movdqa xmm12, xmm10 - pshufd xmm13, xmm11, 0e4h - - psllq xmm11, 4 - psrlq xmm12, 4 - - movdqa xmm14, xmm15 - pand xmm10, xmm15 - pandn xmm14, xmm11 - por xmm10, xmm14 - - movdqa xmm14, xmm15 - pand xmm12, xmm15 - pandn xmm14, xmm13 - por xmm12, xmm14 - - movdqa xmm11, xmm12 - - punpck bw, 8, 10, 9, 11, 12, 14 - - endm - -; -; unSwizzleBlock32 -; - -unSwizzleBlock32_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 4 - - align 16 -@@: - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm2, [rsi+16*2] - movdqa xmm3, [rsi+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - movdqa [rdi], xmm0 - movdqa [rdi+16], xmm2 - movdqa [rdi+r8], xmm4 - movdqa [rdi+r8+16], xmm6 - - add rsi, 64 - lea rdi, [rdi+r8*2] - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock32_amd64 endp - -; -; unSwizzleBlock32_2 (TODO: test me) -; - -unSwizzleBlock32_2_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 2 - - align 16 -@@: - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm2, [rsi+16*2] - movdqa xmm3, [rsi+16*3] - movdqa xmm4, [rsi+16*4] - movdqa xmm5, [rsi+16*5] - movdqa xmm6, [rsi+16*6] - movdqa xmm7, [rsi+16*7] - - punpck2 qdq, 0, 2, 4, 6, 1, 3, 5, 7, 8, 10, 12, 14 - - movdqa [rdi], xmm0 - movdqa [rdi+16], xmm2 - movdqa [rdi+r8], xmm4 - movdqa [rdi+r8+16], xmm6 - lea rdi, [rdi+r8*2] - - movdqa [rdi], xmm8 - movdqa [rdi+16], xmm10 - movdqa [rdi+r8], xmm12 - movdqa [rdi+r8+16], xmm14 - lea rdi, [rdi+r8*2] - - add rsi, 128 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock32_2_amd64 endp - -; -; unSwizzleBlock16 -; - -unSwizzleBlock16_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 4 - - align 16 -@@: - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm2, [rsi+16*2] - movdqa xmm3, [rsi+16*3] - - punpck wd, 0, 2, 1, 3, 4, 6 - punpck dq, 0, 4, 2, 6, 1, 3 - punpck wd, 0, 4, 1, 3, 2, 6 - - movdqa [rdi], xmm0 - movdqa [rdi+16], xmm2 - movdqa [rdi+r8], xmm4 - movdqa [rdi+r8+16], xmm6 - - add rsi, 64 - lea rdi, [rdi+r8*2] - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock16_amd64 endp - -; -; unSwizzleBlock8 -; - -unSwizzleBlock8_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 2 - - ; r9 = r8*3 - lea r9, [r8*2] - add r9, r8 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm4, [rsi+16*2] - movdqa xmm5, [rsi+16*3] - - ; col 1, 3 - - movdqa xmm8, [rsi+16*4] - movdqa xmm9, [rsi+16*5] - movdqa xmm12, [rsi+16*6] - movdqa xmm13, [rsi+16*7] - - ; col 0, 2 - - punpck bw, 0, 4, 1, 5, 2, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 2, 4, 6, 1, 3 - - pshufd xmm1, xmm1, 0b1h - pshufd xmm3, xmm3, 0b1h - - ; col 1, 3 - - punpck bw, 8, 12, 9, 13, 10, 14 - punpck wd, 8, 10, 12, 14, 9, 11 - punpck bw, 8, 10, 9, 11, 12, 14 - punpck qdq, 8, 10, 12, 14, 9, 11 - - pshufd xmm8, xmm8, 0b1h - pshufd xmm10, xmm10, 0b1h - - ; col 0, 2 - - movdqa [rdi], xmm0 - movdqa [rdi+r8], xmm2 - movdqa [rdi+r8*2], xmm1 - movdqa [rdi+r9], xmm3 - lea rdi, [rdi+r8*4] - - ; col 1, 3 - - movdqa [rdi], xmm8 - movdqa [rdi+r8], xmm10 - movdqa [rdi+r8*2], xmm9 - movdqa [rdi+r9], xmm11 - lea rdi, [rdi+r8*4] - - add rsi, 128 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock8_amd64 endp - -; -; unSwizzleBlock4 -; - -unSwizzleBlock4_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 2 - - ; r9 = r8*3 - lea r9, [r8*2] - add r9, r8 - - mov eax, 0f0f0f0fh - movd xmm7, rax - pshufd xmm7, xmm7, 0 - movdqa xmm15, xmm7 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm4, [rsi+16*2] - movdqa xmm3, [rsi+16*3] - - ; col 1, 3 - - movdqa xmm8, [rsi+16*4] - movdqa xmm9, [rsi+16*5] - movdqa xmm12, [rsi+16*6] - movdqa xmm11, [rsi+16*7] - - ; col 0, 2 - - punpck dq, 0, 4, 1, 3, 2, 6 - punpck dq, 0, 2, 4, 6, 1, 3 - punpcknbl - punpck bw, 0, 2, 4, 6, 1, 3 - punpck wd, 0, 2, 1, 3, 4, 6 - - ; col 1, 3 - - punpck dq, 8, 12, 9, 11, 10, 14 - punpck dq, 8, 10, 12, 14, 9, 11 - punpcknbh - punpck bw, 8, 10, 12, 14, 9, 11 - punpck wd, 8, 10, 9, 11, 12, 14 - - ; col 0, 2 - - pshufd xmm0, xmm0, 0d8h - pshufd xmm2, xmm2, 0d8h - pshufd xmm4, xmm4, 0d8h - pshufd xmm6, xmm6, 0d8h - - ; col 1, 3 - - pshufd xmm8, xmm8, 0d8h - pshufd xmm10, xmm10, 0d8h - pshufd xmm12, xmm12, 0d8h - pshufd xmm14, xmm14, 0d8h - - ; col 0, 2 - - punpck qdq, 0, 2, 4, 6, 1, 3 - - ; col 1, 3 - - punpck qdq, 8, 10, 12, 14, 9, 11 - - ; col 0, 2 - - pshuflw xmm1, xmm1, 0b1h - pshuflw xmm3, xmm3, 0b1h - pshufhw xmm1, xmm1, 0b1h - pshufhw xmm3, xmm3, 0b1h - - ; col 1, 3 - - pshuflw xmm8, xmm8, 0b1h - pshuflw xmm10, xmm10, 0b1h - pshufhw xmm8, xmm8, 0b1h - pshufhw xmm10, xmm10, 0b1h - - ; col 0, 2 - - movdqa [rdi], xmm0 - movdqa [rdi+r8], xmm2 - movdqa [rdi+r8*2], xmm1 - movdqa [rdi+r9], xmm3 - lea rdi, [rdi+r8*4] - - ; col 1, 3 - - movdqa [rdi], xmm8 - movdqa [rdi+r8], xmm10 - movdqa [rdi+r8*2], xmm9 - movdqa [rdi+r9], xmm11 - lea rdi, [rdi+r8*4] - - add rsi, 128 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock4_amd64 endp - -; -; unSwizzleBlock8HP -; - -unSwizzleBlock8HP_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 4 - - align 16 -@@: - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm2, [rsi+16*2] - movdqa xmm3, [rsi+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - psrld xmm0, 24 - psrld xmm2, 24 - psrld xmm4, 24 - psrld xmm6, 24 - - packssdw xmm0, xmm2 - packssdw xmm4, xmm6 - packuswb xmm0, xmm4 - - movlps qword ptr [rdi], xmm0 - movhps qword ptr [rdi+r8], xmm0 - - add rsi, 64 - lea rdi, [rdi+r8*2] - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock8HP_amd64 endp - -; -; unSwizzleBlock4HLP -; - -unSwizzleBlock4HLP_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 4 - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - align 16 -@@: - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm2, [rsi+16*2] - movdqa xmm3, [rsi+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - psrld xmm0, 24 - psrld xmm2, 24 - psrld xmm4, 24 - psrld xmm6, 24 - - packssdw xmm0, xmm2 - packssdw xmm4, xmm6 - packuswb xmm0, xmm4 - - pand xmm0, xmm7 - - movlps qword ptr [rdi], xmm0 - movhps qword ptr [rdi+r8], xmm0 - - add rsi, 64 - lea rdi, [rdi+r8*2] - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock4HLP_amd64 endp - -; -; unSwizzleBlock4HHP -; - -unSwizzleBlock4HHP_amd64 proc public - - push rsi - push rdi - - mov rsi, rcx - mov rdi, rdx - mov rcx, 4 - - align 16 -@@: - movdqa xmm0, [rsi+16*0] - movdqa xmm1, [rsi+16*1] - movdqa xmm2, [rsi+16*2] - movdqa xmm3, [rsi+16*3] - - punpck qdq, 0, 2, 1, 3, 4, 6 - - psrld xmm0, 28 - psrld xmm2, 28 - psrld xmm4, 28 - psrld xmm6, 28 - - packssdw xmm0, xmm2 - packssdw xmm4, xmm6 - packuswb xmm0, xmm4 - - movlps qword ptr [rdi], xmm0 - movhps qword ptr [rdi+r8], xmm0 - - add rsi, 64 - lea rdi, [rdi+r8*2] - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -unSwizzleBlock4HHP_amd64 endp - -; -; unSwizzleBlock4P -; - -unSwizzleBlock4P_amd64 proc public - - mov eax, 0f0f0f0fh - movd xmm8, eax - pshufd xmm8, xmm8, 0 - - ; r9 = r8*3 - lea r9, [r8*2] - add r9, r8 - - ; col 0 - - movdqa xmm0, [rcx+16*0] - movdqa xmm1, [rcx+16*1] - movdqa xmm2, [rcx+16*2] - movdqa xmm3, [rcx+16*3] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm8 - pandn xmm1, xmm0 - pand xmm0, xmm8 - pshufd xmm1, xmm1, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm8 - pandn xmm3, xmm2 - pand xmm2, xmm8 - pshufd xmm3, xmm3, 0b1h - psrlq xmm3, 4 - - movdqa xmm5, xmm8 - pandn xmm5, xmm4 - pand xmm4, xmm8 - pshufd xmm5, xmm5, 0b1h - psrlq xmm5, 4 - - movdqa xmm7, xmm8 - pandn xmm7, xmm6 - pand xmm6, xmm8 - pshufd xmm7, xmm7, 0b1h - psrlq xmm7, 4 - - movdqa [rdx], xmm0 - movdqa [rdx+16], xmm2 - movdqa [rdx+r8], xmm4 - movdqa [rdx+r8+16], xmm6 - - movdqa [rdx+r8*2], xmm1 - movdqa [rdx+r8*2+16], xmm3 - movdqa [rdx+r9], xmm5 - movdqa [rdx+r9+16], xmm7 - - lea rdx, [rdx+r8*4] - - ; col 1 - - movdqa xmm0, [rcx+16*4] - movdqa xmm1, [rcx+16*5] - movdqa xmm2, [rcx+16*6] - movdqa xmm3, [rcx+16*7] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm8 - pandn xmm1, xmm0 - pand xmm0, xmm8 - pshufd xmm0, xmm0, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm8 - pandn xmm3, xmm2 - pand xmm2, xmm8 - pshufd xmm2, xmm2, 0b1h - psrlq xmm3, 4 - - movdqa xmm5, xmm8 - pandn xmm5, xmm4 - pand xmm4, xmm8 - pshufd xmm4, xmm4, 0b1h - psrlq xmm5, 4 - - movdqa xmm7, xmm8 - pandn xmm7, xmm6 - pand xmm6, xmm8 - pshufd xmm6, xmm6, 0b1h - psrlq xmm7, 4 - - movdqa [rdx], xmm0 - movdqa [rdx+16], xmm2 - movdqa [rdx+r8], xmm4 - movdqa [rdx+r8+16], xmm6 - - movdqa [rdx+r8*2], xmm1 - movdqa [rdx+r8*2+16], xmm3 - movdqa [rdx+r9], xmm5 - movdqa [rdx+r9+16], xmm7 - - lea rdx, [rdx+r8*4] - - ; col 2 - - movdqa xmm0, [rcx+16*8] - movdqa xmm1, [rcx+16*9] - movdqa xmm2, [rcx+16*10] - movdqa xmm3, [rcx+16*11] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm8 - pandn xmm1, xmm0 - pand xmm0, xmm8 - pshufd xmm1, xmm1, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm8 - pandn xmm3, xmm2 - pand xmm2, xmm8 - pshufd xmm3, xmm3, 0b1h - psrlq xmm3, 4 - - movdqa xmm5, xmm8 - pandn xmm5, xmm4 - pand xmm4, xmm8 - pshufd xmm5, xmm5, 0b1h - psrlq xmm5, 4 - - movdqa xmm7, xmm8 - pandn xmm7, xmm6 - pand xmm6, xmm8 - pshufd xmm7, xmm7, 0b1h - psrlq xmm7, 4 - - movdqa [rdx], xmm0 - movdqa [rdx+16], xmm2 - movdqa [rdx+r8], xmm4 - movdqa [rdx+r8+16], xmm6 - - movdqa [rdx+r8*2], xmm1 - movdqa [rdx+r8*2+16], xmm3 - movdqa [rdx+r9], xmm5 - movdqa [rdx+r9+16], xmm7 - - lea rdx, [rdx+r8*4] - - ; col 3 - - movdqa xmm0, [rcx+16*12] - movdqa xmm1, [rcx+16*13] - movdqa xmm2, [rcx+16*14] - movdqa xmm3, [rcx+16*15] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 4, 2, 6, 1, 3 - punpck bw, 0, 4, 1, 3, 2, 6 - - movdqa xmm1, xmm8 - pandn xmm1, xmm0 - pand xmm0, xmm8 - pshufd xmm0, xmm0, 0b1h - psrlq xmm1, 4 - - movdqa xmm3, xmm8 - pandn xmm3, xmm2 - pand xmm2, xmm8 - pshufd xmm2, xmm2, 0b1h - psrlq xmm3, 4 - - movdqa xmm5, xmm8 - pandn xmm5, xmm4 - pand xmm4, xmm8 - pshufd xmm4, xmm4, 0b1h - psrlq xmm5, 4 - - movdqa xmm7, xmm8 - pandn xmm7, xmm6 - pand xmm6, xmm8 - pshufd xmm6, xmm6, 0b1h - psrlq xmm7, 4 - - movdqa [rdx], xmm0 - movdqa [rdx+16], xmm2 - movdqa [rdx+r8], xmm4 - movdqa [rdx+r8+16], xmm6 - - movdqa [rdx+r8*2], xmm1 - movdqa [rdx+r8*2+16], xmm3 - movdqa [rdx+r9], xmm5 - movdqa [rdx+r9+16], xmm7 - - ; lea rdx, [rdx+r8*4] - - ret - -unSwizzleBlock4P_amd64 endp - -; -; swizzling -; - -; -; SwizzleBlock32_amd64 -; - -SwizzleBlock32_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov rcx, 4 - - cmp r9d, 0ffffffffh - jnz SwizzleBlock32_amd64@WM - - align 16 -@@: - movdqa xmm0, [rsi] - movdqa xmm4, [rsi+16] - movdqa xmm1, [rsi+r8] - movdqa xmm5, [rsi+r8+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm2 - movdqa [rdi+16*2], xmm4 - movdqa [rdi+16*3], xmm6 - - lea rsi, [rsi+r8*2] - add rdi, 64 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock32_amd64@WM: - - movd xmm7, r9d - pshufd xmm7, xmm7, 0 - - align 16 -@@: - movdqa xmm0, [rsi] - movdqa xmm4, [rsi+16] - movdqa xmm1, [rsi+r8] - movdqa xmm5, [rsi+r8+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa xmm3, xmm7 - pshufd xmm5, xmm7, 0e4h - movdqa xmm9, xmm7 - pshufd xmm11, xmm7, 0e4h - - pandn xmm3, [rdi+16*0] - pand xmm0, xmm7 - por xmm0, xmm3 - movdqa [rdi+16*0], xmm0 - - pandn xmm5, [rdi+16*1] - pand xmm2, xmm7 - por xmm2, xmm5 - movdqa [rdi+16*1], xmm2 - - pandn xmm9, [rdi+16*2] - pand xmm4, xmm7 - por xmm4, xmm9 - movdqa [rdi+16*2], xmm4 - - pandn xmm11, [rdi+16*3] - pand xmm6, xmm7 - por xmm6, xmm11 - movdqa [edi+16*3], xmm6 - - lea rsi, [rsi+r8*2] - add rdi, 64 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock32_amd64 endp - -; -; SwizzleBlock16_amd64 -; - -SwizzleBlock16_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov rcx, 4 - - align 16 -@@: - movdqa xmm0, [rsi] - movdqa xmm1, [rsi+16] - movdqa xmm2, [rsi+r8] - movdqa xmm3, [rsi+r8+16] - - punpck wd, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 5 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm1 - movdqa [rdi+16*2], xmm4 - movdqa [rdi+16*3], xmm5 - - lea rsi, [rsi+r8*2] - add rdi, 64 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock16_amd64 endp - -; -; SwizzleBlock8 -; - -SwizzleBlock8_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov ecx, 2 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [rsi] - movdqa xmm2, [rsi+r8] - lea rsi, [rsi+r8*2] - - pshufd xmm1, [rsi], 0b1h - pshufd xmm3, [rsi+r8], 0b1h - lea rsi, [rsi+r8*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm4 - movdqa [rdi+16*2], xmm1 - movdqa [rdi+16*3], xmm5 - - ; col 1, 3 - - pshufd xmm0, [rsi], 0b1h - pshufd xmm2, [rsi+r8], 0b1h - lea rsi, [rsi+r8*2] - - movdqa xmm1, [rsi] - movdqa xmm3, [rsi+r8] - lea rsi, [rsi+r8*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [rdi+16*4], xmm0 - movdqa [rdi+16*5], xmm4 - movdqa [rdi+16*6], xmm1 - movdqa [rdi+16*7], xmm5 - - add edi, 128 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock8_amd64 endp - -; -; SwizzleBlock4 -; - -SwizzleBlock4_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov rcx, 2 - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - align 16 -@@: - ; col 0, 2 - - movdqa xmm0, [rsi] - movdqa xmm2, [rsi+r8] - lea rsi, [rsi+r8*2] - - movdqa xmm1, [rsi] - movdqa xmm3, [rsi+r8] - lea rsi, [rsi+r8*2] - - pshuflw xmm1, xmm1, 0b1h - pshuflw xmm3, xmm3, 0b1h - pshufhw xmm1, xmm1, 0b1h - pshufhw xmm3, xmm3, 0b1h - - punpcknbl - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm1 - movdqa [rdi+16*2], xmm4 - movdqa [rdi+16*3], xmm3 - - ; col 1, 3 - - movdqa xmm0, [rsi] - movdqa xmm2, [rsi+r8] - lea esi, [rsi+r8*2] - - movdqa xmm1, [rsi] - movdqa xmm3, [rsi+r8] - lea rsi, [rsi+r8*2] - - pshuflw xmm0, xmm0, 0b1h - pshuflw xmm2, xmm2, 0b1h - pshufhw xmm0, xmm0, 0b1h - pshufhw xmm2, xmm2, 0b1h - - punpcknbl - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [rdi+16*4], xmm0 - movdqa [rdi+16*5], xmm1 - movdqa [rdi+16*6], xmm4 - movdqa [rdi+16*7], xmm3 - - add rdi, 128 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock4_amd64 endp - -; -; swizzling with unaligned reads -; - -; -; SwizzleBlock32u_amd64 -; - -SwizzleBlock32u_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov rcx, 4 - - cmp r9d, 0ffffffffh - jnz SwizzleBlock32u_amd64@WM - - align 16 -@@: - movdqu xmm0, [rsi] - movdqu xmm4, [rsi+16] - movdqu xmm1, [rsi+r8] - movdqu xmm5, [rsi+r8+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm2 - movdqa [rdi+16*2], xmm4 - movdqa [rdi+16*3], xmm6 - - lea rsi, [rsi+r8*2] - add rdi, 64 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock32u_amd64@WM: - - movd xmm7, r9d - pshufd xmm7, xmm7, 0 - - align 16 -@@: - movdqu xmm0, [rsi] - movdqu xmm4, [rsi+16] - movdqu xmm1, [rsi+r8] - movdqu xmm5, [rsi+r8+16] - - punpck qdq, 0, 4, 1, 5, 2, 6 - - movdqa xmm3, xmm7 - pshufd xmm5, xmm7, 0e4h - movdqa xmm9, xmm7 - pshufd xmm11, xmm7, 0e4h - - pandn xmm3, [rdi+16*0] - pand xmm0, xmm7 - por xmm0, xmm3 - movdqa [rdi+16*0], xmm0 - - pandn xmm5, [rdi+16*1] - pand xmm2, xmm7 - por xmm2, xmm5 - movdqa [rdi+16*1], xmm2 - - pandn xmm9, [rdi+16*2] - pand xmm4, xmm7 - por xmm4, xmm9 - movdqa [rdi+16*2], xmm4 - - pandn xmm11, [rdi+16*3] - pand xmm6, xmm7 - por xmm6, xmm11 - movdqa [edi+16*3], xmm6 - - lea rsi, [rsi+r8*2] - add rdi, 64 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock32u_amd64 endp - -; -; SwizzleBlock16u_amd64 -; - -SwizzleBlock16u_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov rcx, 4 - - align 16 -@@: - movdqu xmm0, [rsi] - movdqu xmm1, [rsi+16] - movdqu xmm2, [rsi+r8] - movdqu xmm3, [rsi+r8+16] - - punpck wd, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 5 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm1 - movdqa [rdi+16*2], xmm4 - movdqa [rdi+16*3], xmm5 - - lea rsi, [rsi+r8*2] - add rdi, 64 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock16u_amd64 endp - -; -; SwizzleBlock8u -; - -SwizzleBlock8u_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov ecx, 2 - - align 16 -@@: - ; col 0, 2 - - movdqu xmm0, [rsi] - movdqu xmm2, [rsi+r8] - lea rsi, [rsi+r8*2] - - pshufd xmm1, [rsi], 0b1h - pshufd xmm3, [rsi+r8], 0b1h - lea rsi, [rsi+r8*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm4 - movdqa [rdi+16*2], xmm1 - movdqa [rdi+16*3], xmm5 - - ; col 1, 3 - - pshufd xmm0, [rsi], 0b1h - pshufd xmm2, [rsi+r8], 0b1h - lea rsi, [rsi+r8*2] - - movdqu xmm1, [rsi] - movdqu xmm3, [rsi+r8] - lea rsi, [rsi+r8*2] - - punpck bw, 0, 2, 1, 3, 4, 6 - punpck wd, 0, 2, 4, 6, 1, 3 - punpck qdq, 0, 1, 2, 3, 4, 5 - - movdqa [rdi+16*4], xmm0 - movdqa [rdi+16*5], xmm4 - movdqa [rdi+16*6], xmm1 - movdqa [rdi+16*7], xmm5 - - add edi, 128 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock8u_amd64 endp - -; -; SwizzleBlock4u -; - -SwizzleBlock4u_amd64 proc public - - push rsi - push rdi - - mov rdi, rcx - mov rsi, rdx - mov rcx, 2 - - mov eax, 0f0f0f0fh - movd xmm7, eax - pshufd xmm7, xmm7, 0 - - align 16 -@@: - ; col 0, 2 - - movdqu xmm0, [rsi] - movdqu xmm2, [rsi+r8] - lea rsi, [rsi+r8*2] - - movdqu xmm1, [rsi] - movdqu xmm3, [rsi+r8] - lea rsi, [rsi+r8*2] - - pshuflw xmm1, xmm1, 0b1h - pshuflw xmm3, xmm3, 0b1h - pshufhw xmm1, xmm1, 0b1h - pshufhw xmm3, xmm3, 0b1h - - punpcknbl - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [rdi+16*0], xmm0 - movdqa [rdi+16*1], xmm1 - movdqa [rdi+16*2], xmm4 - movdqa [rdi+16*3], xmm3 - - ; col 1, 3 - - movdqu xmm0, [rsi] - movdqu xmm2, [rsi+r8] - lea esi, [rsi+r8*2] - - movdqu xmm1, [rsi] - movdqu xmm3, [rsi+r8] - lea rsi, [rsi+r8*2] - - pshuflw xmm0, xmm0, 0b1h - pshuflw xmm2, xmm2, 0b1h - pshufhw xmm0, xmm0, 0b1h - pshufhw xmm2, xmm2, 0b1h - - punpcknbl - punpck bw, 0, 2, 4, 6, 1, 3 - punpck bw, 0, 2, 1, 3, 4, 6 - punpck qdq, 0, 4, 2, 6, 1, 3 - - movdqa [rdi+16*4], xmm0 - movdqa [rdi+16*5], xmm1 - movdqa [rdi+16*6], xmm4 - movdqa [rdi+16*7], xmm3 - - add rdi, 128 - - dec rcx - jnz @B - - pop rdi - pop rsi - - ret - -SwizzleBlock4u_amd64 endp - - end - \ No newline at end of file diff --git a/plugins/gs/gsdx9/x86.cpp b/plugins/gs/gsdx9/x86.cpp deleted file mode 100644 index 4633b10167..0000000000 --- a/plugins/gs/gsdx9/x86.cpp +++ /dev/null @@ -1,836 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#include "stdafx.h" -#include "GSTables.h" -#include "x86.h" - -// unswizzling - -void __fastcall unSwizzleBlock32_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)dst)[i] = ((DWORD*)src)[s[i]]; -} - -void __fastcall unSwizzleBlock16_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable16[0][0]; - - for(int j = 0; j < 8; j++, s += 16, dst += dstpitch) - for(int i = 0; i < 16; i++) - ((WORD*)dst)[i] = ((WORD*)src)[s[i]]; -} - -void __fastcall unSwizzleBlock8_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable8[0][0]; - - for(int j = 0; j < 16; j++, s += 16, dst += dstpitch) - for(int i = 0; i < 16; i++) - dst[i] = src[s[i]]; -} - -void __fastcall unSwizzleBlock4_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable4[0][0]; - - for(int j = 0; j < 16; j++, s += 32, dst += dstpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = s[i]; - BYTE c = (src[addr>>1] >> ((addr&1) << 2)) & 0x0f; - int shift = (i&1) << 2; - dst[i >> 1] = (dst[i >> 1] & (0xf0 >> shift)) | (c << shift); - } - } -} - -void __fastcall unSwizzleBlock8HP_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - for(int i = 0; i < 8; i++) - dst[i] = (BYTE)(((DWORD*)src)[s[i]]>>24); -} - -void __fastcall unSwizzleBlock4HLP_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - for(int i = 0; i < 8; i++) - dst[i] = (BYTE)(((DWORD*)src)[s[i]]>>24)&0xf; -} - -void __fastcall unSwizzleBlock4HHP_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable32[0][0]; - - for(int j = 0; j < 8; j++, s += 8, dst += dstpitch) - for(int i = 0; i < 8; i++) - dst[i] = (BYTE)(((DWORD*)src)[s[i]]>>28); -} - -void __fastcall unSwizzleBlock4P_c(BYTE* src, BYTE* dst, int dstpitch) -{ - DWORD* s = &columnTable4[0][0]; - - for(int j = 0; j < 16; j++, s += 32, dst += dstpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = s[i]; - dst[i] = (src[addr>>1] >> ((addr&1) << 2)) & 0x0f; - } - } -} - -// swizzling - -void __fastcall SwizzleBlock32_c(BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask) -{ - DWORD* d = &columnTable32[0][0]; - - if(WriteMask == 0xffffffff) - { - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)dst)[d[i]] = ((DWORD*)src)[i]; - } - else - { - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~WriteMask) | (((DWORD*)src)[i] & WriteMask); - } -} - -void __fastcall SwizzleBlock16_c(BYTE* dst, BYTE* src, int srcpitch) -{ - DWORD* d = &columnTable16[0][0]; - - for(int j = 0; j < 8; j++, d += 16, src += srcpitch) - for(int i = 0; i < 16; i++) - ((WORD*)dst)[d[i]] = ((WORD*)src)[i]; -} - -void __fastcall SwizzleBlock8_c(BYTE* dst, BYTE* src, int srcpitch) -{ - DWORD* d = &columnTable8[0][0]; - - for(int j = 0; j < 16; j++, d += 16, src += srcpitch) - for(int i = 0; i < 16; i++) - dst[d[i]] = src[i]; -} - -void __fastcall SwizzleBlock4_c(BYTE* dst, BYTE* src, int srcpitch) -{ - DWORD* d = &columnTable4[0][0]; - - for(int j = 0; j < 16; j++, d += 32, src += srcpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = d[i]; - BYTE c = (src[i>>1] >> ((i&1) << 2)) & 0x0f; - DWORD shift = (addr&1) << 2; - dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift); - } - } -} - -// column swizzling (TODO: sse2) - -void __fastcall SwizzleColumn32_c(int y, BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask) -{ - DWORD* d = &columnTable32[((y/2)&3)*2][0]; - - if(WriteMask == 0xffffffff) - { - for(int j = 0; j < 2; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)dst)[d[i]] = ((DWORD*)src)[i]; - } - else - { - for(int j = 0; j < 2; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) - ((DWORD*)dst)[d[i]] = (((DWORD*)dst)[d[i]] & ~WriteMask) | (((DWORD*)src)[i] & WriteMask); - } -} - -void __fastcall SwizzleColumn16_c(int y, BYTE* dst, BYTE* src, int srcpitch) -{ - DWORD* d = &columnTable16[((y/2)&3)*2][0]; - - for(int j = 0; j < 2; j++, d += 16, src += srcpitch) - for(int i = 0; i < 16; i++) - ((WORD*)dst)[d[i]] = ((WORD*)src)[i]; -} - -void __fastcall SwizzleColumn8_c(int y, BYTE* dst, BYTE* src, int srcpitch) -{ - DWORD* d = &columnTable8[((y/4)&3)*4][0]; - - for(int j = 0; j < 4; j++, d += 16, src += srcpitch) - for(int i = 0; i < 16; i++) - dst[d[i]] = src[i]; -} - -void __fastcall SwizzleColumn4_c(int y, BYTE* dst, BYTE* src, int srcpitch) -{ - DWORD* d = &columnTable4[y&(3<<2)][0]; // ((y/4)&3)*4 - - for(int j = 0; j < 4; j++, d += 32, src += srcpitch) - { - for(int i = 0; i < 32; i++) - { - DWORD addr = d[i]; - BYTE c = (src[i>>1] >> ((i&1) << 2)) & 0x0f; - DWORD shift = (addr&1) << 2; - dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift); - } - } -} - -// - -#if defined(_M_AMD64) || _M_IX86_FP >= 2 - -static __m128i s_zero = _mm_setzero_si128(); -static __m128i s_bgrm = _mm_set1_epi32(0x00ffffff); -static __m128i s_am = _mm_set1_epi32(0x00008000); -static __m128i s_bm = _mm_set1_epi32(0x00007c00); -static __m128i s_gm = _mm_set1_epi32(0x000003e0); -static __m128i s_rm = _mm_set1_epi32(0x0000001f); - -void __fastcall ExpandBlock24_sse2(DWORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA) -{ - __m128i TA0 = _mm_set1_epi32((DWORD)pTEXA->TA0 << 24); - - if(!pTEXA->AEM) - { - for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2) - { - for(int i = 0; i < 8; i += 4) - { - __m128i c = _mm_load_si128((__m128i*)&src[i]); - c = _mm_and_si128(c, s_bgrm); - c = _mm_or_si128(c, TA0); - _mm_store_si128((__m128i*)&dst[i], c); - } - } - } - else - { - for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2) - { - for(int i = 0; i < 8; i += 4) - { - __m128i c = _mm_load_si128((__m128i*)&src[i]); - c = _mm_and_si128(c, s_bgrm); - __m128i a = _mm_andnot_si128(_mm_cmpeq_epi32(c, s_zero), TA0); - c = _mm_or_si128(c, a); - _mm_store_si128((__m128i*)&dst[i], c); - } - } - } -} - -void __fastcall ExpandBlock16_sse2(WORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA) -{ - __m128i TA0 = _mm_set1_epi32((DWORD)pTEXA->TA0 << 24); - __m128i TA1 = _mm_set1_epi32((DWORD)pTEXA->TA1 << 24); - __m128i a, b, g, r; - - if(!pTEXA->AEM) - { - for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2) - { - for(int i = 0; i < 16; i += 8) - { - __m128i c = _mm_load_si128((__m128i*)&src[i]); - - __m128i cl = _mm_unpacklo_epi16(c, s_zero); - __m128i ch = _mm_unpackhi_epi16(c, s_zero); - - __m128i alm = _mm_cmplt_epi32(cl, s_am); - __m128i ahm = _mm_cmplt_epi32(ch, s_am); - - // lo - - b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1)); - - cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i], cl); - - // hi - - b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1)); - - ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i+4], ch); - } - } - } - else - { - for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2) - { - for(int i = 0; i < 16; i += 8) - { - __m128i c = _mm_load_si128((__m128i*)&src[i]); - - __m128i cl = _mm_unpacklo_epi16(c, s_zero); - __m128i ch = _mm_unpackhi_epi16(c, s_zero); - - __m128i alm = _mm_cmplt_epi32(cl, s_am); - __m128i ahm = _mm_cmplt_epi32(ch, s_am); - - __m128i trm = _mm_cmpeq_epi16(c, s_zero); - __m128i trlm = _mm_unpacklo_epi16(trm, trm); - __m128i trhm = _mm_unpackhi_epi16(trm, trm); - - // lo - - b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1)); - a = _mm_andnot_si128(trlm, a); - - cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i], cl); - - // hi - - b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1)); - a = _mm_andnot_si128(trhm, a); - - ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i+4], ch); - } - } - } -} - -void __fastcall Expand16_sse2(WORD* src, DWORD* dst, int w, GIFRegTEXA* pTEXA) -{ - ASSERT(!(w&7)); - - __m128i TA0 = _mm_set1_epi32((DWORD)pTEXA->TA0 << 24); - __m128i TA1 = _mm_set1_epi32((DWORD)pTEXA->TA1 << 24); - __m128i a, b, g, r; - - if(!pTEXA->AEM) - { - for(int i = 0; i < w; i += 8) - { - __m128i c = _mm_load_si128((__m128i*)&src[i]); - - __m128i cl = _mm_unpacklo_epi16(c, s_zero); - __m128i ch = _mm_unpackhi_epi16(c, s_zero); - - __m128i alm = _mm_cmplt_epi32(cl, s_am); - __m128i ahm = _mm_cmplt_epi32(ch, s_am); - - // lo - - b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1)); - - cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i], cl); - - // hi - - b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1)); - - ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i+4], ch); - } - } - else - { - for(int i = 0; i < w; i += 8) - { - __m128i c = _mm_load_si128((__m128i*)&src[i]); - - __m128i cl = _mm_unpacklo_epi16(c, s_zero); - __m128i ch = _mm_unpackhi_epi16(c, s_zero); - - __m128i alm = _mm_cmplt_epi32(cl, s_am); - __m128i ahm = _mm_cmplt_epi32(ch, s_am); - - __m128i trm = _mm_cmpeq_epi16(c, s_zero); - __m128i trlm = _mm_unpacklo_epi16(trm, trm); - __m128i trhm = _mm_unpackhi_epi16(trm, trm); - - // lo - - b = _mm_slli_epi32(_mm_and_si128(cl, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(cl, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(cl, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(alm, TA0), _mm_andnot_si128(alm, TA1)); - a = _mm_andnot_si128(trlm, a); - - cl = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i], cl); - - // hi - - b = _mm_slli_epi32(_mm_and_si128(ch, s_bm), 9); - g = _mm_slli_epi32(_mm_and_si128(ch, s_gm), 6); - r = _mm_slli_epi32(_mm_and_si128(ch, s_rm), 3); - a = _mm_or_si128(_mm_and_si128(ahm, TA0), _mm_andnot_si128(ahm, TA1)); - a = _mm_andnot_si128(trhm, a); - - ch = _mm_or_si128(_mm_or_si128(a, b), _mm_or_si128(g, r)); - - _mm_store_si128((__m128i*)&dst[i+4], ch); - } - } -} - -#endif - -void __fastcall ExpandBlock24_c(DWORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA) -{ - DWORD TA0 = (DWORD)pTEXA->TA0 << 24; - - if(!pTEXA->AEM) - { - for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2) - for(int i = 0; i < 8; i++) - dst[i] = TA0 | (src[i]&0xffffff); - } - else - { - for(int j = 0; j < 8; j++, src += 8, dst += dstpitch>>2) - for(int i = 0; i < 8; i++) - dst[i] = ((src[i]&0xffffff) ? TA0 : 0) | (src[i]&0xffffff); - } -} - -void __fastcall ExpandBlock16_c(WORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA) -{ - DWORD TA0 = (DWORD)pTEXA->TA0 << 24; - DWORD TA1 = (DWORD)pTEXA->TA1 << 24; - - if(!pTEXA->AEM) - { - for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2) - for(int i = 0; i < 16; i++) - dst[i] = ((src[i]&0x8000) ? TA1 : TA0) - | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3); - } - else - { - for(int j = 0; j < 8; j++, src += 16, dst += dstpitch>>2) - for(int i = 0; i < 16; i++) - dst[i] = ((src[i]&0x8000) ? TA1 : src[i] ? TA0 : 0) - | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3); - } -} - -void __fastcall Expand16_c(WORD* src, DWORD* dst, int w, GIFRegTEXA* pTEXA) -{ - DWORD TA0 = (DWORD)pTEXA->TA0 << 24; - DWORD TA1 = (DWORD)pTEXA->TA1 << 24; - - if(!pTEXA->AEM) - { - for(int i = 0; i < w; i++) - dst[i] = ((src[i]&0x8000) ? TA1 : TA0) - | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3); - } - else - { - for(int i = 0; i < w; i++) - dst[i] = ((src[i]&0x8000) ? TA1 : src[i] ? TA0 : 0) - | ((src[i]&0x7c00) << 9) | ((src[i]&0x03e0) << 6) | ((src[i]&0x001f) << 3); - } -} - -// - -#if defined(_M_AMD64) || _M_IX86_FP >= 2 - -static __m128 s_uvmin = _mm_set1_ps(+1e10); -static __m128 s_uvmax = _mm_set1_ps(-1e10); - -void __fastcall UVMinMax_sse2(int nVertices, vertex_t* pVertices, uvmm_t* uv) -{ - __m128 uvmin = s_uvmin; - __m128 uvmax = s_uvmax; - - __m128* p = (__m128*)pVertices + 1; - - int i = 0; - - nVertices -= 5; - - for(; i < nVertices; i += 6) // 6 regs for loading, 2 regs for min/max - { - uvmin = _mm_min_ps(uvmin, p[(i+0)*2]); - uvmax = _mm_max_ps(uvmax, p[(i+0)*2]); - uvmin = _mm_min_ps(uvmin, p[(i+1)*2]); - uvmax = _mm_max_ps(uvmax, p[(i+1)*2]); - uvmin = _mm_min_ps(uvmin, p[(i+2)*2]); - uvmax = _mm_max_ps(uvmax, p[(i+2)*2]); - uvmin = _mm_min_ps(uvmin, p[(i+3)*2]); - uvmax = _mm_max_ps(uvmax, p[(i+3)*2]); - uvmin = _mm_min_ps(uvmin, p[(i+4)*2]); - uvmax = _mm_max_ps(uvmax, p[(i+4)*2]); - uvmin = _mm_min_ps(uvmin, p[(i+5)*2]); - uvmax = _mm_max_ps(uvmax, p[(i+5)*2]); - } - - nVertices += 5; - - for(; i < nVertices; i++) - { - uvmin = _mm_min_ps(uvmin, p[i*2]); - uvmax = _mm_max_ps(uvmax, p[i*2]); - } - - _mm_storeh_pi((__m64*)uv, uvmin); - _mm_storeh_pi((__m64*)uv + 1, uvmax); -} - -#endif - -void __fastcall UVMinMax_c(int nVertices, vertex_t* pVertices, uvmm_t* uv) -{ - uv->umin = uv->vmin = +1e10; - uv->umax = uv->vmax = -1e10; - - for(; nVertices-- > 0; pVertices++) - { - float u = pVertices->u; - if(uv->umax < u) uv->umax = u; - if(uv->umin > u) uv->umin = u; - float v = pVertices->v; - if(uv->vmax < v) uv->vmax = v; - if(uv->vmin > v) uv->vmin = v; - } -} - -#if defined(_M_AMD64) || _M_IX86_FP >= 2 - -static __m128i s_clut[64]; - -void __fastcall WriteCLUT_T16_I8_CSM1_sse2(WORD* vm, WORD* clut) -{ - __m128i* src = (__m128i*)vm; - __m128i* dst = (__m128i*)clut; - - for(int i = 0; i < 32; i += 4) - { - __m128i r0 = _mm_load_si128(&src[i+0]); - __m128i r1 = _mm_load_si128(&src[i+1]); - __m128i r2 = _mm_load_si128(&src[i+2]); - __m128i r3 = _mm_load_si128(&src[i+3]); - - __m128i r4 = _mm_unpacklo_epi16(r0, r1); - __m128i r5 = _mm_unpackhi_epi16(r0, r1); - __m128i r6 = _mm_unpacklo_epi16(r2, r3); - __m128i r7 = _mm_unpackhi_epi16(r2, r3); - - r0 = _mm_unpacklo_epi32(r4, r6); - r1 = _mm_unpackhi_epi32(r4, r6); - r2 = _mm_unpacklo_epi32(r5, r7); - r3 = _mm_unpackhi_epi32(r5, r7); - - r4 = _mm_unpacklo_epi16(r0, r1); - r5 = _mm_unpackhi_epi16(r0, r1); - r6 = _mm_unpacklo_epi16(r2, r3); - r7 = _mm_unpackhi_epi16(r2, r3); - - _mm_store_si128(&dst[i+0], r4); - _mm_store_si128(&dst[i+1], r6); - _mm_store_si128(&dst[i+2], r5); - _mm_store_si128(&dst[i+3], r7); - } -} - -void __fastcall WriteCLUT_T32_I8_CSM1_sse2(DWORD* vm, WORD* clut) -{ - __m128i* src = (__m128i*)vm; - __m128i* dst = s_clut; - - for(int j = 0; j < 64; j += 32, src += 32, dst += 32) - { - for(int i = 0; i < 16; i += 4) - { - __m128i r0 = _mm_load_si128(&src[i+0]); - __m128i r1 = _mm_load_si128(&src[i+1]); - __m128i r2 = _mm_load_si128(&src[i+2]); - __m128i r3 = _mm_load_si128(&src[i+3]); - - _mm_store_si128(&dst[i*2+0], _mm_unpacklo_epi64(r0, r1)); - _mm_store_si128(&dst[i*2+1], _mm_unpacklo_epi64(r2, r3)); - _mm_store_si128(&dst[i*2+2], _mm_unpackhi_epi64(r0, r1)); - _mm_store_si128(&dst[i*2+3], _mm_unpackhi_epi64(r2, r3)); - - __m128i r4 = _mm_load_si128(&src[i+0+16]); - __m128i r5 = _mm_load_si128(&src[i+1+16]); - __m128i r6 = _mm_load_si128(&src[i+2+16]); - __m128i r7 = _mm_load_si128(&src[i+3+16]); - - _mm_store_si128(&dst[i*2+4], _mm_unpacklo_epi64(r4, r5)); - _mm_store_si128(&dst[i*2+5], _mm_unpacklo_epi64(r6, r7)); - _mm_store_si128(&dst[i*2+6], _mm_unpackhi_epi64(r4, r5)); - _mm_store_si128(&dst[i*2+7], _mm_unpackhi_epi64(r6, r7)); - } - } - - for(int i = 0; i < 32; i++) - { - __m128i r0 = s_clut[i*2]; - __m128i r1 = s_clut[i*2+1]; - __m128i r2 = _mm_unpacklo_epi16(r0, r1); - __m128i r3 = _mm_unpackhi_epi16(r0, r1); - r0 = _mm_unpacklo_epi16(r2, r3); - r1 = _mm_unpackhi_epi16(r2, r3); - r2 = _mm_unpacklo_epi16(r0, r1); - r3 = _mm_unpackhi_epi16(r0, r1); - _mm_store_si128(&((__m128i*)clut)[i], r2); - _mm_store_si128(&((__m128i*)clut)[i+32], r3); - } -} - -void __fastcall WriteCLUT_T16_I4_CSM1_sse2(WORD* vm, WORD* clut) -{ - // TODO (probably not worth, _c is going to be just as fast) - WriteCLUT_T16_I4_CSM1_c(vm, clut); -} - -void __fastcall WriteCLUT_T32_I4_CSM1_sse2(DWORD* vm, WORD* clut) -{ - __m128i* src = (__m128i*)vm; - __m128i* dst = s_clut; - - __m128i r0 = _mm_load_si128(&src[0]); - __m128i r1 = _mm_load_si128(&src[1]); - __m128i r2 = _mm_load_si128(&src[2]); - __m128i r3 = _mm_load_si128(&src[3]); - - _mm_store_si128(&dst[0], _mm_unpacklo_epi64(r0, r1)); - _mm_store_si128(&dst[1], _mm_unpacklo_epi64(r2, r3)); - _mm_store_si128(&dst[2], _mm_unpackhi_epi64(r0, r1)); - _mm_store_si128(&dst[3], _mm_unpackhi_epi64(r2, r3)); - - for(int i = 0; i < 2; i++) - { - __m128i r0 = s_clut[i*2]; - __m128i r1 = s_clut[i*2+1]; - __m128i r2 = _mm_unpacklo_epi16(r0, r1); - __m128i r3 = _mm_unpackhi_epi16(r0, r1); - r0 = _mm_unpacklo_epi16(r2, r3); - r1 = _mm_unpackhi_epi16(r2, r3); - r2 = _mm_unpacklo_epi16(r0, r1); - r3 = _mm_unpackhi_epi16(r0, r1); - _mm_store_si128(&((__m128i*)clut)[i], r2); - _mm_store_si128(&((__m128i*)clut)[i+32], r3); - } -} - -#endif - -void __fastcall WriteCLUT_T16_I8_CSM1_c(WORD* vm, WORD* clut) -{ - const static DWORD map[] = - { - 0, 2, 8, 10, 16, 18, 24, 26, - 4, 6, 12, 14, 20, 22, 28, 30, - 1, 3, 9, 11, 17, 19, 25, 27, - 5, 7, 13, 15, 21, 23, 29, 31 - }; - - for(int j = 0; j < 8; j++, vm += 32, clut += 32) - { - for(int i = 0; i < 32; i++) - { - clut[i] = vm[map[i]]; - } - } -} - -void __fastcall WriteCLUT_T32_I8_CSM1_c(DWORD* vm, WORD* clut) -{ - const static DWORD map[] = - { - 0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15, - 64, 65, 68, 69, 72, 73, 76, 77, 66, 67, 70, 71, 74, 75, 78, 79, - 16, 17, 20, 21, 24, 25, 28, 29, 18, 19, 22, 23, 26, 27, 30, 31, - 80, 81, 84, 85, 88, 89, 92, 93, 82, 83, 86, 87, 90, 91, 94, 95, - 32, 33, 36, 37, 40, 41, 44, 45, 34, 35, 38, 39, 42, 43, 46, 47, - 96, 97, 100, 101, 104, 105, 108, 109, 98, 99, 102, 103, 106, 107, 110, 111, - 48, 49, 52, 53, 56, 57, 60, 61, 50, 51, 54, 55, 58, 59, 62, 63, - 112, 113, 116, 117, 120, 121, 124, 125, 114, 115, 118, 119, 122, 123, 126, 127 - }; - - for(int j = 0; j < 2; j++, vm += 128, clut += 128) - { - for(int i = 0; i < 128; i++) - { - DWORD dw = vm[map[i]]; - clut[i] = (WORD)(dw & 0xffff); - clut[i+256] = (WORD)(dw >> 16); - } - } -} - -void __fastcall WriteCLUT_T16_I4_CSM1_c(WORD* vm, WORD* clut) -{ - const static DWORD map[] = - { - 0, 2, 8, 10, 16, 18, 24, 26, - 4, 6, 12, 14, 20, 22, 28, 30 - }; - - for(int i = 0; i < 16; i++) - { - clut[i] = vm[map[i]]; - } -} - -void __fastcall WriteCLUT_T32_I4_CSM1_c(DWORD* vm, WORD* clut) -{ - const static DWORD map[] = - { - 0, 1, 4, 5, 8, 9, 12, 13, - 2, 3, 6, 7, 10, 11, 14, 15 - }; - - for(int i = 0; i < 16; i++) - { - DWORD dw = vm[map[i]]; - clut[i] = (WORD)(dw & 0xffff); - clut[i+256] = (WORD)(dw >> 16); - } -} - -// - -#if defined(_M_AMD64) || _M_IX86_FP >= 2 - -extern "C" void __fastcall ReadCLUT32_T32_I8_sse2(WORD* src, DWORD* dst) -{ - for(int i = 0; i < 256; i += 16) - { - ReadCLUT32_T32_I4_sse2(&src[i], &dst[i]); // going to be inlined nicely - } -} - -extern "C" void __fastcall ReadCLUT32_T32_I4_sse2(WORD* src, DWORD* dst) -{ - __m128i r0 = ((__m128i*)src)[0]; - __m128i r1 = ((__m128i*)src)[1]; - __m128i r2 = ((__m128i*)src)[0+32]; - __m128i r3 = ((__m128i*)src)[1+32]; - _mm_store_si128(&((__m128i*)dst)[0], _mm_unpacklo_epi16(r0, r2)); - _mm_store_si128(&((__m128i*)dst)[1], _mm_unpackhi_epi16(r0, r2)); - _mm_store_si128(&((__m128i*)dst)[2], _mm_unpacklo_epi16(r1, r3)); - _mm_store_si128(&((__m128i*)dst)[3], _mm_unpackhi_epi16(r1, r3)); -} - -extern "C" void __fastcall ReadCLUT32_T16_I8_sse2(WORD* src, DWORD* dst) -{ - for(int i = 0; i < 256; i += 16) - { - ReadCLUT32_T16_I4_sse2(&src[i], &dst[i]); - } -} - -extern "C" void __fastcall ReadCLUT32_T16_I4_sse2(WORD* src, DWORD* dst) -{ - __m128i r0 = ((__m128i*)src)[0]; - __m128i r1 = ((__m128i*)src)[1]; - _mm_store_si128(&((__m128i*)dst)[0], _mm_unpacklo_epi16(r0, s_zero)); - _mm_store_si128(&((__m128i*)dst)[1], _mm_unpackhi_epi16(r0, s_zero)); - _mm_store_si128(&((__m128i*)dst)[2], _mm_unpacklo_epi16(r1, s_zero)); - _mm_store_si128(&((__m128i*)dst)[3], _mm_unpackhi_epi16(r1, s_zero)); -} - -#endif - -void __fastcall ReadCLUT32_T32_I8_c(WORD* src, DWORD* dst) -{ - for(int i = 0; i < 256; i++) - { - dst[i] = ((DWORD)src[i+256] << 16) | src[i]; - } -} - -void __fastcall ReadCLUT32_T32_I4_c(WORD* src, DWORD* dst) -{ - for(int i = 0; i < 16; i++) - { - dst[i] = ((DWORD)src[i+256] << 16) | src[i]; - } -} - -void __fastcall ReadCLUT32_T16_I8_c(WORD* src, DWORD* dst) -{ - for(int i = 0; i < 256; i++) - { - dst[i] = (DWORD)src[i]; - } -} - -void __fastcall ReadCLUT32_T16_I4_c(WORD* src, DWORD* dst) -{ - for(int i = 0; i < 16; i++) - { - dst[i] = (DWORD)src[i]; - } -} - -// \ No newline at end of file diff --git a/plugins/gs/gsdx9/x86.h b/plugins/gs/gsdx9/x86.h deleted file mode 100644 index c4622dacd8..0000000000 --- a/plugins/gs/gsdx9/x86.h +++ /dev/null @@ -1,238 +0,0 @@ -/* - * Copyright (C) 2003-2005 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 - * - */ - -#pragma once - -#include "GS.h" - -extern "C" void __fastcall memsetd(void* dst, unsigned int c, size_t len); - -extern "C" void unSwizzleBlock32_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void unSwizzleBlock16_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void unSwizzleBlock8_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void unSwizzleBlock4_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void unSwizzleBlock8HP_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void unSwizzleBlock4HLP_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void unSwizzleBlock4HHP_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void unSwizzleBlock4P_amd64(BYTE* src, BYTE* dst, __int64 dstpitch); -extern "C" void SwizzleBlock32_amd64(BYTE* dst, BYTE* src, __int64 srcpitch, DWORD WriteMask = 0xffffffff); -extern "C" void SwizzleBlock16_amd64(BYTE* dst, BYTE* src, __int64 srcpitch); -extern "C" void SwizzleBlock8_amd64(BYTE* dst, BYTE* src, __int64 srcpitch); -extern "C" void SwizzleBlock4_amd64(BYTE* dst, BYTE* src, __int64 srcpitch); -extern "C" void SwizzleBlock32u_amd64(BYTE* dst, BYTE* src, __int64 srcpitch, DWORD WriteMask = 0xffffffff); -extern "C" void SwizzleBlock16u_amd64(BYTE* dst, BYTE* src, __int64 srcpitch); -extern "C" void SwizzleBlock8u_amd64(BYTE* dst, BYTE* src, __int64 srcpitch); -extern "C" void SwizzleBlock4u_amd64(BYTE* dst, BYTE* src, __int64 srcpitch); -extern "C" void __fastcall unSwizzleBlock32_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall unSwizzleBlock16_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall unSwizzleBlock8_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall unSwizzleBlock4_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall unSwizzleBlock8HP_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall unSwizzleBlock4HLP_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall unSwizzleBlock4HHP_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall unSwizzleBlock4P_sse2(BYTE* src, BYTE* dst, int dstpitch); -extern "C" void __fastcall SwizzleBlock32_sse2(BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask = 0xffffffff); -extern "C" void __fastcall SwizzleBlock16_sse2(BYTE* dst, BYTE* src, int srcpitch); -extern "C" void __fastcall SwizzleBlock8_sse2(BYTE* dst, BYTE* src, int srcpitch); -extern "C" void __fastcall SwizzleBlock4_sse2(BYTE* dst, BYTE* src, int srcpitch); -extern "C" void __fastcall SwizzleBlock32u_sse2(BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask = 0xffffffff); -extern "C" void __fastcall SwizzleBlock16u_sse2(BYTE* dst, BYTE* src, int srcpitch); -extern "C" void __fastcall SwizzleBlock8u_sse2(BYTE* dst, BYTE* src, int srcpitch); -extern "C" void __fastcall SwizzleBlock4u_sse2(BYTE* dst, BYTE* src, int srcpitch); -extern void __fastcall unSwizzleBlock32_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall unSwizzleBlock16_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall unSwizzleBlock8_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall unSwizzleBlock4_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall unSwizzleBlock8HP_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall unSwizzleBlock4HLP_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall unSwizzleBlock4HHP_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall unSwizzleBlock4P_c(BYTE* src, BYTE* dst, int dstpitch); -extern void __fastcall SwizzleBlock32_c(BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask = 0xffffffff); -extern void __fastcall SwizzleBlock16_c(BYTE* dst, BYTE* src, int srcpitch); -extern void __fastcall SwizzleBlock8_c(BYTE* dst, BYTE* src, int srcpitch); -extern void __fastcall SwizzleBlock4_c(BYTE* dst, BYTE* src, int srcpitch); - -extern void __fastcall SwizzleColumn32_c(int y, BYTE* dst, BYTE* src, int srcpitch, DWORD WriteMask = 0xffffffff); -extern void __fastcall SwizzleColumn16_c(int y, BYTE* dst, BYTE* src, int srcpitch); -extern void __fastcall SwizzleColumn8_c(int y, BYTE* dst, BYTE* src, int srcpitch); -extern void __fastcall SwizzleColumn4_c(int y, BYTE* dst, BYTE* src, int srcpitch); - -extern void __fastcall ExpandBlock24_sse2(DWORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA); -extern void __fastcall ExpandBlock16_sse2(WORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA); -extern void __fastcall Expand16_sse2(WORD* src, DWORD* dst, int w, GIFRegTEXA* pTEXA); -extern void __fastcall ExpandBlock24_c(DWORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA); -extern void __fastcall ExpandBlock16_c(WORD* src, DWORD* dst, int dstpitch, GIFRegTEXA* pTEXA); -extern void __fastcall Expand16_c(WORD* src, DWORD* dst, int w, GIFRegTEXA* pTEXA); - -extern "C" void SaturateColor_amd64(int* c); -extern "C" void __fastcall SaturateColor_sse2(int* c); -extern "C" void __fastcall SaturateColor_asm(int* c); - -struct uvmm_t {float umin, vmin, umax, vmax;}; -struct vertex_t {float xyzw[4]; DWORD color[2]; float u, v;}; -extern "C" void __fastcall UVMinMax_sse2(int nVertices, vertex_t* pVertices, uvmm_t* uv); -extern "C" void __fastcall UVMinMax_c(int nVertices, vertex_t* pVertices, uvmm_t* uv); - -extern "C" void __fastcall WriteCLUT_T16_I8_CSM1_sse2(WORD* vm, WORD* clut); -extern "C" void __fastcall WriteCLUT_T32_I8_CSM1_sse2(DWORD* vm, WORD* clut); -extern "C" void __fastcall WriteCLUT_T16_I4_CSM1_sse2(WORD* vm, WORD* clut); -extern "C" void __fastcall WriteCLUT_T32_I4_CSM1_sse2(DWORD* vm, WORD* clut); -extern void __fastcall WriteCLUT_T16_I8_CSM1_c(WORD* vm, WORD* clut); -extern void __fastcall WriteCLUT_T32_I8_CSM1_c(DWORD* vm, WORD* clut); -extern void __fastcall WriteCLUT_T16_I4_CSM1_c(WORD* vm, WORD* clut); -extern void __fastcall WriteCLUT_T32_I4_CSM1_c(DWORD* vm, WORD* clut); - -extern "C" void __fastcall ReadCLUT32_T32_I8_sse2(WORD* src, DWORD* dst); -extern "C" void __fastcall ReadCLUT32_T32_I4_sse2(WORD* src, DWORD* dst); -extern "C" void __fastcall ReadCLUT32_T16_I8_sse2(WORD* src, DWORD* dst); -extern "C" void __fastcall ReadCLUT32_T16_I4_sse2(WORD* src, DWORD* dst); -extern void __fastcall ReadCLUT32_T32_I8_c(WORD* src, DWORD* dst); -extern void __fastcall ReadCLUT32_T32_I4_c(WORD* src, DWORD* dst); -extern void __fastcall ReadCLUT32_T16_I8_c(WORD* src, DWORD* dst); -extern void __fastcall ReadCLUT32_T16_I4_c(WORD* src, DWORD* dst); - -#ifdef _M_AMD64 - -#define SaturateColor SaturateColor_amd64 - -#define unSwizzleBlock32 unSwizzleBlock32_amd64 -#define unSwizzleBlock16 unSwizzleBlock16_amd64 -#define unSwizzleBlock8 unSwizzleBlock8_amd64 -#define unSwizzleBlock4 unSwizzleBlock4_amd64 -#define unSwizzleBlock8HP unSwizzleBlock8HP_amd64 -#define unSwizzleBlock4HLP unSwizzleBlock4HLP_amd64 -#define unSwizzleBlock4HHP unSwizzleBlock4HHP_amd64 -#define unSwizzleBlock4P unSwizzleBlock4P_amd64 -#define SwizzleBlock32 SwizzleBlock32_amd64 -#define SwizzleBlock16 SwizzleBlock16_amd64 -#define SwizzleBlock8 SwizzleBlock8_amd64 -#define SwizzleBlock4 SwizzleBlock4_amd64 -#define SwizzleBlock32u SwizzleBlock32u_amd64 -#define SwizzleBlock16u SwizzleBlock16u_amd64 -#define SwizzleBlock8u SwizzleBlock8u_amd64 -#define SwizzleBlock4u SwizzleBlock4u_amd64 - -#define SwizzleColumn32 SwizzleColumn32_c -#define SwizzleColumn16 SwizzleColumn16_c -#define SwizzleColumn8 SwizzleColumn8_c -#define SwizzleColumn4 SwizzleColumn4_c - -#define ExpandBlock24 ExpandBlock24_sse2 -#define ExpandBlock16 ExpandBlock16_sse2 -#define Expand16 Expand16_sse2 - -#define UVMinMax UVMinMax_sse2 - -#define WriteCLUT_T16_I8_CSM1 WriteCLUT_T16_I8_CSM1_sse2 -#define WriteCLUT_T32_I8_CSM1 WriteCLUT_T32_I8_CSM1_sse2 -#define WriteCLUT_T16_I4_CSM1 WriteCLUT_T16_I4_CSM1_sse2 -#define WriteCLUT_T32_I4_CSM1 WriteCLUT_T32_I4_CSM1_sse2 - -#define ReadCLUT32_T32_I8 ReadCLUT32_T32_I8_sse2 -#define ReadCLUT32_T32_I4 ReadCLUT32_T32_I4_sse2 -#define ReadCLUT32_T16_I8 ReadCLUT32_T16_I8_sse2 -#define ReadCLUT32_T16_I4 ReadCLUT32_T16_I4_sse2 - -#elif _M_IX86_FP >= 2 - -#define SaturateColor SaturateColor_sse2 - -#define unSwizzleBlock32 unSwizzleBlock32_sse2 -#define unSwizzleBlock16 unSwizzleBlock16_sse2 -#define unSwizzleBlock8 unSwizzleBlock8_sse2 -#define unSwizzleBlock4 unSwizzleBlock4_sse2 -#define unSwizzleBlock8HP unSwizzleBlock8HP_sse2 -#define unSwizzleBlock4HLP unSwizzleBlock4HLP_sse2 -#define unSwizzleBlock4HHP unSwizzleBlock4HHP_sse2 -#define unSwizzleBlock4P unSwizzleBlock4P_sse2 -#define SwizzleBlock32 SwizzleBlock32_sse2 -#define SwizzleBlock16 SwizzleBlock16_sse2 -#define SwizzleBlock8 SwizzleBlock8_sse2 -#define SwizzleBlock4 SwizzleBlock4_sse2 -#define SwizzleBlock32u SwizzleBlock32u_sse2 -#define SwizzleBlock16u SwizzleBlock16u_sse2 -#define SwizzleBlock8u SwizzleBlock8u_sse2 -#define SwizzleBlock4u SwizzleBlock4u_sse2 - -#define SwizzleColumn32 SwizzleColumn32_c -#define SwizzleColumn16 SwizzleColumn16_c -#define SwizzleColumn8 SwizzleColumn8_c -#define SwizzleColumn4 SwizzleColumn4_c - -#define ExpandBlock24 ExpandBlock24_sse2 -#define ExpandBlock16 ExpandBlock16_sse2 -#define Expand16 Expand16_sse2 - -#define UVMinMax UVMinMax_sse2 - -#define WriteCLUT_T16_I8_CSM1 WriteCLUT_T16_I8_CSM1_sse2 -#define WriteCLUT_T32_I8_CSM1 WriteCLUT_T32_I8_CSM1_sse2 -#define WriteCLUT_T16_I4_CSM1 WriteCLUT_T16_I4_CSM1_sse2 -#define WriteCLUT_T32_I4_CSM1 WriteCLUT_T32_I4_CSM1_sse2 - -#define ReadCLUT32_T32_I8 ReadCLUT32_T32_I8_sse2 -#define ReadCLUT32_T32_I4 ReadCLUT32_T32_I4_sse2 -#define ReadCLUT32_T16_I8 ReadCLUT32_T16_I8_sse2 -#define ReadCLUT32_T16_I4 ReadCLUT32_T16_I4_sse2 - -#else - -#define SaturateColor SaturateColor_asm - -#define unSwizzleBlock32 unSwizzleBlock32_c -#define unSwizzleBlock16 unSwizzleBlock16_c -#define unSwizzleBlock8 unSwizzleBlock8_c -#define unSwizzleBlock4 unSwizzleBlock4_c -#define unSwizzleBlock8HP unSwizzleBlock8HP_c -#define unSwizzleBlock4HLP unSwizzleBlock4HLP_c -#define unSwizzleBlock4HHP unSwizzleBlock4HHP_c -#define unSwizzleBlock4P unSwizzleBlock4P_c -#define SwizzleBlock32 SwizzleBlock32_c -#define SwizzleBlock16 SwizzleBlock16_c -#define SwizzleBlock8 SwizzleBlock8_c -#define SwizzleBlock4 SwizzleBlock4_c -#define SwizzleBlock32u SwizzleBlock32_c -#define SwizzleBlock16u SwizzleBlock16_c -#define SwizzleBlock8u SwizzleBlock8_c -#define SwizzleBlock4u SwizzleBlock4_c - -#define SwizzleColumn32 SwizzleColumn32_c -#define SwizzleColumn16 SwizzleColumn16_c -#define SwizzleColumn8 SwizzleColumn8_c -#define SwizzleColumn4 SwizzleColumn4_c - -#define ExpandBlock24 ExpandBlock24_c -#define ExpandBlock16 ExpandBlock16_c -#define Expand16 Expand16_c - -#define UVMinMax UVMinMax_c - -#define WriteCLUT_T16_I8_CSM1 WriteCLUT_T16_I8_CSM1_c -#define WriteCLUT_T32_I8_CSM1 WriteCLUT_T32_I8_CSM1_c -#define WriteCLUT_T16_I4_CSM1 WriteCLUT_T16_I4_CSM1_c -#define WriteCLUT_T32_I4_CSM1 WriteCLUT_T32_I4_CSM1_c - -#define ReadCLUT32_T32_I8 ReadCLUT32_T32_I8_c -#define ReadCLUT32_T32_I4 ReadCLUT32_T32_I4_c -#define ReadCLUT32_T16_I8 ReadCLUT32_T16_I8_c -#define ReadCLUT32_T16_I4 ReadCLUT32_T16_I4_c - -#endif