Rewrite the Interframe filters using proper C++ classes.
Also drop support for MMX and 16 bit filters
This commit is contained in:
parent
a25179e4d5
commit
52db9a46f6
|
@ -298,6 +298,7 @@ SET(SRC_SDL
|
|||
|
||||
SET(SRC_FILTERS
|
||||
src/filters/filters.cpp
|
||||
src/filters/new_interframe.cpp
|
||||
src/filters/2xSaI.cpp
|
||||
src/filters/admame.cpp
|
||||
src/filters/bilinear.cpp
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
#include <stdexcept>
|
||||
#include <iostream>
|
||||
|
||||
#include "interframe.hpp"
|
||||
#include "../common/Types.h"
|
||||
|
||||
//sdl
|
||||
|
@ -121,7 +120,9 @@ public:
|
|||
* This one is smart.
|
||||
* It knows it's a 32 bit filter, and the input width will not change from when it is initialized.
|
||||
*
|
||||
* \param[in] srcPtr A pointer to a 16/32 bit RGB Pixel Array
|
||||
* \param[in] srcPtr A pointer to the input 32 bit RGB Pixel Array
|
||||
* \param[in] deltaPtr A pointer to a 32 bit RGB Pixel Array (used to store the difference between frames)
|
||||
* \param[in] dstPtr A pointer to the output 32 bit RGB Pixel Array
|
||||
*/
|
||||
void run(u8 *srcPtr, u8 *deltaPtr, u8 *dstPtr, int height)
|
||||
{
|
||||
|
@ -187,8 +188,6 @@ void Scanlines (u8 *srcPtr, u32 srcPitch, u8 *, u8 *dstPtr, u32 dstPitch, int wi
|
|||
void Scanlines32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height);
|
||||
// "TV" here means each pixel is faded horizontally & vertically rather than
|
||||
// inserting black scanlines
|
||||
// this depends on RGB_LOW_BITS_MASK (included from interframe.hpp
|
||||
//extern int RGB_LOW_BITS_MASK;
|
||||
void ScanlinesTV(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height);
|
||||
void ScanlinesTV32(u8 *srcPtr, u32 srcPitch, u8 * /* deltaPtr */, u8 *dstPtr, u32 dstPitch, int width, int height);
|
||||
|
||||
|
|
|
@ -0,0 +1,153 @@
|
|||
//Credits:
|
||||
// Kawaks' Mr. K for the code
|
||||
// Incorporated into vba by Anthony Di Franco
|
||||
// Converted to C++ by Arthur Moore
|
||||
#include "../System.h"
|
||||
#include <stdlib.h>
|
||||
#include <memory.h>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "new_interframe.hpp"
|
||||
|
||||
void interframe_filter::setWidth(unsigned int _width)
|
||||
{
|
||||
width = _width;
|
||||
|
||||
//32 bit filter, so 8 bytes per pixel
|
||||
// The +1 is for a 1 pixel border that the emulator spits out
|
||||
horiz_bytes = (width+1) * 4;
|
||||
//Unfortunately, the filter keeps the border on the scaled output, but DOES NOT scale it
|
||||
// horiz_bytes_out = width * 4 * myScale + 4;
|
||||
|
||||
}
|
||||
|
||||
SmartIB::SmartIB()
|
||||
{
|
||||
frm1 = (u8 *)calloc(322*242,4);
|
||||
// 1 frame ago
|
||||
frm2 = (u8 *)calloc(322*242,4);
|
||||
// 2 frames ago
|
||||
frm3 = (u8 *)calloc(322*242,4);
|
||||
// 3 frames ago
|
||||
}
|
||||
|
||||
SmartIB::~SmartIB()
|
||||
{
|
||||
//\HACK to prevent double freeing. (It looks like this is not being called in a thread safe manner!!!)
|
||||
|
||||
if(frm1)
|
||||
free(frm1);
|
||||
if( frm2 && (frm1 != frm2) )
|
||||
free(frm2);
|
||||
if( frm3 && (frm1 != frm3) && (frm2 != frm3) )
|
||||
free(frm3);
|
||||
frm1 = frm2 = frm3 = NULL;
|
||||
}
|
||||
|
||||
void SmartIB::run(u8 *srcPtr, int starty, int height)
|
||||
{
|
||||
if(!getWidth())
|
||||
{
|
||||
throw std::runtime_error("ERROR: Filter width not set");
|
||||
}
|
||||
run(srcPtr, get_horiz_bytes(), getWidth(), starty, height);
|
||||
}
|
||||
|
||||
void SmartIB::run(u8 *srcPtr, u32 srcPitch, int width, int starty, int height)
|
||||
{
|
||||
setWidth(width);
|
||||
//Make sure the math was correct
|
||||
if( (srcPitch != get_horiz_bytes()) )
|
||||
{
|
||||
throw std::runtime_error("ERROR: Filter programmer is an idiot, and messed up an important calculation!");
|
||||
}
|
||||
|
||||
u32 *src0 = (u32 *)srcPtr + starty * srcPitch / 4;
|
||||
u32 *src1 = (u32 *)frm1 + starty * srcPitch / 4;
|
||||
u32 *src2 = (u32 *)frm2 + starty * srcPitch / 4;
|
||||
u32 *src3 = (u32 *)frm3 + starty * srcPitch / 4;
|
||||
|
||||
u32 colorMask = 0xfefefe;
|
||||
|
||||
int sPitch = srcPitch >> 2;
|
||||
int pos = 0;
|
||||
|
||||
for (int j = 0; j < height; j++)
|
||||
for (int i = 0; i < sPitch; i++) {
|
||||
u32 color = src0[pos];
|
||||
src0[pos] =
|
||||
(src1[pos] != src2[pos]) &&
|
||||
(src3[pos] != color) &&
|
||||
((color == src2[pos]) || (src1[pos] == src3[pos]))
|
||||
? (((color & colorMask) >> 1) + ((src1[pos] & colorMask) >> 1)) :
|
||||
color;
|
||||
src3[pos] = color; /* oldest buffer now holds newest frame */
|
||||
pos++;
|
||||
}
|
||||
|
||||
/* Swap buffers around */
|
||||
u8 *temp = frm1;
|
||||
frm1 = frm3;
|
||||
frm3 = frm2;
|
||||
frm2 = temp;
|
||||
}
|
||||
|
||||
|
||||
MotionBlurIB::MotionBlurIB()
|
||||
{
|
||||
frm1 = (u8 *)calloc(322*242,4);
|
||||
// 1 frame ago
|
||||
frm2 = (u8 *)calloc(322*242,4);
|
||||
// 2 frames ago
|
||||
frm3 = (u8 *)calloc(322*242,4);
|
||||
// 3 frames ago
|
||||
}
|
||||
|
||||
MotionBlurIB::~MotionBlurIB()
|
||||
{
|
||||
//\HACK to prevent double freeing. (It looks like this is not being called in a thread safe manner!!!)
|
||||
|
||||
if(frm1)
|
||||
free(frm1);
|
||||
if( frm2 && (frm1 != frm2) )
|
||||
free(frm2);
|
||||
if( frm3 && (frm1 != frm3) && (frm2 != frm3) )
|
||||
free(frm3);
|
||||
frm1 = frm2 = frm3 = NULL;
|
||||
}
|
||||
|
||||
void MotionBlurIB::run(u8 *srcPtr, int starty, int height)
|
||||
{
|
||||
if(!getWidth())
|
||||
{
|
||||
throw std::runtime_error("ERROR: Filter width not set");
|
||||
}
|
||||
run(srcPtr, get_horiz_bytes(), getWidth(), starty, height);
|
||||
}
|
||||
|
||||
void MotionBlurIB::run(u8 *srcPtr, u32 srcPitch, int width, int starty, int height)
|
||||
{
|
||||
setWidth(width);
|
||||
//Make sure the math was correct
|
||||
if( (srcPitch != get_horiz_bytes()) )
|
||||
{
|
||||
throw std::runtime_error("ERROR: Filter programmer is an idiot, and messed up an important calculation!");
|
||||
}
|
||||
|
||||
u32 *src0 = (u32 *)srcPtr + starty * srcPitch / 4;
|
||||
u32 *src1 = (u32 *)frm1 + starty * srcPitch / 4;
|
||||
|
||||
u32 colorMask = 0xfefefe;
|
||||
|
||||
int sPitch = srcPitch >> 2;
|
||||
int pos = 0;
|
||||
|
||||
for (int j = 0; j < height; j++)
|
||||
for (int i = 0; i < sPitch; i++) {
|
||||
u32 color = src0[pos];
|
||||
src0[pos] = (((color & colorMask) >> 1) +
|
||||
((src1[pos] & colorMask) >> 1));
|
||||
src1[pos] = color;
|
||||
pos++;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
/// Filters (Using propper C++ classes instead of statics)
|
||||
|
||||
#ifndef NEW_INTERFRAME_HPP
|
||||
#define NEW_INTERFRAME_HPP
|
||||
|
||||
#include "../common/Types.h"
|
||||
#include <string>
|
||||
|
||||
class interframe_filter
|
||||
{
|
||||
private:
|
||||
///The filter's width
|
||||
unsigned int width;
|
||||
///Don't need to calculate these every time (based off width)
|
||||
unsigned int horiz_bytes;
|
||||
// unsigned int horiz_bytes_out;
|
||||
//Children need this pre-calculated data, but it's NOT public
|
||||
protected:
|
||||
unsigned int get_horiz_bytes() {return horiz_bytes;}
|
||||
// unsigned int get_horiz_bytes_out() {return horiz_bytes_out;}
|
||||
public:
|
||||
interframe_filter(): width(0) {}
|
||||
virtual std::string getName() {return "Dummy Filter";}
|
||||
virtual int getScale() {return 0;}
|
||||
///Set the number of pixels per horizontal row
|
||||
///Always use this after initialization if using the new run function.
|
||||
void setWidth(unsigned int _width);
|
||||
unsigned int getWidth() {return width;}
|
||||
///DEPRECATED Original Interframe function
|
||||
virtual void run(u8 *srcPtr, u32 srcPitch, int width, int starty, int height) {}
|
||||
///New smarter Interframe function
|
||||
virtual void run(u8 *srcPtr, int starty, int height) {}
|
||||
};
|
||||
|
||||
|
||||
// Interframe blending filters (These are the 32 bit versions)
|
||||
class SmartIB : interframe_filter
|
||||
{
|
||||
private:
|
||||
u8 *frm1 = NULL;
|
||||
u8 *frm2 = NULL;
|
||||
u8 *frm3 = NULL;
|
||||
public:
|
||||
SmartIB();
|
||||
~SmartIB();
|
||||
std::string getName() {return "SmartIB";}
|
||||
void run(u8 *srcPtr, u32 srcPitch, int width, int starty, int height);
|
||||
void run(u8 *srcPtr, int starty, int height);
|
||||
};
|
||||
|
||||
class MotionBlurIB : interframe_filter
|
||||
{
|
||||
private:
|
||||
u8 *frm1 = NULL;
|
||||
u8 *frm2 = NULL;
|
||||
u8 *frm3 = NULL;
|
||||
public:
|
||||
MotionBlurIB();
|
||||
~MotionBlurIB();
|
||||
std::string getName() {return "MotionBlurIB";}
|
||||
void run(u8 *srcPtr, u32 srcPitch, int width, int starty, int height);
|
||||
void run(u8 *srcPtr, int starty, int height);
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //NEW_INTERFRAME_HPP
|
||||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "../System.h"
|
||||
#include "../filters/filters.hpp"
|
||||
#include "../filters/interframe.hpp"
|
||||
|
||||
namespace VBA
|
||||
{
|
||||
|
|
|
@ -18,8 +18,6 @@
|
|||
|
||||
#include "filters.h"
|
||||
|
||||
#include "../filters/filters.hpp"
|
||||
|
||||
//
|
||||
// Screen filters
|
||||
//
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "../System.h"
|
||||
#include "../filters/filters.hpp"
|
||||
#include "../filters/interframe.hpp"
|
||||
|
||||
//
|
||||
// Screen filters
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
#include "../gba/Cheats.h"
|
||||
|
||||
#include "../filters/filters.hpp"
|
||||
#include "../filters/interframe.hpp"
|
||||
|
||||
template <typename T>
|
||||
void CheckPointer(T pointer)
|
||||
|
|
Loading…
Reference in New Issue