// 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> 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; } }