diff --git a/ReactionRecorder.cs b/ReactionRecorder.cs
--- a/ReactionRecorder.cs
+++ b/ReactionRecorder.cs
@@ -29,24 +29,31 @@ namespace DesertPaintLab
{
const int COLOR_TOLERANCE = 3;
- const int DEFAULT_SWATCH_HEIGHT = 24;
+ const int DEFAULT_SWATCH_HEIGHT = 24; // including top and bottom borders
const int DEFAULT_SWATCH_WIDTH = 260;
const int DEFAULT_COLOR_BAR_WIDTH = 306;
const int DEFAULT_RED_BAR_SPACING = 32;
const int DEFAULT_GREEN_BAR_SPACING = 42;
const int DEFAULT_BLUE_BAR_SPACING = 52;
+ const int DEFAULT_SWATCH_TEST_WIDTH = 26; // width to test on ends of swatch (10% on either end)
+
static int swatchHeight = DEFAULT_SWATCH_HEIGHT;
static int swatchWidth = DEFAULT_SWATCH_WIDTH;
+ static int swatchTestWidth = DEFAULT_SWATCH_TEST_WIDTH;
static int colorBarWidth = DEFAULT_COLOR_BAR_WIDTH;
static int redBarSpacing = DEFAULT_RED_BAR_SPACING;
static int greenBarSpacing = DEFAULT_GREEN_BAR_SPACING;
static int blueBarSpacing = DEFAULT_BLUE_BAR_SPACING;
+ static int pixelMultiplier = 1;
private static bool IsPapyTexture(byte r, byte g, byte b)
{
- return ((r > 0xD0) && (g >= 0xC4) && (b >= 0x91)) &&
- ((r < 0xF4) && (g <= 0xED) && (b <= 0xCD));
+ // red between 208 and 244
+ // green between 192 and 237
+ // blue between 145 and 205
+ return ((r > 0xD0) && (g >= 0xC0) && (b >= 0x91)) &&
+ ((r < 0xF4) && (g <= 0xED) && (b <= 0xCD));
}
public static void SetPixelMultiplier(int pixelMultiplier)
@@ -57,6 +64,8 @@ namespace DesertPaintLab
redBarSpacing = DEFAULT_RED_BAR_SPACING * pixelMultiplier;
greenBarSpacing = DEFAULT_GREEN_BAR_SPACING * pixelMultiplier;
blueBarSpacing = DEFAULT_BLUE_BAR_SPACING * pixelMultiplier;
+ swatchTestWidth = DEFAULT_SWATCH_TEST_WIDTH * pixelMultiplier;
+ ReactionRecorder.pixelMultiplier = pixelMultiplier;
}
unsafe private static void ColorAt(byte *pixBytes, int x, int y, int stride, out byte r, out byte g, out byte b)
@@ -67,7 +76,19 @@ namespace DesertPaintLab
b = pixBytes[pixelStart + 2];
}
- unsafe private static bool IsPossibleBorderPixel(byte* pixBytes, int x, int y, int stride)
+ private static bool IsDarkPixel(int r, int g, int b)
+ {
+ return ((r < 0x46) && (g < 0x46) && (b < 0x47));
+ }
+
+ private static bool IsColorMatch(byte test_r, byte test_g, byte test_b, byte target_r, byte target_g, byte target_b)
+ {
+ return ((Math.Abs(test_r - target_r) <= COLOR_TOLERANCE) &&
+ (Math.Abs(test_g - target_g) <= COLOR_TOLERANCE) &&
+ (Math.Abs(test_b - target_b) <= COLOR_TOLERANCE));
+ }
+
+ unsafe private static bool IsPossibleSwatchSlice(byte* pixBytes, int x, int y, int stride)
{
int testPixelStart = (y * stride) + (x * 3);
byte r = pixBytes[testPixelStart];
@@ -77,21 +98,60 @@ namespace DesertPaintLab
bool isDarkPixel = false;
bool isPapyAbove = false;
bool isPapyBelow = false;
- // 1.) Check if this is a dark pixel.
- isDarkPixel = ((r < 0x46) && (g < 0x46) && (b < 0x46));
+
+ // 1.) Check if the top pixel is a dark pixel.
+ isDarkPixel = IsDarkPixel(r, g, b); // ((r < 0x46) && (g < 0x46) && (b < 0x46));
- // 2.) Check the pixel above it,
- // to see if it's from the papy texture.
+ // 2.) Check the pixel above it to see if it's from the papy texture.
int otherPixelStart = testPixelStart - stride;
isPapyAbove = ((otherPixelStart >= 0) &&
IsPapyTexture(pixBytes[otherPixelStart++], pixBytes[otherPixelStart++], pixBytes[otherPixelStart]));
- // 3.) Check the pixel below where the swatch should be,
- // to see if it's also from the papy texture.
+ // 3.) Check the pixel below where the swatch should be to see if it's also from the papy texture.
otherPixelStart = testPixelStart + (stride * swatchHeight);
isPapyBelow = (IsPapyTexture(pixBytes[otherPixelStart++], pixBytes[otherPixelStart++], pixBytes[otherPixelStart]));
bool result = isDarkPixel && isPapyAbove && isPapyBelow;
+
+ // grab the swatch color
+ int swatchColorStart = testPixelStart + (2 * pixelMultiplier * stride); // 2 rows below the test pixel, skipping the faded color
+ r = pixBytes[swatchColorStart];
+ g = pixBytes[swatchColorStart+1];
+ b = pixBytes[swatchColorStart+2];
+
+ // scan the column from 2 below the top to 2 above the bottom to ensure the color matches
+ for (int i = (2*pixelMultiplier); result && (i < swatchHeight-(2*pixelMultiplier)); ++i)
+ {
+ otherPixelStart = testPixelStart + (stride * i);
+ result &= IsColorMatch(pixBytes[otherPixelStart], pixBytes[otherPixelStart+1], pixBytes[otherPixelStart+2], r, g, b);
+ }
+
+ return result;
+ }
+
+ unsafe private static bool IsPossibleSwatchUpperLeft(byte* pixBytes, int x, int y, int stride)
+ {
+ int testPixelStart = (y * stride) + (x * 3);
+
+ bool result = true;
+ // test the left edge for dark pixels
+ for (int i = 0; result && (i < swatchHeight-pixelMultiplier); ++i)
+ {
+ int otherPixelStart = testPixelStart + (stride * i);
+ result &= IsDarkPixel(pixBytes[otherPixelStart], pixBytes[otherPixelStart+1], pixBytes[otherPixelStart+2]);
+ }
+
+ // test the dark top border and for papyrus below the swatch
+ for (int i = 0; result && (i < swatchWidth); ++i)
+ {
+ int otherPixelStart = testPixelStart + (3 * i);
+ result &= IsDarkPixel(pixBytes[otherPixelStart], pixBytes[otherPixelStart+1], pixBytes[otherPixelStart+2]);
+ otherPixelStart = otherPixelStart - stride;
+ result &= IsPapyTexture(pixBytes[otherPixelStart], pixBytes[otherPixelStart+1], pixBytes[otherPixelStart+2]);
+ otherPixelStart = testPixelStart + (stride * swatchHeight) + (3 * i);
+ result &= IsPapyTexture(pixBytes[otherPixelStart], pixBytes[otherPixelStart+1], pixBytes[otherPixelStart+2]);
+ }
+
return result;
}
@@ -102,7 +162,7 @@ namespace DesertPaintLab
bool colorMatch = true;
for (int x = 0; x < screenshotWidth - colorBarWidth; ++x)
{
- for (int y = 0; y < (screenshotHeight - 53); ++y)
+ for (int y = 0; y < (screenshotHeight - (blueBarSpacing + 1) /*53*/); ++y)
{
// Look for the color swatch.
pixelStart = (y * stride) + (x * 3);
@@ -110,13 +170,14 @@ namespace DesertPaintLab
pixel_g = pixBytes[pixelStart + 1];
pixel_b = pixBytes[pixelStart + 2];
- bool foundSwatch = IsPossibleBorderPixel(pixBytes, x, y, stride); // ((pixel_r < 0x46) && (pixel_g < 0x46) && (pixel_b < 0x46));
+ bool foundSwatch = IsPossibleSwatchUpperLeft(pixBytes, x, y, stride); // ((pixel_r < 0x46) && (pixel_g < 0x46) && (pixel_b < 0x46));
if (foundSwatch)
{
int borderXOffset = 0;
- for (borderXOffset = 0; foundSwatch && (borderXOffset < swatchWidth); ++borderXOffset)
+ for (borderXOffset = (2 * pixelMultiplier); foundSwatch && (borderXOffset < swatchTestWidth); ++borderXOffset)
{
- foundSwatch &= IsPossibleBorderPixel(pixBytes, x + borderXOffset, y, stride);
+ foundSwatch &= IsPossibleSwatchSlice(pixBytes, x + borderXOffset, y, stride);
+ foundSwatch &= IsPossibleSwatchSlice(pixBytes, x + swatchWidth - borderXOffset, y, stride);
}
}
@@ -129,9 +190,7 @@ namespace DesertPaintLab
for (int i = 1; i < swatchHeight - 2; ++i)
{
otherPixelStart = pixelStart + (stride * i);
- if ((Math.Abs(pixel_r - pixBytes[otherPixelStart++]) > COLOR_TOLERANCE) ||
- (Math.Abs(pixel_g - pixBytes[otherPixelStart++]) > COLOR_TOLERANCE) ||
- (Math.Abs(pixel_b - pixBytes[otherPixelStart]) > COLOR_TOLERANCE))
+ if (!IsColorMatch(pixel_r, pixel_g, pixel_b, pixBytes[otherPixelStart], pixBytes[otherPixelStart+1], pixBytes[otherPixelStart+2]))
{
colorMatch = false;
break;
diff --git a/gtk-gui/gui.stetic b/gtk-gui/gui.stetic
--- a/gtk-gui/gui.stetic
+++ b/gtk-gui/gui.stetic
@@ -6,7 +6,7 @@
-
+