Skip to content

Commit

Permalink
add support for android sound_archive & map type, Fix #64
Browse files Browse the repository at this point in the history
  • Loading branch information
UlyssesWu committed Jan 3, 2022
1 parent e6ac914 commit 679ed53
Show file tree
Hide file tree
Showing 7 changed files with 211 additions and 2 deletions.
1 change: 1 addition & 0 deletions FreeMote.Psb/FreeMote.Psb.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
</ItemGroup>
<ItemGroup>
<Compile Include="Plugins\ManagedTlgFormatter.cs" />
<Compile Include="Plugins\AudioFileFormatter.cs" />
<Compile Include="Resources\ArchDatas.cs" />
<Compile Include="Resources\AudioMetadata.cs" />
<Compile Include="IPsbType.cs" />
Expand Down
89 changes: 89 additions & 0 deletions FreeMote.Psb/Plugins/AudioFileFormatter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
using System.Collections.Generic;
using System.ComponentModel.Composition;
using FreeMote.Psb;

namespace FreeMote.Plugins
{
[Export(typeof(IPsbAudioFormatter))]
[ExportMetadata("Name", "FreeMote.Audio.File")]
[ExportMetadata("Author", "Ulysses")]
[ExportMetadata("Comment", "Export/Import audio file.")]
internal class AudioFileFormatter : IPsbAudioFormatter
{
public List<string> Extensions { get; } = new() { ".wav", ".ogg" };
public bool CanToWave(IArchData archData, Dictionary<string, object> context = null)
{
return archData is AudioFileArchData;
}

public bool CanToArchData(byte[] wave, Dictionary<string, object> context = null)
{
if (wave == null || wave.Length < 4)
{
return false;
}

if (wave[0] == 'O' && wave[1] == 'g' && wave[2] == 'g') return true;
if (wave[0] == 'R' && wave[1] == 'I' && wave[2] == 'F' && wave[3] == 'F') return true;

return false;
}

public byte[] ToWave(AudioMetadata md, IArchData archData, string fileName = null, Dictionary<string, object> context = null)
{
var arch = archData as AudioFileArchData;
return arch?.Data?.Data;
}

public bool ToArchData(AudioMetadata md, IArchData archData, in byte[] wave, string fileName, string waveExt, Dictionary<string, object> context = null)
{
if (archData is not AudioFileArchData fileArchData)
{
return false;
}

if (wave[0] == 'O' && wave[1] == 'g' && wave[2] == 'g')
{
fileArchData.Format = PsbAudioFormat.OGG;
}
else //if (wave[0] == 'R' && wave[1] == 'I' && wave[2] == 'F' && wave[3] == 'F')
{
fileArchData.Format = PsbAudioFormat.WAV;
}

if (fileArchData.Data == null)
{
fileArchData.Data = new PsbResource { Data = wave };
}
else
{
fileArchData.Data.Data = wave;
}
return true;
}

public bool TryGetArchData(AudioMetadata md, PsbDictionary channel, out IArchData data, Dictionary<string, object> context = null)
{
data = null;
if (channel.Count == 1 && channel["archData"] is PsbDictionary archDic && archDic.TryGetPsbValue<PsbBool>("background", out var background) && archDic.TryGetPsbValue<PsbString>("filetype", out var fileType) && archDic.TryGetPsbValue<PsbString>("ext", out var ext) && archDic.TryGetPsbValue<PsbResource>("data", out var aData))
{
var newData = new AudioFileArchData
{
Data = aData,
Background = background,
Format = ext == ".ogg" ? PsbAudioFormat.OGG : PsbAudioFormat.WAV
};

if (archDic["loop"] is PsbList aLoop)
{
newData.Loop = aLoop;
}

data = newData;
return true;
}

return false;
}
}
}
2 changes: 1 addition & 1 deletion FreeMote.Psb/Plugins/FreeMount.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
using System.Reflection;
using System.Text;
using FreeMote.Psb;
using Microsoft.IO;

namespace FreeMote.Plugins
{
Expand Down Expand Up @@ -65,6 +64,7 @@ public class FreeMount : IDisposable
private void AddDefaultCatalogs(AggregateCatalog catalog)
{
catalog.Catalogs.Add(new TypeCatalog(typeof(WavFormatter))); //Wav
catalog.Catalogs.Add(new TypeCatalog(typeof(AudioFileFormatter))); //Audio file
}

/// <summary>
Expand Down
29 changes: 29 additions & 0 deletions FreeMote.Psb/PsbValues.cs
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,16 @@ public void WriteTo(BinaryWriter bw)
{
bw.Write((byte) Type);
}

public static implicit operator bool(PsbBool b)
{
return b.Value;
}

public static explicit operator PsbBool(bool b)
{
return new PsbBool(b);
}
}

public enum PsbNumberType
Expand Down Expand Up @@ -1128,6 +1138,25 @@ public PsbDictionary() : base()
{
}

public bool TryGetPsbValue<T>(string key, out T value) where T : IPsbValue
{
var get = TryGetValue(key, out IPsbValue v);
if (get)
{
if (v is T tv)
{
value = tv;
return true;
}

value = default;
return false;
}

value = default;
return false;
}

public Dictionary<string, IPsbValue> Value => this;

public IPsbCollection Parent { get; set; } = null;
Expand Down
60 changes: 60 additions & 0 deletions FreeMote.Psb/Resources/ArchDatas.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,66 @@ private static void Apply(ref PsbResource res, byte[] resData)
}
}

/// <summary>
/// Simple ogg/wav
/// </summary>
public class AudioFileArchData : IArchData
{
private PsbAudioFormat _format = PsbAudioFormat.OGG;
public uint Index => Data.Index ?? uint.MaxValue;

public string Extension { get; set; } = ".ogg";
public string WaveExtension { get; set; } = ".ogg";

public PsbAudioFormat Format
{
get => _format;
set
{
_format = value;
switch (_format)
{
case PsbAudioFormat.OGG:
Extension = ".ogg";
WaveExtension = Extension;
break;
case PsbAudioFormat.WAV:
Extension = ".wav";
WaveExtension = Extension;
break;
}
}
}

public PsbAudioPan ChannelPan => PsbAudioPan.Mono;
public IList<PsbResource> DataList => new List<PsbResource> { Data };
public PsbDictionary PsbArchData { get; set; }

public bool Background { get; set; } = true;

public PsbResource Data { get; set; }
public PsbList Loop { get; set; }


public IPsbValue ToPsbArchData()
{
var result = new PsbDictionary
{
{"background", (PsbBool)Background},
{"data", Data},
{"ext", Extension.ToPsbString()},
{"filetype", PsbString.Empty}
};
if (Loop is {Count: > 0})
{
result.Add("loop", Loop);
}

return result;
}

}

/// <summary>
/// XWMA
/// </summary>
Expand Down
31 changes: 30 additions & 1 deletion FreeMote.Psb/Types/MapType.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Linq;

namespace FreeMote.Psb.Types
{
Expand All @@ -7,6 +8,7 @@ namespace FreeMote.Psb.Types
/// </summary>
class MapType : BaseImageType, IPsbType
{
public const string Source = "layer";
public PsbType PsbType => PsbType.Map;
public bool IsThisType(PSB psb)
{
Expand All @@ -15,7 +17,34 @@ public bool IsThisType(PSB psb)

public List<T> CollectResources<T>(PSB psb, bool deDuplication = true) where T : IResourceMetadata
{
return new List<T>();
var resourceList = FindTileResources(psb, deDuplication).Cast<T>().ToList();

return resourceList;
}

private List<ImageMetadata> FindTileResources(PSB psb, bool deDuplication)
{
List<ImageMetadata> resList = new List<ImageMetadata>(psb.Resources.Count);

if (psb.Objects == null || !psb.Objects.ContainsKey(Source) || psb.Objects[Source] is not PsbList list)
{
return resList;
}

foreach (var item in list)
{
if (item is not PsbDictionary obj || !obj.ContainsKey("image") || obj["image"] is not PsbDictionary image)
{
continue;
}

var md = PsbResHelper.GenerateImageMetadata(image, null);
md.PsbType = PsbType.Map;
md.Spec = psb.Platform;
resList.Add(md);
}

return resList;
}
}
}
1 change: 1 addition & 0 deletions FreeMote/PsbEnums.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ public enum PsbAudioFormat
XWMA,
VAG,
ADPCM,
OGG,
}

public enum PsbAudioPan
Expand Down

0 comments on commit 679ed53

Please sign in to comment.