Add 32-bit support to Tex file decoder and exporter

Deal with P files that claim to be textured even though no texture is present
This commit is contained in:
ficedula 2023-10-24 19:59:52 +01:00
parent e93da51270
commit 112bb28a1b
4 changed files with 23 additions and 5 deletions

View File

@ -5,7 +5,7 @@
<TargetFramework>net7.0-windows</TargetFramework> <TargetFramework>net7.0-windows</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<Version>0.2.0</Version> <Version>0.2.1</Version>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>

View File

@ -126,7 +126,7 @@ namespace Ficedula.FF7.Exporters {
SetupBaking(); SetupBaking();
foreach (var group in poly.Chunks) { foreach (var group in poly.Chunks) {
if (group.Texture != null) { if ((group.Texture != null) && (group.Texture.Value < materials.Count())) {
var mesh = new MeshBuilder<VertexPositionNormal, VertexColor1Texture1, VertexJoints4>(); var mesh = new MeshBuilder<VertexPositionNormal, VertexColor1Texture1, VertexJoints4>();
for (int i = 0; i < group.Indices.Count; i += 3) { for (int i = 0; i < group.Indices.Count; i += 3) {
var v0 = group.Verts[group.Indices[i]]; var v0 = group.Verts[group.Indices[i]];

View File

@ -9,7 +9,11 @@ using System.Threading.Tasks;
namespace Ficedula.FF7.Exporters { namespace Ficedula.FF7.Exporters {
public static class TexFileUtil { public static class TexFileUtil {
public unsafe static SKBitmap ToBitmap(this TexFile tex, int palette) { public unsafe static SKBitmap ToBitmap(this TexFile tex, int palette) {
var data = tex.ApplyPalette(palette); List<uint[]> data;
if (tex.BytesPerPixel == 4)
data = tex.As32Bit();
else
data = tex.ApplyPalette(palette);
var bmp = new SKBitmap(tex.Width, tex.Height, SKColorType.Rgba8888, SKAlphaType.Premul); var bmp = new SKBitmap(tex.Width, tex.Height, SKColorType.Rgba8888, SKAlphaType.Premul);
foreach(int y in Enumerable.Range(0, tex.Height)) { foreach(int y in Enumerable.Range(0, tex.Height)) {
var row = data[y]; var row = data[y];

View File

@ -6,6 +6,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -16,8 +17,9 @@ namespace Ficedula.FF7 {
public List<uint[]> Palettes { get; } = new(); public List<uint[]> Palettes { get; } = new();
public List<byte[]> Pixels { get; } public List<byte[]> Pixels { get; }
public int Width => Pixels[0].Length; public int Width => Pixels[0].Length / BytesPerPixel;
public int Height => Pixels.Count; public int Height => Pixels.Count;
public int BytesPerPixel { get; private set; }
public TexFile(Stream source) { public TexFile(Stream source) {
source.Position = 0x30; source.Position = 0x30;
@ -31,6 +33,9 @@ namespace Ficedula.FF7 {
source.Position = 0x58; source.Position = 0x58;
int paletteSize = source.ReadI32() * 4; int paletteSize = source.ReadI32() * 4;
source.Position = 0x68;
BytesPerPixel = source.ReadI32();
foreach(int p in Enumerable.Range(0, numPalettes)) { foreach(int p in Enumerable.Range(0, numPalettes)) {
source.Position = 0xEC + colours * 4 * p; source.Position = 0xEC + colours * 4 * p;
Palettes.Add( Palettes.Add(
@ -43,7 +48,7 @@ namespace Ficedula.FF7 {
source.Position = 0xEC + paletteSize; source.Position = 0xEC + paletteSize;
Pixels = Enumerable.Range(0, height) Pixels = Enumerable.Range(0, height)
.Select(_ => .Select(_ =>
Enumerable.Range(0, width) Enumerable.Range(0, width * BytesPerPixel)
.Select(__ => source.ReadU8()) .Select(__ => source.ReadU8())
.ToArray() .ToArray()
) )
@ -56,5 +61,14 @@ namespace Ficedula.FF7 {
.Select(row => row.Select(b => palette[b]).ToArray()) .Select(row => row.Select(b => palette[b]).ToArray())
.ToList(); .ToList();
} }
public List<uint[]> As32Bit() {
Trace.Assert(BytesPerPixel == 4);
return Pixels
.Select(row => Enumerable.Range(0, Width)
.Select(x => BitConverter.ToUInt32(row, x * BytesPerPixel))
.ToArray())
.ToList();
}
} }
} }