mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/PCK-Studio.git
synced 2026-09-27 15:20:46 +00:00
Add AudioPCKFile
This commit is contained in:
@@ -0,0 +1,115 @@
|
||||
using PckStudio.Classes.FileTypes;
|
||||
using PckStudio.Classes.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PckStudio.Classes.IO.PCK
|
||||
{
|
||||
|
||||
public class InvalidAudioPckException : Exception
|
||||
{
|
||||
public InvalidAudioPckException(string message) : base(message)
|
||||
{ }
|
||||
}
|
||||
|
||||
internal class PCKAudioFileReader : StreamDataReader
|
||||
{
|
||||
private PCKAudioFile _file;
|
||||
private List<string> LUT = new List<string>();
|
||||
|
||||
|
||||
public static PCKAudioFile Read(Stream stream, bool isLittleEndian)
|
||||
{
|
||||
return new PCKAudioFileReader(isLittleEndian).ReadFromStream(stream);
|
||||
}
|
||||
|
||||
private PCKAudioFileReader(bool isLittleEndian) : base(isLittleEndian)
|
||||
{
|
||||
}
|
||||
|
||||
private PCKAudioFile ReadFromStream(Stream stream)
|
||||
{
|
||||
int pck_type = ReadInt(stream);
|
||||
if (pck_type > 0xf00000) // 03 00 00 00 == true
|
||||
throw new OverflowException(nameof(pck_type));
|
||||
if (pck_type > 1)
|
||||
throw new InvalidAudioPckException(nameof(pck_type));
|
||||
_file = new PCKAudioFile();
|
||||
ReadLookUpTabel(stream);
|
||||
ReadCategories(stream);
|
||||
ReadCategorySongs(stream);
|
||||
return _file;
|
||||
}
|
||||
|
||||
private void ReadLookUpTabel(Stream stream)
|
||||
{
|
||||
int count = ReadInt(stream);
|
||||
LUT = new List<string>(count);
|
||||
for (int i = 0; i < count; i++)
|
||||
{
|
||||
int index = ReadInt(stream);
|
||||
LUT.Insert(index, ReadString(stream));
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadCategories(Stream stream)
|
||||
{
|
||||
int categoryEntryCount = ReadInt(stream);
|
||||
for (; 0 < categoryEntryCount; categoryEntryCount--)
|
||||
{
|
||||
var parameterType = (PCKAudioFile.AudioCategory.EAudioParameterType)ReadInt(stream);
|
||||
var audioType = (PCKAudioFile.AudioCategory.EAudioType)ReadInt(stream);
|
||||
string name = ReadString(stream);
|
||||
Console.WriteLine(name);
|
||||
_file.AddCategory(parameterType, audioType);
|
||||
}
|
||||
}
|
||||
|
||||
private void ReadCategorySongs(Stream stream)
|
||||
{
|
||||
List<string> credits = new List<string>();
|
||||
List<string> creditIds = new List<string>();
|
||||
foreach (var c in _file.Categories)
|
||||
{
|
||||
if (c is null) continue;
|
||||
int audioCount = ReadInt(stream);
|
||||
for (; 0 < audioCount; audioCount--)
|
||||
{
|
||||
string key = LUT[ReadInt(stream)];
|
||||
string value = ReadString(stream);
|
||||
switch (key)
|
||||
{
|
||||
case "CUENAME":
|
||||
c.SongNames.Add(value);
|
||||
break;
|
||||
case "CREDIT":
|
||||
credits.Add(value);
|
||||
break;
|
||||
case "CREDITID":
|
||||
creditIds.Add(value);
|
||||
_file.AddCreditId(value);
|
||||
break;
|
||||
default:
|
||||
throw new InvalidDataException(nameof(key));
|
||||
}
|
||||
}
|
||||
};
|
||||
foreach (var credit in credits.Zip(creditIds, (str, id) => (str, id)))
|
||||
{
|
||||
_file.SetCredit(credit.id, credit.str);
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadString(Stream stream)
|
||||
{
|
||||
int len = ReadInt(stream);
|
||||
string s = ReadString(stream, len, IsUsingLittleEndian ? Encoding.Unicode : Encoding.BigEndianUnicode);
|
||||
ReadInt(stream); // padding
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
using PckStudio.Classes.FileTypes;
|
||||
using PckStudio.Classes.Utils;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace PckStudio.Classes.IO.PCK
|
||||
{
|
||||
internal class PCKAudioFileWriter : StreamDataWriter
|
||||
{
|
||||
|
||||
private PCKAudioFile _file;
|
||||
private static readonly List<string> LUT = new List<string>
|
||||
{
|
||||
"CUENAME",
|
||||
"CREDIT",
|
||||
"CREDITID"
|
||||
};
|
||||
|
||||
public static void Write(Stream stream, PCKAudioFile file, bool isLittleEndian)
|
||||
{
|
||||
new PCKAudioFileWriter(file, isLittleEndian).WriteToStream(stream);
|
||||
}
|
||||
|
||||
private PCKAudioFileWriter(PCKAudioFile file, bool isLittleEndian) : base(isLittleEndian)
|
||||
{
|
||||
_file = file;
|
||||
}
|
||||
|
||||
private void WriteToStream(Stream stream)
|
||||
{
|
||||
WriteInt(stream, _file.type);
|
||||
WriteLookUpTable(stream);
|
||||
WriteCategories(stream);
|
||||
WriteCategorySongs(stream);
|
||||
}
|
||||
|
||||
private void WriteString(Stream stream, string s)
|
||||
{
|
||||
WriteInt(stream, s.Length);
|
||||
WriteString(stream, s, IsUsingLittleEndian ? Encoding.Unicode : Encoding.BigEndianUnicode);
|
||||
WriteInt(stream, 0); // padding
|
||||
}
|
||||
|
||||
private void WriteLookUpTable(Stream stream)
|
||||
{
|
||||
WriteInt(stream, 3);
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
WriteInt(stream, i);
|
||||
WriteString(stream, LUT[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteCategories(Stream stream)
|
||||
{
|
||||
WriteInt(stream, _file.GetCategoryCount());
|
||||
foreach (var category in _file.Categories)
|
||||
{
|
||||
if (category is null) continue;
|
||||
WriteInt(stream, (int)category.parameterType);
|
||||
WriteInt(stream, (int)category.audioType);
|
||||
WriteString(stream, category.Name);
|
||||
}
|
||||
}
|
||||
|
||||
private void WriteCategorySongs(Stream stream)
|
||||
{
|
||||
bool addCredit = true;
|
||||
foreach (var category in _file.Categories)
|
||||
{
|
||||
if (category is null) continue;
|
||||
WriteInt(stream, category.SongNames.Count + (addCredit ? _file.Credits.Count * 2 : 0));
|
||||
foreach (var name in category.SongNames)
|
||||
{
|
||||
WriteInt(stream, LUT.IndexOf("CUENAME"));
|
||||
WriteString(stream, name);
|
||||
}
|
||||
if (addCredit)
|
||||
{
|
||||
foreach (var credit in _file.Credits)
|
||||
{
|
||||
WriteInt(stream, LUT.IndexOf("CREDIT"));
|
||||
WriteString(stream, credit.Value);
|
||||
WriteInt(stream, LUT.IndexOf("CREDITID"));
|
||||
WriteString(stream, credit.Key);
|
||||
}
|
||||
}
|
||||
addCredit = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user