209 lines
5.2 KiB
C++
209 lines
5.2 KiB
C++
// VisualBoyAdvance - Nintendo Gameboy/GameboyAdvance (TM) emulator.
|
|
// Copyright (C) 1999-2003 Forgotten
|
|
// Copyright (C) 2005 Forgotten and the VBA development team
|
|
// Copyright (C) 2007-2008 VBA-M development team
|
|
// Copyright (C) saunyuan
|
|
// 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 this program; if not, write to the Free Software Foundation,
|
|
// Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
// VBA.cpp : Defines the class behaviors for the application.
|
|
|
|
#include "stdafx.h"
|
|
#include "rpi.h"
|
|
|
|
extern void SuperEagle(u8*,u32,u8*,u8*,u32,int,int);
|
|
|
|
static HINSTANCE rpiDLL = NULL;
|
|
static RENDPLUG_Output fnOutput = NULL;
|
|
static RENDPLUG_GetInfo fnGetInfo = NULL;
|
|
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();
|
|
|
|
char sBuffer[256];
|
|
char *ptr;
|
|
|
|
GetModuleFileName(NULL, sBuffer, sizeof(sBuffer));
|
|
ptr = strrchr(sBuffer, '\\');
|
|
if (ptr)
|
|
*ptr = '\0';
|
|
strcat(sBuffer, "\\plugins\\");
|
|
strcat(sBuffer, sPluginName);
|
|
|
|
rpiDLL = LoadLibrary(sBuffer);
|
|
if (!rpiDLL)
|
|
return false;
|
|
|
|
fnGetInfo = (RENDPLUG_GetInfo) GetProcAddress(rpiDLL, "RenderPluginGetInfo");
|
|
fnOutput = (RENDPLUG_Output) GetProcAddress(rpiDLL, "RenderPluginOutput");
|
|
if (fnGetInfo == NULL || fnOutput == NULL)
|
|
{
|
|
FreeLibrary(rpiDLL);
|
|
rpiDLL = NULL;
|
|
return false;
|
|
}
|
|
|
|
RENDER_PLUGIN_INFO *pRPI = fnGetInfo();
|
|
if (pRPI == NULL)
|
|
{
|
|
FreeLibrary(rpiDLL);
|
|
rpiDLL = NULL;
|
|
return false;
|
|
}
|
|
|
|
memcpy(&MyPlugInfo, pRPI, sizeof(MyPlugInfo));
|
|
|
|
unsigned long Flags = MyPlugInfo.Flags & 0x0000F0000;
|
|
|
|
if (Flags == RPI_OUT_SCL2)
|
|
{
|
|
nScaleFactor = 2;
|
|
}
|
|
else if (Flags == RPI_OUT_SCL3)
|
|
{
|
|
nScaleFactor = 3;
|
|
}
|
|
else if (Flags == RPI_OUT_SCL4)
|
|
{
|
|
nScaleFactor = 4;
|
|
}
|
|
else
|
|
{
|
|
nScaleFactor = 2;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
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;
|
|
// 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/2)) * nScaleFactor;
|
|
MyPlugOutput.OutW = width * 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<height*nScaleFactor;j++)
|
|
{
|
|
for(i=0;i<width*nScaleFactor;i++)
|
|
{
|
|
*(pOCur++) = ((*pICur & 0xF800) << rshiftDiff) |
|
|
((*pICur & 0x07E0) << gshiftDiff) |
|
|
((*pICur & 0x001F) << bshiftDiff);
|
|
*pICur++;
|
|
}
|
|
pI = pICur = (u16 *)((char *)pI + dstPitch);
|
|
pO = pOCur = (u32 *)((char *)pO + dstPitch);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// red shift is negative. That means we're most likely swapping RGB to BGR
|
|
// shift operators don't support negative values.
|
|
|
|
rshiftDiff = -rshiftDiff;
|
|
for(j=0;j<height*nScaleFactor;j++)
|
|
{
|
|
for(i=0;i<width*nScaleFactor;i++)
|
|
{
|
|
*(pOCur++) = ((*pICur & 0xF800) >> rshiftDiff) |
|
|
((*pICur & 0x07E0) << gshiftDiff) |
|
|
((*pICur & 0x001F) << bshiftDiff);
|
|
*pICur++;
|
|
}
|
|
pI = pICur = (u16 *)((char *)pI + dstPitch);
|
|
pO = pOCur = (u32 *)((char *)pO + dstPitch);
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
int rpiScaleFactor()
|
|
{
|
|
return nScaleFactor;
|
|
}
|
|
|
|
void rpiCleanup()
|
|
{
|
|
if (rpiDLL != NULL)
|
|
{
|
|
FreeLibrary(rpiDLL);
|
|
rpiDLL = NULL;
|
|
}
|
|
if (pBuffer16)
|
|
{
|
|
free(pBuffer16);
|
|
pBuffer16 = NULL;
|
|
Buffer16Size = 0;
|
|
}
|
|
}
|