97 lines
4.4 KiB
C#
97 lines
4.4 KiB
C#
// Decompiled with JetBrains decompiler
|
|
// Type: SEGATools.Security.InitialProgramTocConverter
|
|
// Assembly: SEGATools, Version=1.0.3.0, Culture=neutral, PublicKeyToken=611be24fdeb07e08
|
|
// MVID: D631183F-57B1-40A1-B502-5364D288307A
|
|
// Assembly location: SEGATools.dll
|
|
|
|
using System;
|
|
using System.Runtime.InteropServices;
|
|
using System.Text;
|
|
|
|
namespace SEGATools.Security
|
|
{
|
|
internal sealed class InitialProgramTocConverter
|
|
{
|
|
private const string TOC_ID = "TOC1";
|
|
private const int TOC_ID_LENGTH = 4;
|
|
private const int TOC_TRACKINFO_LENGTH = 4;
|
|
private const int TOC_NUMBER_OF_TRACKINFO = 97;
|
|
private const int TOC_TRACKINFO_SIZE = 388;
|
|
private const int TOC_DATA_SIZE = 392;
|
|
private const int TOC_TRACK_INDEX_OFFSET = 3;
|
|
private const int TOC_TRACK_POST_GAP = 150;
|
|
private static readonly Logger.ILog logger = Logger.CreateLog();
|
|
|
|
private static uint TocTrackNumber(uint n) => (n & 16711680U) >> 16;
|
|
|
|
private static uint TocTrackFAD(uint n) => n & 16777215U;
|
|
|
|
private static InitialProgramTrackInfo.ControlData TocTrackType(uint n) => (InitialProgramTrackInfo.ControlData) ((n & 4026531840U) >> 28);
|
|
|
|
internal static InitialProgramToc ToInitialProgramToc(
|
|
byte[] buffer,
|
|
int startIndex)
|
|
{
|
|
if (startIndex < 0 || buffer.Length - startIndex < 392)
|
|
{
|
|
InitialProgramTocConverter.logger.ErrorFormat("Buffer too small: {0} bytes", (object) (buffer.Length - startIndex));
|
|
throw new ArgumentOutOfRangeException();
|
|
}
|
|
string str = Encoding.ASCII.GetString(buffer, startIndex, "TOC1".Length);
|
|
if (!"TOC1".Equals(str))
|
|
{
|
|
InitialProgramTocConverter.logger.ErrorFormat("Expected TOC identifier \"{0}\", got \"{1}\"", (object) "TOC1", (object) str);
|
|
throw new InitialProgramTocIdentifierMissingException();
|
|
}
|
|
InitialProgramTocConverter.TOC structure = (InitialProgramTocConverter.TOC) Marshal.PtrToStructure(Marshal.UnsafeAddrOfPinnedArrayElement((Array) buffer, startIndex + 4), typeof (InitialProgramTocConverter.TOC));
|
|
int length = (int) InitialProgramTocConverter.TocTrackNumber(structure.LastTrack) - (int) InitialProgramTocConverter.TocTrackNumber(structure.FirstTrack) + 1;
|
|
InitialProgramTocConverter.logger.InfoFormat("Number Of Tracks = {0}", (object) length);
|
|
InitialProgramTrackInfo[] tracks = length > 0 ? new InitialProgramTrackInfo[length] : throw new InitialProgramTocWrongNumberOfTracksException();
|
|
int num = tracks.Length - 1;
|
|
for (int trackNumber = num; trackNumber >= 0; --trackNumber)
|
|
{
|
|
uint track1 = structure.Tracks[trackNumber];
|
|
uint StartFAD = InitialProgramTocConverter.TocTrackFAD(track1);
|
|
InitialProgramTrackInfo.ControlData controlData = InitialProgramTocConverter.TocTrackType(track1);
|
|
if (!Enum.IsDefined(typeof (InitialProgramTrackInfo.ControlData), (object) controlData))
|
|
{
|
|
InitialProgramTocConverter.logger.ErrorFormat("Track {0} control value is not supported: {1}", (object) trackNumber, (object) controlData);
|
|
throw new InitialProgramTocWrongControlDataException(trackNumber, controlData);
|
|
}
|
|
InitialProgramTocTrackBuilder programTocTrackBuilder = InitialProgramTocTrackBuilder.aTrackWithIndex(3 + trackNumber).WithStartFAD(StartFAD).WithCtrl(controlData);
|
|
uint LastFAD;
|
|
if (trackNumber == num)
|
|
{
|
|
LastFAD = InitialProgramTocConverter.TocTrackFAD(structure.LeadOut) - 1U;
|
|
}
|
|
else
|
|
{
|
|
uint track2 = structure.Tracks[trackNumber + 1];
|
|
LastFAD = InitialProgramTocConverter.TocTrackFAD(track2) - 1U;
|
|
if (controlData != InitialProgramTocConverter.TocTrackType(track2))
|
|
LastFAD -= 150U;
|
|
}
|
|
programTocTrackBuilder.WithLastFAD(LastFAD);
|
|
InitialProgramTrackInfo programTrackInfo = programTocTrackBuilder.Build();
|
|
tracks[trackNumber] = programTrackInfo;
|
|
InitialProgramTocConverter.logger.DebugFormat("IP TOC: found {0}", (object) programTrackInfo);
|
|
}
|
|
return new InitialProgramToc(tracks);
|
|
}
|
|
|
|
[StructLayout(LayoutKind.Explicit, Size = 388, Pack = 1)]
|
|
private struct TOC
|
|
{
|
|
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 97, ArraySubType = UnmanagedType.U4)]
|
|
[FieldOffset(0)]
|
|
public uint[] Tracks;
|
|
[FieldOffset(388)]
|
|
public uint FirstTrack;
|
|
[FieldOffset(392)]
|
|
public uint LastTrack;
|
|
[FieldOffset(396)]
|
|
public uint LeadOut;
|
|
}
|
|
}
|
|
}
|