1
mirror of https://github.com/sampletext32/ParkanPlayground.git synced 2025-12-12 05:41:21 +04:00

Material parsing and viewing

This commit is contained in:
bird_egop
2025-12-04 03:50:29 +03:00
parent 3b1fd5ef97
commit 75b1548f55
18 changed files with 1694 additions and 63 deletions

82
MaterialLib/Interpolate.c Normal file
View File

@@ -0,0 +1,82 @@

void __cdecl
Interpolate(MaterialExternal *src1_ptr,MaterialExternal *src2_ptr,float progress,
MaterialExternal *dst_ptr,uint targetFlags)
{
if ((targetFlags & 2) == 0) {
(dst_ptr->stage).diffuse.R = (src1_ptr->stage).diffuse.R;
(dst_ptr->stage).diffuse.G = (src1_ptr->stage).diffuse.G;
(dst_ptr->stage).diffuse.B = (src1_ptr->stage).diffuse.B;
}
else {
(dst_ptr->stage).diffuse.R =
((src2_ptr->stage).diffuse.R - (src1_ptr->stage).diffuse.R) * progress +
(src1_ptr->stage).diffuse.R;
(dst_ptr->stage).diffuse.G =
((src2_ptr->stage).diffuse.G - (src1_ptr->stage).diffuse.G) * progress +
(src1_ptr->stage).diffuse.G;
(dst_ptr->stage).diffuse.B =
((src2_ptr->stage).diffuse.B - (src1_ptr->stage).diffuse.B) * progress +
(src1_ptr->stage).diffuse.B;
}
if ((targetFlags & 1) == 0) {
(dst_ptr->stage).ambient.R = (src1_ptr->stage).ambient.R;
(dst_ptr->stage).ambient.G = (src1_ptr->stage).ambient.G;
(dst_ptr->stage).ambient.B = (src1_ptr->stage).ambient.B;
}
else {
(dst_ptr->stage).ambient.R =
((src2_ptr->stage).ambient.R - (src1_ptr->stage).ambient.R) * progress +
(src1_ptr->stage).ambient.R;
(dst_ptr->stage).ambient.G =
((src2_ptr->stage).ambient.G - (src1_ptr->stage).ambient.G) * progress +
(src1_ptr->stage).ambient.G;
(dst_ptr->stage).ambient.B =
((src2_ptr->stage).ambient.B - (src1_ptr->stage).ambient.B) * progress +
(src1_ptr->stage).ambient.B;
}
if ((targetFlags & 4) == 0) {
(dst_ptr->stage).specular.R = (src1_ptr->stage).specular.R;
(dst_ptr->stage).specular.G = (src1_ptr->stage).specular.G;
(dst_ptr->stage).specular.B = (src1_ptr->stage).specular.B;
}
else {
(dst_ptr->stage).specular.R =
((src2_ptr->stage).specular.R - (src1_ptr->stage).specular.R) * progress +
(src1_ptr->stage).specular.R;
(dst_ptr->stage).specular.G =
((src2_ptr->stage).specular.G - (src1_ptr->stage).specular.G) * progress +
(src1_ptr->stage).specular.G;
(dst_ptr->stage).specular.B =
((src2_ptr->stage).specular.B - (src1_ptr->stage).specular.B) * progress +
(src1_ptr->stage).specular.B;
}
if ((targetFlags & 8) == 0) {
(dst_ptr->stage).emissive.R = (src1_ptr->stage).emissive.R;
(dst_ptr->stage).emissive.G = (src1_ptr->stage).emissive.G;
(dst_ptr->stage).emissive.B = (src1_ptr->stage).emissive.B;
}
else {
(dst_ptr->stage).emissive.R =
((src2_ptr->stage).emissive.R - (src1_ptr->stage).emissive.R) * progress +
(src1_ptr->stage).emissive.R;
(dst_ptr->stage).emissive.G =
((src2_ptr->stage).emissive.G - (src1_ptr->stage).emissive.G) * progress +
(src1_ptr->stage).emissive.G;
(dst_ptr->stage).emissive.B =
((src2_ptr->stage).emissive.B - (src1_ptr->stage).emissive.B) * progress +
(src1_ptr->stage).emissive.B;
}
if ((targetFlags & 0x10) != 0) {
(dst_ptr->stage).ambient.A =
((src2_ptr->stage).ambient.A - (src1_ptr->stage).ambient.A) * progress +
(src1_ptr->stage).ambient.A;
(dst_ptr->stage).Power = (src1_ptr->stage).Power;
return;
}
(dst_ptr->stage).ambient.A = (src1_ptr->stage).ambient.A;
(dst_ptr->stage).Power = (src1_ptr->stage).Power;
return;
}

137
MaterialLib/MaterialFile.cs Normal file
View File

@@ -0,0 +1,137 @@
namespace MaterialLib;
public class MaterialFile
{
// === Metadata (not from file content) ===
public string FileName { get; set; }
public int Version { get; set; } // From NRes ElementCount
public int Magic1 { get; set; } // From NRes Magic1
// === Derived from Version/ElementCount ===
public int MaterialRenderingType { get; set; } // (Version >> 2) & 0xF - 0=Standard, 1=Special, 2=Particle
public bool SupportsBumpMapping { get; set; } // (Version & 2) != 0
public int IsParticleEffect { get; set; } // Version & 40 - 0=Normal, 8=Particle/Effect
// === File Content (in read order) ===
// Read order: StageCount (ushort), AnimCount (ushort), then conditionally blend modes and params
// Global Blend Modes (read if Magic1 >= 2)
public BlendMode SourceBlendMode { get; set; } // Default: Unknown (0xFF)
public BlendMode DestBlendMode { get; set; } // Default: Unknown (0xFF)
// Global Parameters (read if Magic1 > 2 and > 3 respectively)
public float GlobalAlphaMultiplier { get; set; } // Default: 1.0 (always 1.0 in all 628 materials)
public float GlobalEmissiveIntensity { get; set; } // Default: 0.0 (0=no glow, rare values: 1000, 10000)
public List<MaterialStage> Stages { get; set; } = new();
public List<MaterialAnimation> Animations { get; set; } = new();
}
public enum BlendMode : byte
{
Zero = 1,
One = 2,
SrcColor = 3,
InvSrcColor = 4,
SrcAlpha = 5,
InvSrcAlpha = 6,
DestAlpha = 7,
InvDestAlpha = 8,
DestColor = 9,
InvDestColor = 10,
SrcAlphaSat = 11,
BothSrcAlpha = 12,
BothInvSrcAlpha = 13,
// Custom or Unknown
Unknown = 0xFF
}
public class MaterialStage
{
// === FILE READ ORDER (34 bytes per stage) ===
// This matches the order bytes are read from the file (decompiled.c lines 159-217)
// NOT the C struct memory layout (which is Diffuse, Ambient, Specular, Emissive)
// 1. Ambient Color (4 bytes, read first from file)
public float AmbientR;
public float AmbientG;
public float AmbientB;
public float AmbientA; // Scaled by 0.01 when read from file
// 2. Diffuse Color (4 bytes, read second from file)
public float DiffuseR;
public float DiffuseG;
public float DiffuseB;
public float DiffuseA;
// 3. Specular Color (4 bytes, read third from file)
public float SpecularR;
public float SpecularG;
public float SpecularB;
public float SpecularA;
// 4. Emissive Color (4 bytes, read fourth from file)
public float EmissiveR;
public float EmissiveG;
public float EmissiveB;
public float EmissiveA;
// 5. Power (1 byte → float, read fifth from file)
public float Power;
// 6. Texture Stage Index (1 byte, read sixth from file)
// 255 = not set/default, 0-47 = reference to specific texture stage
public int TextureStageIndex;
// 7. Texture Name (16 bytes, read seventh from file)
public string TextureName { get; set; }
}
public class MaterialAnimation
{
// === File Read Order ===
// Combined field (4 bytes): bits 3-31 = Target, bits 0-2 = LoopMode
public AnimationTarget Target;
public AnimationLoopMode LoopMode;
// Key count (2 bytes), then keys
public List<AnimKey> Keys { get; set; } = new();
// Cached description for UI (computed once during parsing)
public string TargetDescription { get; set; } = string.Empty;
}
[Flags]
public enum AnimationTarget : int
{
// NOTE: This is a BITSET (flags enum). Multiple flags can be combined.
// When a flag is SET, that component is INTERPOLATED between stages.
// When a flag is NOT SET, that component is COPIED from the source stage (no interpolation).
// If ALL flags are 0, the ENTIRE stage is copied without any interpolation.
Ambient = 1, // 0x01 - Interpolates Ambient RGB (Interpolate.c lines 23-37)
Diffuse = 2, // 0x02 - Interpolates Diffuse RGB (Interpolate.c lines 7-21)
Specular = 4, // 0x04 - Interpolates Specular RGB (Interpolate.c lines 39-53)
Emissive = 8, // 0x08 - Interpolates Emissive RGB (Interpolate.c lines 55-69)
Power = 16 // 0x10 - Interpolates Ambient.A and sets Power (Interpolate.c lines 71-76)
}
public enum AnimationLoopMode : int
{
Loop = 0,
PingPong = 1,
Clamp = 2,
Random = 3
}
public struct AnimKey
{
// === File Read Order (6 bytes per key) ===
public ushort StageIndex; // Read first
public ushort DurationMs; // Read second
public ushort InterpolationCurve; // Read third - Always 0 (linear interpolation) in all 1848 keys
}

View File

@@ -0,0 +1,5 @@
<Project Sdk="Microsoft.NET.Sdk">
<ItemGroup>
<ProjectReference Include="..\Common\Common.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,176 @@
using System.Buffers.Binary;
using System.Text;
namespace MaterialLib;
public static class MaterialParser
{
public static MaterialFile ReadFromStream(Stream fs, string fileName, int elementCount, int magic1)
{
var file = new MaterialFile
{
FileName = fileName,
Version = elementCount,
Magic1 = magic1
};
// Derived fields
file.MaterialRenderingType = elementCount >> 2 & 0xf;
file.SupportsBumpMapping = (elementCount & 2) != 0;
file.IsParticleEffect = elementCount & 40;
// Reading content
var stageCount = fs.ReadUInt16LittleEndian();
var animCount = fs.ReadUInt16LittleEndian();
uint magic = (uint)magic1;
// Defaults found in C code
file.GlobalAlphaMultiplier = 1.0f; // field8_0x15c
file.GlobalEmissiveIntensity = 0.0f; // field9_0x160
file.SourceBlendMode = BlendMode.Unknown; // field6_0x154
file.DestBlendMode = BlendMode.Unknown; // field7_0x158
if (magic >= 2)
{
file.SourceBlendMode = (BlendMode)fs.ReadByte();
file.DestBlendMode = (BlendMode)fs.ReadByte();
}
if (magic > 2)
{
file.GlobalAlphaMultiplier = fs.ReadFloatLittleEndian();
}
if (magic > 3)
{
file.GlobalEmissiveIntensity = fs.ReadFloatLittleEndian();
}
// --- 2. Material Stages ---
const float Inv255 = 1.0f / 255.0f;
const float Field7Mult = 0.01f;
Span<byte> textureNameBuffer = stackalloc byte[16];
for (int i = 0; i < stageCount; i++)
{
var stage = new MaterialStage();
// === FILE READ ORDER (matches decompiled.c lines 159-217) ===
// 1. Ambient (4 bytes, A scaled by 0.01) - Lines 159-168
stage.AmbientR = fs.ReadByte() * Inv255;
stage.AmbientG = fs.ReadByte() * Inv255;
stage.AmbientB = fs.ReadByte() * Inv255;
stage.AmbientA = fs.ReadByte() * Field7Mult; // 0.01 scaling
// 2. Diffuse (4 bytes) - Lines 171-180
stage.DiffuseR = fs.ReadByte() * Inv255;
stage.DiffuseG = fs.ReadByte() * Inv255;
stage.DiffuseB = fs.ReadByte() * Inv255;
stage.DiffuseA = fs.ReadByte() * Inv255;
// 3. Specular (4 bytes) - Lines 183-192
stage.SpecularR = fs.ReadByte() * Inv255;
stage.SpecularG = fs.ReadByte() * Inv255;
stage.SpecularB = fs.ReadByte() * Inv255;
stage.SpecularA = fs.ReadByte() * Inv255;
// 4. Emissive (4 bytes) - Lines 195-204
stage.EmissiveR = fs.ReadByte() * Inv255;
stage.EmissiveG = fs.ReadByte() * Inv255;
stage.EmissiveB = fs.ReadByte() * Inv255;
stage.EmissiveA = fs.ReadByte() * Inv255;
// 5. Power (1 byte → float) - Line 207
stage.Power = (float)fs.ReadByte();
// 6. Texture Stage Index (1 byte) - Line 210
stage.TextureStageIndex = fs.ReadByte();
// 7. Texture Name (16 bytes) - Lines 212-217
textureNameBuffer.Clear();
fs.ReadExactly(textureNameBuffer);
stage.TextureName = Encoding.ASCII.GetString(textureNameBuffer).TrimEnd('\0');
file.Stages.Add(stage);
}
// --- 3. Animations ---
for (int i = 0; i < animCount; i++)
{
var anim = new MaterialAnimation();
uint typeAndParams = fs.ReadUInt32LittleEndian();
anim.Target = (AnimationTarget)(typeAndParams >> 3);
anim.LoopMode = (AnimationLoopMode)(typeAndParams & 7);
ushort keyCount = fs.ReadUInt16LittleEndian();
for (int k = 0; k < keyCount; k++)
{
var key = new AnimKey
{
StageIndex = fs.ReadUInt16LittleEndian(),
DurationMs = fs.ReadUInt16LittleEndian(),
InterpolationCurve = fs.ReadUInt16LittleEndian()
};
anim.Keys.Add(key);
}
// Precompute description for UI to avoid per-frame allocations
anim.TargetDescription = ComputeTargetDescription(anim.Target);
file.Animations.Add(anim);
}
return file;
}
private static string ComputeTargetDescription(AnimationTarget target)
{
// Precompute the description once during parsing
if ((int)target == 0)
return "No interpolation - entire stage is copied as-is (Flags: 0x0)";
var parts = new List<string>();
if ((target & AnimationTarget.Ambient) != 0)
parts.Add("Ambient RGB");
if ((target & AnimationTarget.Diffuse) != 0)
parts.Add("Diffuse RGB");
if ((target & AnimationTarget.Specular) != 0)
parts.Add("Specular RGB");
if ((target & AnimationTarget.Emissive) != 0)
parts.Add("Emissive RGB");
if ((target & AnimationTarget.Power) != 0)
parts.Add("Ambient.A + Power");
return $"Interpolates: {string.Join(", ", parts)} | Other components copied (Flags: 0x{(int)target:X})";
}
}
// Helper extensions
internal static class StreamExtensions
{
public static float ReadFloatLittleEndian(this Stream stream)
{
Span<byte> buffer = stackalloc byte[4];
stream.ReadExactly(buffer);
return BinaryPrimitives.ReadSingleLittleEndian(buffer);
}
public static ushort ReadUInt16LittleEndian(this Stream stream)
{
Span<byte> buffer = stackalloc byte[2];
stream.ReadExactly(buffer);
return BinaryPrimitives.ReadUInt16LittleEndian(buffer);
}
public static uint ReadUInt32LittleEndian(this Stream stream)
{
Span<byte> buffer = stackalloc byte[4];
stream.ReadExactly(buffer);
return BinaryPrimitives.ReadUInt32LittleEndian(buffer);
}
}

290
MaterialLib/decompiled.c Normal file
View File

@@ -0,0 +1,290 @@
/* returns index into g_MaterialGlobalDescriptors */
int __fastcall LoadMaterialByName(char *itemname)
{
char *pcVar1;
undefined1 *puVar2;
byte *pbVar3;
uint uVar4;
undefined4 *puVar5;
int iVar6;
int iVar7;
MaterialGlobalDescriptor_ptr_4_undefined4 piVar8;
nres_metadata_item *pnVar8;
int iVar9;
MaterialStageWorldDllInternal *pMVar10;
int iVar11;
ITexture **ppIVar12;
MaterialAnimationKey *pMVar13;
MaterialGlobalDescriptor *pMVar14;
float unaff_EBX;
MaterialStageExternal *pfVar16;
ushort unaff_DI;
MaterialAnimation *pMVar15;
uint uVar16;
int iStack_90;
uint uStack_8c;
char acStack_88 [8];
int iStack_80;
char acStack_58 [88];
iVar6 = (*(*g_material_resfile)->get_index_in_file_by_itemname)(g_material_resfile,itemname);
if (iVar6 < 0) {
sprintf(acStack_58,s_Material_%s_not_found._100246f8,itemname);
/* WARNING: Subroutine does not return */
write_error_to_file_and_msgbox(acStack_58,(void *)0x0);
}
iVar7 = 0;
if (0 < g_MaterialGlobalDescriptor_count) {
pMVar14 = g_MaterialGlobalDescriptors;
do {
if (pMVar14->index_in_file == iVar6) {
if (-1 < iVar7) {
g_MaterialGlobalDescriptors[iVar7].RefCount =
g_MaterialGlobalDescriptors[iVar7].RefCount + 1;
return iVar7;
}
break;
}
iVar7 += 1;
pMVar14 = pMVar14 + 1;
} while (iVar7 < g_MaterialGlobalDescriptor_count);
}
iVar7 = 0;
if (0 < g_MaterialGlobalDescriptor_count) {
piVar8 = &g_MaterialGlobalDescriptors[0].RefCount;
do {
if (ADJ(piVar8)->RefCount == 0) break;
iVar7 += 1;
piVar8 = piVar8 + 0x5c;
} while (iVar7 < g_MaterialGlobalDescriptor_count);
}
if (iVar7 == g_MaterialGlobalDescriptor_count) {
g_MaterialGlobalDescriptor_count += 1;
}
iStack_80 = iVar7;
g_currentMaterialFileData_ptr =
(*(*g_material_resfile)->get_item_data_ptr_by_index)(g_material_resfile,iVar6,1);
pnVar8 = (*(*g_material_resfile)->get_metadata_ptr)(g_material_resfile);
uVar16 = 0;
uVar4 = pnVar8[iVar6].magic1;
if ((pnVar8[iVar6].element_count_or_version & 1) != 0) {
uVar16 = 0x200000;
}
g_MaterialGlobalDescriptors[iVar7].extra_meta.field0_0x0 = 0;
g_MaterialGlobalDescriptors[iVar7].extra_meta.field2_0x8 = 0;
g_MaterialGlobalDescriptors[iVar7].extra_meta.field1_0x4 =
pnVar8[iVar6].element_count_or_version >> 2 & 0xf;
iVar9 = g_bumpmapping_enabled_value;
if (((pnVar8[iVar6].element_count_or_version & 2) != 0) &&
((g_MaterialGlobalDescriptors[iVar7].extra_meta.field0_0x0 = 1, iVar9 == 0 ||
(g_supports_texture_mode_6 == 0)))) {
uVar16 |= 0x80000;
}
if ((pnVar8[iVar6].element_count_or_version & 0x40) != 0) {
g_MaterialGlobalDescriptors[iVar7].extra_meta.field2_0x8 = 1;
}
iVar9 = 0;
g_MaterialGlobalDescriptors[iVar7].RefCount = g_MaterialGlobalDescriptors[iVar7].RefCount + 1;
puVar5 = g_currentMaterialFileData_ptr;
g_MaterialGlobalDescriptors[iVar7].index_in_file = iVar6;
iVar6 = 0;
do {
pcVar1 = (char *)(iVar9 + (int)puVar5);
iVar9 += 1;
acStack_88[iVar6 + -0x1c] = *pcVar1;
iVar6 += 1;
} while (iVar6 < 2);
g_MaterialGlobalDescriptors[iVar7].stageCount = (uint)unaff_DI;
iVar6 = 0;
do {
iVar11 = iVar9;
iVar9 = iVar11 + 1;
acStack_88[iVar6 + -0x1c] = *(char *)(iVar11 + (int)puVar5);
iVar6 += 1;
} while (iVar6 < 2);
DAT_10128674 = iVar9;
g_MaterialGlobalDescriptors[iVar7].animCount = (uint)unaff_DI;
if (0x13 < unaff_DI) {
/* WARNING: Subroutine does not return */
write_error_to_file_and_msgbox(s_Too_many_animations_for_material_100246cc,(void *)0x0);
}
g_MaterialGlobalDescriptors[iVar7].field8_0x15c = 1.0;
g_MaterialGlobalDescriptors[iVar7].field9_0x160 = 0;
if (uVar4 < 2) {
g_MaterialGlobalDescriptors[iVar7].field6_0x154 = 0xff;
g_MaterialGlobalDescriptors[iVar7].field7_0x158 = 0xff;
}
else {
g_MaterialGlobalDescriptors[iVar7].field6_0x154 = (uint)*(byte *)(iVar9 + (int)puVar5);
iVar6 = iVar11 + 3;
DAT_10128674 = iVar6;
g_MaterialGlobalDescriptors[iVar7].field7_0x158 = (uint)*(byte *)(iVar11 + 2 + (int)puVar5);
if (2 < uVar4) {
iVar9 = 0;
do {
puVar2 = (undefined1 *)(iVar6 + (int)puVar5);
iVar6 += 1;
(&stack0xffffff68)[iVar9] = *puVar2;
iVar9 += 1;
} while (iVar9 < 4);
DAT_10128674 = iVar6;
g_MaterialGlobalDescriptors[iVar7].field8_0x15c = unaff_EBX;
if (3 < uVar4) {
iVar9 = 0;
do {
puVar2 = (undefined1 *)(iVar6 + (int)puVar5);
iVar6 += 1;
(&stack0xffffff68)[iVar9] = *puVar2;
iVar9 += 1;
} while (iVar9 < 4);
DAT_10128674 = iVar6;
g_MaterialGlobalDescriptors[iVar7].field9_0x160 = unaff_EBX;
}
}
}
pMVar10 = (MaterialStageWorldDllInternal *)
_malloc(g_MaterialGlobalDescriptors[iVar7].stageCount * 0x4c);
g_MaterialGlobalDescriptors[iVar7].stages = pMVar10;
iVar6 = 0;
if (0 < g_MaterialGlobalDescriptors[iVar7].stageCount) {
iVar9 = 0;
do {
pfVar16 = (MaterialStageExternal *)
((int)&((g_MaterialGlobalDescriptors[iVar7].stages)->diffuse).R + iVar9);
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->ambient).R = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->ambient).G = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->ambient).B = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->ambient).A = (float)*pbVar3 * 0.01;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->diffuse).R = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->diffuse).G = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->diffuse).B = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->diffuse).A = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->specular).R = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->specular).G = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->specular).B = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->specular).A = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->emissive).R = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->emissive).G = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->emissive).B = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
(pfVar16->emissive).A = (float)*pbVar3 * 1/255f;
pbVar3 = (byte *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
pfVar16->Power = (float)(uint)*pbVar3;
pcVar1 = (char *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 = DAT_10128674 + 1;
pfVar16->current_m_LL_ITexture = (ITexture **)(int)*pcVar1;
iVar11 = 0;
do {
pcVar1 = (char *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
acStack_88[iVar11] = *pcVar1;
iVar11 += 1;
} while (iVar11 < 0x10);
if (acStack_88[0] == '\0') {
pfVar16->m_LL_ITexture = (ITexture **)0xffffffff;
pfVar16->current_m_LL_ITexture = (ITexture **)0xffffffff;
}
else {
ppIVar12 = (ITexture **)LoadAndCacheTexture(acStack_88,uVar16);
pfVar16->m_LL_ITexture = ppIVar12;
}
iVar6 += 1;
iVar9 += 0x4c;
} while (iVar6 < g_MaterialGlobalDescriptors[iVar7].stageCount);
}
iVar6 = 0;
if (0 < g_MaterialGlobalDescriptors[iVar7].animCount) {
pMVar15 = g_MaterialGlobalDescriptors[iVar7].animations;
do {
puVar5 = g_currentMaterialFileData_ptr;
iVar9 = 0;
do {
pcVar1 = (char *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
acStack_88[iVar9 + -4] = *pcVar1;
iVar9 += 1;
} while (iVar9 < 4);
pMVar15->FieldSelector = (int)uStack_8c >> 3;
pMVar15->loop_mode = uStack_8c & 7;
iVar9 = 0;
do {
pcVar1 = (char *)(DAT_10128674 + (int)puVar5);
DAT_10128674 += 1;
acStack_88[iVar9 + -0x1c] = *pcVar1;
iVar9 += 1;
} while (iVar9 < 2);
pMVar15->keyCount = (uint)unaff_DI;
pMVar13 = (MaterialAnimationKey *)_malloc((uint)unaff_DI << 3);
pMVar15->keys = pMVar13;
iVar9 = 0;
if (0 < (int)pMVar15->keyCount) {
do {
iVar11 = 0;
do {
pcVar1 = (char *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
acStack_88[iVar11 + -0x1c] = *pcVar1;
iVar11 += 1;
} while (iVar11 < 2);
pMVar15->keys[iVar9].stage_index = (uint)unaff_DI;
iVar11 = 0;
do {
pcVar1 = (char *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
acStack_88[iVar11 + -0x1c] = *pcVar1;
iVar11 += 1;
} while (iVar11 < 2);
pMVar15->keys[iVar9].duration_ms = unaff_DI;
iVar11 = 0;
do {
pcVar1 = (char *)(DAT_10128674 + (int)g_currentMaterialFileData_ptr);
DAT_10128674 += 1;
acStack_88[iVar11 + -0x1c] = *pcVar1;
iVar11 += 1;
} while (iVar11 < 2);
pMVar15->keys[iVar9].field2_0x6 = unaff_DI;
iVar9 += 1;
} while (iVar9 < (int)pMVar15->keyCount);
}
iVar6 += 1;
pMVar15 = pMVar15 + 1;
} while (iVar6 < g_MaterialGlobalDescriptors[iVar7].animCount);
}
return iStack_90;
}