Template
*
This commit is contained in:
@@ -0,0 +1,4 @@
|
|||||||
|
/Src/.vs
|
||||||
|
/Src/bin
|
||||||
|
/Src/obj
|
||||||
|
/TestData
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
[submodule "Dependencies/libcd.net"]
|
||||||
|
path = Dependencies/libcd.net
|
||||||
|
url = https://github.com/L-proger/libcd.net.git
|
||||||
|
branch = main
|
||||||
+1
Submodule Dependencies/libcd.net added at 581aae64a6
+192
@@ -0,0 +1,192 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
//File table parsing algorithm: https://github.com/mbystryantsev/consolgames-tools/blob/master/game-specific/Silent%20Hill/FilesExtractor/Silent.cpp
|
||||||
|
|
||||||
|
namespace LibCD {
|
||||||
|
class App {
|
||||||
|
static string CalledFileDir([CallerFilePath] string path = null) {
|
||||||
|
return System.IO.Path.GetDirectoryName(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
static string TestDataDir {
|
||||||
|
get {
|
||||||
|
return Path.Combine(CalledFileDir(), "..", "TestData");
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string ImageFilePath {
|
||||||
|
get { return Path.Combine(TestDataDir, "Image.bin"); }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void PrintFileSystem(ISO9660.FileSystem.Directory dir, string fullPath) {
|
||||||
|
fullPath += dir.Name;
|
||||||
|
Console.WriteLine(fullPath);
|
||||||
|
|
||||||
|
foreach (var file in dir.Files) {
|
||||||
|
Console.WriteLine($"{fullPath}/{file.Name} | LBA: {file.LBA} SIZE: {file.Size}");
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (var childDir in dir.Directories) {
|
||||||
|
PrintFileSystem(childDir, fullPath + "/");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static ISO9660.FileSystem.File? FindFile(ISO9660.FileSystem fs, string name) {
|
||||||
|
var dir = fs.RootDirectory;
|
||||||
|
foreach (var file in dir.Files) {
|
||||||
|
if (file.Name.StartsWith(name)) {
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct ShFileRecord {
|
||||||
|
public uint b1;
|
||||||
|
public uint b2;
|
||||||
|
public uint b3;
|
||||||
|
|
||||||
|
public uint StartSector {
|
||||||
|
get {
|
||||||
|
return b1 & 0x7ffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public uint ChunkCount {
|
||||||
|
get {
|
||||||
|
return b1 >> 19;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint DirectoryIndex {
|
||||||
|
get {
|
||||||
|
return b2 & 0xf;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public uint Name0 {
|
||||||
|
get {
|
||||||
|
return (b2 >> 4) & 0xffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
public uint Dummy {
|
||||||
|
get {
|
||||||
|
return (b2 >> 28);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Name1 {
|
||||||
|
get {
|
||||||
|
return b3 & 0xffffff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ExtensionIndex {
|
||||||
|
get {
|
||||||
|
return b3 >> 24;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public string Name {
|
||||||
|
get {
|
||||||
|
string result = "";
|
||||||
|
uint[] values = new uint[] { Name0, Name1 };
|
||||||
|
|
||||||
|
for (int j = 0; j < 2; j++) {
|
||||||
|
uint v = values[j];
|
||||||
|
for (int i = 0; i < 4 && v != 0; i++) {
|
||||||
|
byte c = (byte)((v & 0x3F) + 0x20);
|
||||||
|
result += (char)c;
|
||||||
|
v >>= 6;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Directory {
|
||||||
|
get {
|
||||||
|
return DefaultDirectoryStruct[DirectoryIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Extension {
|
||||||
|
get {
|
||||||
|
return DefaultExtensions[DirectoryIndex];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public string Path {
|
||||||
|
get {
|
||||||
|
return System.IO.Path.Combine(Directory, $"{Name}{Extension}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint Size {
|
||||||
|
get {
|
||||||
|
return ChunkCount * 0x100;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static string[] DefaultExtensions = new string[16]
|
||||||
|
{
|
||||||
|
".TIM", ".VAB", ".BIN", ".DMS",
|
||||||
|
".ANM", ".PLM", ".IPD", ".ILM",
|
||||||
|
".TMD", ".DAT", ".KDT", ".CMP",
|
||||||
|
".TXT", "", "", ""
|
||||||
|
};
|
||||||
|
|
||||||
|
static string[] DefaultDirectoryStruct = new string[16]
|
||||||
|
{
|
||||||
|
"1ST", "ANIM", "BG", "CHARA",
|
||||||
|
"ITEM", "MISC", "SND", "TEST",
|
||||||
|
"TIM", "VIN", "XA", "",
|
||||||
|
"", "", "", ""
|
||||||
|
};
|
||||||
|
|
||||||
|
public static void Main() {
|
||||||
|
Console.WriteLine(ImageFilePath);
|
||||||
|
|
||||||
|
var fs = new ISO9660.FileSystem(File.OpenRead(ImageFilePath));
|
||||||
|
var xaDiscLabel = fs.PrimaryVolumeDescriptor.GetXADiscLabel();
|
||||||
|
|
||||||
|
var exeFile = FindFile(fs, "SLUS_007.07");
|
||||||
|
var dataFile = FindFile(fs, "SILENT");
|
||||||
|
|
||||||
|
var exeFileStream = exeFile.OpenRead(fs.SectorStream);
|
||||||
|
exeFileStream.Seek(0xB91C, SeekOrigin.Current);
|
||||||
|
|
||||||
|
List<ShFileRecord> fileRecords = new List<ShFileRecord>();
|
||||||
|
for(int i = 0; i < 2074; ++i) {
|
||||||
|
fileRecords.Add(LibCD.Serialization.StreamReader.ReadStruct<ShFileRecord>(exeFileStream));
|
||||||
|
}
|
||||||
|
|
||||||
|
string exportDirectory = @"E:\CdContent";
|
||||||
|
foreach (var file in fileRecords) {
|
||||||
|
fs.SectorStream.SeekToSector(file.StartSector);
|
||||||
|
var srcFileStream = new CdByteStream(fs.SectorStream);
|
||||||
|
byte[] data = srcFileStream.Read((int)file.Size);
|
||||||
|
|
||||||
|
string outPath = Path.Combine(exportDirectory, file.Path);
|
||||||
|
string outDir = Path.GetDirectoryName(outPath);
|
||||||
|
Directory.CreateDirectory(outDir);
|
||||||
|
|
||||||
|
File.WriteAllBytes(outPath, data);
|
||||||
|
|
||||||
|
|
||||||
|
Console.WriteLine($"{file.Path}");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
Console.WriteLine("Done");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Dependencies\libcd.net\Src\LibCD.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
Reference in New Issue
Block a user