//Loop cature the screen private static async Task ModeScreenCapture(int InitByteSize, byte[] SerialBytes) { try { //Loop mode variables bool ConnectionFailed = false; //Initialize Screen Capturer if (!await InitializeScreenCapture(200)) { Debug.WriteLine("Failed to initialize the screen capturer."); ShowFailedCaptureMessage(); return; } //Update led status icons UpdateLedStatusIcons(true); //Start updating the leds while (!vTask_UpdateLed.TaskStopRequest) { int CurrentSerialByte = InitByteSize; IntPtr BitmapIntPtr = IntPtr.Zero; Bitmap BitmapImage = null; try { //Capture screenshot try { BitmapIntPtr = AppImport.CaptureScreenshot(); } catch { } //Check screenshot if (BitmapIntPtr == IntPtr.Zero) { Debug.WriteLine("Screenshot is corrupted, restarting capture."); await InitializeScreenCapture(200); continue; } //Set capture range if (vScreenOutputHeight < vScreenOutputWidth) { vCaptureRange = (setLedCaptureRange * vScreenOutputHeight) / 100 / 2; } else { vCaptureRange = (setLedCaptureRange * vScreenOutputWidth) / 100 / 2; } //Debug.WriteLine("Screen width: " + vScreenWidth + " / Screen height: " + vScreenHeight + " / Capture range: " + vCaptureZoneRange + " / Resize: " + resizeScreenshot); unsafe { byte *BitmapData = (byte *)BitmapIntPtr; //Adjust the black bars margin if (setAdjustBlackBars) { if (setAdjustBlackbarRate == 0 || (Environment.TickCount - vMarginBlackLastUpdate) > setAdjustBlackbarRate) { //Set blackbar range vBlackBarStepVertical = (setAdjustBlackbarRange * vScreenOutputHeight) / 100; vBlackBarRangeVertical = vScreenOutputWidth - vMarginMinimumOffset; vBlackBarStepHorizontal = (setAdjustBlackbarRange * vScreenOutputWidth) / 100; vBlackBarRangeHorizontal = vScreenOutputHeight - vMarginMinimumOffset; AdjustBlackBars(setLedSideFirst, BitmapData); AdjustBlackBars(setLedSideSecond, BitmapData); AdjustBlackBars(setLedSideThird, BitmapData); AdjustBlackBars(setLedSideFourth, BitmapData); vMarginBlackLastUpdate = Environment.TickCount; } } //Check led capture sides color ScreenColors(setLedSideFirst, setLedCountFirst, SerialBytes, BitmapData, ref CurrentSerialByte); ScreenColors(setLedSideSecond, setLedCountSecond, SerialBytes, BitmapData, ref CurrentSerialByte); ScreenColors(setLedSideThird, setLedCountThird, SerialBytes, BitmapData, ref CurrentSerialByte); ScreenColors(setLedSideFourth, setLedCountFourth, SerialBytes, BitmapData, ref CurrentSerialByte); //Check if debug mode is enabled if (setDebugMode) { //Convert IntPtr to bitmap image BitmapImage = BitmapConvertData(BitmapData, vScreenOutputWidth, vScreenOutputHeight, vScreenOutputSize, false); //Debug update screen capture preview ActionDispatcherInvoke(delegate { try { App.vFormSettings.image_DebugPreview.Source = BitmapToBitmapImage(BitmapImage); } catch { } }); //Debug save screen capture as image if (setDebugSave) { BitmapSaveScreenCapture(BitmapImage); } } } //Smooth led frame transition if (setLedSmoothing > 0) { //Merge current bytes with history for (int ledCount = InitByteSize; ledCount < (SerialBytes.Length - InitByteSize); ledCount++) { //Debug.WriteLine("Led smoothing old: " + SerialBytes[ledCount]); if (vCaptureByteHistory1 != null && setLedSmoothing >= 1) { SerialBytes[ledCount] = Convert.ToByte((vCaptureByteHistory1[ledCount] + SerialBytes[ledCount]) / 2); } if (vCaptureByteHistory2 != null && setLedSmoothing >= 2) { SerialBytes[ledCount] = Convert.ToByte((vCaptureByteHistory2[ledCount] + SerialBytes[ledCount]) / 2); } if (vCaptureByteHistory3 != null && setLedSmoothing >= 3) { SerialBytes[ledCount] = Convert.ToByte((vCaptureByteHistory3[ledCount] + SerialBytes[ledCount]) / 2); } //Debug.WriteLine("Led smoothing new: " + SerialBytes[ledCount]); } //Update capture bytes history vCaptureByteHistory3 = vCaptureByteHistory2; vCaptureByteHistory2 = vCaptureByteHistory1; vCaptureByteHistory1 = CloneByteArray(SerialBytes); } //Rotate the leds as calibrated if (setLedRotate > 0) { for (int RotateCount = 0; RotateCount < setLedRotate; RotateCount++) { AVFunctions.MoveByteInArrayLeft(SerialBytes, 3, SerialBytes.Length - 1); AVFunctions.MoveByteInArrayLeft(SerialBytes, 3, SerialBytes.Length - 1); AVFunctions.MoveByteInArrayLeft(SerialBytes, 3, SerialBytes.Length - 1); } } else if (setLedRotate < 0) { int LedRotateAbs = Math.Abs(setLedRotate); for (int RotateCount = 0; RotateCount < LedRotateAbs; RotateCount++) { AVFunctions.MoveByteInArrayRight(SerialBytes, SerialBytes.Length - 1, 3); AVFunctions.MoveByteInArrayRight(SerialBytes, SerialBytes.Length - 1, 3); AVFunctions.MoveByteInArrayRight(SerialBytes, SerialBytes.Length - 1, 3); } } //Send the serial bytes to device if (!SerialComPortWrite(SerialBytes)) { ConnectionFailed = true; break; } //Delay the loop task await TaskDelayLoop(setUpdateRate, vTask_UpdateLed); } catch (Exception ex) { Debug.WriteLine("Screen capture loop failed: " + ex.Message); } finally { //Clear screen capture resources if (BitmapIntPtr != IntPtr.Zero) { CaptureFreeMemory(BitmapIntPtr); } if (BitmapImage != null) { BitmapImage.Dispose(); } } } //Show failed connection message if (ConnectionFailed) { ShowFailedConnectionMessage(); } } catch (Exception ex) { Debug.WriteLine("Screen capture task failed: " + ex.Message); } finally { ResetScreenCapture(); } }