#pragma once #include #include #include #include #include #include #include #include #include #include #include #define CAMERA_CONTROL_PROP_SIZE 7 #define DRAW_MODE_SIZE 5 template void SafeRelease(T **ppT) { if (*ppT) { (*ppT)->Release(); *ppT = nullptr; } } typedef void (*IMAGE_TRANSFORM_FN)( BYTE* pDest, LONG lDestStride, const BYTE* pSrc, LONG lSrcStride, DWORD dwWidthInPixels, DWORD dwHeightInPixels ); struct CameraControlProp { long minValue = 0; long maxValue = 0; long delta = 0; long defaultValue = 0; long defFlags = 0; long value = 0; long valueFlags = 0; }; struct MediaTypeInfo { GUID subtype = GUID_NULL; UINT32 width = 0; UINT32 height = 0; double frameRate = 0.0; IMFMediaType* p_mediaType = nullptr; std::string description = ""; LONG *plStride = nullptr; }; typedef enum { DrawModeStretch = 0, DrawModeCrop = 1, DrawModeLetterbox = 2, DrawModeCrop4_3 = 3, DrawModeLetterbox4_3 = 4, } LocalCameraDrawMode; extern std::string CAMERA_CONTROL_LABELS[]; extern std::string DRAW_MODE_LABELS[]; namespace games::iidx { class IIDXLocalCamera { protected: virtual ~IIDXLocalCamera() {}; ULONG m_nRefCount; CRITICAL_SECTION m_critsec; std::string m_name; BOOL m_prefer_16_by_9; WCHAR *m_pwszSymbolicLink = nullptr; UINT32 m_cchSymbolicLink = 0; // For reading frames from Camera IMFMediaSource *m_pSource = nullptr; IMFSourceReader *m_pSourceReader = nullptr; // Camera Format information double m_frameRate = 0; LONG m_cameraWidth; LONG m_cameraHeight; // Draw rectangles RECT m_rcSource; RECT m_rcDest; // Thread to draw texture asynchorously std::thread *m_drawThread = nullptr; // DirectX9 DeviceEx LPDIRECT3DDEVICE9EX m_device; // Address to hook camera texture onto the game LPDIRECT3DTEXTURE9 *m_texture_target = nullptr; // Target texture LPDIRECT3DTEXTURE9 m_texture = nullptr; IDirect3DSurface9 *m_pDestSurf = nullptr; // Storing original texture for clean up LPDIRECT3DTEXTURE9 m_texture_original = nullptr; IAMCameraControl *m_pCameraControl = nullptr; // Camera Control std::vector m_controlProps = {}; BOOL m_controlOptionsInitialized = false; public: // True if first part of the setup steps (those in the constructor) succeeded BOOL m_initialized = false; // True if all the setup steps succeeded BOOL m_active = false; // Media type select std::vector m_mediaTypeInfos = {}; int m_selectedMediaTypeIndex = 0; bool m_useAutoMediaType = true; IMFMediaType *m_pAutoMediaType = nullptr; std::string m_selectedMediaTypeDescription = ""; bool m_allowManualControl = false; LocalCameraDrawMode m_drawMode = DrawModeCrop4_3; IIDXLocalCamera( std::string name, BOOL prefer_16_by_9, IMFActivate *pActivate, IDirect3DDeviceManager9 *pD3DManager, LPDIRECT3DDEVICE9EX device, LPDIRECT3DTEXTURE9 *texture_target ); LPDIRECT3DTEXTURE9 GetTexture(); ULONG Release(); IAMCameraControl* GetCameraControl(); HRESULT GetCameraControlProp(int index, CameraControlProp *pProp); HRESULT SetCameraControlProp(int index, long value, long flags); HRESULT ResetCameraControlProps(); std::string GetName(); std::string GetSymLink(); HRESULT ChangeMediaType(IMFMediaType *pType); HRESULT StartCapture(); void UpdateDrawRect(); private: HRESULT CreateD3DDeviceManager(); void CreateThread(); MediaTypeInfo GetMediaTypeInfo(IMFMediaType *pType); std::string GetVideoFormatName(GUID subtype); HRESULT TryMediaType(IMFMediaType *pType, UINT32 *pBestWidth, double *pBestFrameRate); HRESULT InitTargetTexture(); HRESULT InitCameraControl(); HRESULT DrawSample(IMFMediaBuffer *pSrcBuffer); HRESULT ReadSample(); LPDIRECT3DTEXTURE9 Render(); }; }