void Awake() { m_TuneOpen = new TinyFileDialogs.OpenFileDialog( ); m_TuneOpen.title = "Open tune"; m_TuneOpen.filterPatterns = fileFilters; m_TuneOpen.description = filterDescription; m_TuneOpen.defaultPath = UnityEngine.Application.dataPath; m_SampleOpen = new TinyFileDialogs.OpenFileDialog( ); m_SampleOpen.title = "Load sample"; m_SampleOpen.filterPatterns = new string [] { "*.wav" }; m_SampleOpen.description = "Wave-file (8-bit sample depth)"; m_SampleOpen.defaultPath = UnityEngine.Application.dataPath; m_TuneSave = new TinyFileDialogs.SaveFileDialog( ); m_TuneSave.title = "Save tune"; m_TuneSave.filterPatterns = fileFilters; m_TuneOpen.description = filterDescription; m_TuneOpen.defaultPath = UnityEngine.Application.dataPath; m_WavSave = new TinyFileDialogs.SaveFileDialog( ); m_WavSave.title = "Save WAVE"; m_WavSave.filterPatterns = new string [] { "*.wav" }; m_WavSave.description = "WAVE-file(s)"; m_WavSave.defaultPath = UnityEngine.Application.dataPath; m_VgmSave = new TinyFileDialogs.SaveFileDialog( ); m_VgmSave.title = "Save VGM"; m_VgmSave.filterPatterns = new string [] { "*.vgz", "*.vgm" }; m_VgmSave.description = "VGM-file(s)"; m_VgmSave.defaultPath = UnityEngine.Application.dataPath; }
IEnumerator SaveVGMRoutine(TinyFileDialogs.SaveFileDialog sfd) { playback.Stop( ); playback.psg.audioSource.enabled = false; playback.follow = false; data.currentPattern = 0; m_OperationInProgress = true; bool isCompressed = sfd.filePath.Contains(".vgz"); Stream fileStream = isCompressed ? new MemoryStream( ) : sfd.OpenFile( ); BinaryWriter bw = new BinaryWriter(fileStream); bw.Write(Encoding.ASCII.GetBytes("Vgm ")); //0x00 //wrote eof offset later when we know 0x04 bw.Seek(0x08, SeekOrigin.Begin); bw.Write(( uint )0x00000170); //0x08 bw.Write(( uint )playback.psg.chip.clock); //0x0C //gd3???? 0x14 //write wait values later when we know 0x18 //implement loop offset some rainy day 0x1C + 0x20 bw.Seek(0x24, SeekOrigin.Begin); bw.Write(( uint )playback.playbackRate); //0x24 bw.Write(( ushort )SN76489.NOISE_TAPPED); //0x28 bw.Write(( byte )(SN76489.NOISE_SR_WIDTH + 1)); //0x2A bw.Write(( byte )0x00); bw.Seek(0x34, SeekOrigin.Begin); bw.Write(( uint )0x0C); bw.Seek(0x40, SeekOrigin.Begin); List <PSGWrapper.RegisterWrite> dataSamples = playback.psg.RecordRegisters( ); playback.Play(false); int c = 0; while (playback.isPlaying) { playback.psg.ManualClock( ); m_Progress = playback.songProgress * 50; c++; if (c > 44100) { c = 0; yield return(null); } } playback.psg.RecordRegisters(false); playback.psg.ResetChip( ); int loopWaitAmount = 0; int waitAmount = 0; int loopOffset = 0x40; int bytesWritten = 0; bool foundLoop = false; for (int i = 0; i < dataSamples.Count; i++) { if (dataSamples [i].wait > 0) { switch (dataSamples [i].wait) { case 735: bw.Write(( byte )VGMCommands.Wait735); bytesWritten++; break; case 882: bw.Write(( byte )VGMCommands.Wait882); bytesWritten++; break; default: int totalWait = dataSamples [i].wait; do { bw.Write(( byte )VGMCommands.WaitSamples); bw.Write(( ushort )System.Math.Min(65535, totalWait)); totalWait -= 65535; bytesWritten += 3; } while (totalWait > 65535); break; } if (dataSamples [i].pattern >= playback.patternLoop) { loopWaitAmount += dataSamples [i].wait; } waitAmount += dataSamples [i].wait; c++; if (c > 44100) { c = 0; yield return(null); } m_Progress = 50 + (( float )i / dataSamples.Count) * 50; } bw.Write(( byte )dataSamples [i].command); bytesWritten++; if (dataSamples [i].command != VGMCommands.EOF) { bw.Write(( byte )dataSamples [i].data); bytesWritten++; } if (dataSamples [i].pattern == playback.patternLoop && i == 0) { foundLoop = true; } if (!foundLoop && dataSamples [i].pattern == playback.patternLoop) { loopOffset += bytesWritten; foundLoop = true; } } //bw.Write((byte)0x66); int gd3Offset = ( int )bw.BaseStream.Position - 0x14; bw.Write(Encoding.ASCII.GetBytes("Gd3 ")); bw.Write(( uint )0x00010000); int sizeOffset = ( int )bw.BaseStream.Position; bw.Write(( uint )0); bw.Write(Encoding.Unicode.GetBytes(SongData.songName + "\0")); //track name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes("\0")); //game name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes("Sega Game Gear\0")); //system name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes(SongData.artistName + "\0")); //artist name bw.Write(Encoding.Unicode.GetBytes("\0")); bw.Write(Encoding.Unicode.GetBytes(System.DateTime.Today.ToString(@"yyyy\/MM\/dd") + "\0")); //release date bw.Write(Encoding.Unicode.GetBytes("SnoozeTracker\0")); //converter bw.Write(Encoding.Unicode.GetBytes("https://github.com/tEFFx/SnoozeTracker\0")); //notes int eofOffset = ( int )bw.BaseStream.Position - 0x04; bw.Seek(sizeOffset, SeekOrigin.Begin); bw.Write(( uint )(eofOffset - sizeOffset)); bw.Seek(0x04, SeekOrigin.Begin); bw.Write(( uint )(eofOffset)); bw.Seek(0x14, SeekOrigin.Begin); bw.Write(( uint )(gd3Offset)); bw.Seek(0x18, SeekOrigin.Begin); bw.Write(( uint )waitAmount); if (playback.patternLoop != 0) { bw.Write(( uint )(loopOffset - 0x1C)); bw.Write(( uint )(loopWaitAmount)); } if (isCompressed) { Stream fs = sfd.OpenFile( ); GZipStream gzipStream = new GZipStream(fs, CompressionMode.Compress, CompressionLevel.BestCompression, true); byte [] buffer = new byte [fileStream.Length]; fileStream.Position = 0; fileStream.Read(buffer, 0, ( int )fileStream.Length); gzipStream.Write(buffer, 0, ( int )fileStream.Length); gzipStream.Close( ); } bw.Close( ); playback.psg.audioSource.enabled = true; playback.psg.enabled = false; playback.psg.enabled = true; playback.follow = true; m_OperationInProgress = false; playback.Stop( ); }