From 2e1060a9e856c35db2cd3616a57567d0ec64fa61 Mon Sep 17 00:00:00 2001 From: DJRobX Date: Mon, 19 Nov 2007 09:03:21 +0000 Subject: [PATCH] Convert RPI output to 32 bit as needed --- src/win32/VBA.cpp | 1 + src/win32/rpi.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 90 insertions(+), 4 deletions(-) diff --git a/src/win32/VBA.cpp b/src/win32/VBA.cpp index f9a50b13..2a7549be 100644 --- a/src/win32/VBA.cpp +++ b/src/win32/VBA.cpp @@ -795,6 +795,7 @@ void VBA::updateFilter() if (rpiInit(pluginName)) filterFunction = rpiFilter; filterMagnification = rpiScaleFactor(); + b16to32Video=true; break; case FILTER_TVMODE: filterFunction = ScanlinesTV32; diff --git a/src/win32/rpi.cpp b/src/win32/rpi.cpp index fcc4a048..c43d14d1 100644 --- a/src/win32/rpi.cpp +++ b/src/win32/rpi.cpp @@ -10,6 +10,12 @@ static RENDER_PLUGIN_INFO MyPlugInfo; static RENDER_PLUGIN_OUTP MyPlugOutput; static int nScaleFactor; +extern int systemRedShift, systemGreenShift, systemBlueShift; +extern int realsystemRedShift, realsystemGreenShift, realsystemBlueShift; +extern int realsystemColorDepth; +u8 *pBuffer16 = NULL; +u32 Buffer16Size = 0; + bool rpiInit(const char *sPluginName) { rpiCleanup(); @@ -71,20 +77,93 @@ bool rpiInit(const char *sPluginName) void rpiFilter(u8 *srcPtr, u32 srcPitch, u8 *deltaPtr, u8 *dstPtr, u32 dstPitch, int width, int height) { + u8 *pBuff; + + if (realsystemColorDepth == 32) + { + // Kega filters are 16 bit only. Assumes we've forced 16 bit input + ASSERT(systemColorDepth == 16); + u32 bufferNeeded = dstPitch * (height + nScaleFactor) * nScaleFactor; + if (Buffer16Size < bufferNeeded) + { + Buffer16Size = bufferNeeded; + if (pBuffer16) + free(pBuffer16); + pBuffer16 = (u8 *)malloc(Buffer16Size); + } + pBuff = pBuffer16; + } + else + pBuff = dstPtr; + MyPlugOutput.Size = sizeof(MyPlugOutput); MyPlugOutput.Flags = MyPlugInfo.Flags; MyPlugOutput.SrcPtr = srcPtr; MyPlugOutput.SrcPitch = srcPitch; MyPlugOutput.SrcW = width; - MyPlugOutput.SrcH = height; - MyPlugOutput.DstPtr = dstPtr; + // Without this funky math on the height value, the RPI filter isn't fully + // rendering the frame. I don't like passing in values that seem + // to be greater than the buffer size, but it's the only way to get + // proper results. + MyPlugOutput.SrcH = height+(nScaleFactor/2); + MyPlugOutput.DstPtr = pBuff; MyPlugOutput.DstPitch = dstPitch; MyPlugOutput.DstW = width * nScaleFactor; - MyPlugOutput.DstH = height * nScaleFactor; + MyPlugOutput.DstH = (height+(nScaleFactor/2)) * nScaleFactor; MyPlugOutput.OutW = width * nScaleFactor; - MyPlugOutput.OutH = height * nScaleFactor; + MyPlugOutput.OutH = (height+(nScaleFactor/2)) * nScaleFactor; fnOutput(&MyPlugOutput); + + if (realsystemColorDepth == 32) + { + register int i,j; + int rshiftDiff = realsystemRedShift - systemRedShift; + int gshiftDiff = realsystemGreenShift - systemGreenShift; + int bshiftDiff = realsystemBlueShift - systemBlueShift; + + u16 *pI, *pICur; + u32 *pO, *pOCur; + + pI = pICur = (u16 *)pBuff; + pO = pOCur = (u32 *)dstPtr; + + if (rshiftDiff >= 0) + { + for(j=0;j> rshiftDiff) | + ((*pICur & 0x07E0) << gshiftDiff) | + ((*pICur & 0x001F) << bshiftDiff); + *pICur++; + } + pI = pICur = (u16 *)((char *)pI + dstPitch); + pO = pOCur = (u32 *)((char *)pO + dstPitch); + } + + } + } } int rpiScaleFactor() @@ -99,4 +178,10 @@ void rpiCleanup() FreeLibrary(rpiDLL); rpiDLL = NULL; } + if (pBuffer16) + { + free(pBuffer16); + pBuffer16 = NULL; + Buffer16Size = 0; + } }