mirror of
https://github.com/TASVideos/desmume
synced 2024-07-01 07:14:37 +00:00
Compare commits
7 Commits
58003ba771
...
7302572c6a
Author | SHA1 | Date | |
---|---|---|---|
|
7302572c6a | ||
|
6309a9c6a7 | ||
|
779606ec2f | ||
|
ffb8666a8f | ||
|
ff6c33a8d6 | ||
|
08a41a90eb | ||
|
6cedfcf22d |
|
@ -20,84 +20,100 @@
|
|||
|
||||
#define DEPOSTERIZE_THRESHOLD 23 // Possible values are [0-255], where lower a value prevents blending and a higher value allows for more blending
|
||||
|
||||
|
||||
static u32 Deposterize_InterpLTE(const u32 pixA, const u32 pixB)
|
||||
namespace
|
||||
{
|
||||
const u32 aB = (pixB & 0xFF000000) >> 24;
|
||||
if (aB == 0)
|
||||
template <u32 Den>
|
||||
struct UnpackedPixel
|
||||
{
|
||||
return pixA;
|
||||
}
|
||||
|
||||
const u32 rA = (pixA & 0x000000FF);
|
||||
const u32 gA = (pixA & 0x0000FF00) >> 8;
|
||||
const u32 bA = (pixA & 0x00FF0000) >> 16;
|
||||
const u32 aA = (pixA & 0xFF000000) >> 24;
|
||||
|
||||
const u32 rB = (pixB & 0x000000FF);
|
||||
const u32 gB = (pixB & 0x0000FF00) >> 8;
|
||||
const u32 bB = (pixB & 0x00FF0000) >> 16;
|
||||
|
||||
const u32 rC = ( (rB - rA <= DEPOSTERIZE_THRESHOLD) || (rA - rB <= DEPOSTERIZE_THRESHOLD) ) ? ((rA+rB)>>1) : rA;
|
||||
const u32 gC = ( (gB - gA <= DEPOSTERIZE_THRESHOLD) || (gA - gB <= DEPOSTERIZE_THRESHOLD) ) ? ((gA+gB)>>1) : gA;
|
||||
const u32 bC = ( (bB - bA <= DEPOSTERIZE_THRESHOLD) || (bA - bB <= DEPOSTERIZE_THRESHOLD) ) ? ((bA+bB)>>1) : bA;
|
||||
const u32 aC = ( (aB - aA <= DEPOSTERIZE_THRESHOLD) || (aA - aB <= DEPOSTERIZE_THRESHOLD) ) ? ((aA+aB)>>1) : aA;
|
||||
|
||||
return (rC | (gC << 8) | (bC << 16) | (aC << 24));
|
||||
}
|
||||
u32 r;
|
||||
u32 g;
|
||||
u32 b;
|
||||
u32 a;
|
||||
|
||||
static u32 Deposterize_Blend(const u32 pixA, const u32 pixB, const u32 weightA, const u32 weightB)
|
||||
{
|
||||
const u32 aB = (pixB & 0xFF000000) >> 24;
|
||||
if (aB == 0)
|
||||
{
|
||||
return pixA;
|
||||
}
|
||||
|
||||
const u32 rbA = pixA & 0x00FF00FF;
|
||||
const u32 gA = pixA & 0x0000FF00;
|
||||
const u32 aA = (pixA & 0xFF000000) >> 24;
|
||||
|
||||
const u32 rbB = pixB & 0x00FF00FF;
|
||||
const u32 gB = pixB & 0x0000FF00;
|
||||
|
||||
// Note: The sum of weightA and weightB must equal 16.
|
||||
const u32 rbC = ( ((rbA * weightA) + (rbB * weightB)) / 16 ) & 0x00FF00FF;
|
||||
const u32 gC = ( (( gA * weightA) + ( gB * weightB)) / 16 ) & 0x0000FF00;
|
||||
const u32 aC = ( (( aA * weightA) + ( aB * weightB)) / 16 ) << 24;
|
||||
|
||||
return (rbC | gC | aC);
|
||||
}
|
||||
explicit UnpackedPixel() = default;
|
||||
UnpackedPixel(const UnpackedPixel &) = default;
|
||||
UnpackedPixel &operator=(const UnpackedPixel &) & = default;
|
||||
|
||||
static u32 Deposterize_BlendPixel(const u32 color[9])
|
||||
{
|
||||
const u32 blend[9] = {
|
||||
color[0],
|
||||
Deposterize_InterpLTE(color[0], color[1]),
|
||||
Deposterize_InterpLTE(color[0], color[2]),
|
||||
Deposterize_InterpLTE(color[0], color[3]),
|
||||
Deposterize_InterpLTE(color[0], color[4]),
|
||||
Deposterize_InterpLTE(color[0], color[5]),
|
||||
Deposterize_InterpLTE(color[0], color[6]),
|
||||
Deposterize_InterpLTE(color[0], color[7]),
|
||||
Deposterize_InterpLTE(color[0], color[8])
|
||||
explicit UnpackedPixel(u32 pix) :
|
||||
r(Den * ( pix & 0xff)),
|
||||
g(Den * ((pix >> 8) & 0xff)),
|
||||
b(Den * ((pix >> 16) & 0xff)),
|
||||
a(Den * ((pix >> 24) & 0xff))
|
||||
{}
|
||||
|
||||
u32 pack() const
|
||||
{
|
||||
return r/Den +
|
||||
(g/Den << 8) +
|
||||
(b/Den << 16) +
|
||||
(a/Den << 24);
|
||||
}
|
||||
};
|
||||
|
||||
return Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[5], 2, 14),
|
||||
Deposterize_Blend(blend[0], blend[1], 2, 14),
|
||||
8, 8),
|
||||
Deposterize_Blend(Deposterize_Blend(blend[0], blend[7], 2, 14),
|
||||
Deposterize_Blend(blend[0], blend[3], 2, 14),
|
||||
8, 8),
|
||||
8, 8),
|
||||
Deposterize_Blend(Deposterize_Blend(Deposterize_Blend(blend[0], blend[6], 7, 9),
|
||||
Deposterize_Blend(blend[0], blend[2], 7, 9),
|
||||
8, 8),
|
||||
Deposterize_Blend(Deposterize_Blend(blend[0], blend[8], 7, 9),
|
||||
Deposterize_Blend(blend[0], blend[4], 7, 9),
|
||||
8, 8),
|
||||
8, 8),
|
||||
12, 4);
|
||||
|
||||
template <u32 Mult, u32 Den, class Func>
|
||||
inline UnpackedPixel<Den*Mult> combine(const UnpackedPixel<Den> &pixA, const UnpackedPixel<Den> &pixB, Func &&func)
|
||||
{
|
||||
UnpackedPixel<Den*Mult> ret;
|
||||
ret.r = func(pixA.r, pixB.r);
|
||||
ret.g = func(pixA.g, pixB.g);
|
||||
ret.b = func(pixA.b, pixB.b);
|
||||
ret.a = func(pixA.a, pixB.a);
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline UnpackedPixel<2> Deposterize_InterpLTE(const UnpackedPixel<1> &pixA, const UnpackedPixel<1> &pixB)
|
||||
{
|
||||
return combine<2>(pixA, pixB, [&](u32 a, u32 b) {
|
||||
if (pixB.a == 0)
|
||||
return 2 * a;
|
||||
int diff = a - b;
|
||||
if (-DEPOSTERIZE_THRESHOLD <= diff && diff <= DEPOSTERIZE_THRESHOLD)
|
||||
return a + b;
|
||||
return 2 * a;
|
||||
});
|
||||
}
|
||||
|
||||
template <u32 WeightA, u32 WeightB, u32 Den>
|
||||
inline UnpackedPixel<Den*(WeightA+WeightB)> Deposterize_Blend(const UnpackedPixel<Den> &pixA, const UnpackedPixel<Den> &pixB)
|
||||
{
|
||||
return combine<WeightA+WeightB>(pixA, pixB, [](u32 a, u32 b) {
|
||||
return a * WeightA + b * WeightB;
|
||||
});
|
||||
}
|
||||
|
||||
u32 Deposterize_BlendPixel(const u32 color[9])
|
||||
{
|
||||
UnpackedPixel<1> center(color[0]);
|
||||
UnpackedPixel<2> center2 = Deposterize_Blend<1,1>(center, center);
|
||||
|
||||
auto interp = [&](int i) {
|
||||
return Deposterize_InterpLTE(center, UnpackedPixel<1>(color[i]));
|
||||
};
|
||||
|
||||
auto result = Deposterize_Blend<3, 1>(
|
||||
Deposterize_Blend<1, 1>(
|
||||
Deposterize_Blend<1, 1>(
|
||||
Deposterize_Blend<2, 14>(center2, interp(5)),
|
||||
Deposterize_Blend<2, 14>(center2, interp(1))
|
||||
),
|
||||
Deposterize_Blend<1, 1>(
|
||||
Deposterize_Blend<2, 14>(center2, interp(7)),
|
||||
Deposterize_Blend<2, 14>(center2, interp(3))
|
||||
)
|
||||
),
|
||||
Deposterize_Blend<1, 1>(
|
||||
Deposterize_Blend<1, 1>(
|
||||
Deposterize_Blend<7, 9>(center2, interp(6)),
|
||||
Deposterize_Blend<7, 9>(center2, interp(2))
|
||||
),
|
||||
Deposterize_Blend<1, 1>(
|
||||
Deposterize_Blend<7, 9>(center2, interp(8)),
|
||||
Deposterize_Blend<7, 9>(center2, interp(4))
|
||||
)
|
||||
)
|
||||
);
|
||||
return result.pack();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderDeposterize(SSurface Src, SSurface Dst)
|
||||
|
|
|
@ -1152,8 +1152,8 @@ struct ColorDistanceARGB
|
|||
{
|
||||
static double dist(uint32_t pix1, uint32_t pix2, double luminanceWeight)
|
||||
{
|
||||
const double a1 = getAlpha(pix1) / 255.0 ;
|
||||
const double a2 = getAlpha(pix2) / 255.0 ;
|
||||
const int a1 = getAlpha(pix1);
|
||||
const int a2 = getAlpha(pix2);
|
||||
/*
|
||||
Requirements for a color distance handling alpha channel: with a1, a2 in [0, 1]
|
||||
|
||||
|
@ -1162,13 +1162,22 @@ struct ColorDistanceARGB
|
|||
3. if a1 = 1, ??? maybe: 255 * (1 - a2) + a2 * distYCbCr()
|
||||
*/
|
||||
|
||||
if (a1 == 0)
|
||||
return a2;
|
||||
if (a2 == 0)
|
||||
return a1;
|
||||
|
||||
//return std::min(a1, a2) * DistYCbCrBuffer::dist(pix1, pix2) + 255 * abs(a1 - a2);
|
||||
//=> following code is 15% faster:
|
||||
const double d = DistYCbCrBuffer::dist(pix1, pix2);
|
||||
if (a1 == 255 && a2 == 255)
|
||||
return d;
|
||||
if (a1 == a2)
|
||||
return a1 * d / 255.0;
|
||||
if (a1 < a2)
|
||||
return a1 * d + 255 * (a2 - a1);
|
||||
return a1 * d / 255.0 + (a2 - a1);
|
||||
else
|
||||
return a2 * d + 255 * (a1 - a2);
|
||||
return a2 * d / 255.0 + (a1 - a2);
|
||||
|
||||
//alternative? return std::sqrt(a1 * a2 * square(DistYCbCrBuffer::dist(pix1, pix2)) + square(255 * (a1 - a2)));
|
||||
}
|
||||
|
|
|
@ -51,6 +51,13 @@
|
|||
#include "main.h"
|
||||
#include "winutil.h"
|
||||
|
||||
//60 is a poor choice for a threshold; the theoretical maximum you can get even at an exact 45 degree angle is 70
|
||||
//Sloshy sticks or slightly-off angles make it impossible to reach 60, as it's far too close to 70.
|
||||
//Too-small values feel bad, too
|
||||
//50 is a more normal choice
|
||||
//#define S9X_JOY_NEUTRAL 60
|
||||
int S9X_JOY_NEUTRAL = 50;
|
||||
|
||||
// Gamepad Dialog Strings
|
||||
// Support Unicode display
|
||||
//#define INPUTCONFIG_TITLE "Input Configuration"
|
||||
|
@ -520,6 +527,9 @@ BOOL di_init()
|
|||
{
|
||||
HWND hParentWnd = MainWindow->getHWnd();
|
||||
|
||||
S9X_JOY_NEUTRAL = GetPrivateProfileInt("Controls", "DigitalizationThreshold", S9X_JOY_NEUTRAL, IniName);
|
||||
|
||||
|
||||
pDI = NULL;
|
||||
memset(cDIBuf, 0, sizeof(cDIBuf));
|
||||
|
||||
|
@ -669,10 +679,6 @@ int FunkyNormalize(int cur, int min, int max)
|
|||
return Result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define S9X_JOY_NEUTRAL 60
|
||||
|
||||
void CheckAxis (short joy, short control, int val,
|
||||
int min, int max,
|
||||
bool &first, bool &second)
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifdef __MACH__
|
||||
#define _DARWIN_C_SOURCE /* As below, plus strl* functions */
|
||||
#else
|
||||
#define _XOPEN_SOURCE 500 /* For strdup, realpath */
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <boolean.h>
|
||||
|
|
Loading…
Reference in New Issue
Block a user