diff --git a/build/win32/Cxbx.vcxproj b/build/win32/Cxbx.vcxproj
index f2d5be566..e7b9e89bd 100644
--- a/build/win32/Cxbx.vcxproj
+++ b/build/win32/Cxbx.vcxproj
@@ -283,7 +283,6 @@ $(SOLUTIONDIR)Export.bat
-
@@ -544,7 +543,6 @@ $(SOLUTIONDIR)Export.bat
%(PreprocessorDefinitions)
-
%(AdditionalIncludeDirectories)
diff --git a/build/win32/Cxbx.vcxproj.filters b/build/win32/Cxbx.vcxproj.filters
index 4f0b0415e..92ba99d11 100644
--- a/build/win32/Cxbx.vcxproj.filters
+++ b/build/win32/Cxbx.vcxproj.filters
@@ -199,9 +199,6 @@
GUI
-
- Emulator
-
@@ -552,9 +549,6 @@
GUI
-
- Emulator
-
diff --git a/src/CxbxKrnl/EmuD3D8.cpp b/src/CxbxKrnl/EmuD3D8.cpp
index d26eddad4..f6912c6ab 100644
--- a/src/CxbxKrnl/EmuD3D8.cpp
+++ b/src/CxbxKrnl/EmuD3D8.cpp
@@ -53,7 +53,6 @@ namespace xboxkrnl
#include "EmuAlloc.h"
#include "MemoryManager.h"
#include "EmuXTL.h"
-#include "libyuv_extract.h" // for YUY2ToARGB
#include
#include
@@ -1324,7 +1323,7 @@ static void EmuUnswizzleTextureStages()
// break;
//CxbxKrnlCleanup("Temporarily unsupported format for active texture unswizzle (0x%.08X)", SurfaceDesc.Format);
- hRet = pTexture->LockRect(v, &LockedRect, NULL, NULL);
+ hRet = pTexture->LockRect(v, &LockedRect, NULL, 0);
if(FAILED(hRet))
continue;
@@ -1336,7 +1335,7 @@ static void EmuUnswizzleTextureStages()
RECT iRect = {0,0,0,0};
POINT iPoint = {0,0};
- void *pTemp = malloc(dwHeight*dwPitch);
+ void *pTemp = malloc(dwPitch*dwHeight);
XTL::EmuUnswizzleRect
(
@@ -3210,7 +3209,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_CreateTexture)
*/
D3DLOCKED_RECT LockedRect;
- pTexture->EmuTexture8->LockRect(0, &LockedRect, NULL, NULL);
+ pTexture->EmuTexture8->LockRect(0, &LockedRect, NULL, D3DLOCK_READONLY);
Texture_Data = (DWORD)LockedRect.pBits;
g_DataToTexture.insert(Texture_Data, pTexture);
pTexture->EmuTexture8->UnlockRect(0);
@@ -4255,6 +4254,8 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_Clear)
return ret;
}
+#define CXBX_SWAP_PRESENT_FORWARD (256 + 4 + 1) // = CxbxPresentForwardMarker + D3DSWAP_FINISH + D3DSWAP_COPY
+
// ******************************************************************
// * patch: D3DDevice_Present
// ******************************************************************
@@ -4266,8 +4267,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_Present)
PVOID pDummy2
)
{
-
-
+ // LOG_FORWARD("D3DDevice_Swap");
DbgPrintf("EmuD3D8: EmuD3DDevice_Present\n"
"(\n"
" pSourceRect : 0x%.08X\n"
@@ -4277,69 +4277,17 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_Present)
");\n",
pSourceRect, pDestRect, pDummy1, pDummy2);
- HRESULT hRet = S_OK;
-
- CxbxReleaseBackBufferLock();
-
- // TODO: Make a video option to wait for VBlank before calling Present.
- // Makes syncing to 30fps easier (which is the native frame rate for Azurik
- // and Halo).
-// g_pDD7->WaitForVerticalBlank( DDWAITVB_BLOCKEND, NULL );
-// g_pDD7->WaitForVerticalBlank( DDWAITVB_BLOCKEND, NULL );
-
- hRet = g_pD3DDevice8->Present(pSourceRect, pDestRect, (HWND)pDummy1, (CONST RGNDATA*)pDummy2);
-
- // Put primitives per frame in the title
- /*{
- char szString[64];
-
- sprintf( szString, "Cxbx: PPF(%d)", g_dwPrimPerFrame );
-
- SetWindowText( CxbxKrnl_hEmuParent, szString );
-
- g_dwPrimPerFrame = 0;
- }*/
-
- // not really accurate because you definately dont always present on every vblank
- g_VBData.Swap = g_VBData.VBlank;
-
- if(g_VBData.VBlank == g_VBLastSwap + 1)
- g_VBData.Flags = 1; // D3DVBLANK_SWAPDONE
- else
- {
- g_VBData.Flags = 2; // D3DVBLANK_SWAPMISSED
- g_SwapData.MissedVBlanks++;
- }
-
- // Handle Swap Callback function
- {
- g_SwapData.Swap++;
-
- if(g_pSwapCallback != NULL)
- {
-
- g_pSwapCallback(&g_SwapData);
-
- }
- }
-
- g_bHackUpdateSoftwareOverlay = FALSE;
-
-
-
- return hRet;
+ return EMUPATCH(D3DDevice_Swap)(CXBX_SWAP_PRESENT_FORWARD); // Xbox present ignores
}
// ******************************************************************
// * patch: D3DDevice_Swap
// ******************************************************************
-HRESULT WINAPI XTL::EMUPATCH(D3DDevice_Swap)
+DWORD WINAPI XTL::EMUPATCH(D3DDevice_Swap)
(
DWORD Flags
)
{
-
-
DbgPrintf("EmuD3D8: EmuD3DDevice_Swap\n"
"(\n"
" Flags : 0x%.08X\n"
@@ -4348,7 +4296,8 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_Swap)
// TODO: Ensure this flag is always the same across library versions
if(Flags != 0)
- EmuWarning("XTL::EmuD3DDevice_Swap: Flags != 0");
+ if (Flags != CXBX_SWAP_PRESENT_FORWARD) // Avoid a warning when forwarded
+ EmuWarning("XTL::EmuD3DDevice_Swap: Flags != 0");
CxbxReleaseBackBufferLock();
@@ -4358,7 +4307,33 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_Swap)
// g_pDD7->WaitForVerticalBlank( DDWAITVB_BLOCKEND, NULL );
// g_pDD7->WaitForVerticalBlank( DDWAITVB_BLOCKEND, NULL );
- HRESULT hRet = g_pD3DDevice8->Present(0, 0, 0, 0);
+ g_pD3DDevice8->Present(0, 0, 0, 0);
+
+ if (Flags == CXBX_SWAP_PRESENT_FORWARD) // Only do this when forwarded from Present
+ {
+ // Put primitives per frame in the title
+ /*{
+ char szString[64];
+
+ sprintf( szString, "Cxbx: PPF(%d)", g_dwPrimPerFrame );
+
+ SetWindowText( CxbxKrnl_hEmuParent, szString );
+
+ g_dwPrimPerFrame = 0;
+ }*/
+
+ // TODO : Check if this should be done at Swap-not-Present-time too :
+ // not really accurate because you definately dont always present on every vblank
+ g_VBData.Swap = g_VBData.VBlank;
+
+ if (g_VBData.VBlank == g_VBLastSwap + 1)
+ g_VBData.Flags = 1; // D3DVBLANK_SWAPDONE
+ else
+ {
+ g_VBData.Flags = 2; // D3DVBLANK_SWAPMISSED
+ g_SwapData.MissedVBlanks++;
+ }
+ }
// Handle Swap Callback function
{
@@ -4374,9 +4349,13 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_Swap)
g_bHackUpdateSoftwareOverlay = FALSE;
-
+ DWORD result;
+ if (Flags == CXBX_SWAP_PRESENT_FORWARD) // Only do this when forwarded from Present
+ result = S_OK; // Present always returns success
+ else
+ result = g_SwapData.Swap; // Swap returns number of swaps
- return hRet;
+ return result;
}
// ******************************************************************
@@ -4838,10 +4817,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DResource_Register)
}
}
- RECT iRect = {0,0,0,0};
- POINT iPoint = {0,0};
-
- BYTE *pSrc = (BYTE*)pBase;
+ BYTE *pSrc = (BYTE*)pBase; // TODO : Fix (look at Dxbx) this, as it gives cube textures identical sides
if(( pResource->Data == X_D3DRESOURCE_DATA_BACK_BUFFER)
||( (DWORD)pBase == X_D3DRESOURCE_DATA_BACK_BUFFER))
@@ -4858,20 +4834,27 @@ HRESULT WINAPI XTL::EMUPATCH(D3DResource_Register)
pSrc += dwMipPitch;
}
}
- else
- {
+ else
+ {
if (level == 0)
pResource->Data = (DWORD)pSrc;
if((DWORD)pSrc == 0x80000000)
- {
+ {
// TODO: Fix or handle this situation..?
// This is probably an unallocated resource, mapped into contiguous memory (0x80000000)
- }
+ }
+ else if (pSrc == nullptr)
+ {
+ // TODO: Fix or handle this situation..?
+ }
else
{
if (bSwizzled)
{
+ RECT iRect = { 0,0,0,0 };
+ POINT iPoint = { 0,0 };
+
// First we need to unswizzle the texture data
XTL::EmuUnswizzleRect
(
@@ -4889,23 +4872,35 @@ HRESULT WINAPI XTL::EMUPATCH(D3DResource_Register)
}
else
{
+ /* TODO : // Let DirectX convert the surface (including palette formats) :
+ if(!EmuXBFormatRequiresConversionToARGB) {
+ D3DXLoadSurfaceFromMemory(
+ pResource->EmuSurface8,
+ nullptr, // no destination palette
+ &destRect,
+ pSrc, // Source buffer
+ dwMipPitch, // Source pitch
+ pCurrentPalette,
+ &SrcRect,
+ D3DX_DEFAULT, // D3DX_FILTER_NONE,
+ 0 // No ColorKey?
+ );
+ } else {
+ */
BYTE *pDest = (BYTE*)LockedRect.pBits;
- if (pSrc)
+ if ((DWORD)LockedRect.Pitch == dwMipPitch && dwMipPitch == dwMipWidth*dwBPP)
{
- if ((DWORD)LockedRect.Pitch == dwMipPitch && dwMipPitch == dwMipWidth*dwBPP)
+ memcpy(pDest, pSrc + dwMipOffs, dwMipWidth*dwMipHeight*dwBPP);
+ }
+ else
+ {
+ for (DWORD v = 0; v < dwMipHeight; v++)
{
- memcpy(pDest, pSrc + dwMipOffs, dwMipWidth*dwMipHeight*dwBPP);
- }
- else
- {
- for (DWORD v = 0; v < dwMipHeight; v++)
- {
- memcpy(pDest, pSrc + dwMipOffs, dwMipWidth*dwBPP);
+ memcpy(pDest, pSrc + dwMipOffs, dwMipWidth*dwBPP);
- pDest += LockedRect.Pitch;
- pSrc += dwMipPitch;
- }
+ pDest += LockedRect.Pitch;
+ pSrc += dwMipPitch;
}
}
}
@@ -6040,27 +6035,6 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_EnableOverlay)
return;
}
-XTL::IDirect3DSurface8 *ExtraXRGBSurface = nullptr; // this is our pointer to the memory location containing our copy of the front buffer
-
-void AssureExtraXRGBSurface(XTL::IDirect3DSurface8 *pBackBufferSurface, std::string Caller)
-{
- XTL::D3DSURFACE_DESC SurfaceDesc;
- HRESULT aResult;
-
- // Assure we have a reusable surface (in the correct format) which the back buffer can be converted into :
- if (ExtraXRGBSurface == nullptr) {
- pBackBufferSurface->GetDesc(&SurfaceDesc);
- aResult = g_pD3DDevice8->CreateImageSurface(
- SurfaceDesc.Width,
- SurfaceDesc.Height,
- XTL::D3DFMT_A8R8G8B8, // This format is supported by D3DXSaveSurfaceToFile (D3DFMT_X8R8G8B8 works too)
- &ExtraXRGBSurface);
- if FAILED(aResult) {
-// DbgPrintf("EmuD3D8 : %s could not create a extra buffer!\n", DxbxD3DErrorString(aResult), Caller);
- }
- }
-}
-
// ******************************************************************
// * patch: D3DDevice_UpdateOverlay
// ******************************************************************
@@ -6129,10 +6103,14 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_UpdateOverlay)
}
}
+ RECT SourRect = { 0, 0, (LONG)g_dwOverlayW, (LONG)g_dwOverlayH };
+ if (SrcRect != NULL)
+ SourRect = *SrcRect;
+
// update overlay!
if(g_bSupportsYUY2)
{
- RECT SourRect = {0, 0, (LONG)g_dwOverlayW, (LONG)g_dwOverlayH}, DestRect;
+ RECT DestRect;
MONITORINFO MonitorInfo = {0};
int nTitleHeight = 0;//GetSystemMetrics(SM_CYCAPTION);
@@ -6167,72 +6145,53 @@ VOID WINAPI XTL::EMUPATCH(D3DDevice_UpdateOverlay)
{
IDirect3DSurface8 *pBackBufferSurface = nullptr;
HRESULT hRet = g_pD3DDevice8->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &pBackBufferSurface);
- // if we obtained the backbuffer, manually translate the YUY2 into the backbuffer format
+ // if we obtained the backbuffer, load the YUY2 into the backbuffer
if (hRet == D3D_OK) {
- IDirect3DSurface8 *pOverlayBufferSurface = nullptr;
- D3DLOCKED_RECT LockedRectDest;
-
// Get backbuffer dimenions; TODO : remember this once, at creation/resize time
D3DSURFACE_DESC BackBufferDesc;
pBackBufferSurface->GetDesc(&BackBufferDesc);
- // Determine if the overlay can be written directly to the backbuffer :
- bool CanWriteToBackbuffer = false;
- if ((BackBufferDesc.Format == D3DFMT_A8R8G8B8) || (BackBufferDesc.Format == D3DFMT_X8R8G8B8)) {
- if (DstRect == SrcRect) {
- CanWriteToBackbuffer = true;
- } else {
- if (DstRect != nullptr && SrcRect != nullptr) {
- if ((DstRect->left == SrcRect->left)
- && (DstRect->right == SrcRect->right)
- && (DstRect->top == SrcRect->top)
- && (DstRect->bottom == SrcRect->bottom)) {
- CanWriteToBackbuffer = true;
- }
- }
+ // Limit the width and height of the output to the backbuffer dimensions.
+ // This will (hopefully) prevent exceptions in Blinx - The Time Sweeper
+ // (see https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/issues/285)
+ RECT DestRect = { 0 };
+ {
+ // If there's a destination rectangle given, copy that into our local variable :
+ if (DstRect != NULL)
+ DestRect = *DstRect;
+
+ // Use our (bounded) copy when bounds exceed :
+ if (DestRect.right > BackBufferDesc.Width) {
+ DestRect.right = BackBufferDesc.Width;
+ DstRect = &DestRect;
+ }
+
+ if (g_dwOverlayH > BackBufferDesc.Height) {
+ DestRect.bottom = BackBufferDesc.Height;
+ DstRect = &DestRect;
}
}
- // If we can write to the back buffer, work with that, else use the screenshotbuffer as temporary surface :
- if (CanWriteToBackbuffer) {
- pOverlayBufferSurface = pBackBufferSurface;
- } else {
- AssureExtraXRGBSurface(pBackBufferSurface, "EmuD3DDevice_UpdateOverlay");
- pOverlayBufferSurface = ExtraXRGBSurface; // Note : This surface is always in ARGB format
- }
+ uint08 *pYUY2Input = (uint08*)pSurface->Lock; // TODO : DxbxGetDataFromXboxResource(pSurface);
- // Manually translate the YUY2 formatted input surface into the RGB buffer of the pre-determined output surface :
- if (pOverlayBufferSurface->LockRect(&LockedRectDest, DstRect, 0) == D3D_OK) {
- // Determine the start of the Xbox overlay buffer and Native destination buffer :
- uint08 *pYUY2Input = (uint08*)pSurface->Lock; // TODO : DxbxGetDataFromXboxResource(pSurface);
- uint08 *pARGBOutput = (uint08*)LockedRectDest.pBits;
-
- // Limit the width and height of the output to the backbuffer dimensions.
- // This will (hopefully) prevent exceptions in Blinx - The Time Sweeper
- // (see https://github.com/Cxbx-Reloaded/Cxbx-Reloaded/issues/285)
- uint32 W = min(g_dwOverlayW, BackBufferDesc.Width);
- uint32 H = min(g_dwOverlayH, BackBufferDesc.Height);
-
- // full color conversion (YUY2->XRGB)
- YUY2ToARGB(pYUY2Input, g_dwOverlayP, pARGBOutput, LockedRectDest.Pitch, W, H);
-
- pOverlayBufferSurface->UnlockRect(); // TODO : Could this be done after calling D3DXLoadSurfaceFromSurface (and would that improve performance)?
-
- if (!CanWriteToBackbuffer) {
- // When the overlay could not directly be converted into the back buffer,
- // we now have to stretch-copy there (this also does a format-conversion, if needed) :
- if (D3DXLoadSurfaceFromSurface(
- /* pDestSurface = */ pBackBufferSurface,
- /* pDestPalette = */ nullptr, // Palette not needed for YUY2
- DstRect,
- /* pSrcSurface = */ pOverlayBufferSurface,
- /* pSrcPalette = */ nullptr, // Palette not needed for YUY2
- SrcRect,
- /* Filter = */ D3DX_FILTER_POINT, // Dxbx note : D3DX_FILTER_LINEAR gives a smoother image, but 'bleeds' across borders
- /* ColorKey = */ ColorKey) != D3D_OK) {
- DbgPrintf("EmuD3D8 : UpdateOverlay could not convert buffer!\n");
- }
- }
+ // Use D3DXLoadSurfaceFromMemory() to do conversion, stretching and filtering
+ // avoiding the need for YUY2toARGB() (might become relevant when porting to D3D9 or OpenGL)
+ // see https://msdn.microsoft.com/en-us/library/windows/desktop/bb172902(v=vs.85).aspx
+ hRet = D3DXLoadSurfaceFromMemory(
+ /* pDestSurface = */ pBackBufferSurface,
+ /* pDestPalette = */ nullptr, // Palette not needed for YUY2
+ /* pDestRect = */DstRect, // Either the unmodified original (can be NULL) or a pointer to our local variable
+ /* pSrcMemory = */ pYUY2Input, // Source buffer
+ /* SrcFormat = */ D3DFMT_YUY2,
+ /* SrcPitch = */ g_dwOverlayP,
+ /* pSrcPalette = */ nullptr, // Palette not needed for YUY2
+ /* pSrcRect = */ &SourRect,
+ /* Filter = */ D3DX_FILTER_POINT, // Dxbx note : D3DX_FILTER_LINEAR gives a smoother image, but 'bleeds' across borders
+ /* ColorKey = */ EnableColorKey ? ColorKey : 0);
+ if (hRet != D3D_OK) {
+ DbgPrintf("EmuD3D8 : UpdateOverlay could not convert buffer!\n");
+ //DbgPrintf("EmuD3D8 : Error: %s error description: %s\n",
+ // DXGetErrorString(hRet), DXGetErrorDescription(hRet));
}
pBackBufferSurface->Release();
@@ -9702,7 +9661,7 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_PersistDisplay)()
{
void* ptr = g_MemoryManager.Allocate( BackBufferDesc.Width * BackBufferDesc.Height * dwBytesPerPixel );
- if( SUCCEEDED( pBackBuffer->LockRect( &LockedRect, NULL, 0 ) ) )
+ if( SUCCEEDED( pBackBuffer->LockRect( &LockedRect, NULL, D3DLOCK_READONLY ) ) )
{
CopyMemory( ptr, LockedRect.pBits, BackBufferDesc.Width * BackBufferDesc.Height * dwBytesPerPixel );
@@ -10487,4 +10446,4 @@ HRESULT WINAPI XTL::EMUPATCH(D3DDevice_GetMaterial)(D3DMATERIAL8* pMaterial)
return S_OK;
-}
+}
\ No newline at end of file
diff --git a/src/CxbxKrnl/EmuD3D8.h b/src/CxbxKrnl/EmuD3D8.h
index ed6819429..393bcc91e 100644
--- a/src/CxbxKrnl/EmuD3D8.h
+++ b/src/CxbxKrnl/EmuD3D8.h
@@ -669,7 +669,7 @@ HRESULT WINAPI EMUPATCH(D3DDevice_Present)
// ******************************************************************
// * patch: D3DDevice_Swap
// ******************************************************************
-HRESULT WINAPI EMUPATCH(D3DDevice_Swap)
+DWORD WINAPI EMUPATCH(D3DDevice_Swap)
(
DWORD Flags
);
diff --git a/src/CxbxKrnl/libyuv_extract.cpp b/src/CxbxKrnl/libyuv_extract.cpp
deleted file mode 100644
index aa46e04a5..000000000
--- a/src/CxbxKrnl/libyuv_extract.cpp
+++ /dev/null
@@ -1,226 +0,0 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check it.
-// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
-#include "libyuv_extract.h"
-
-// The following code is an extract of libyuv to keep code size low (this may be revisited later).
-// Source : https://github.com/lemenkov/libyuv/commit/7e936044d154b9fe159a67f9562e10b1ef1cb590
-
-/* From libyuv\README.chromium :
-Name: libyuv
-URL: http://code.google.com/p/libyuv/
-Version: 1514
-License: BSD
-License File: LICENSE
-
-Description:
-libyuv is an open source project that includes YUV conversion and scaling functionality.
-*/
-
-// From libyuv\include\libyuv\row.h :
-
-// This struct is for Intel color conversion.
-struct YuvConstants {
- int8 kUVToB[32];
- int8 kUVToG[32];
- int8 kUVToR[32];
- int16 kUVBiasB[16];
- int16 kUVBiasG[16];
- int16 kUVBiasR[16];
- int16 kYToRgb[16];
-};
-
-// From libyuv\include\libyuv\row.h :
-
-#if defined(VISUALC_HAS_AVX2)
-#define SIMD_ALIGNED(var) __declspec(align(32)) var
-#else
-#define SIMD_ALIGNED(var) __declspec(align(16)) var
-#endif
-
-// From libyuv\source\row_common.cc :
-
-// llvm x86 is poor at ternary operator, so use branchless min/max.
-#define USE_BRANCHLESS 1
-#if USE_BRANCHLESS
-static __inline int32 clamp0(int32 v) {
- return ((-(v) >> 31) & (v));
-}
-
-static __inline int32 clamp255(int32 v) {
- return (((255 - (v)) >> 31) | (v)) & 255;
-}
-
-static __inline uint32 Clamp(int32 val) {
- int v = clamp0(val);
- return (uint32)(clamp255(v));
-}
-
-static __inline uint32 Abs(int32 v) {
- int m = v >> 31;
- return (v + m) ^ m;
-}
-#else // USE_BRANCHLESS
-static __inline int32 clamp0(int32 v) {
- return (v < 0) ? 0 : v;
-}
-
-static __inline int32 clamp255(int32 v) {
- return (v > 255) ? 255 : v;
-}
-
-static __inline uint32 Clamp(int32 val) {
- int v = clamp0(val);
- return (uint32)(clamp255(v));
-}
-
-static __inline uint32 Abs(int32 v) {
- return (v < 0) ? -v : v;
-}
-#endif // USE_BRANCHLESS
-
-// From libyuv\source\row_common.cc :
-
-// BT.601 YUV to RGB reference
-// R = (Y - 16) * 1.164 - V * -1.596
-// G = (Y - 16) * 1.164 - U * 0.391 - V * 0.813
-// B = (Y - 16) * 1.164 - U * -2.018
-
-// Y contribution to R,G,B. Scale and bias.
-#define YG 18997 /* round(1.164 * 64 * 256 * 256 / 257) */
-#define YGB -1160 /* 1.164 * 64 * -16 + 64 / 2 */
-
-// U and V contributions to R,G,B.
-#define UB -128 /* max(-128, round(-2.018 * 64)) */
-#define UG 25 /* round(0.391 * 64) */
-#define VG 52 /* round(0.813 * 64) */
-#define VR -102 /* round(-1.596 * 64) */
-
-// Bias values to subtract 16 from Y and 128 from U and V.
-#define BB (UB * 128 + YGB)
-#define BG (UG * 128 + VG * 128 + YGB)
-#define BR (VR * 128 + YGB)
-
-const struct YuvConstants SIMD_ALIGNED(kYuvI601Constants) = {
- { UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0,
- UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0, UB, 0 },
- { UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG,
- UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG, UG, VG },
- { 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR,
- 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR, 0, VR },
- { BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB, BB },
- { BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG, BG },
- { BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR, BR },
- { YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG, YG } };
-
-// C reference code that mimics the YUV assembly.
-static __inline void YuvPixel(uint8 y,
- uint8 u,
- uint8 v,
- uint8* b,
- uint8* g,
- uint8* r,
- const struct YuvConstants* yuvconstants) {
- int ub = yuvconstants->kUVToB[0];
- int ug = yuvconstants->kUVToG[0];
- int vg = yuvconstants->kUVToG[1];
- int vr = yuvconstants->kUVToR[1];
- int bb = yuvconstants->kUVBiasB[0];
- int bg = yuvconstants->kUVBiasG[0];
- int br = yuvconstants->kUVBiasR[0];
- int yg = yuvconstants->kYToRgb[0];
-
- uint32 y1 = (uint32)(y * 0x0101 * yg) >> 16;
- *b = Clamp((int32)(-(u * ub) + y1 + bb) >> 6);
- *g = Clamp((int32)(-(u * ug + v * vg) + y1 + bg) >> 6);
- *r = Clamp((int32)(-(v * vr) + y1 + br) >> 6);
-}
-
-void YUY2ToARGBRow_C(const uint8* src_yuy2,
- uint8* rgb_buf,
- const struct YuvConstants* yuvconstants,
- int width) {
- int x;
- for (x = 0; x < width - 1; x += 2) {
- YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3], rgb_buf + 0, rgb_buf + 1,
- rgb_buf + 2, yuvconstants);
- rgb_buf[3] = 255;
- YuvPixel(src_yuy2[2], src_yuy2[1], src_yuy2[3], rgb_buf + 4, rgb_buf + 5,
- rgb_buf + 6, yuvconstants);
- rgb_buf[7] = 255;
- src_yuy2 += 4;
- rgb_buf += 8; // Advance 2 pixels.
- }
- if (width & 1) {
- YuvPixel(src_yuy2[0], src_yuy2[1], src_yuy2[3], rgb_buf + 0, rgb_buf + 1,
- rgb_buf + 2, yuvconstants);
- rgb_buf[3] = 255;
- }
-}
-
-// Convert YUY2 to ARGB.
-LIBYUV_API
-int YUY2ToARGB(const uint8* src_yuy2,
- int src_stride_yuy2,
- uint8* dst_argb,
- int dst_stride_argb,
- int width,
- int height) {
- int y;
- void(*YUY2ToARGBRow)(const uint8* src_yuy2, uint8* dst_argb,
- const struct YuvConstants* yuvconstants, int width) =
- YUY2ToARGBRow_C;
- if (!src_yuy2 || !dst_argb || width <= 0 || height == 0) {
- return -1;
- }
- // Negative height means invert the image.
- if (height < 0) {
- height = -height;
- src_yuy2 = src_yuy2 + (height - 1) * src_stride_yuy2;
- src_stride_yuy2 = -src_stride_yuy2;
- }
- // Coalesce rows.
- if (src_stride_yuy2 == width * 2 && dst_stride_argb == width * 4) {
- width *= height;
- height = 1;
- src_stride_yuy2 = dst_stride_argb = 0;
- }
-#if defined(HAS_YUY2TOARGBROW_SSSE3)
- if (TestCpuFlag(kCpuHasSSSE3)) {
- YUY2ToARGBRow = YUY2ToARGBRow_Any_SSSE3;
- if (IS_ALIGNED(width, 16)) {
- YUY2ToARGBRow = YUY2ToARGBRow_SSSE3;
- }
- }
-#endif
-#if defined(HAS_YUY2TOARGBROW_AVX2)
- if (TestCpuFlag(kCpuHasAVX2)) {
- YUY2ToARGBRow = YUY2ToARGBRow_Any_AVX2;
- if (IS_ALIGNED(width, 32)) {
- YUY2ToARGBRow = YUY2ToARGBRow_AVX2;
- }
- }
-#endif
-#if defined(HAS_YUY2TOARGBROW_NEON)
- if (TestCpuFlag(kCpuHasNEON)) {
- YUY2ToARGBRow = YUY2ToARGBRow_Any_NEON;
- if (IS_ALIGNED(width, 8)) {
- YUY2ToARGBRow = YUY2ToARGBRow_NEON;
- }
- }
-#endif
-#if defined(HAS_YUY2TOARGBROW_MSA)
- if (TestCpuFlag(kCpuHasMSA)) {
- YUY2ToARGBRow = YUY2ToARGBRow_Any_MSA;
- if (IS_ALIGNED(width, 8)) {
- YUY2ToARGBRow = YUY2ToARGBRow_MSA;
- }
- }
-#endif
- for (y = 0; y < height; ++y) {
- YUY2ToARGBRow(src_yuy2, dst_argb, &kYuvI601Constants, width);
- src_yuy2 += src_stride_yuy2;
- dst_argb += dst_stride_argb;
- }
- return 0;
-}
diff --git a/src/CxbxKrnl/libyuv_extract.h b/src/CxbxKrnl/libyuv_extract.h
deleted file mode 100644
index bafae1b69..000000000
--- a/src/CxbxKrnl/libyuv_extract.h
+++ /dev/null
@@ -1,18 +0,0 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check it.
-// PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
-#include "Cxbx.h"
-
-typedef int08 int8;
-typedef uint08 uint8;
-
-// From libyuv\include\libyuv\basic_types.h :
-#define LIBYUV_API
-
-LIBYUV_API
-int YUY2ToARGB(const uint8* src_yuy2,
- int src_stride_yuy2,
- uint8* dst_argb,
- int dst_stride_argb,
- int width,
- int height);
\ No newline at end of file