diff --git a/ReactionRecorder.cs b/ReactionRecorder.cs --- a/ReactionRecorder.cs +++ b/ReactionRecorder.cs @@ -48,6 +48,10 @@ namespace DesertPaintLab int blueBarSpacing = DEFAULT_BLUE_BAR_SPACING; int pixelMultiplier = 1; + bool firstRun = true; + int lastSwatchX = -1; + int lastSwatchY = -1; + private static ReactionRecorder _instance; public static ReactionRecorder Instance { @@ -251,99 +255,125 @@ namespace DesertPaintLab return result; } + unsafe private bool TestPosition(int x, int y, byte* pixBytes, int screenshotWidth, int screenshotHeight, int stride, ref PaintColor reactedColor, ref int redPixelStart) + { + byte pixel_r, pixel_g, pixel_b; + int pixelStart, otherPixelStart; + bool colorMatch = true; + + // Look for the color swatch. + pixelStart = (y * stride) + (x * 3); + pixel_r = pixBytes[pixelStart]; + pixel_g = pixBytes[pixelStart + 1]; + pixel_b = pixBytes[pixelStart + 2]; + + bool foundSwatch = IsPossibleSwatchUpperLeft(pixBytes, x, y, stride); // ((pixel_r < 0x46) && (pixel_g < 0x46) && (pixel_b < 0x46)); + if (foundSwatch) + { + int borderXOffset = 0; + for (borderXOffset = (2 * pixelMultiplier); foundSwatch && (borderXOffset < swatchTestWidth); ++borderXOffset) + { + foundSwatch &= IsPossibleSwatchSlice(pixBytes, x + borderXOffset, y, stride); + foundSwatch &= IsPossibleSwatchSlice(pixBytes, x + swatchWidth - borderXOffset, y, stride); + } + } + + if (foundSwatch) + { + // found a swatch with an appropriate dark top border with papyrus texture above it and papyrus a jump below it + // 4.) Scan the left border of the potential swatch + // location. + colorMatch = true; + for (int i = 2; i < swatchHeight - (2 * pixelMultiplier); ++i) + { + otherPixelStart = pixelStart + (stride * i); + if (!IsColorMatch(pixel_r, pixel_g, pixel_b, pixBytes[otherPixelStart], pixBytes[otherPixelStart + 1], pixBytes[otherPixelStart + 2])) + { + colorMatch = false; + break; + } + } + + if (colorMatch) + { + // WE FOUND THE SWATCH! + // Now we know where the color bars are. + redPixelStart = pixelStart + (redBarSpacing * stride); + int redPixelCount = 0; + while ((pixBytes[redPixelStart] > 0x9F) && + (pixBytes[redPixelStart + 1] < 0x62) && + (pixBytes[redPixelStart + 2] < 0x62)) + { + redPixelCount++; + // pixBytes[redPixelStart] = 0x00; + // pixBytes[redPixelStart + 1] = 0xFF; + // pixBytes[redPixelStart + 2] = 0xFF; + redPixelStart += 3; + } + + reactedColor.Red = (byte)Math.Round((float)redPixelCount * 255f / (float)colorBarWidth); + int greenPixelStart = pixelStart + (greenBarSpacing * stride); + + int greenPixelCount = 0; + while ((pixBytes[greenPixelStart] < 0x62) && + (pixBytes[greenPixelStart + 1] > 0x9F) && + (pixBytes[greenPixelStart + 2] < 0x62)) + { + greenPixelCount++; + // pixBytes[greenPixelStart] = 0x00; + // pixBytes[greenPixelStart + 1] = 0xFF; + // pixBytes[greenPixelStart + 2] = 0xFF; + greenPixelStart += 3; + } + + reactedColor.Green = (byte)Math.Round((float)greenPixelCount * 255f / (float)colorBarWidth); + int bluePixelStart = pixelStart + (blueBarSpacing * stride); + + int bluePixelCount = 0; + while ((pixBytes[bluePixelStart] < 0x62) && + (pixBytes[bluePixelStart + 1] < 0x62) && + (pixBytes[bluePixelStart + 2] > 0x9F)) + { + bluePixelCount++; + // pixBytes[bluePixelStart] = 0x00; + // pixBytes[bluePixelStart + 1] = 0xFF; + // pixBytes[bluePixelStart + 2] = 0xFF; + bluePixelStart += 3; + } + + reactedColor.Blue = (byte)Math.Round((float)bluePixelCount * 255f / (float)colorBarWidth); + WriteLog("Found the color swatch at {0}, {1}. Color={2}", x, y, reactedColor); + return true; + } + } + return false; + } + unsafe public bool CaptureReaction(byte* pixBytes, int screenshotWidth, int screenshotHeight, int stride, ref PaintColor reactedColor, ref int redPixelStart) { - byte pixel_r, pixel_g, pixel_b; - int pixelStart, otherPixelStart; - bool colorMatch = true; + if (!firstRun) + { + // If this is not the first run, let's check the last location, to see if the UI is still there. + if (TestPosition(lastSwatchX, lastSwatchY, pixBytes, screenshotWidth, screenshotHeight, stride, ref reactedColor, ref redPixelStart)) + { + return true; + } + else + { + firstRun = true; + } + } + for (int x = 0; x < screenshotWidth - colorBarWidth; ++x) { for (int y = 0; y < (screenshotHeight - (blueBarSpacing + 1) /*53*/); ++y) { - // Look for the color swatch. - pixelStart = (y * stride) + (x * 3); - pixel_r = pixBytes[pixelStart]; - pixel_g = pixBytes[pixelStart + 1]; - pixel_b = pixBytes[pixelStart + 2]; - - bool foundSwatch = IsPossibleSwatchUpperLeft(pixBytes, x, y, stride); // ((pixel_r < 0x46) && (pixel_g < 0x46) && (pixel_b < 0x46)); - if (foundSwatch) - { - int borderXOffset = 0; - for (borderXOffset = (2 * pixelMultiplier); foundSwatch && (borderXOffset < swatchTestWidth); ++borderXOffset) - { - foundSwatch &= IsPossibleSwatchSlice(pixBytes, x + borderXOffset, y, stride); - foundSwatch &= IsPossibleSwatchSlice(pixBytes, x + swatchWidth - borderXOffset, y, stride); - } - } - - if (foundSwatch) - { - // found a swatch with an appropriate dark top border with papyrus texture above it and papyrus a jump below it - // 4.) Scan the left border of the potential swatch - // location. - colorMatch = true; - for (int i = 2; i < swatchHeight - (2 * pixelMultiplier); ++i) - { - otherPixelStart = pixelStart + (stride * i); - if (!IsColorMatch(pixel_r, pixel_g, pixel_b, pixBytes[otherPixelStart], pixBytes[otherPixelStart+1], pixBytes[otherPixelStart+2])) - { - colorMatch = false; - break; - } - } - - if (colorMatch) - { - // WE FOUND THE SWATCH! - // Now we know where the color bars are. - redPixelStart = pixelStart + (redBarSpacing * stride); - int redPixelCount = 0; - while ((pixBytes[redPixelStart] > 0x9F) && - (pixBytes[redPixelStart + 1] < 0x62) && - (pixBytes[redPixelStart + 2] < 0x62)) - { - redPixelCount++; - // pixBytes[redPixelStart] = 0x00; - // pixBytes[redPixelStart + 1] = 0xFF; - // pixBytes[redPixelStart + 2] = 0xFF; - redPixelStart += 3; - } - - reactedColor.Red = (byte)Math.Round((float)redPixelCount * 255f / (float)colorBarWidth); - int greenPixelStart = pixelStart + (greenBarSpacing * stride); - - int greenPixelCount = 0; - while ((pixBytes[greenPixelStart] < 0x62) && - (pixBytes[greenPixelStart + 1] > 0x9F) && - (pixBytes[greenPixelStart + 2] < 0x62)) - { - greenPixelCount++; - // pixBytes[greenPixelStart] = 0x00; - // pixBytes[greenPixelStart + 1] = 0xFF; - // pixBytes[greenPixelStart + 2] = 0xFF; - greenPixelStart += 3; - } - - reactedColor.Green = (byte)Math.Round((float)greenPixelCount * 255f / (float)colorBarWidth); - int bluePixelStart = pixelStart + (blueBarSpacing * stride); - - int bluePixelCount = 0; - while ((pixBytes[bluePixelStart] < 0x62) && - (pixBytes[bluePixelStart + 1] < 0x62) && - (pixBytes[bluePixelStart + 2] > 0x9F)) - { - bluePixelCount++; - // pixBytes[bluePixelStart] = 0x00; - // pixBytes[bluePixelStart + 1] = 0xFF; - // pixBytes[bluePixelStart + 2] = 0xFF; - bluePixelStart += 3; - } - - reactedColor.Blue = (byte)Math.Round((float)bluePixelCount * 255f / (float)colorBarWidth); - WriteLog("Found the color swatch at {0}, {1}. Color={2}", x, y, reactedColor); - return true; - } + if (TestPosition(x, y, pixBytes, screenshotWidth, screenshotHeight, stride, ref reactedColor, ref redPixelStart)) + { + lastSwatchX = x; + lastSwatchY = y; + firstRun = false; + return true; } } }