private void CaptureLoads() { try { if (timerStarted) { framesSinceLastManualSplit++; //Console.WriteLine("TIME NOW: {0}", DateTime.Now - lastTime); //Console.WriteLine("TIME DIFF START: {0}", DateTime.Now - lastTime); lastTime = DateTime.Now; //Capture image using the settings defined for the component Bitmap capture = settings.CaptureImage(Crash4State); isLoading = false; try { // CSV Test code. /* * FeatureDetector.compareImageCaptureCrash4(capture, test_hsv_ranges, test_gradient_ranges, achieved_hsv_ranges, achieved_gradient_thresholds, average_thresholded_gradients); * * string csv_out = timer.CurrentState.CurrentTime.RealTime.ToString(); * * for (int i = 0; i < achieved_hsv_ranges.Count; i++) * { * csv_out += ";" + achieved_hsv_ranges[i]; * } * * for (int i = 0; i < achieved_gradient_thresholds.Count; i++) * { * csv_out += ";" + achieved_gradient_thresholds[i]; * csv_out += ";" + average_thresholded_gradients[i]; * } * * Console.WriteLine(csv_out);*/ // ... //DateTime current_time = DateTime.Now; //isLoading = FeatureDetector.compareFeatureVector(features.ToArray(), FeatureDetector.listOfFeatureVectorsEng, out tempMatchingBins, -1.0f, false); //Console.WriteLine("Timing for detection: {0}", (DateTime.Now - current_time).TotalSeconds); if (Crash4State == Crash4LoadState.WAITING_FOR_LOAD1 || Crash4State == Crash4LoadState.LOAD1 || Crash4State == Crash4LoadState.WAITING_FOR_LOAD2) { // Do HSV comparison on the raw image, without any features //float achieved_threshold = 0.0f; //float achieved_threshold_2 = 0.0f; //isLoading = FeatureDetector.compareImageCaptureHSVCrash4(capture, 0.3f, out achieved_threshold, 5, 55, 50, 101, 75, 101); //isLoading &= FeatureDetector.compareImageCaptureHSVCrash4(capture, 0.08f, out achieved_threshold_2, -1, 361, 30, 101, -1, 30); FeatureDetector.compareImageCaptureCrash4(capture, hsv_ranges_load_1, gradient_thresholds_load_1, achieved_hsv_ranges, achieved_gradient_thresholds, average_thresholded_gradients, 2); isLoading = (achieved_hsv_ranges[0] > 0.03) && (achieved_gradient_thresholds[0] > 0.09) && (average_thresholded_gradients[1] > 40); if (output_first_load_debug && settings.DetailedDetectionLog) { string csv_out = "first_load;" + timer.CurrentState.CurrentTime.RealTime.ToString(); csv_out += ";" + achieved_hsv_ranges[0]; csv_out += ";" + achieved_gradient_thresholds[0]; csv_out += ";" + average_thresholded_gradients[1]; Console.WriteLine(csv_out); } //Console.WriteLine("Loading 1: " + isLoading.ToString() + ", achieved Threshold 1: " + achieved_threshold.ToString() + ", achieved Threshold 2: " + achieved_threshold_2.ToString()); if (Crash4State == Crash4LoadState.LOAD1 && (Single.IsNaN(average_thresholded_gradients[1]) || (average_thresholded_gradients[1] < 20 && achieved_gradient_thresholds[0] <= 0.04 && achieved_hsv_ranges[0] <= 0.02))) { if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("Weird black screen thing during LOAD1, setting isLoading to true manually, tolerance frames: " + load1_tolerance_frames); } //settings.StoreCaptureImage(GameName, GameCategory, capture); load1_tolerance_frames--; if (load1_tolerance_frames > 0) { isLoading = true; } } if (isLoading && Crash4State == Crash4LoadState.WAITING_FOR_LOAD1) { load1_tolerance_frames = LOAD1_BLACK_SCREEN_TOLERANCE_FRAMES; // Store current time - this is the start of our load! Crash4State = Crash4LoadState.LOAD1; load1_phase_start = timer.CurrentState.CurrentTime; if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("Transition to LOAD1:"); } } else if (isLoading && Crash4State == Crash4LoadState.LOAD1) { // Everything fine - nothing to do here. } else if (!isLoading && Crash4State == Crash4LoadState.LOAD1) { // Transtiion from load phase 1 into load phase 2 - this checks the next couple of frames until it potentially finds the load screen phase 2. Crash4State = Crash4LoadState.WAITING_FOR_LOAD2; load1_phase_end = timer.CurrentState.CurrentTime; if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("Transition to WAITING_FOR_LOAD2"); } } else if (Crash4State == Crash4LoadState.WAITING_FOR_LOAD2) { // We're waiting for LOAD2 until the tolerance. If LOAD1 detection happens in the mean time, we reset back to LOAD1. // Check if the elapsed time is over our tolerance load1_tolerance_frames = LOAD1_BLACK_SCREEN_TOLERANCE_FRAMES; if (isLoading) { // Store current time - this is the start of our load - this might happen if orange letters are shortly before the real load screen. Crash4State = Crash4LoadState.LOAD1; load1_phase_start = timer.CurrentState.CurrentTime; if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("load screen detected while waiting for LOAD2: Transition to LOAD1: Loading 1: "); } } else if ((timer.CurrentState.CurrentTime - load1_phase_end).RealTime.Value.TotalSeconds > LOAD_PHASE_TOLERANCE_TIME) { // Transition to TRANSITION_TO_LOAD2 state. if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("TOLERANCE OVER: Transition to TRANSITION_TO_LOAD2"); } Crash4State = Crash4LoadState.TRANSITION_TO_LOAD2; } } } else { load1_tolerance_frames = LOAD1_BLACK_SCREEN_TOLERANCE_FRAMES; // Do HSV comparison on the raw image, without any features /*float achieved_threshold_1 = 0.0f; * float achieved_threshold_2 = 0.0f; * * FeatureDetector.compareImageCaptureHSVCrash4(capture, 0.3f, out achieved_threshold_1, 200, 230, 80, 101, 50, 101); * * FeatureDetector.compareImageCaptureHSVCrash4(capture, 0.3f, out achieved_threshold_2, -1, 360, 95, 101, -1, 15);*/ FeatureDetector.compareImageCaptureCrash4(capture, hsv_ranges_load_2, gradient_thresholds_load_2, achieved_hsv_ranges, achieved_gradient_thresholds, average_thresholded_gradients, 0); isLoading = (achieved_gradient_thresholds[0] > 0.03) && (average_thresholded_gradients[1] > 40); isLoading &= ((achieved_hsv_ranges[0] > 0.40) && (achieved_hsv_ranges[1] > 0.04)) || ((achieved_hsv_ranges[0] > 0.35) && (achieved_hsv_ranges[1] > 0.05)) || ((achieved_hsv_ranges[0] > 0.30) && (achieved_hsv_ranges[1] > 0.06)) || ((achieved_hsv_ranges[0] > 0.25) && (achieved_hsv_ranges[1] > 0.12)) || ((achieved_hsv_ranges[0] > 0.20) && (achieved_hsv_ranges[1] > 0.17)); if (output_second_load_debug && settings.DetailedDetectionLog) { string csv_out = "second_load;" + timer.CurrentState.CurrentTime.RealTime.ToString(); csv_out += ";" + achieved_hsv_ranges[0]; csv_out += ";" + achieved_hsv_ranges[1]; csv_out += ";" + achieved_gradient_thresholds[0]; csv_out += ";" + average_thresholded_gradients[1]; Console.WriteLine(csv_out); } //if((achieved_threshold_1 > 0.35f && achieved_threshold_2 > 0.10f) || (achieved_threshold_1 > 0.20f && achieved_threshold_2 > 0.15f)) if (isLoading) { // Everything fine, nothing to do here, except for transitioning to LOAD2 // Transition to LOAD2 state. if (Crash4State == Crash4LoadState.TRANSITION_TO_LOAD2) { if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("TRANSITION TO LOAD2: Loading 2: "); } Crash4State = Crash4LoadState.LOAD2; } } else if (Crash4State == Crash4LoadState.LOAD2) { // We're done and went through a whole load cycle. // Compute the duration and update the timer. var load_time = (timer.CurrentState.CurrentTime - load1_phase_start).RealTime.Value; timer.CurrentState.LoadingTimes += load_time; Crash4State = Crash4LoadState.WAITING_FOR_LOAD1; Console.WriteLine(load_time.TotalSeconds + ";" + load1_phase_start.RealTime.ToString() + ";" + timer.CurrentState.CurrentTime.RealTime.ToString()); if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("<<<<<<<<<<<<< LOAD DONE! back to to WAITING_FOR_LOAD1: elapsed time: " + load_time.TotalSeconds); } //Console.WriteLine("LOAD DONE (pt2): Loading 2: " + isLoading.ToString() + ", achieved Threshold (blue): " + achieved_threshold_1.ToString() + ", achieved Threshold (black): " + achieved_threshold_2.ToString()); } else { // This was a screen that detected the yellow/orange letters, didn't detect them again for the tolerance frame and then *didn't* detect LOAD2. // Back to WAITING_FOR_LOAD1. if (output_state_info && settings.DetailedDetectionLog) { Console.WriteLine("TRANSITION TO WAITING_FOR_LOAD1 (didn't see swirl): Loading 2: "); } Crash4State = Crash4LoadState.WAITING_FOR_LOAD1; } //Console.WriteLine("Loading 2: " + isLoading.ToString() + ", achieved Threshold (blue): " + achieved_threshold_1.ToString() + ", achieved Threshold (black): " + achieved_threshold_2.ToString()); } } catch (Exception ex) { isLoading = false; Console.WriteLine("Error: " + ex.ToString()); throw ex; } /* * matchingBins = tempMatchingBins; * * timer.CurrentState.IsGameTimePaused = isLoading; * * if (settings.RemoveFadeins || settings.RemoveFadeouts) * { * float new_avg_transition_max = 0.0f; * try * { * //isTransition = FeatureDetector.compareFeatureVectorTransition(features.ToArray(), FeatureDetector.listOfFeatureVectorsEng, max_per_patch, min_per_patch, - 1.0f, out new_avg_transition_max, out tempMatchingBins, 0.8f, false);//FeatureDetector.isGameTransition(capture, 30); * } * catch (Exception ex) * { * isTransition = false; * Console.WriteLine("Error: " + ex.ToString()); * throw ex; * } * //Console.WriteLine("Transition: {0}", isTransition); * if (wasLoading && isTransition && settings.RemoveFadeins) * { * postLoadTransition = true; * transitionStart = DateTime.Now; * } * * if (wasTransition == false && isTransition && settings.RemoveFadeouts) * { * //This could be a pre-load transition, start timing it * transitionStart = DateTime.Now; * } * * * //Console.WriteLine("GAMETIMEPAUSETIME: {0}", timer.CurrentState.GameTimePauseTime); * * * if (wasTransition && isLoading) * { * // This was a pre-load transition, subtract the gametime * TimeSpan delta = (DateTime.Now - transitionStart); * * if(settings.RemoveFadeouts) * { * if (delta.TotalSeconds > numSecondsTransitionMax) * { * Console.WriteLine("{2}: Transition longer than {0} seconds, doesn't count! (Took {1} seconds)", numSecondsTransitionMax, delta.TotalSeconds, SplitNames[Math.Max(Math.Min(liveSplitState.CurrentSplitIndex, SplitNames.Count - 1), 0)]); * } * else * { * timer.CurrentState.SetGameTime(timer.CurrentState.GameTimePauseTime - delta); * * total_paused_time += delta.TotalSeconds; * Console.WriteLine("PRE-LOAD TRANSITION {2} seconds: {0}, totalPausedTime: {1}", delta.TotalSeconds, total_paused_time, SplitNames[Math.Max(Math.Min(liveSplitState.CurrentSplitIndex, SplitNames.Count - 1), 0)]); * } * * } * * } * * if(settings.RemoveFadeins) * { * if (postLoadTransition && isTransition == false) * { * TimeSpan delta = (DateTime.Now - transitionStart); * * total_paused_time += delta.TotalSeconds; * Console.WriteLine("POST-LOAD TRANSITION {2} seconds: {0}, totalPausedTime: {1}", delta.TotalSeconds, total_paused_time, SplitNames[Math.Max(Math.Min(liveSplitState.CurrentSplitIndex, SplitNames.Count - 1), 0)]); * } * * * if (postLoadTransition == true && isTransition) * { * // We are transitioning after a load screen, this stops the timer, and actually increases the load time * timer.CurrentState.IsGameTimePaused = true; * * * } * else * { * postLoadTransition = false; * } * * } * * } * * * * if (isLoading && !wasLoading) * { * segmentTimeStart = DateTime.Now; * } * * if (isLoading) * { * pausedFramesSegment++; * } * * if (wasLoading && !isLoading) * { * TimeSpan delta = (DateTime.Now - segmentTimeStart); * framesSum += delta.TotalSeconds * 60.0f; * int framesRounded = Convert.ToInt32(delta.TotalSeconds * 60.0f); * framesSumRounded += framesRounded; * total_paused_time += delta.TotalSeconds; * * Console.WriteLine("SEGMENT FRAMES {7}: {0}, fromTime (@60fps) {1}, timeDelta {2}, totalFrames {3}, fromTime(int) {4}, totalFrames(int) {5}, totalPausedTime(double) {6}", * pausedFramesSegment, delta.TotalSeconds, * delta.TotalSeconds * 60.0f, framesSum, framesRounded, framesSumRounded, total_paused_time, SplitNames[Math.Max(Math.Min(liveSplitState.CurrentSplitIndex, SplitNames.Count - 1), 0)]); * pausedFramesSegment = 0; * } * * * if (settings.AutoSplitterEnabled && !(settings.AutoSplitterDisableOnSkipUntilSplit && LastSplitSkip)) * { * //This is just so that if the detection is not correct by a single frame, it still only splits if a few successive frames are loading * if (isLoading && NSTState == CrashNSTState.RUNNING) * { * pausedFrames++; * runningFrames = 0; * } * else if (!isLoading && NSTState == CrashNSTState.LOADING) * { * runningFrames++; * pausedFrames = 0; * } * * if (NSTState == CrashNSTState.RUNNING && pausedFrames >= settings.AutoSplitterJitterToleranceFrames) * { * runningFrames = 0; * pausedFrames = 0; * //We enter pause. * NSTState = CrashNSTState.LOADING; * if (framesSinceLastManualSplit >= settings.AutoSplitterManualSplitDelayFrames) * { * NumberOfLoadsPerSplit[liveSplitState.CurrentSplitIndex]++; * * if (CumulativeNumberOfLoadsForSplitIndex(liveSplitState.CurrentSplitIndex) >= settings.GetCumulativeNumberOfLoadsForSplit(liveSplitState.CurrentSplit.Name)) * { * * timer.Split(); * * * } * } * * } * else if (NSTState == CrashNSTState.LOADING && runningFrames >= settings.AutoSplitterJitterToleranceFrames) * { * runningFrames = 0; * pausedFrames = 0; * //We enter runnning. * NSTState = CrashNSTState.RUNNING; * } * } * * * //Console.WriteLine("TIME TAKEN FOR DETECTION: {0}", DateTime.Now - lastTime);*/ } } catch (Exception ex) { isTransition = false; isLoading = false; Console.WriteLine("Error: " + ex.ToString()); } }