33using System . Collections . Generic ;
44using System . IO ;
55using System . Runtime . InteropServices ;
6+ using static CATHODE . LEGACY . ShadersPAK ;
67
78namespace CATHODE
89{
910 /* DATA/ENV/PRODUCTION/x/RENDERABLE/LEVEL_SHADERS_DX11.PAK & LEVEL_SHADERS_DX11_BIN.PAK & LEVEL_SHADERS_DX11_IDX_REMAP.PAK */
1011 public class Shaders : CathodeFile
1112 {
13+ public List < Shader > Entries = new List < Shader > ( ) ;
1214 public static new Implementation Implementation = Implementation . NONE ;
1315 public Shaders ( string path ) : base ( path ) { }
1416
@@ -25,71 +27,132 @@ override protected bool LoadInternal()
2527 if ( ! File . Exists ( _filepathBIN ) ) return false ;
2628 if ( ! File . Exists ( _filepathIDX ) ) return false ;
2729
28- using ( BinaryReader reader = new BinaryReader ( File . OpenRead ( _filepathBIN ) ) )
30+ List < Utilities . PAKContent > content = Utilities . ReadPAK ( _filepathBIN , FileIdentifiers . SHADER_DATA ) ;
31+ for ( int i = 0 ; i < content . Count ; i ++ )
2932 {
30- reader . BaseStream . Position = 4 ; //skip magic
31- if ( ( FileIdentifiers ) reader . ReadInt32 ( ) != FileIdentifiers . ASSET_FILE ) return false ;
32- if ( ( FileIdentifiers ) reader . ReadInt32 ( ) != FileIdentifiers . SHADER_DATA ) return false ;
33- int binEntryCount = reader . ReadInt32 ( ) ;
34- if ( BigEndianUtils . ReadInt32 ( reader ) != binEntryCount ) return false ;
35-
36- //Skip rest of the main header
37- reader . BaseStream . Position = 32 ;
38-
39- //Pull each entry's individual header
40- List < CathodeShaderHeader > _header = new List < CathodeShaderHeader > ( ) ;
41- for ( int i = 0 ; i < binEntryCount ; i ++ )
42- {
43- CathodeShaderHeader newStringEntry = new CathodeShaderHeader ( ) ;
44- reader . BaseStream . Position += 8 ; //skip blanks
45-
46- newStringEntry . FileLength = reader . ReadInt32 ( ) ;
47- newStringEntry . FileLengthWithPadding = reader . ReadInt32 ( ) ;
48- newStringEntry . FileOffset = reader . ReadInt32 ( ) ;
49-
50- reader . BaseStream . Position += 8 ; //skip blanks
51-
52- newStringEntry . StringPart1 = reader . ReadBytes ( 4 ) ;
53- newStringEntry . FileIndex = reader . ReadInt32 ( ) ; //potentially actually int8 or int16 not 32
54-
55- reader . BaseStream . Position += 8 ; //skip blanks
33+ if ( content [ i ] . BinIndex != i ) return false ;
5634
57- newStringEntry . StringPart2 = reader . ReadBytes ( 4 ) ;
58-
59- //TEMP: For now I'm just setting the filename to be the index... need to work out how the _BIN relates to the initial .PAK to get names, etc
60- newStringEntry . FileName = newStringEntry . FileIndex + ".DXBC" ;
61- //END OF TEMP
62-
63- _header . Add ( newStringEntry ) ;
64- }
65- int endOfHeaders = ( int ) reader . BaseStream . Position ;
66-
67- //Pull each entry's file content
68- foreach ( CathodeShaderHeader shaderEntry in _header )
35+ using ( BinaryReader reader = new BinaryReader ( new MemoryStream ( content [ i ] . Data ) ) )
6936 {
70- reader . BaseStream . Position = shaderEntry . FileOffset + endOfHeaders ;
71- shaderEntry . FileContent = reader . ReadBytes ( shaderEntry . FileLength ) ;
37+
7238 }
7339 }
7440
75- using ( BinaryReader reader = new BinaryReader ( File . OpenRead ( _filepathIDX ) ) )
41+ //Read the index remapping pak (this is actually just an incrementing count lol)
42+ content = Utilities . ReadPAK ( _filepathIDX , FileIdentifiers . SHADER_DATA ) ;
43+ for ( int i = 0 ; i < content . Count ; i ++ )
7644 {
45+ if ( content [ i ] . BinIndex != i ) return false ;
7746
47+ using ( BinaryReader reader = new BinaryReader ( new MemoryStream ( content [ i ] . Data ) ) )
48+ {
49+ int index = reader . ReadInt32 ( ) ;
50+ if ( index != i ) return false ;
51+ }
7852 }
7953
80- using ( BinaryReader reader = new BinaryReader ( File . OpenRead ( _filepath ) ) )
54+ content = Utilities . ReadPAK ( _filepath , FileIdentifiers . SHADER_DATA ) ;
55+ for ( int i = 0 ; i < content . Count ; i ++ )
8156 {
82- reader . BaseStream . Position += 4 ; //Skip unused
83- if ( ( FileIdentifiers ) reader . ReadInt32 ( ) != FileIdentifiers . ASSET_FILE ) return false ;
84- if ( ( FileIdentifiers ) reader . ReadInt32 ( ) != FileIdentifiers . SHADER_DATA ) return false ;
85- int pakEntryCount = reader . ReadInt32 ( ) ;
86- if ( BigEndianUtils . ReadInt32 ( reader ) != pakEntryCount ) return false ;
57+ using ( BinaryReader reader = new BinaryReader ( new MemoryStream ( content [ i ] . Data ) ) )
58+ {
59+ reader . BaseStream . Position = 8 ; //0x7725BBA4, 36, 1
60+
61+ int textureCount = reader . ReadInt16 ( ) ;
62+ int [ ] cstCounts = new int [ 5 ] ;
63+ for ( int x = 0 ; x < 5 ; x ++ ) cstCounts [ x ] = reader . ReadInt32 ( ) ;
64+ int textureLinkCount = reader . ReadInt16 ( ) ;
65+ string name = Utilities . ReadString ( reader . ReadBytes ( 40 ) ) ;
66+ ShaderCategory category = ( ShaderCategory ) reader . ReadInt16 ( ) ;
67+
68+ // Index 0: 0x04: seems to be metal. 0x01: seems to be non-metal. But it has many exceptions so maybe check renderdoc.
69+ // Index 1: ParallaxMap? It seems to be either 0x30 and 0x80 for the most part, sometimes it combines both into 0xB0.
70+ // Index 2: Lower part of this byte is NormalMap0 related! 0x04 means it has normal map 0. No hits for 1, 2 or 8 yet.
71+ // 0x03 is a thing, but not normal map. What is it? Can be 0x07 where it has normal map and both the 0x03 thing.
72+ // 0x0C is also a thing (8 and 4), so it has normal map and something else?
73+ // I'm gonna say 0x03 means DiffuseMap1.
74+ // Index 3: 0x04 Not OcclusionTint. (NormalMap0 + NormalMap0UVMultiplier + NormalMap0Strength?)
75+ // Index 4: Seems to tell me about AO. If 4, then it has AO tint. If 1 it has AO texture.
76+ // Index 6: Seems to tell me about Dirt/OpacityNoise.
77+ // 0x19 (0001 1001): has opacity noise and dirt maps.
78+ // 0x38 (0011 1000): has dirt map.
79+ // 0x39 (0011 1001): has opacity noise and dirt maps.
80+ // Index 10: First half, only found 4, and it seems to be something included in all (Diffuse0 as well?).
81+ // Seems like the least significant bit enables/disables opacity noise?
82+ int [ ] flags = new int [ 20 ] ;
83+ for ( int x = 0 ; x < 20 ; x ++ ) flags [ x ] = reader . ReadByte ( ) ;
84+
85+ int unk = reader . ReadInt32 ( ) ;
86+
87+ int entryCount = reader . ReadInt16 ( ) ;
88+ for ( int x = 0 ; x < entryCount ; x ++ )
89+ {
90+ int unk1 = reader . ReadInt16 ( ) ;
91+ int unk2 = reader . ReadInt32 ( ) ;
92+ }
93+
94+ for ( int x = 0 ; x < textureCount ; x ++ )
95+ {
96+ int unk1 = reader . ReadByte ( ) ;
97+ int unk2 = reader . ReadByte ( ) ;
98+ int [ ] unk3 = new int [ 16 ] ;
99+ for ( int z = 0 ; z < 16 ; z ++ ) unk3 [ z ] = reader . ReadInt16 ( ) ;
100+ float unk4 = reader . ReadSingle ( ) ;
101+ int unk5 = reader . ReadInt16 ( ) ;
102+ float unk6 = reader . ReadSingle ( ) ;
103+ }
104+
105+ for ( int x = 0 ; x < textureCount ; x ++ )
106+ {
107+ int unk1 = reader . ReadByte ( ) ;
108+ }
109+
110+ int [ ] [ ] cstLinks = new int [ 5 ] [ ] ;
111+ for ( int x = 0 ; x < 5 ; x ++ )
112+ {
113+ cstLinks [ x ] = new int [ cstCounts [ x ] ] ;
114+ for ( int z = 0 ; z < cstCounts [ x ] ; z ++ )
115+ {
116+ cstLinks [ x ] [ z ] = reader . ReadByte ( ) ;
117+ }
118+ }
119+
120+ int [ ] textureLinks = new int [ textureLinkCount ] ;
121+ for ( int x = 0 ; x < textureLinkCount ; x ++ )
122+ {
123+ textureLinks [ x ] = reader . ReadByte ( ) ;
124+ }
125+
126+ int vertexShader = reader . ReadInt32 ( ) ;
127+ int pixelShader = reader . ReadInt32 ( ) ;
128+ int hullShader = reader . ReadInt32 ( ) ;
129+ int domainShader = reader . ReadInt32 ( ) ;
130+
131+ //Interestingly, seems like neither of these are used
132+ int geometryShader = reader . ReadInt32 ( ) ;
133+ int computeShader = reader . ReadInt32 ( ) ;
134+ }
87135 }
136+
88137 return true ;
89138 }
90139
91140 override protected bool SaveInternal ( )
92141 {
142+ using ( BinaryWriter writer = new BinaryWriter ( File . OpenWrite ( _filepathBIN ) ) )
143+ {
144+
145+ }
146+ using ( BinaryWriter writer = new BinaryWriter ( File . OpenWrite ( _filepathIDX ) ) )
147+ {
148+ writer . BaseStream . SetLength ( 0 ) ;
149+ writer . Write ( 0 ) ;
150+ writer . Write ( ( int ) FileIdentifiers . ASSET_FILE ) ;
151+ writer . Write ( ( int ) FileIdentifiers . MODEL_DATA ) ;
152+ writer . Write ( Entries . Count ) ;
153+ writer . Write ( Entries . Count ) ;
154+ writer . Write ( new byte [ 12 ] ) ;
155+ }
93156 using ( BinaryWriter writer = new BinaryWriter ( File . OpenWrite ( _filepath ) ) )
94157 {
95158
@@ -99,7 +162,7 @@ override protected bool SaveInternal()
99162 #endregion
100163
101164 #region STRUCTURES
102- public class CathodeShaderHeader
165+ public class Shader
103166 {
104167 public string FileName = "" ; //The name of the file in the shader archive (unsure how to get this right now with the weird _BIN/PAK way of working)
105168
@@ -111,6 +174,7 @@ public class CathodeShaderHeader
111174
112175 public byte [ ] FileContent ; //The content for the file
113176
177+ //I think this is just garbage that got dumped by accident
114178 public byte [ ] StringPart1 ; //4 bytes that look like they're part of a filepath
115179 public byte [ ] StringPart2 ; //4 bytes that look like they're part of a filepath
116180 }
0 commit comments