/// <summary> /// Create new replay for a specific track number. /// </summary> /// <param name="setTrackNum">Set track number</param> public Replay(int setTrackNum, bool createNew, Track track) { trackNum = setTrackNum; // if creating new, we're done if (createNew == true) { return; } bool replayFileFound = false; FileHelper.StorageContainerMRE.WaitOne(); FileHelper.StorageContainerMRE.Reset(); try { StorageDevice storageDevice = FileHelper.XnaUserDevice; if ((storageDevice != null) && storageDevice.IsConnected) { using (StorageContainer container = Storage.OpenContainer(storageDevice, "RacingGame")) { if (container.FileExists(ReplayFilenames[trackNum])) { replayFileFound = true; using (Stream stream = container.OpenFile(ReplayFilenames[trackNum], FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { using (BinaryReader reader = new BinaryReader(stream)) { // Load total lap time lapTime = reader.ReadSingle(); // Load matrix values int numOfMatrixValues = reader.ReadInt32(); for (int num = 0; num < numOfMatrixValues; num++) { trackMatrixValues.Add( FileHelper.ReadMatrix(reader)); } // Load checkpoint times int numOfCheckpointTimes = reader.ReadInt32(); for (int num = 0; num < numOfCheckpointTimes; num++) { checkpointTimes.Add(reader.ReadSingle()); } } } } } } } catch (Exception exc) { #if WINDOWS System.Diagnostics.Trace.WriteLine("Settings Load Failure: " + exc.ToString()); #endif } FileHelper.StorageContainerMRE.Set(); // Load if possible if (!replayFileFound && File.Exists(Path.Combine( Directories.ContentDirectory, ReplayFilenames[trackNum]))) { using (Stream stream = TitleContainer.OpenStream( "Content\\" + ReplayFilenames[trackNum])) { using (BinaryReader reader = new BinaryReader(stream)) { // Load total lap time lapTime = reader.ReadSingle(); // Load matrix values int numOfMatrixValues = reader.ReadInt32(); for (int num = 0; num < numOfMatrixValues; num++) { trackMatrixValues.Add( FileHelper.ReadMatrix(reader)); } // Load checkpoint times int numOfCheckpointTimes = reader.ReadInt32(); for (int num = 0; num < numOfCheckpointTimes; num++) { checkpointTimes.Add(reader.ReadSingle()); } } } } if (!replayFileFound) { // Create new default replay for this track! // Get all track positions based on the current top highscore time! lapTime = Highscores.GetTopLapTime(trackNum); int numOfMatrixValues = 1 + (int)(lapTime / TrackMatrixIntervals); float lastTrackPos = 0.0f; int oldTrackSegmentNumber = 0; // Go twice as long and abort when we reach the finish line! for (int num = 0; num < numOfMatrixValues * 2; num++) { // See Landscape.TestRenderLandscape for more details. float carTrackPos = 0.00001f + ((float)num / (float)(numOfMatrixValues - 1));// * //not needed, scaled in GetTrackPositionMatrix: track.Length; float difference = carTrackPos - lastTrackPos; carTrackPos = lastTrackPos + difference * 0.1f; lastTrackPos = carTrackPos; float roadWidth, nextRoadWidth; Matrix carMatrix = track.GetTrackPositionMatrix(carTrackPos, out roadWidth, out nextRoadWidth); // Store trackMatrixValues.Add(carMatrix); // Also check if we passed a checkpoint int trackSegmentNumber = (int)(carTrackPos * track.NumberOfSegments); // Segment changed if (trackSegmentNumber != oldTrackSegmentNumber) { // Check if we passed a checkpoint. for (int checkpointNum = 0; checkpointNum < track. CheckpointSegmentPositions.Count; checkpointNum++) { // We have to check if we are between the old // and the current track segement numbers, we // might skip one or two in 200ms. if (track.CheckpointSegmentPositions[checkpointNum] > oldTrackSegmentNumber && track.CheckpointSegmentPositions[checkpointNum] <= trackSegmentNumber) { // We passed that checkpoint, add the simulated time checkpointTimes.Add( lapTime * (float)num / (float)(numOfMatrixValues - 1)); break; } } } oldTrackSegmentNumber = trackSegmentNumber; // Reached finish? if (carTrackPos >= 1.0f) { // Then abort, do not add more. break; } } // Add the final checkpoint for the laptime checkpointTimes.Add(lapTime); } }