public static bool SaveTileData(SongTileData saveGame, string name) { //BinaryFormatter formatter = new BinaryFormatter(); //using (FileStream stream = new FileStream(GetSavePath("parsed/"+name+".bytes"), FileMode.Create)) { // try { // formatter.Serialize(stream, saveGame); // } // catch (Exception e) { // Debug.LogWarning(e.Message); // return false; // } //} //return true; return(SaveBinarySongDataSystem.SaveTileData(saveGame, name)); }
IEnumerator PrepareTileData(LevelDataModel lv, int minTickPerTile, int maxTickPerTile, SongDataModel songDataModel, Action <float> onProgress = null, Action onComplete = null, Action <string> onError = null) { //listNoteData = noteData; var listTilesData = new List <TileData>(1000); var noteData = lv.noteData; var playbackData = lv.playbackData; //float BPM = lv.BPM; //we know that note data will always less or equals to playback data //so we will start by traverse through list note data NoteData currentNote, nextNote; int currentNoteIndex; //int loopCount = 0; //int maxLoop = 10; float lastReleaseThreadTime = Time.realtimeSinceStartup; float maxTimeLockThread = 1; //this variable is used to reduce number of cast operation float noteDataCount = noteData.Count; //for each note in view list for (int i = 0; i < noteData.Count; i++) { currentNoteIndex = i; //set up range for checking song data currentNote = noteData[currentNoteIndex]; nextNote = null; //don't hog up all the CPU, save some for rendering task if (lastReleaseThreadTime + maxTimeLockThread >= Time.realtimeSinceStartup) { lastReleaseThreadTime = Time.realtimeSinceStartup; Helpers.CallbackWithValue(onProgress, ((i / noteDataCount))); yield return(null); } //try to get next view note (must be different at timestamp with current note) while (++i < noteData.Count) { //++i; nextNote = noteData[i]; //stop the loop right when next note is found if (nextNote.timeAppear != currentNote.timeAppear) { //decrease i so that at the end of the loop, it can be increased gracefully --i; break; } } if (i >= noteData.Count) { i = noteData.Count - 1; } //how many notes existed at the same timestamp int numConcurrentNotes = i - currentNoteIndex + 1; //print("Num concurrent notes" + numConcurrentNotes + " at " + i); //for each note, create a tile for (int j = currentNoteIndex; j <= i; j++) { //print(string.Format("i {0}, j {1}, Concurrent notes: {2}", i, j, numConcurrentNotes)); //print(string.Format("Current note: {0}, timestamp {1}; Next note; {2}, timestamp: {3}", currentNote.nodeID, currentNote.timeAppear, nextNote.nodeID, nextNote.timeAppear)); //with each note data, there is a tile TileData tileData = new TileData(); tileData.type = TileType.Normal; tileData.notes = new List <NoteData>(); tileData.startTime = currentNote.timeAppear; tileData.startTimeInTicks = currentNote.tickAppear; tileData.soundDelay = 0; //fetch midi data for tile //float endTime = ((nextNote == null) ? currentNote.timeAppear + currentNote.duration : nextNote.timeAppear); //AddConcurrentMidiData( // ref tileData, // playbackData, // currentNote.timeAppear, // endTime, // currentNoteIndex // ); int startTime, endTime; startTime = endTime = -1; switch (numConcurrentNotes) { //only 1 tile case 1: tileData.subType = TileType.Normal; startTime = currentNote.tickAppear; endTime = ((nextNote == null) ? currentNote.tickAppear + currentNote.durationInTick : nextNote.tickAppear); break; //dual tile case 2: tileData.subType = TileType.Dual; if (j % 2 == 0) { startTime = currentNote.tickAppear; endTime = currentNote.tickAppear + (int)(currentNote.durationInTick * 0.5f); } else { tileData.soundDelay = currentNote.duration * 0.5f; startTime = currentNote.tickAppear + (int)(currentNote.durationInTick * 0.5f); endTime = ((nextNote == null) ? currentNote.tickAppear + currentNote.durationInTick : nextNote.tickAppear); } break; //big tile case 3: tileData.subType = TileType.Big; if (listTilesData.Count > 1) { TileData lastTileData = listTilesData[listTilesData.Count - 1]; if (lastTileData.startTimeInTicks != currentNote.tickAppear) { startTime = currentNote.tickAppear; endTime = ((nextNote == null) ? currentNote.tickAppear + currentNote.durationInTick : nextNote.tickAppear); } else { startTime = endTime = -1; } } break; } if (startTime >= 0 && endTime >= 0) { //print("Adding note data into tile " + j); AddConcurrentMidiDataByTick( ref tileData, playbackData, startTime, endTime, j ); tileData.durationInTicks = currentNote.durationInTick; tileData.duration = currentNote.duration; //Debug.Log(string.Format("Duration of note {0}, ID: {2} is {1}", i, tileData.duration, currentNote.nodeID)); //if a tile has duration belong to the normal tile's range if (minTickPerTile <= tileData.durationInTicks && tileData.durationInTicks <= maxTickPerTile) { //set it as so tileData.type = TileType.Normal; listTilesData.Add(tileData); } else { //else, it is either a long note... if (maxTickPerTile < tileData.durationInTicks) { tileData.type = TileType.LongNote; listTilesData.Add(tileData); } else { //... or just an error note, f**k that shit //Debug.LogWarning(string.Format("A tile data has duration of {0}, which is less than a normal tile ({1}), please check. It has Index of {2}, midi note {3}", tileData.durationInTicks, currentLevelData.songData.tickPerTile, currentNoteIndex, currentNote.nodeID)); } } } } } //Debug.Log("Prepare tile data completed"); //easy, start render in the next frame SongTileData b_data = new SongTileData(); b_data.BPM = lv.BPM; b_data.denominator = lv.denominator; b_data.tickPerQuarterNote = lv.tickPerQuarterNote; b_data.titledata = listTilesData; b_data.songDataModel = songDataModel; SaveTileData(b_data, "songs/parsed/" + b_data.songDataModel.storeID); JobCompleted(); yield return(null); //Helpers.Callback(onComplete); }