static void ExportAllLow(string filename, uint voca_baseaddress, bool isNest) { voca_baseaddress = U.toOffset(voca_baseaddress); if (!U.isSafetyOffset(voca_baseaddress)) { return; } string dir = Path.GetDirectoryName(filename); string basename = Path.GetFileNameWithoutExtension(filename); //楽器リスト本体 InputFormRef InputFormRef = Init(null); InputFormRef.ReInit(voca_baseaddress); List <string> lines = new List <string>(); uint voca_endaddress = voca_baseaddress + ((InputFormRef.DataCount + 1) * InputFormRef.BlockSize); uint addr = voca_baseaddress; for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize) { StringBuilder sb = new StringBuilder(); sb.Append(U.ToHexString(Program.ROM.u8(addr + 0))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 1))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 2))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 3))); sb.Append("\t"); uint type = Program.ROM.u8(addr); if (type == 0x00 || type == 0x08 || type == 0x10 || type == 0x18 ) {//directsound waveデータ. uint songdata_addr = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(songdata_addr)) { continue; } uint sample_length = Program.ROM.u32(songdata_addr + 12); if (!U.isSafetyLength(songdata_addr + 12 + 4, sample_length)) { continue; } if (!SongUtil.IsDirectSoundData(Program.ROM.Data, songdata_addr)) {//壊れたデータ continue; } string waveFilename = basename + U.To0xHexString(i) + ".DirectSound.bin"; byte[] bin = Program.ROM.getBinaryData(songdata_addr, 12 + 4 + sample_length); U.WriteAllBytes(Path.Combine(dir, waveFilename), bin); sb.Append(waveFilename); sb.Append("\t"); } else if (type == 0x03 || type == 0x0B ) {//波形データ uint songdata_addr = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(songdata_addr)) { continue; } byte[] bin = Program.ROM.getBinaryData(songdata_addr, 16); string waveFilename = basename + U.To0xHexString(i) + ".Wave.bin"; U.WriteAllBytes(Path.Combine(dir, waveFilename), bin); sb.Append(waveFilename); sb.Append("\t"); } else if (type == 0x80) {//ドラム uint drum_voices = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(drum_voices)) { continue; } if (drum_voices == voca_baseaddress) { sb.Append("@SELF+0"); sb.Append("\t"); } else if (isNest) { if (drum_voices >= voca_baseaddress && drum_voices < voca_endaddress) { sb.Append("@SELF+" + U.ToHexString(drum_voices - voca_baseaddress)); sb.Append("\t"); } else { sb.Append("@BROKENDATA"); sb.Append("\t"); } } else { string drumFilename = basename + U.To0xHexString(i) + ".Drum.instrument"; ExportAllLow(Path.Combine(dir, drumFilename), drum_voices, true); sb.Append(drumFilename); sb.Append("\t"); } } else if (type == 0x40) {//マルチサンプル uint multisample_voices = Program.ROM.p32(addr + 4); uint sample_location = Program.ROM.p32(addr + 8); if (!U.isSafetyOffset(multisample_voices)) { continue; } if (!U.isSafetyOffset(sample_location)) { continue; } if (multisample_voices == voca_baseaddress) { sb.Append("@SELF+0"); sb.Append("\t"); } else if (isNest) { if (multisample_voices >= voca_baseaddress && multisample_voices < voca_endaddress) { sb.Append("@SELF+" + U.ToHexString(multisample_voices - voca_baseaddress)); sb.Append("\t"); } else { sb.Append("@BROKENDATA"); sb.Append("\t"); } } else {//自己参照以外を記録します string multiFilename = basename + U.To0xHexString(i) + ".Multi.instrument"; ExportAllLow(Path.Combine(dir, multiFilename), multisample_voices, true); sb.Append(multiFilename); sb.Append("\t"); } byte[] bin = Program.ROM.getBinaryData(sample_location, 128); string waveFilename = basename + U.To0xHexString(i) + ".Multi.keys.bin"; U.WriteAllBytes(Path.Combine(dir, waveFilename), bin); sb.Append(waveFilename); sb.Append("\t"); } else { sb.Append(U.ToHexString(Program.ROM.u8(addr + 4))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 5))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 6))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 7))); sb.Append("\t"); } if (type != 0x40) {//マルチサンプル以外は、最後の4バイトはデータです sb.Append(U.ToHexString(Program.ROM.u8(addr + 8))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 9))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 10))); sb.Append("\t"); sb.Append(U.ToHexString(Program.ROM.u8(addr + 11))); } U.AddrResult ar = InputFormRef.LoopCallback(i, addr); if (!ar.isNULL()) { sb.Append("\t//"); sb.Append(ar.name); } lines.Add(sb.ToString()); } File.WriteAllLines(filename, lines); }
public static void RecycleOldInstrument(ref List <Address> recycle, string basename, uint voca_basepointer) { if (!U.isSafetyOffset(voca_basepointer)) { return; } uint voca_baseaddress = Program.ROM.u32(voca_basepointer); if (!U.isPointer(voca_baseaddress)) { return; } voca_baseaddress = U.toOffset(voca_baseaddress); if (!U.isSafetyOffset(voca_baseaddress)) { return; } //既に記録しているならば無視. for (int i = 0; i < recycle.Count; i++) { if (recycle[i].Addr == voca_baseaddress) { return; } } //楽器リスト本体 InputFormRef InputFormRef = Init(null); InputFormRef.ReInitPointer(voca_basepointer); FEBuilderGBA.Address.AddAddress(recycle , InputFormRef , basename , new uint[] { 4, 8 } ); uint voca_endaddress = voca_baseaddress + ((InputFormRef.DataCount + 1) * InputFormRef.BlockSize); uint addr = voca_baseaddress; for (int i = 0; i < InputFormRef.DataCount; i++, addr += InputFormRef.BlockSize) { uint type = Program.ROM.u8(addr); if (type == 0x00 || type == 0x08 || type == 0x10 || type == 0x18 ) {//directsound waveデータ. uint songdata_addr = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(songdata_addr)) { continue; } uint sample_length = Program.ROM.u32(songdata_addr + 12); if (!U.isSafetyLength(songdata_addr + 12 + 4, sample_length)) {//壊れたデータ 長さが取れない FEBuilderGBA.Address.AddPointer(recycle , addr + 4 , 0 , basename + U.To0xHexString(i) + "DIRECTSOUND(BROKEN)" , FEBuilderGBA.Address.DataTypeEnum.SONGINSTDIRECTSOUND); continue; } if (!SongUtil.IsDirectSoundData(Program.ROM.Data, songdata_addr)) {//壊れたデータ FEBuilderGBA.Address.AddPointer(recycle , addr + 4 , 0 , basename + U.To0xHexString(i) + "DIRECTSOUND(BROKEN)" , FEBuilderGBA.Address.DataTypeEnum.SONGINSTDIRECTSOUND); continue; } FEBuilderGBA.Address.AddPointer(recycle , addr + 4 , 12 + 4 + sample_length , basename + U.To0xHexString(i) + "DIRECTSOUND" , FEBuilderGBA.Address.DataTypeEnum.SONGINSTDIRECTSOUND); } else if (type == 0x03 || type == 0x0B ) {//波形データ uint songdata_addr = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(songdata_addr)) { continue; } FEBuilderGBA.Address.AddPointer(recycle , addr + 4 , 16 , basename + U.To0xHexString(i) + "WAVE" , FEBuilderGBA.Address.DataTypeEnum.SONGINSTWAVE); } else if (type == 0x80) {//ドラム uint drum_voices = Program.ROM.p32(addr + 4); if (!U.isSafetyOffset(drum_voices)) { continue; } RecycleOldInstrument(ref recycle , basename + U.To0xHexString(i) + "DRUM " , addr + 4); } else if (type == 0x40) {//マルチサンプル uint multisample_voices = Program.ROM.p32(addr + 4); uint sample_location = Program.ROM.p32(addr + 8); if (!U.isSafetyOffset(multisample_voices)) { continue; } if (!U.isSafetyOffset(sample_location)) { continue; } RecycleOldInstrument(ref recycle , basename + U.To0xHexString(i) + "MULTI " , addr + 4); FEBuilderGBA.Address.AddPointer(recycle , addr + 8 , 128 , basename + U.To0xHexString(i) + "MULTI2" , FEBuilderGBA.Address.DataTypeEnum.BIN); } } }