├── .gitignore ├── README.md ├── RenderWareFile.sln └── RenderWareFile ├── Enums ├── BinMeshHeaderFlags.cs ├── NativeDataType.cs ├── Section.cs ├── TextureAddressMode.cs ├── TextureFilterMode.cs ├── TexturePlatformID.cs └── TextureRasterFormat.cs ├── GenericSection.cs ├── Other ├── Color.cs ├── Matrix3x3.cs ├── NativeDataGC.cs ├── Triangle.cs ├── Vertex2.cs └── Vertex3.cs ├── Properties └── AssemblyInfo.cs ├── RWSection.cs ├── ReadFileMethods.cs ├── RenderWareFile.csproj ├── Sections ├── AtomicSector_0009.cs ├── Atomic_0014.cs ├── BinMeshPLG_050E.cs ├── Clump_0010.cs ├── ColTree_002C.cs ├── CollisionPLG_011D.cs ├── CollisionPLG_011D_Scooby.cs ├── Extension_0003.cs ├── FrameList_000E.cs ├── GeometryList_001A.cs ├── Geometry_000F.cs ├── MaterialEffectsPLG_0120.cs ├── MaterialList_0008.cs ├── Material_0007.cs ├── NativeDataPLG_0510.cs ├── PlaneSection_000A.cs ├── String_0002.cs ├── Structs │ ├── AtomicSectorStruct_0001.cs │ ├── AtomicStruct_0001.cs │ ├── ClumpStruct_0001.cs │ ├── ColTreeStruct_0001.cs │ ├── FrameListStruct_0001.cs │ ├── GeometryListStruct_0001.cs │ ├── GeometryStruct_0001.cs │ ├── MaterialListStruct_0001.cs │ ├── MaterialStruct_0001.cs │ ├── NativeDataStruct_0001.cs │ ├── PlaneStruct_0001.cs │ ├── TextureDictionaryStruct_0001.cs │ ├── TextureNativeStruct_0001.cs │ ├── TextureStruct_0001.cs │ └── WorldStruct_0001.cs ├── TextureDictionary_0016.cs ├── TextureNative_0015.cs ├── Texture_0006.cs ├── UserDataPLG_011F.cs └── World_000B.cs └── Shared.cs /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | ## 4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore 5 | 6 | # User-specific files 7 | *.suo 8 | *.user 9 | *.userosscache 10 | *.sln.docstates 11 | 12 | # User-specific files (MonoDevelop/Xamarin Studio) 13 | *.userprefs 14 | 15 | # Build results 16 | [Dd]ebug/ 17 | [Dd]ebugPublic/ 18 | [Rr]elease/ 19 | [Rr]eleases/ 20 | x64/ 21 | x86/ 22 | bld/ 23 | [Bb]in/ 24 | [Oo]bj/ 25 | [Ll]og/ 26 | 27 | # Visual Studio 2015 cache/options directory 28 | .vs/ 29 | # Uncomment if you have tasks that create the project's static files in wwwroot 30 | #wwwroot/ 31 | 32 | # MSTest test Results 33 | [Tt]est[Rr]esult*/ 34 | [Bb]uild[Ll]og.* 35 | 36 | # NUNIT 37 | *.VisualState.xml 38 | TestResult.xml 39 | 40 | # Build Results of an ATL Project 41 | [Dd]ebugPS/ 42 | [Rr]eleasePS/ 43 | dlldata.c 44 | 45 | # .NET Core 46 | project.lock.json 47 | project.fragment.lock.json 48 | artifacts/ 49 | **/Properties/launchSettings.json 50 | 51 | *_i.c 52 | *_p.c 53 | *_i.h 54 | *.ilk 55 | *.meta 56 | *.obj 57 | *.pch 58 | *.pdb 59 | *.pgc 60 | *.pgd 61 | *.rsp 62 | *.sbr 63 | *.tlb 64 | *.tli 65 | *.tlh 66 | *.tmp 67 | *.tmp_proj 68 | *.log 69 | *.vspscc 70 | *.vssscc 71 | .builds 72 | *.pidb 73 | *.svclog 74 | *.scc 75 | 76 | # Chutzpah Test files 77 | _Chutzpah* 78 | 79 | # Visual C++ cache files 80 | ipch/ 81 | *.aps 82 | *.ncb 83 | *.opendb 84 | *.opensdf 85 | *.sdf 86 | *.cachefile 87 | *.VC.db 88 | *.VC.VC.opendb 89 | 90 | # Visual Studio profiler 91 | *.psess 92 | *.vsp 93 | *.vspx 94 | *.sap 95 | 96 | # TFS 2012 Local Workspace 97 | $tf/ 98 | 99 | # Guidance Automation Toolkit 100 | *.gpState 101 | 102 | # ReSharper is a .NET coding add-in 103 | _ReSharper*/ 104 | *.[Rr]e[Ss]harper 105 | *.DotSettings.user 106 | 107 | # JustCode is a .NET coding add-in 108 | .JustCode 109 | 110 | # TeamCity is a build add-in 111 | _TeamCity* 112 | 113 | # DotCover is a Code Coverage Tool 114 | *.dotCover 115 | 116 | # Visual Studio code coverage results 117 | *.coverage 118 | *.coveragexml 119 | 120 | # NCrunch 121 | _NCrunch_* 122 | .*crunch*.local.xml 123 | nCrunchTemp_* 124 | 125 | # MightyMoose 126 | *.mm.* 127 | AutoTest.Net/ 128 | 129 | # Web workbench (sass) 130 | .sass-cache/ 131 | 132 | # Installshield output folder 133 | [Ee]xpress/ 134 | 135 | # DocProject is a documentation generator add-in 136 | DocProject/buildhelp/ 137 | DocProject/Help/*.HxT 138 | DocProject/Help/*.HxC 139 | DocProject/Help/*.hhc 140 | DocProject/Help/*.hhk 141 | DocProject/Help/*.hhp 142 | DocProject/Help/Html2 143 | DocProject/Help/html 144 | 145 | # Click-Once directory 146 | publish/ 147 | 148 | # Publish Web Output 149 | *.[Pp]ublish.xml 150 | *.azurePubxml 151 | # TODO: Comment the next line if you want to checkin your web deploy settings 152 | # but database connection strings (with potential passwords) will be unencrypted 153 | *.pubxml 154 | *.publishproj 155 | 156 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 157 | # checkin your Azure Web App publish settings, but sensitive information contained 158 | # in these scripts will be unencrypted 159 | PublishScripts/ 160 | 161 | # NuGet Packages 162 | *.nupkg 163 | # The packages folder can be ignored because of Package Restore 164 | **/packages/* 165 | # except build/, which is used as an MSBuild target. 166 | !**/packages/build/ 167 | # Uncomment if necessary however generally it will be regenerated when needed 168 | #!**/packages/repositories.config 169 | # NuGet v3's project.json files produces more ignorable files 170 | *.nuget.props 171 | *.nuget.targets 172 | 173 | # Microsoft Azure Build Output 174 | csx/ 175 | *.build.csdef 176 | 177 | # Microsoft Azure Emulator 178 | ecf/ 179 | rcf/ 180 | 181 | # Windows Store app package directories and files 182 | AppPackages/ 183 | BundleArtifacts/ 184 | Package.StoreAssociation.xml 185 | _pkginfo.txt 186 | 187 | # Visual Studio cache files 188 | # files ending in .cache can be ignored 189 | *.[Cc]ache 190 | # but keep track of directories ending in .cache 191 | !*.[Cc]ache/ 192 | 193 | # Others 194 | ClientBin/ 195 | ~$* 196 | *~ 197 | *.dbmdl 198 | *.dbproj.schemaview 199 | *.jfm 200 | *.pfx 201 | *.publishsettings 202 | orleans.codegen.cs 203 | 204 | # Since there are multiple workflows, uncomment next line to ignore bower_components 205 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 206 | #bower_components/ 207 | 208 | # RIA/Silverlight projects 209 | Generated_Code/ 210 | 211 | # Backup & report files from converting an old project file 212 | # to a newer Visual Studio version. Backup files are not needed, 213 | # because we have git ;-) 214 | _UpgradeReport_Files/ 215 | Backup*/ 216 | UpgradeLog*.XML 217 | UpgradeLog*.htm 218 | 219 | # SQL Server files 220 | *.mdf 221 | *.ldf 222 | *.ndf 223 | 224 | # Business Intelligence projects 225 | *.rdl.data 226 | *.bim.layout 227 | *.bim_*.settings 228 | 229 | # Microsoft Fakes 230 | FakesAssemblies/ 231 | 232 | # GhostDoc plugin setting file 233 | *.GhostDoc.xml 234 | 235 | # Node.js Tools for Visual Studio 236 | .ntvs_analysis.dat 237 | node_modules/ 238 | 239 | # Typescript v1 declaration files 240 | typings/ 241 | 242 | # Visual Studio 6 build log 243 | *.plg 244 | 245 | # Visual Studio 6 workspace options file 246 | *.opt 247 | 248 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.) 249 | *.vbw 250 | 251 | # Visual Studio LightSwitch build output 252 | **/*.HTMLClient/GeneratedArtifacts 253 | **/*.DesktopClient/GeneratedArtifacts 254 | **/*.DesktopClient/ModelManifest.xml 255 | **/*.Server/GeneratedArtifacts 256 | **/*.Server/ModelManifest.xml 257 | _Pvt_Extensions 258 | 259 | # Paket dependency manager 260 | .paket/paket.exe 261 | paket-files/ 262 | 263 | # FAKE - F# Make 264 | .fake/ 265 | 266 | # JetBrains Rider 267 | .idea/ 268 | *.sln.iml 269 | 270 | # CodeRush 271 | .cr/ 272 | 273 | # Python Tools for Visual Studio (PTVS) 274 | __pycache__/ 275 | *.pyc 276 | 277 | # Cake - Uncomment if you are using it 278 | # tools/** 279 | # !tools/packages.config 280 | 281 | # Telerik's JustMock configuration file 282 | *.jmconfig 283 | 284 | # BizTalk build output 285 | *.btp.cs 286 | *.btm.cs 287 | *.odx.cs 288 | *.xsd.cs 289 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | RenderWareFile is a small library for working with RenderWare binary files. 2 | -------------------------------------------------------------------------------- /RenderWareFile.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27130.2036 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderWareFile", "RenderWareFile\RenderWareFile.csproj", "{005F2D00-06DE-4EF9-BFEE-80EFAC49E114}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {005F2D00-06DE-4EF9-BFEE-80EFAC49E114}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {005F2D00-06DE-4EF9-BFEE-80EFAC49E114}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {005F2D00-06DE-4EF9-BFEE-80EFAC49E114}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {005F2D00-06DE-4EF9-BFEE-80EFAC49E114}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {CFDBC223-17AF-4B13-B18F-D3E44E7DE24B} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /RenderWareFile/Enums/BinMeshHeaderFlags.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile.Sections 2 | { 3 | public enum BinMeshHeaderFlags : int 4 | { 5 | TriangleList = 0x00000000, 6 | TriangleStrip = 0x00000001, 7 | TriangleFan = 0x00000002, 8 | LineList = 0x00000004, 9 | PolyLine = 0x00000008, 10 | PointList = 0x00000010, 11 | PrimitiveMask = 0x000000FF, 12 | Unindexed = 0x00000100 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RenderWareFile/Enums/NativeDataType.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile.Sections 2 | { 3 | public enum NativeDataType 4 | { 5 | OpenGL = 2, 6 | PS2 = 4, 7 | XBOX = 5, 8 | GameCube = 6 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /RenderWareFile/Enums/Section.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile 2 | { 3 | public enum Section : int 4 | { 5 | None = 0x0, 6 | Struct = 0x1, 7 | String = 0x2, 8 | Extension = 0x3, 9 | Texture = 0x6, 10 | Material = 0x7, 11 | MaterialList = 0x8, 12 | AtomicSector = 0x9, 13 | PlaneSector = 0xA, 14 | World = 0xB, 15 | FrameList = 0xE, 16 | Geometry = 0xF, 17 | Clump = 0x10, 18 | Atomic = 0x14, 19 | TextureNative = 0x15, 20 | TextureDictionary = 0x16, 21 | GeometryList = 0x1A, 22 | ChunkGroupStart = 0x29, 23 | ChunkGroupEnd = 0x2A, 24 | ColTree = 0x2C, 25 | MorphPLG = 0x105, 26 | SkyMipmapVal = 0x110, 27 | CollisionPLG = 0x11D, 28 | HAnimPLG = 0x11E, 29 | UserDataPLG = 0x11F, 30 | MaterialEffectsPLG = 0x120, 31 | BinMeshPLG = 0x50E, 32 | NativeDataPLG = 0x510, 33 | BFBB_CollisionData_Section1 = 0x00BEEF01, 34 | BFBB_CollisionData_Section2 = 0x00BEEF02, 35 | BFBB_CollisionData_Section3 = 0x00BEEF03, 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /RenderWareFile/Enums/TextureAddressMode.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile.Sections 2 | { 3 | public enum TextureAddressMode : byte 4 | { 5 | TEXTUREADDRESSNATEXTUREADDRESS = 0, // no tiling 6 | TEXTUREADDRESSWRAP = 1, // tile in U or V direction 7 | TEXTUREADDRESSMIRROR = 2, // mirror in U or V direction 8 | TEXTUREADDRESSCLAMP = 3, 9 | TEXTUREADDRESSBORDER = 4 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /RenderWareFile/Enums/TextureFilterMode.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile.Sections 2 | { 3 | public enum TextureFilterMode : byte 4 | { 5 | FILTERNAFILTERMODE = 0, // filtering is disabled 6 | FILTERNEAREST = 1, // Point sampled 7 | FILTERLINEAR = 2, // Bilinear 8 | FILTERMIPNEAREST = 3, // Point sampled per pixel mip map 9 | FILTERMIPLINEAR = 4, // Bilinear per pixel mipmap 10 | FILTERLINEARMIPNEAREST = 5, // MipMap interp point sampled 11 | FILTERLINEARMIPLINEAR = 6 // Trilinear 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /RenderWareFile/Enums/TexturePlatformID.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile.Sections 2 | { 3 | public enum TexturePlatformID : short 4 | { 5 | PLATFORM_ANY = 0, 6 | PLATFORM_D3D8 = 1, 7 | PLATFORM_D3D9 = 2, 8 | PLATFORM_GAMECUBE = 3, 9 | PLATFORM_NULL = 4, 10 | PLATFORM_OPENGL = 5, 11 | PLATFORM_PS2 = 6, 12 | PLATFORM_SOFTWARE_RASTER = 7, 13 | PLATFORM_XBOX = 8, 14 | PLATFORM_PSP = 9, 15 | } 16 | } -------------------------------------------------------------------------------- /RenderWareFile/Enums/TextureRasterFormat.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile.Sections 2 | { 3 | public enum TextureRasterFormat : int 4 | { 5 | RASTER_DEFAULT = 0, 6 | RASTER_C1555 = 0x0100, 7 | RASTER_C565 = 0x0200, 8 | RASTER_C4444 = 0x0300, 9 | RASTER_LUM8 = 0x0400, 10 | RASTER_C8888 = 0x0500, 11 | RASTER_C888 = 0x0600, 12 | RASTER_D16 = 0x0700, 13 | RASTER_D24 = 0x0800, 14 | RASTER_D32 = 0x0900, 15 | RASTER_C555 = 0x0A00, 16 | RASTER_AUTOMIPMAP = 0x1000, 17 | RASTER_PAL8 = 0x2000, 18 | RASTER_PAL4 = 0x4000, 19 | RASTER_MIPMAP = 0x8000 20 | } 21 | } -------------------------------------------------------------------------------- /RenderWareFile/GenericSection.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace RenderWareFile 5 | { 6 | public class GenericSection : RWSection 7 | { 8 | public byte[] data; 9 | 10 | public GenericSection Read(BinaryReader binaryReader, Section section) 11 | { 12 | sectionIdentifier = section; 13 | sectionSize = binaryReader.ReadInt32(); 14 | renderWareVersion = binaryReader.ReadInt32(); 15 | 16 | data = binaryReader.ReadBytes(sectionSize); 17 | 18 | return this; 19 | } 20 | 21 | public override void SetListBytes(int fileVersion, ref List listBytes) 22 | { 23 | listBytes.AddRange(data); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /RenderWareFile/Other/Color.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace RenderWareFile 4 | { 5 | public struct Color 6 | { 7 | public byte R { get; set; } 8 | public byte G { get; set; } 9 | public byte B { get; set; } 10 | public byte A { get; set; } 11 | 12 | public Color(byte r, byte g, byte b, byte a) 13 | { 14 | R = r; 15 | G = g; 16 | B = b; 17 | A = a; 18 | } 19 | 20 | public Color(byte[] v) 21 | { 22 | R = v[0]; 23 | G = v[1]; 24 | B = v[2]; 25 | A = v[3]; 26 | } 27 | 28 | public Color(int a) 29 | { 30 | this = new Color(BitConverter.GetBytes(a)); 31 | } 32 | 33 | public static Color FromString(string s) 34 | { 35 | if (s.Length != 8) throw new ArgumentException(); 36 | 37 | Color c = new Color 38 | { 39 | R = Convert.ToByte(new string(new char[] { s[0], s[1] }), 16), 40 | G = Convert.ToByte(new string(new char[] { s[2], s[3] }), 16), 41 | B = Convert.ToByte(new string(new char[] { s[4], s[5] }), 16), 42 | A = Convert.ToByte(new string(new char[] { s[6], s[7] }), 16) 43 | }; 44 | return c; 45 | } 46 | 47 | public static explicit operator int(Color v) 48 | { 49 | return BitConverter.ToInt32(new byte[] { v.R, v.G, v.B, v.A }, 0); 50 | } 51 | 52 | public static bool operator ==(Color c1, Color c2) 53 | { 54 | return Equals(c1, c2); 55 | } 56 | 57 | public static bool operator !=(Color c1, Color c2) 58 | { 59 | return !Equals(c1, c2); 60 | } 61 | 62 | public override string ToString() 63 | { 64 | return String.Format("{0, 2:X2}{1, 2:X2}{2, 2:X2}{3, 2:X2}", R, G, B, A); 65 | } 66 | 67 | public override bool Equals(object obj) 68 | { 69 | if (obj is Color c) return (GetHashCode() == c.GetHashCode()); 70 | else return false; 71 | } 72 | 73 | public override int GetHashCode() 74 | { 75 | var hashCode = 1960784236; 76 | hashCode = hashCode * -1521134295 + R.GetHashCode(); 77 | hashCode = hashCode * -1521134295 + G.GetHashCode(); 78 | hashCode = hashCode * -1521134295 + B.GetHashCode(); 79 | hashCode = hashCode * -1521134295 + A.GetHashCode(); 80 | return hashCode; 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /RenderWareFile/Other/Matrix3x3.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile.Sections 2 | { 3 | public struct Matrix3x3 4 | { 5 | public float M11; 6 | public float M12; 7 | public float M13; 8 | public float M21; 9 | public float M22; 10 | public float M23; 11 | public float M31; 12 | public float M32; 13 | public float M33; 14 | 15 | public static Matrix3x3 Identity => new Matrix3x3() 16 | { 17 | M11 = 1f, 18 | M12 = 0f, 19 | M13 = 0f, 20 | M21 = 0f, 21 | M22 = 1f, 22 | M23 = 0f, 23 | M31 = 0f, 24 | M32 = 0f, 25 | M33 = 1f, 26 | }; 27 | } 28 | } -------------------------------------------------------------------------------- /RenderWareFile/Other/NativeDataGC.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | using static RenderWareFile.Shared; 6 | 7 | namespace RenderWareFile.Sections 8 | { 9 | public enum Declarations : byte 10 | { 11 | Vertex = 0x09, 12 | Normal = 0x0A, 13 | Color = 0x0B, 14 | TextCoord = 0x0D, 15 | TextCoord2 = 0x0E 16 | } 17 | 18 | public enum ByteTypes : byte 19 | { 20 | OneByte = 0x02, 21 | TwoBytes = 0x03 22 | } 23 | 24 | public abstract class Declaration 25 | { 26 | public int startOffset; 27 | public Declarations declarationType; 28 | public byte sizeOfEntry; 29 | public ByteTypes byteType; 30 | public byte unknown2; 31 | } 32 | 33 | public class Vertex3Declaration : Declaration 34 | { 35 | public List entryList; 36 | } 37 | 38 | public class Vertex2Declaration : Declaration 39 | { 40 | public List entryList; 41 | } 42 | 43 | public class ColorDeclaration : Declaration 44 | { 45 | public List entryList; 46 | } 47 | 48 | public class TriangleDeclaration 49 | { 50 | public int startOffset; 51 | public int size; 52 | public List TriangleListList; 53 | 54 | public int MaterialIndex; 55 | } 56 | 57 | public class TriangleList 58 | { 59 | public byte setting; 60 | public byte setting2; 61 | public byte entryAmount; 62 | 63 | public List entries; 64 | } 65 | 66 | public class NativeDataGC 67 | { 68 | public short unknown1; 69 | public short meshIndex; 70 | public int unknown2; 71 | public Declaration[] declarations; 72 | public TriangleDeclaration[] triangleDeclarations; 73 | 74 | public NativeDataGC(BinaryReader binaryReader, bool fixFlag) 75 | { 76 | int headerLenght = binaryReader.ReadInt32(); // counting from after dataLenght 77 | int dataLenght = binaryReader.ReadInt32(); // counting from after headerEndPosition 78 | 79 | long nativeDataStart = binaryReader.BaseStream.Position; // from here the file is little endian 80 | 81 | unknown1 = Switch(binaryReader.ReadInt16()); 82 | meshIndex = Switch(binaryReader.ReadInt16()); 83 | unknown2 = Switch(binaryReader.ReadInt32()); 84 | var declarationAmount = Switch(binaryReader.ReadInt32()); 85 | 86 | declarations = new Declaration[declarationAmount]; 87 | for (int i = 0; i < declarationAmount; i++) 88 | { 89 | var startOffset = Switch(binaryReader.ReadInt32()); 90 | var declarationType = (Declarations)binaryReader.ReadByte(); 91 | var sizeOfEntry = binaryReader.ReadByte(); 92 | var byteType = (ByteTypes)binaryReader.ReadByte(); 93 | var unknown2 = binaryReader.ReadByte(); 94 | 95 | switch (declarationType) 96 | { 97 | case Declarations.Vertex: 98 | case Declarations.Normal: 99 | declarations[i] = new Vertex3Declaration() 100 | { 101 | startOffset = startOffset, 102 | declarationType = declarationType, 103 | sizeOfEntry = sizeOfEntry, 104 | byteType = byteType, 105 | unknown2 = unknown2, 106 | }; 107 | break; 108 | case Declarations.TextCoord: 109 | case Declarations.TextCoord2: 110 | declarations[i] = new Vertex2Declaration() 111 | { 112 | startOffset = startOffset, 113 | declarationType = declarationType, 114 | sizeOfEntry = sizeOfEntry, 115 | byteType = byteType, 116 | unknown2 = unknown2, 117 | }; 118 | break; 119 | case Declarations.Color: 120 | declarations[i] = new ColorDeclaration() 121 | { 122 | startOffset = startOffset, 123 | declarationType = declarationType, 124 | sizeOfEntry = sizeOfEntry, 125 | byteType = byteType, 126 | unknown2 = unknown2, 127 | }; 128 | break; 129 | default: 130 | throw new NotSupportedException($"Unknown declaration type: {declarationType} at {binaryReader.BaseStream.Position}"); 131 | } 132 | } 133 | 134 | List list = new List(); 135 | 136 | foreach (int i in MaterialList) 137 | { 138 | list.Add(new TriangleDeclaration() 139 | { 140 | startOffset = Switch(binaryReader.ReadInt32()), 141 | size = Switch(binaryReader.ReadInt32()), 142 | MaterialIndex = i, 143 | TriangleListList = new List() 144 | }); 145 | } 146 | 147 | triangleDeclarations = list.ToArray(); 148 | 149 | long headerEndPosition = binaryReader.BaseStream.Position; 150 | 151 | for (int i = 0; i < triangleDeclarations.Length; i++) 152 | { 153 | binaryReader.BaseStream.Position = headerEndPosition + triangleDeclarations[i].startOffset; 154 | 155 | while (!(binaryReader.BaseStream.Position == headerEndPosition + triangleDeclarations[i].startOffset + triangleDeclarations[i].size)) 156 | { 157 | byte setting = binaryReader.ReadByte(); 158 | 159 | if (setting == 0) continue; 160 | else if (setting != 0x98) throw new Exception(); 161 | 162 | byte setting2 = binaryReader.ReadByte(); 163 | 164 | byte entryAmount = binaryReader.ReadByte(); 165 | List entries = new List(); 166 | 167 | for (int j = 0; j < entryAmount; j++) 168 | { 169 | List objectList = new List(); 170 | 171 | if (fixFlag) binaryReader.BaseStream.Position += 1; 172 | 173 | for (int k = 0; k < declarationAmount; k++) 174 | { 175 | if (declarations[k].byteType == ByteTypes.OneByte) 176 | objectList.Add(binaryReader.ReadByte()); 177 | else if (declarations[k].byteType == ByteTypes.TwoBytes) 178 | objectList.Add(Switch(binaryReader.ReadInt16())); 179 | else throw new Exception(); 180 | } 181 | 182 | entries.Add(objectList.ToArray()); 183 | } 184 | 185 | triangleDeclarations[i].TriangleListList.Add(new TriangleList() { setting = setting, setting2 = setting2, entryAmount = entryAmount, entries = entries }); 186 | } 187 | } 188 | 189 | for (int d = 0; d < declarations.Count(); d++) 190 | { 191 | binaryReader.BaseStream.Position = headerEndPosition + declarations[d].startOffset; 192 | 193 | byte[] data = d + 1 < declarations.Length ? 194 | binaryReader.ReadBytes(declarations[d + 1].startOffset - declarations[d].startOffset) : 195 | binaryReader.ReadBytes(dataLenght - declarations[d].startOffset); 196 | 197 | if (declarations[d].declarationType == Declarations.Vertex || declarations[d].declarationType == Declarations.Normal) 198 | { 199 | var dec = (Vertex3Declaration)declarations[d]; 200 | dec.entryList = new List(); 201 | for (int i = 0; i + 11 < data.Count(); i += 12) 202 | { 203 | Vertex3 v = new Vertex3( 204 | BitConverter.ToSingle(new byte[] { data[i + 3], data[i + 2], data[i + 1], data[i] }, 0), 205 | BitConverter.ToSingle(new byte[] { data[i + 7], data[i + 6], data[i + 5], data[i + 4] }, 0), 206 | BitConverter.ToSingle(new byte[] { data[i + 11], data[i + 10], data[i + 9], data[i + 8] }, 0)); 207 | dec.entryList.Add(v); 208 | } 209 | } 210 | else if (declarations[d].declarationType == Declarations.Color) 211 | { 212 | var dec = (ColorDeclaration)declarations[d]; 213 | dec.entryList = new List(); 214 | for (int i = 0; i < data.Count(); i += 0x4) 215 | { 216 | Color v = new Color(new byte[] { data[i], data[i + 1], data[i + 2], data[i + 3] }); 217 | dec.entryList.Add(v); 218 | } 219 | } 220 | else if (declarations[d].declarationType == Declarations.TextCoord) 221 | { 222 | var dec = (Vertex2Declaration)declarations[d]; 223 | dec.entryList = new List(); 224 | for (int i = 0; i < data.Count(); i += 0x8) 225 | { 226 | Vertex2 v = new Vertex2( 227 | BitConverter.ToSingle(new byte[] { data[i + 3], data[i + 2], data[i + 1], data[i] }, 0), 228 | BitConverter.ToSingle(new byte[] { data[i + 7], data[i + 6], data[i + 5], data[i + 4] }, 0)); 229 | dec.entryList.Add(v); 230 | } 231 | } 232 | else if (declarations[d].declarationType == Declarations.TextCoord2) 233 | { 234 | var dec = (Vertex2Declaration)declarations[d]; 235 | dec.entryList = new List(); 236 | for (int i = 0; i < data.Count(); i += 0x8) 237 | { 238 | Vertex2 v = new Vertex2( 239 | BitConverter.ToSingle(new byte[] { data[i + 3], data[i + 2], data[i + 1], data[i] }, 0), 240 | BitConverter.ToSingle(new byte[] { data[i + 7], data[i + 6], data[i + 5], data[i + 4] }, 0)); 241 | dec.entryList.Add(v); 242 | } 243 | } 244 | } 245 | } 246 | 247 | public List GetBytes() 248 | { 249 | List listData = new List(); 250 | 251 | foreach (TriangleDeclaration td in triangleDeclarations) 252 | { 253 | td.startOffset = listData.Count(); 254 | foreach (TriangleList tl in td.TriangleListList) 255 | { 256 | listData.Add(tl.setting); 257 | listData.Add(tl.setting2); 258 | tl.entryAmount = (byte)tl.entries.Count(); 259 | listData.Add(tl.entryAmount); 260 | 261 | for (int i = 0; i < tl.entryAmount; i++) 262 | { 263 | for (int j = 0; j < tl.entries[i].Length; j++) 264 | { 265 | if (declarations[j].byteType == ByteTypes.OneByte) 266 | listData.Add((byte)tl.entries[i][j]); 267 | else if (declarations[j].byteType == ByteTypes.TwoBytes) 268 | listData.AddRange(BitConverter.GetBytes((short)tl.entries[i][j]).Reverse()); 269 | } 270 | } 271 | } 272 | 273 | while (listData.Count() % 0x20 != 0) 274 | listData.Add(0); 275 | 276 | td.size = listData.Count() - td.startOffset; 277 | } 278 | 279 | foreach (var d in declarations) 280 | { 281 | d.startOffset = listData.Count(); 282 | if (d.declarationType == Declarations.Vertex || d.declarationType == Declarations.Normal) 283 | { 284 | foreach (var v in ((Vertex3Declaration)d).entryList) 285 | { 286 | listData.AddRange(BitConverter.GetBytes(v.X).Reverse()); 287 | listData.AddRange(BitConverter.GetBytes(v.Y).Reverse()); 288 | listData.AddRange(BitConverter.GetBytes(v.Z).Reverse()); 289 | } 290 | d.sizeOfEntry = 0xC; 291 | } 292 | else if (d.declarationType == Declarations.Color) 293 | { 294 | foreach (var c in ((ColorDeclaration)d).entryList) 295 | { 296 | listData.Add(c.R); 297 | listData.Add(c.G); 298 | listData.Add(c.B); 299 | listData.Add(c.A); 300 | } 301 | d.sizeOfEntry = 0x4; 302 | } 303 | else if (d.declarationType == Declarations.TextCoord || d.declarationType == Declarations.TextCoord2) 304 | { 305 | foreach (var tc in ((Vertex2Declaration)d).entryList) 306 | { 307 | listData.AddRange(BitConverter.GetBytes(tc.X).Reverse()); 308 | listData.AddRange(BitConverter.GetBytes(tc.Y).Reverse()); 309 | } 310 | d.sizeOfEntry = 0x8; 311 | } 312 | 313 | while (listData.Count() % 0x20 != 0) 314 | listData.Add(0); 315 | } 316 | 317 | int dataLenght = listData.Count(); 318 | int headerLenght = 12 + 8 * declarations.Length + 8 * triangleDeclarations.Length; 319 | 320 | List list = new List(); 321 | list.AddRange(BitConverter.GetBytes(headerLenght)); 322 | list.AddRange(BitConverter.GetBytes(dataLenght)); 323 | 324 | list.AddRange(BitConverter.GetBytes(unknown1).Reverse()); 325 | list.AddRange(BitConverter.GetBytes(meshIndex).Reverse()); 326 | list.AddRange(BitConverter.GetBytes(unknown2).Reverse()); 327 | list.AddRange(BitConverter.GetBytes(declarations.Length).Reverse()); 328 | 329 | for (int i = 0; i < declarations.Length; i++) 330 | { 331 | list.AddRange(BitConverter.GetBytes(declarations[i].startOffset).Reverse()); 332 | list.Add((byte)declarations[i].declarationType); 333 | list.Add(declarations[i].sizeOfEntry); 334 | list.Add((byte)declarations[i].byteType); 335 | list.Add(declarations[i].unknown2); 336 | } 337 | 338 | for (int i = 0; i < triangleDeclarations.Length; i++) 339 | { 340 | list.AddRange(BitConverter.GetBytes(triangleDeclarations[i].startOffset).Reverse()); 341 | list.AddRange(BitConverter.GetBytes(triangleDeclarations[i].size).Reverse()); 342 | } 343 | 344 | list.AddRange(listData); 345 | return list; 346 | } 347 | } 348 | } 349 | -------------------------------------------------------------------------------- /RenderWareFile/Other/Triangle.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile 2 | { 3 | public struct Triangle 4 | { 5 | public ushort materialIndex; 6 | public ushort vertex1; 7 | public ushort vertex2; 8 | public ushort vertex3; 9 | 10 | public Triangle(ushort m, ushort v1, ushort v2, ushort v3) 11 | { 12 | materialIndex = m; 13 | vertex1 = v1; 14 | vertex2 = v2; 15 | vertex3 = v3; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /RenderWareFile/Other/Vertex2.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile 2 | { 3 | public struct Vertex2 4 | { 5 | public float X; 6 | public float Y; 7 | 8 | public Vertex2(float a, float b) 9 | { 10 | X = a; 11 | Y = b; 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /RenderWareFile/Other/Vertex3.cs: -------------------------------------------------------------------------------- 1 | namespace RenderWareFile 2 | { 3 | public struct Vertex3 4 | { 5 | public float X { get; set; } 6 | public float Y { get; set; } 7 | public float Z { get; set; } 8 | 9 | public Vertex3(float a, float b, float c) 10 | { 11 | X = a; 12 | Y = b; 13 | Z = c; 14 | } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /RenderWareFile/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.InteropServices; 3 | 4 | // As informações gerais sobre um assembly são controladas por 5 | // conjunto de atributos. Altere estes valores de atributo para modificar as informações 6 | // associada a um assembly. 7 | [assembly: AssemblyTitle("RenderWareBSP")] 8 | [assembly: AssemblyDescription("")] 9 | [assembly: AssemblyConfiguration("")] 10 | [assembly: AssemblyCompany("")] 11 | [assembly: AssemblyProduct("RenderWareBSP")] 12 | [assembly: AssemblyCopyright("Copyright © 2018")] 13 | [assembly: AssemblyTrademark("")] 14 | [assembly: AssemblyCulture("")] 15 | 16 | // Definir ComVisible como false torna os tipos neste assembly invisíveis 17 | // para componentes COM. Caso precise acessar um tipo neste assembly de 18 | // COM, defina o atributo ComVisible como true nesse tipo. 19 | [assembly: ComVisible(false)] 20 | 21 | // O GUID a seguir será destinado à ID de typelib se este projeto for exposto para COM 22 | [assembly: Guid("005f2d00-06de-4ef9-bfee-80efac49e114")] 23 | 24 | // As informações da versão de um assembly consistem nos quatro valores a seguir: 25 | // 26 | // Versão Principal 27 | // Versão Secundária 28 | // Número da Versão 29 | // Revisão 30 | // 31 | // É possível especificar todos os valores ou usar como padrão os Números de Build e da Revisão 32 | // usando o '*' como mostrado abaixo: 33 | // [assembly: AssemblyVersion("1.0.*")] 34 | [assembly: AssemblyVersion("1.0.0.0")] 35 | [assembly: AssemblyFileVersion("1.0.0.0")] 36 | -------------------------------------------------------------------------------- /RenderWareFile/RWSection.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | 5 | namespace RenderWareFile 6 | { 7 | public abstract class RWSection 8 | { 9 | public Section sectionIdentifier; 10 | public int sectionSize; 11 | public int renderWareVersion; 12 | 13 | public byte[] GetBytes(int fileVersion) 14 | { 15 | List listBytes = new List() 16 | { 17 | 0, 0, 0, 0, 18 | 0, 0, 0, 0, 19 | 0, 0, 0, 0 20 | }; 21 | 22 | SetListBytes(fileVersion, ref listBytes); 23 | 24 | sectionSize = listBytes.Count() - 0xC; 25 | 26 | renderWareVersion = fileVersion; 27 | 28 | listBytes[0] = BitConverter.GetBytes((int)sectionIdentifier)[0]; 29 | listBytes[1] = BitConverter.GetBytes((int)sectionIdentifier)[1]; 30 | listBytes[2] = BitConverter.GetBytes((int)sectionIdentifier)[2]; 31 | listBytes[3] = BitConverter.GetBytes((int)sectionIdentifier)[3]; 32 | listBytes[4] = BitConverter.GetBytes(sectionSize)[0]; 33 | listBytes[5] = BitConverter.GetBytes(sectionSize)[1]; 34 | listBytes[6] = BitConverter.GetBytes(sectionSize)[2]; 35 | listBytes[7] = BitConverter.GetBytes(sectionSize)[3]; 36 | listBytes[8] = BitConverter.GetBytes(renderWareVersion)[0]; 37 | listBytes[9] = BitConverter.GetBytes(renderWareVersion)[1]; 38 | listBytes[10] = BitConverter.GetBytes(renderWareVersion)[2]; 39 | listBytes[11] = BitConverter.GetBytes(renderWareVersion)[3]; 40 | 41 | return listBytes.ToArray(); 42 | } 43 | 44 | public abstract void SetListBytes(int fileVersion, ref List listBytes); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /RenderWareFile/ReadFileMethods.cs: -------------------------------------------------------------------------------- 1 | using RenderWareFile.Sections; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile 6 | { 7 | public static class ReadFileMethods 8 | { 9 | public static bool isShadow = false; 10 | public static bool isCollision = false; 11 | public static bool treatStuffAsByteArray = false; 12 | 13 | public static RWSection[] ReadRenderWareFile(string fileName) 14 | { 15 | return ReadRenderWareFile(new FileStream(fileName, FileMode.Open)); 16 | } 17 | 18 | public static RWSection[] ReadRenderWareFile(byte[] file) 19 | { 20 | return ReadRenderWareFile(new MemoryStream(file)); 21 | } 22 | 23 | public static RWSection[] ReadRenderWareFile(Stream File) 24 | { 25 | using (BinaryReader binaryReader = new BinaryReader(File)) 26 | { 27 | List renderWareFile = new List(); 28 | 29 | while (binaryReader.BaseStream.Position < binaryReader.BaseStream.Length) 30 | { 31 | Section currentSection = (Section)binaryReader.ReadInt32(); 32 | if (currentSection == Section.World) 33 | renderWareFile.Add(new World_000B().Read(binaryReader)); 34 | else if (currentSection == Section.Clump) 35 | renderWareFile.Add(new Clump_0010().Read(binaryReader)); 36 | else if (currentSection == Section.TextureDictionary) 37 | renderWareFile.Add(new TextureDictionary_0016().Read(binaryReader)); 38 | else 39 | renderWareFile.Add(new GenericSection().Read(binaryReader, currentSection)); 40 | } 41 | return renderWareFile.ToArray(); 42 | } 43 | } 44 | 45 | public static byte[] ExportRenderWareFile(RWSection RWFile, int version) 46 | { 47 | List list = new List(); 48 | list.AddRange(RWFile.GetBytes(version)); 49 | 50 | return list.ToArray(); 51 | } 52 | 53 | public static byte[] ExportRenderWareFile(RWSection[] RWFile, int version) 54 | { 55 | List list = new List(); 56 | foreach (RWSection i in RWFile) 57 | list.AddRange(i.GetBytes(version)); 58 | 59 | return list.ToArray(); 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /RenderWareFile/RenderWareFile.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {005F2D00-06DE-4EF9-BFEE-80EFAC49E114} 8 | Library 9 | Properties 10 | RenderWareFile 11 | RenderWareFile 12 | v4.8 13 | 512 14 | 15 | 16 | 17 | 18 | true 19 | full 20 | false 21 | bin\Debug\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | false 26 | 27 | 28 | pdbonly 29 | true 30 | bin\Release\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/AtomicSector_0009.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class AtomicSector_0009 : RWSection 8 | { 9 | public AtomicSectorStruct_0001 atomicSectorStruct; 10 | public Extension_0003 atomicSectorExtension; 11 | 12 | public AtomicSector_0009 Read(BinaryReader binaryReader) 13 | { 14 | sectionIdentifier = Section.AtomicSector; 15 | sectionSize = binaryReader.ReadInt32(); 16 | renderWareVersion = binaryReader.ReadInt32(); 17 | 18 | long startSectionPosition = binaryReader.BaseStream.Position; 19 | 20 | Section atomicStructSection = (Section)binaryReader.ReadInt32(); 21 | if (atomicStructSection != Section.Struct) throw new Exception(); 22 | atomicSectorStruct = new AtomicSectorStruct_0001().Read(binaryReader); 23 | 24 | Section atomicExtensionSection = (Section)binaryReader.ReadInt32(); 25 | if (atomicExtensionSection != Section.Extension) throw new Exception(); 26 | atomicSectorExtension = new Extension_0003().Read(binaryReader); 27 | 28 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 29 | 30 | return this; 31 | } 32 | 33 | public override void SetListBytes(int fileVersion, ref List listBytes) 34 | { 35 | sectionIdentifier = Section.AtomicSector; 36 | 37 | listBytes.AddRange(atomicSectorStruct.GetBytes(fileVersion)); 38 | listBytes.AddRange(atomicSectorExtension.GetBytes(fileVersion)); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Atomic_0014.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class Atomic_0014 : RWSection 8 | { 9 | public AtomicStruct_0001 atomicStruct; 10 | public Extension_0003 atomicExtension; 11 | 12 | public Atomic_0014 Read(BinaryReader binaryReader, Section section) 13 | { 14 | sectionIdentifier = Section.Atomic; 15 | sectionSize = binaryReader.ReadInt32(); 16 | renderWareVersion = binaryReader.ReadInt32(); 17 | 18 | long startSectionPosition = binaryReader.BaseStream.Position; 19 | 20 | Section atomicStructSection = (Section)binaryReader.ReadInt32(); 21 | if (atomicStructSection != Section.Struct) throw new Exception(); 22 | atomicStruct = new AtomicStruct_0001().Read(binaryReader); 23 | 24 | Section atomicExtensionSection = (Section)binaryReader.ReadInt32(); 25 | if (atomicExtensionSection != Section.Extension) throw new Exception(); 26 | atomicExtension = new Extension_0003().Read(binaryReader); 27 | 28 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 29 | 30 | return this; 31 | } 32 | 33 | public override void SetListBytes(int fileVersion, ref List listBytes) 34 | { 35 | sectionIdentifier = Section.Atomic; 36 | 37 | listBytes.AddRange(atomicStruct.GetBytes(fileVersion)); 38 | listBytes.AddRange(atomicExtension.GetBytes(fileVersion)); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/BinMeshPLG_050E.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace RenderWareFile.Sections 7 | { 8 | public struct BinMesh 9 | { 10 | public int indexCount; // number of vertex indices in this mesh 11 | public int materialIndex; // material index 12 | public int[] vertexIndices; // vertex indices 13 | } 14 | 15 | public class BinMeshPLG_050E : RWSection 16 | { 17 | public BinMeshHeaderFlags binMeshHeaderFlags; 18 | public int numMeshes; // number of objects/meshes (usually same number of materials) 19 | public int totalIndexCount; // total number of indices 20 | 21 | public BinMesh[] binMeshList; 22 | 23 | public bool isNativeData = false; 24 | 25 | public BinMeshPLG_050E Read(BinaryReader binaryReader) 26 | { 27 | sectionIdentifier = Section.BinMeshPLG; 28 | sectionSize = binaryReader.ReadInt32(); 29 | renderWareVersion = binaryReader.ReadInt32(); 30 | 31 | binMeshHeaderFlags = (BinMeshHeaderFlags)binaryReader.ReadInt32(); 32 | numMeshes = binaryReader.ReadInt32(); 33 | totalIndexCount = binaryReader.ReadInt32(); 34 | 35 | binMeshList = new BinMesh[numMeshes]; 36 | 37 | Shared.MaterialList = new List(); 38 | 39 | for (int i = 0; i < numMeshes; i++) 40 | { 41 | binMeshList[i] = new BinMesh 42 | { 43 | indexCount = binaryReader.ReadInt32(), 44 | materialIndex = binaryReader.ReadInt32() 45 | }; 46 | 47 | if (sectionSize != 12 + 8 * numMeshes) 48 | { 49 | binMeshList[i].vertexIndices = new int[binMeshList[i].indexCount]; 50 | 51 | for (int j = 0; j < binMeshList[i].vertexIndices.Count(); j++) 52 | binMeshList[i].vertexIndices[j] = binaryReader.ReadInt32(); 53 | } 54 | else 55 | { 56 | Shared.MaterialList.Add(binMeshList[i].materialIndex); 57 | isNativeData = true; 58 | } 59 | } 60 | 61 | return this; 62 | } 63 | 64 | public override void SetListBytes(int fileVersion, ref List listBytes) 65 | { 66 | sectionIdentifier = Section.BinMeshPLG; 67 | 68 | listBytes.AddRange(BitConverter.GetBytes((int)binMeshHeaderFlags)); 69 | listBytes.AddRange(BitConverter.GetBytes(numMeshes)); 70 | listBytes.AddRange(BitConverter.GetBytes(totalIndexCount)); 71 | 72 | for (int i = 0; i < binMeshList.Count(); i++) 73 | { 74 | listBytes.AddRange(BitConverter.GetBytes(binMeshList[i].indexCount)); 75 | listBytes.AddRange(BitConverter.GetBytes(binMeshList[i].materialIndex)); 76 | 77 | if (!isNativeData) 78 | for (int j = 0; j < binMeshList[i].vertexIndices.Count(); j++) 79 | listBytes.AddRange(BitConverter.GetBytes(binMeshList[i].vertexIndices[j])); 80 | } 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Clump_0010.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class Clump_0010 : RWSection 8 | { 9 | public ClumpStruct_0001 clumpStruct; 10 | public FrameList_000E frameList; 11 | public GeometryList_001A geometryList; 12 | public List atomicList; 13 | public Extension_0003 clumpExtension; 14 | 15 | public Clump_0010 Read(BinaryReader binaryReader) 16 | { 17 | sectionIdentifier = Section.Clump; 18 | sectionSize = binaryReader.ReadInt32(); 19 | renderWareVersion = binaryReader.ReadInt32(); 20 | 21 | long startSectionPosition = binaryReader.BaseStream.Position; 22 | 23 | Section clumpStructSection = (Section)binaryReader.ReadInt32(); 24 | if (clumpStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.ToString()); 25 | clumpStruct = new ClumpStruct_0001().Read(binaryReader); 26 | 27 | Section frameListSection = (Section)binaryReader.ReadInt32(); 28 | if (frameListSection != Section.FrameList) throw new Exception(binaryReader.BaseStream.ToString()); 29 | frameList = new FrameList_000E().Read(binaryReader); 30 | 31 | Section geometryListSection = (Section)binaryReader.ReadInt32(); 32 | if (geometryListSection != Section.GeometryList) throw new Exception(binaryReader.BaseStream.ToString()); 33 | geometryList = new GeometryList_001A().Read(binaryReader); 34 | 35 | atomicList = new List(); 36 | for (int i = 0; i < clumpStruct.atomicCount; i++) 37 | { 38 | Section atomicListSection = (Section)binaryReader.ReadInt32(); 39 | if (atomicListSection != Section.Atomic) throw new Exception(binaryReader.BaseStream.Position.ToString()); 40 | atomicList.Add(new Atomic_0014().Read(binaryReader, atomicListSection)); 41 | } 42 | 43 | Section clumpExtensionSection = (Section)binaryReader.ReadInt32(); 44 | if (clumpExtensionSection == Section.Extension) 45 | clumpExtension = new Extension_0003().Read(binaryReader); 46 | 47 | //binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 48 | 49 | return this; 50 | } 51 | 52 | public override void SetListBytes(int fileVersion, ref List listBytes) 53 | { 54 | sectionIdentifier = Section.Clump; 55 | 56 | listBytes.AddRange(clumpStruct.GetBytes(fileVersion)); 57 | listBytes.AddRange(frameList.GetBytes(fileVersion)); 58 | listBytes.AddRange(geometryList.GetBytes(fileVersion)); 59 | for (int i = 0; i < atomicList.Count; i++) 60 | listBytes.AddRange(atomicList[i].GetBytes(fileVersion)); 61 | listBytes.AddRange(clumpExtension.GetBytes(fileVersion)); 62 | } 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/ColTree_002C.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace RenderWareFile.Sections 5 | { 6 | public class ColTree_002C : RWSection 7 | { 8 | public RWSection colTreeStruct; 9 | 10 | public ColTree_002C Read(BinaryReader binaryReader) 11 | { 12 | sectionIdentifier = Section.ColTree; 13 | sectionSize = binaryReader.ReadInt32(); 14 | renderWareVersion = binaryReader.ReadInt32(); 15 | 16 | Section colTreeStructSection = (Section)binaryReader.ReadInt32(); 17 | 18 | if (colTreeStructSection == Section.Struct) 19 | colTreeStruct = new ColTreeStruct_0001().Read(binaryReader); 20 | else throw new System.Exception(); 21 | 22 | return this; 23 | } 24 | 25 | public override void SetListBytes(int fileVersion, ref List listBytes) 26 | { 27 | sectionIdentifier = Section.ColTree; 28 | 29 | listBytes.AddRange(colTreeStruct.GetBytes(fileVersion)); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/CollisionPLG_011D.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class CollisionPLG_011D : RWSection 8 | { 9 | public int unknownValue; 10 | public RWSection colTree; 11 | 12 | public CollisionPLG_011D Read(BinaryReader binaryReader) 13 | { 14 | sectionIdentifier = Section.CollisionPLG; 15 | sectionSize = binaryReader.ReadInt32(); 16 | renderWareVersion = binaryReader.ReadInt32(); 17 | 18 | if (ReadFileMethods.isShadow & ReadFileMethods.isCollision) 19 | { 20 | unknownValue = binaryReader.ReadInt32(); 21 | 22 | Section colTreeSection = (Section)binaryReader.ReadInt32(); 23 | if (colTreeSection == Section.ColTree) 24 | colTree = new ColTree_002C().Read(binaryReader); 25 | else throw new Exception(); 26 | } 27 | else 28 | { 29 | binaryReader.BaseStream.Position += sectionSize; 30 | } 31 | 32 | return this; 33 | } 34 | 35 | public override void SetListBytes(int fileVersion, ref List listBytes) 36 | { 37 | sectionIdentifier = Section.CollisionPLG; 38 | 39 | listBytes.AddRange(BitConverter.GetBytes(unknownValue)); 40 | listBytes.AddRange(colTree.GetBytes(fileVersion)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/CollisionPLG_011D_Scooby.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public enum ScoobySectorType : byte 8 | { 9 | Leaf = 0x01, 10 | Branch = 0x02, 11 | } 12 | 13 | public struct Split_Scooby 14 | { 15 | public ScoobySectorType positiveType; 16 | public ScoobySectorType negativeType; 17 | public SectorType splitDirection; 18 | public byte padding; 19 | 20 | // index of startIndex_amountOfTriangles entry in list if leaf node, index of split in split list for branch node 21 | public short positiveIndex; 22 | public short negativeIndex; 23 | 24 | public float negativeSplitPos; 25 | public float positiveSplitPos; 26 | } 27 | 28 | public class CollisionPLG_011D_Scooby : RWSection 29 | { 30 | public Split_Scooby[] splits; 31 | public short[][] startIndex_amountOfTriangles; 32 | public int[] triangles; 33 | 34 | public CollisionPLG_011D_Scooby Read(BinaryReader binaryReader) 35 | { 36 | sectionIdentifier = Section.CollisionPLG; 37 | sectionSize = binaryReader.ReadInt32(); 38 | renderWareVersion = binaryReader.ReadInt32(); 39 | 40 | int numLeafNodes = binaryReader.ReadInt32(); 41 | int numTriangles = binaryReader.ReadInt32(); 42 | 43 | splits = new Split_Scooby[numLeafNodes - 1]; 44 | 45 | for (int i = 0; i < numLeafNodes - 1; i++) 46 | splits[i] = new Split_Scooby 47 | { 48 | positiveType = (ScoobySectorType)binaryReader.ReadByte(), 49 | negativeType = (ScoobySectorType)binaryReader.ReadByte(), 50 | splitDirection = (SectorType)binaryReader.ReadByte(), 51 | padding = binaryReader.ReadByte(), 52 | 53 | positiveIndex = binaryReader.ReadInt16(), 54 | negativeIndex = binaryReader.ReadInt16(), 55 | 56 | positiveSplitPos = binaryReader.ReadSingle(), 57 | negativeSplitPos = binaryReader.ReadSingle() 58 | }; 59 | 60 | startIndex_amountOfTriangles = new short[numLeafNodes][]; 61 | 62 | for (int i = 0; i < numLeafNodes; i++) 63 | startIndex_amountOfTriangles[i] = new short[] 64 | { 65 | binaryReader.ReadInt16(), 66 | binaryReader.ReadInt16() 67 | }; 68 | 69 | triangles = new int[numTriangles]; 70 | 71 | for (int i = 0; i < numTriangles; i++) 72 | triangles[i] = binaryReader.ReadInt32(); 73 | 74 | return this; 75 | } 76 | 77 | public override void SetListBytes(int fileVersion, ref List listBytes) 78 | { 79 | sectionIdentifier = Section.CollisionPLG; 80 | 81 | listBytes.AddRange(BitConverter.GetBytes(splits.Length + 1)); 82 | listBytes.AddRange(BitConverter.GetBytes(triangles.Length)); 83 | 84 | foreach (var split in splits) 85 | { 86 | listBytes.Add((byte)split.positiveType); 87 | listBytes.Add((byte)split.negativeType); 88 | listBytes.Add((byte)split.splitDirection); 89 | listBytes.Add(split.padding); 90 | 91 | listBytes.AddRange(BitConverter.GetBytes(split.positiveIndex)); 92 | listBytes.AddRange(BitConverter.GetBytes(split.negativeIndex)); 93 | 94 | listBytes.AddRange(BitConverter.GetBytes(split.positiveSplitPos)); 95 | listBytes.AddRange(BitConverter.GetBytes(split.negativeSplitPos)); 96 | } 97 | 98 | foreach (var i in startIndex_amountOfTriangles) 99 | foreach (var j in i) 100 | listBytes.AddRange(BitConverter.GetBytes(j)); 101 | 102 | foreach (var i in triangles) 103 | listBytes.AddRange(BitConverter.GetBytes(i)); 104 | } 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Extension_0003.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | using System.Linq; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class Extension_0003 : RWSection 8 | { 9 | public List extensionSectionList { get; set; } 10 | 11 | public Extension_0003 Read(BinaryReader binaryReader) 12 | { 13 | sectionIdentifier = Section.Extension; 14 | sectionSize = binaryReader.ReadInt32(); 15 | renderWareVersion = binaryReader.ReadInt32(); 16 | 17 | long CurrentPosition = binaryReader.BaseStream.Position; 18 | 19 | extensionSectionList = new List(); 20 | while (binaryReader.BaseStream.Position < CurrentPosition + sectionSize) 21 | { 22 | Section currentSection = (Section)binaryReader.ReadInt32(); 23 | if (currentSection == Section.BinMeshPLG) extensionSectionList.Add(new BinMeshPLG_050E().Read(binaryReader)); 24 | else if (currentSection == Section.NativeDataPLG) extensionSectionList.Add(new NativeDataPLG_0510().Read(binaryReader)); 25 | else if (currentSection == Section.CollisionPLG && ReadFileMethods.isShadow) extensionSectionList.Add(new CollisionPLG_011D().Read(binaryReader)); 26 | else if (currentSection == Section.UserDataPLG) extensionSectionList.Add(new UserDataPLG_011F().Read(binaryReader)); 27 | else if (currentSection == Section.MaterialEffectsPLG) extensionSectionList.Add(new MaterialEffectsPLG_0120().Read(binaryReader)); 28 | else extensionSectionList.Add(new GenericSection().Read(binaryReader, currentSection)); 29 | } 30 | 31 | return this; 32 | } 33 | 34 | public override void SetListBytes(int fileVersion, ref List listBytes) 35 | { 36 | sectionIdentifier = Section.Extension; 37 | 38 | if (extensionSectionList != null) 39 | for (int i = 0; i < extensionSectionList.Count(); i++) 40 | listBytes.AddRange(extensionSectionList[i].GetBytes(fileVersion)); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/FrameList_000E.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class FrameList_000E : RWSection 8 | { 9 | public FrameListStruct_0001 frameListStruct; 10 | public List extensionList; 11 | 12 | public FrameList_000E Read(BinaryReader binaryReader) 13 | { 14 | sectionIdentifier = Section.FrameList; 15 | sectionSize = binaryReader.ReadInt32(); 16 | renderWareVersion = binaryReader.ReadInt32(); 17 | 18 | Section frameListStructSection = (Section)binaryReader.ReadInt32(); 19 | if (frameListStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.ToString()); 20 | frameListStruct = new FrameListStruct_0001().Read(binaryReader); 21 | 22 | extensionList = new List(); 23 | for (int i = 0; i < frameListStruct.frames.Count; i++) 24 | { 25 | Section frameListExtensionSection = (Section)binaryReader.ReadInt32(); 26 | if (frameListExtensionSection != Section.Extension) throw new Exception(binaryReader.BaseStream.ToString()); 27 | extensionList.Add(new Extension_0003().Read(binaryReader)); 28 | } 29 | 30 | return this; 31 | } 32 | 33 | public override void SetListBytes(int fileVersion, ref List listBytes) 34 | { 35 | sectionIdentifier = Section.FrameList; 36 | 37 | listBytes.AddRange(frameListStruct.GetBytes(fileVersion)); 38 | foreach (Extension_0003 i in extensionList) 39 | listBytes.AddRange(i.GetBytes(fileVersion)); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/GeometryList_001A.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class GeometryList_001A : RWSection 8 | { 9 | public GeometryListStruct_0001 geometryListStruct; 10 | public List geometryList = new List(); 11 | 12 | public GeometryList_001A Read(BinaryReader binaryReader) 13 | { 14 | sectionIdentifier = Section.GeometryList; 15 | sectionSize = binaryReader.ReadInt32(); 16 | renderWareVersion = binaryReader.ReadInt32(); 17 | 18 | long startSectionPosition = binaryReader.BaseStream.Position; 19 | 20 | Section geometryListStructSection = (Section)binaryReader.ReadInt32(); 21 | if (geometryListStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.Position.ToString()); 22 | geometryListStruct = new GeometryListStruct_0001().Read(binaryReader); 23 | 24 | geometryList.Clear(); 25 | for (int i = 0; i < geometryListStruct.numberOfGeometries; i++) 26 | { 27 | Section geometryListSection = (Section)binaryReader.ReadInt32(); 28 | if (geometryListSection != Section.Geometry) throw new Exception(binaryReader.BaseStream.Position.ToString()); 29 | geometryList.Add(new Geometry_000F().Read(binaryReader)); 30 | } 31 | 32 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 33 | 34 | return this; 35 | } 36 | 37 | public override void SetListBytes(int fileVersion, ref List listBytes) 38 | { 39 | sectionIdentifier = Section.GeometryList; 40 | 41 | listBytes.AddRange(geometryListStruct.GetBytes(fileVersion)); 42 | for (int i = 0; i < geometryList.Count; i++) 43 | listBytes.AddRange(geometryList[i].GetBytes(fileVersion)); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Geometry_000F.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public enum GeometryFlags : short 8 | { 9 | none = 0x0000, 10 | isTristrip = 0x0001, 11 | hasVertexPositions = 0x0002, 12 | hasTextCoords = 0x0004, 13 | hasVertexColors = 0x0008, 14 | hasNormals = 0x0010, 15 | hasLights = 0x0020, 16 | modeulateMaterialColor = 0x00040, 17 | hasTextCoords2 = 0x0080 18 | } 19 | 20 | public enum GeometryFlags2 : short 21 | { 22 | none = 0x0000, 23 | isNativeGeometry = 0x0100 24 | } 25 | 26 | public class Geometry_000F : RWSection 27 | { 28 | public GeometryStruct_0001 geometryStruct; 29 | public MaterialList_0008 materialList; 30 | public Extension_0003 geometryExtension; 31 | 32 | public Geometry_000F Read(BinaryReader binaryReader) 33 | { 34 | sectionIdentifier = Section.Geometry; 35 | sectionSize = binaryReader.ReadInt32(); 36 | renderWareVersion = binaryReader.ReadInt32(); 37 | 38 | long startSectionPosition = binaryReader.BaseStream.Position; 39 | 40 | Section geometryStructSection = (Section)binaryReader.ReadInt32(); 41 | if (geometryStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.Position.ToString()); 42 | geometryStruct = new GeometryStruct_0001().Read(binaryReader); 43 | 44 | Section materialListSection = (Section)binaryReader.ReadInt32(); 45 | if (materialListSection != Section.MaterialList) throw new Exception(binaryReader.BaseStream.Position.ToString()); 46 | materialList = new MaterialList_0008().Read(binaryReader); 47 | 48 | Section geometryExtensionSection = (Section)binaryReader.ReadInt32(); 49 | if (geometryExtensionSection != Section.Extension) throw new Exception(binaryReader.BaseStream.Position.ToString()); 50 | geometryExtension = new Extension_0003().Read(binaryReader); 51 | 52 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 53 | 54 | return this; 55 | } 56 | 57 | public override void SetListBytes(int fileVersion, ref List listBytes) 58 | { 59 | sectionIdentifier = Section.Geometry; 60 | 61 | listBytes.AddRange(geometryStruct.GetBytes(fileVersion)); 62 | listBytes.AddRange(materialList.GetBytes(fileVersion)); 63 | listBytes.AddRange(geometryExtension.GetBytes(fileVersion)); 64 | } 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/MaterialEffectsPLG_0120.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class MaterialEffectBumpMap : MaterialEffect 8 | { 9 | public float Intensity { get; set; } 10 | public bool ContainsBumpMap 11 | { 12 | get => BumpMapTexture != null; 13 | set 14 | { 15 | if (value) 16 | BumpMapTexture = new Texture_0006(); 17 | else 18 | BumpMapTexture = null; 19 | } 20 | } 21 | public bool ContainsHeightMap 22 | { 23 | get => HeightMapTexture != null; 24 | set 25 | { 26 | if (value) 27 | HeightMapTexture = new Texture_0006(); 28 | else 29 | HeightMapTexture = null; 30 | } 31 | } 32 | 33 | public Texture_0006 BumpMapTexture { get; set; } 34 | public Texture_0006 HeightMapTexture { get; set; } 35 | 36 | public MaterialEffectBumpMap Read(BinaryReader binaryReader) 37 | { 38 | Intensity = binaryReader.ReadSingle(); 39 | 40 | bool ContainsBumpMap = binaryReader.ReadInt32() != 0; 41 | if (ContainsBumpMap) 42 | { 43 | Section textureSection = (Section)binaryReader.ReadInt32(); 44 | if (textureSection != Section.Texture) throw new Exception(); 45 | BumpMapTexture = new Texture_0006().Read(binaryReader); 46 | } 47 | 48 | bool ContainsHeightMap = binaryReader.ReadInt32() != 0; 49 | if (ContainsHeightMap) 50 | { 51 | Section textureSection = (Section)binaryReader.ReadInt32(); 52 | if (textureSection != Section.Texture) throw new Exception(); 53 | HeightMapTexture = new Texture_0006().Read(binaryReader); 54 | } 55 | 56 | return this; 57 | } 58 | 59 | public override byte[] GetBytes(int fileVersion) 60 | { 61 | List listBytes = new List(); 62 | 63 | listBytes.AddRange(BitConverter.GetBytes((int)MaterialEffectType.BumpMap)); 64 | listBytes.AddRange(BitConverter.GetBytes(Intensity)); 65 | listBytes.AddRange(BitConverter.GetBytes(BumpMapTexture == null ? 0 : 1)); 66 | if (BumpMapTexture != null) 67 | listBytes.AddRange(BumpMapTexture.GetBytes(fileVersion)); 68 | listBytes.AddRange(BitConverter.GetBytes(HeightMapTexture == null ? 0 : 1)); 69 | if (HeightMapTexture != null) 70 | listBytes.AddRange(HeightMapTexture.GetBytes(fileVersion)); 71 | 72 | return listBytes.ToArray(); 73 | } 74 | } 75 | 76 | public class MaterialEffectEnvironmentMap : MaterialEffect 77 | { 78 | public float ReflectionCoefficient { get; set; } 79 | public bool UseFrameBufferAlphaChannel { get; set; } 80 | public Texture_0006 EnvironmentMapTexture { get; set; } = new Texture_0006(); 81 | 82 | public MaterialEffectEnvironmentMap Read(BinaryReader binaryReader) 83 | { 84 | ReflectionCoefficient = binaryReader.ReadSingle(); 85 | UseFrameBufferAlphaChannel = binaryReader.ReadInt32() != 0; 86 | bool ContainsEnvironmentMap = binaryReader.ReadInt32() != 0; 87 | if (ContainsEnvironmentMap) 88 | { 89 | Section textureSection = (Section)binaryReader.ReadInt32(); 90 | if (textureSection != Section.Texture) throw new Exception(); 91 | EnvironmentMapTexture = new Texture_0006().Read(binaryReader); 92 | } 93 | 94 | return this; 95 | } 96 | 97 | public override byte[] GetBytes(int fileVersion) 98 | { 99 | List listBytes = new List(); 100 | 101 | listBytes.AddRange(BitConverter.GetBytes((int)MaterialEffectType.EnvironmentMap)); 102 | listBytes.AddRange(BitConverter.GetBytes(ReflectionCoefficient)); 103 | listBytes.AddRange(BitConverter.GetBytes(UseFrameBufferAlphaChannel ? 1 : 0)); 104 | 105 | listBytes.AddRange(BitConverter.GetBytes(EnvironmentMapTexture == null ? 0 : 1)); 106 | if (EnvironmentMapTexture != null) 107 | listBytes.AddRange(EnvironmentMapTexture.GetBytes(fileVersion)); 108 | 109 | return listBytes.ToArray(); 110 | } 111 | } 112 | 113 | public enum BlendFactorType : int 114 | { 115 | None = 0x00, 116 | Zero = 0x01, 117 | One = 0x02, 118 | SourceColor = 0x03, 119 | InverseSourceColor = 0x04, 120 | SourceAlpha = 0x05, 121 | InverseSourceAlpha = 0x06, 122 | DestinationAlpha = 0x07, 123 | InverseDestinationAlpha = 0x08, 124 | DestinationColor = 0x09, 125 | InverseDestinationColor = 0x0A, 126 | SourceAlphaSaturated = 0x0B 127 | } 128 | 129 | public class MaterialEffectDualTextures : MaterialEffect 130 | { 131 | public BlendFactorType SourceBlendMode { get; set; } 132 | public BlendFactorType DestBlendMode { get; set; } 133 | public Texture_0006 Texture { get; set; } = new Texture_0006(); 134 | 135 | public MaterialEffectDualTextures Read(BinaryReader binaryReader) 136 | { 137 | SourceBlendMode = (BlendFactorType)binaryReader.ReadInt32(); 138 | DestBlendMode = (BlendFactorType)binaryReader.ReadInt32(); 139 | 140 | bool ContainsTexture = binaryReader.ReadInt32() != 0; 141 | if (ContainsTexture) 142 | { 143 | Section textureSection = (Section)binaryReader.ReadInt32(); 144 | if (textureSection != Section.Texture) throw new Exception(); 145 | Texture = new Texture_0006().Read(binaryReader); 146 | } 147 | 148 | return this; 149 | } 150 | 151 | public override byte[] GetBytes(int fileVersion) 152 | { 153 | List listBytes = new List(); 154 | 155 | listBytes.AddRange(BitConverter.GetBytes((int)MaterialEffectType.DualTextures)); 156 | listBytes.AddRange(BitConverter.GetBytes((int)SourceBlendMode)); 157 | listBytes.AddRange(BitConverter.GetBytes((int)DestBlendMode)); 158 | 159 | listBytes.AddRange(BitConverter.GetBytes(Texture == null ? 0 : 1)); 160 | if (Texture != null) 161 | listBytes.AddRange(Texture.GetBytes(fileVersion)); 162 | 163 | return listBytes.ToArray(); 164 | } 165 | } 166 | 167 | public class MaterialEffectUvTransformation : MaterialEffect 168 | { 169 | public MaterialEffectUvTransformation Read() 170 | { 171 | return this; 172 | } 173 | 174 | public override byte[] GetBytes(int fileVersion) 175 | { 176 | List listBytes = new List(); 177 | listBytes.AddRange(BitConverter.GetBytes((int)MaterialEffectType.UvTransformation)); 178 | return listBytes.ToArray(); 179 | } 180 | } 181 | 182 | public abstract class MaterialEffect 183 | { 184 | public abstract byte[] GetBytes(int fileVersion); 185 | } 186 | 187 | public enum MaterialEffectType 188 | { 189 | NoEffect = 0, 190 | BumpMap = 1, 191 | EnvironmentMap = 2, 192 | BumpEnvironmentMap = 3, 193 | DualTextures = 4, 194 | UvTransformation = 5, 195 | DualTexturesUvTransformation = 6 196 | } 197 | 198 | public class MaterialEffectsPLG_0120 : RWSection 199 | { 200 | public MaterialEffectType value; 201 | 202 | public MaterialEffectType MaterialEffectType 203 | { 204 | get => value; 205 | set 206 | { 207 | if (value == MaterialEffectType.BumpMap || value == MaterialEffectType.BumpEnvironmentMap) 208 | materialEffect1 = new MaterialEffectBumpMap(); 209 | else if (value == MaterialEffectType.EnvironmentMap) 210 | materialEffect1 = new MaterialEffectEnvironmentMap(); 211 | else if (value == MaterialEffectType.DualTextures || value == MaterialEffectType.DualTexturesUvTransformation) 212 | materialEffect1 = new MaterialEffectDualTextures(); 213 | else if (value == MaterialEffectType.UvTransformation) 214 | materialEffect1 = new MaterialEffectUvTransformation(); 215 | else 216 | materialEffect1 = null; 217 | 218 | if (value == MaterialEffectType.BumpEnvironmentMap) 219 | materialEffect2 = new MaterialEffectEnvironmentMap(); 220 | else if (value == MaterialEffectType.DualTexturesUvTransformation) 221 | materialEffect2 = new MaterialEffectUvTransformation(); 222 | else 223 | materialEffect2 = null; 224 | 225 | this.value = value; 226 | } 227 | } 228 | public MaterialEffect materialEffect1; 229 | public MaterialEffect materialEffect2; 230 | public bool isAtomicExtension = false; 231 | 232 | public MaterialEffectsPLG_0120 Read(BinaryReader binaryReader) 233 | { 234 | sectionIdentifier = Section.MaterialEffectsPLG; 235 | sectionSize = binaryReader.ReadInt32(); 236 | renderWareVersion = binaryReader.ReadInt32(); 237 | 238 | long startSectionPosition = binaryReader.BaseStream.Position; 239 | 240 | value = (MaterialEffectType)binaryReader.ReadInt32(); 241 | 242 | if (binaryReader.BaseStream.Position == startSectionPosition + sectionSize) 243 | { 244 | isAtomicExtension = true; 245 | return this; 246 | } 247 | 248 | for (int i = 0; i < 2; i++) 249 | { 250 | MaterialEffect mEffect; 251 | MaterialEffectType locValue = (MaterialEffectType)binaryReader.ReadInt32(); 252 | switch (locValue) 253 | { 254 | case MaterialEffectType.BumpMap: 255 | mEffect = new MaterialEffectBumpMap().Read(binaryReader); break; 256 | case MaterialEffectType.EnvironmentMap: 257 | mEffect = new MaterialEffectEnvironmentMap().Read(binaryReader); break; 258 | case MaterialEffectType.DualTextures: 259 | mEffect = new MaterialEffectDualTextures().Read(binaryReader); break; 260 | case MaterialEffectType.UvTransformation: 261 | mEffect = new MaterialEffectUvTransformation().Read(); break; 262 | case MaterialEffectType.NoEffect: 263 | mEffect = null; break; 264 | default: 265 | throw new Exception(); 266 | } 267 | switch (i) 268 | { 269 | case 0: 270 | materialEffect1 = mEffect; 271 | break; 272 | case 1: 273 | materialEffect2 = mEffect; 274 | break; 275 | } 276 | } 277 | 278 | return this; 279 | } 280 | 281 | public override void SetListBytes(int fileVersion, ref List listBytes) 282 | { 283 | sectionIdentifier = Section.MaterialEffectsPLG; 284 | 285 | if (isAtomicExtension) 286 | listBytes.AddRange(BitConverter.GetBytes((int)value)); 287 | else 288 | { 289 | listBytes.AddRange(BitConverter.GetBytes((int)value)); 290 | 291 | if (materialEffect1 != null) 292 | listBytes.AddRange(materialEffect1.GetBytes(fileVersion)); 293 | else 294 | listBytes.AddRange(new byte[4]); 295 | 296 | if (materialEffect2 != null) 297 | listBytes.AddRange(materialEffect2.GetBytes(fileVersion)); 298 | else 299 | listBytes.AddRange(new byte[4]); 300 | } 301 | } 302 | } 303 | } 304 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/MaterialList_0008.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace RenderWareFile.Sections 7 | { 8 | public class MaterialList_0008 : RWSection 9 | { 10 | public MaterialListStruct_0001 materialListStruct; 11 | public Material_0007[] materialList; 12 | 13 | public MaterialList_0008 Read(BinaryReader binaryReader) 14 | { 15 | sectionIdentifier = Section.MaterialList; 16 | sectionSize = binaryReader.ReadInt32(); 17 | renderWareVersion = binaryReader.ReadInt32(); 18 | 19 | int startOfSection = (int)binaryReader.BaseStream.Position; 20 | 21 | Section materialListStructSection = (Section)binaryReader.ReadInt32(); 22 | if (materialListStructSection != Section.Struct) throw new Exception(); 23 | materialListStruct = new MaterialListStruct_0001().Read(binaryReader); 24 | 25 | #if DEBUG 26 | List materials = new List(); 27 | for (int i = 0; binaryReader.BaseStream.Position < startOfSection + sectionSize; i++) 28 | { 29 | Section materialSection = (Section)binaryReader.ReadInt32(); 30 | if (materialSection != Section.Material) throw new Exception(); 31 | materials.Add(new Material_0007().Read(binaryReader)); 32 | } 33 | materialList = materials.ToArray(); 34 | materialListStruct.materialCount = materialList.Length; 35 | #else 36 | materialList = new Material_0007[materialListStruct.materialCount]; 37 | for (int i = 0; i < materialListStruct.materialCount; i++) 38 | { 39 | Section materialSection = (Section)binaryReader.ReadInt32(); 40 | if (materialSection != Section.Material) throw new Exception(); 41 | materialList[i] = new Material_0007().Read(binaryReader); 42 | } 43 | #endif 44 | 45 | return this; 46 | } 47 | 48 | public override void SetListBytes(int fileVersion, ref List listBytes) 49 | { 50 | sectionIdentifier = Section.MaterialList; 51 | 52 | listBytes.AddRange(materialListStruct.GetBytes(fileVersion)); 53 | for (int i = 0; i < materialList.Count(); i++) 54 | { 55 | listBytes.AddRange(materialList[i].GetBytes(fileVersion)); 56 | } 57 | } 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Material_0007.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class Material_0007 : RWSection 8 | { 9 | public MaterialStruct_0001 materialStruct { get; set; } 10 | public Texture_0006 texture { get; set; } 11 | public Extension_0003 materialExtension { get; set; } 12 | 13 | public bool IsTextured 14 | { 15 | get => materialStruct.isTextured != 0; 16 | set 17 | { 18 | if (value) 19 | { 20 | materialStruct.isTextured = 1; 21 | if (texture == null) 22 | texture = new Texture_0006(); 23 | } 24 | else 25 | { 26 | materialStruct.isTextured = 0; 27 | texture = null; 28 | } 29 | } 30 | } 31 | 32 | public Material_0007 Read(BinaryReader binaryReader) 33 | { 34 | sectionIdentifier = Section.Material; 35 | sectionSize = binaryReader.ReadInt32(); 36 | renderWareVersion = binaryReader.ReadInt32(); 37 | 38 | Section materialListStructSection = (Section)binaryReader.ReadInt32(); 39 | if (materialListStructSection != Section.Struct) throw new Exception(); 40 | materialStruct = new MaterialStruct_0001().Read(binaryReader); 41 | 42 | if (materialStruct.isTextured != 0) 43 | { 44 | Section textureSection = (Section)binaryReader.ReadInt32(); 45 | if (textureSection != Section.Texture) throw new Exception(); 46 | texture = new Texture_0006().Read(binaryReader); 47 | } 48 | 49 | Section materialExtensionSection = (Section)binaryReader.ReadInt32(); 50 | if (materialExtensionSection != Section.Extension) throw new Exception(); 51 | materialExtension = new Extension_0003().Read(binaryReader); 52 | 53 | return this; 54 | } 55 | 56 | public override void SetListBytes(int fileVersion, ref List listBytes) 57 | { 58 | sectionIdentifier = Section.Material; 59 | 60 | listBytes.AddRange(materialStruct.GetBytes(fileVersion)); 61 | if (materialStruct.isTextured != 0) 62 | listBytes.AddRange(texture.GetBytes(fileVersion)); 63 | listBytes.AddRange(materialExtension.GetBytes(fileVersion)); 64 | } 65 | 66 | public override string ToString() 67 | { 68 | if (texture != null) 69 | return texture.diffuseTextureName.stringString; 70 | return "Diffuse Color: " + materialStruct.color.ToString(); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/NativeDataPLG_0510.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class NativeDataPLG_0510 : RWSection 8 | { 9 | public NativeDataStruct_0001 nativeDataStruct; 10 | 11 | public NativeDataPLG_0510 Read(BinaryReader binaryReader) 12 | { 13 | sectionIdentifier = Section.NativeDataPLG; 14 | sectionSize = binaryReader.ReadInt32(); 15 | renderWareVersion = binaryReader.ReadInt32(); 16 | 17 | Section nativeStructSection = (Section)binaryReader.ReadInt32(); 18 | if (nativeStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.Position.ToString()); 19 | nativeDataStruct = new NativeDataStruct_0001().Read(binaryReader); 20 | 21 | return this; 22 | } 23 | 24 | public override void SetListBytes(int fileVersion, ref List listBytes) 25 | { 26 | sectionIdentifier = Section.NativeDataPLG; 27 | listBytes.AddRange(nativeDataStruct.GetBytes(fileVersion)); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/PlaneSection_000A.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class PlaneSector_000A : RWSection 8 | { 9 | public PlaneStruct_0001 planeStruct; 10 | public RWSection leftSection; 11 | public RWSection rightSection; 12 | 13 | public PlaneSector_000A Read(BinaryReader binaryReader) 14 | { 15 | sectionIdentifier = Section.PlaneSector; 16 | sectionSize = binaryReader.ReadInt32(); 17 | renderWareVersion = binaryReader.ReadInt32(); 18 | 19 | Section planeStructSection = (Section)binaryReader.ReadInt32(); 20 | if (planeStructSection != Section.Struct) throw new Exception(); 21 | planeStruct = new PlaneStruct_0001().Read(binaryReader); 22 | 23 | Section leftSectionSection = (Section)binaryReader.ReadInt32(); 24 | if (leftSectionSection == Section.AtomicSector & planeStruct.leftIsAtomic == 1) 25 | { 26 | leftSection = new AtomicSector_0009().Read(binaryReader); 27 | } 28 | else if (leftSectionSection == Section.PlaneSector & planeStruct.leftIsAtomic == 0) 29 | { 30 | leftSection = new PlaneSector_000A().Read(binaryReader); 31 | } 32 | else throw new Exception(); 33 | 34 | Section rightSectionSection = (Section)binaryReader.ReadInt32(); 35 | if (rightSectionSection == Section.AtomicSector & planeStruct.rightIsAtomic == 1) 36 | { 37 | rightSection = new AtomicSector_0009().Read(binaryReader); 38 | } 39 | else if (rightSectionSection == Section.PlaneSector & planeStruct.rightIsAtomic == 0) 40 | { 41 | rightSection = new PlaneSector_000A().Read(binaryReader); 42 | } 43 | else throw new Exception(); 44 | 45 | return this; 46 | } 47 | 48 | public override void SetListBytes(int fileVersion, ref List listBytes) 49 | { 50 | sectionIdentifier = Section.PlaneSector; 51 | 52 | listBytes.AddRange(planeStruct.GetBytes(fileVersion)); 53 | listBytes.AddRange(leftSection.GetBytes(fileVersion)); 54 | listBytes.AddRange(rightSection.GetBytes(fileVersion)); 55 | } 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/String_0002.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.IO; 3 | 4 | namespace RenderWareFile.Sections 5 | { 6 | public class String_0002 : RWSection 7 | { 8 | public String_0002() 9 | { 10 | stringString = ""; 11 | } 12 | 13 | public String_0002(string value) 14 | { 15 | stringString = value; 16 | } 17 | 18 | public string stringString { get; private set; } 19 | 20 | public String_0002 Read(BinaryReader binaryReader) 21 | { 22 | sectionIdentifier = Section.String; 23 | sectionSize = binaryReader.ReadInt32(); 24 | renderWareVersion = binaryReader.ReadInt32(); 25 | 26 | long startSectionPosition = binaryReader.BaseStream.Position; 27 | 28 | stringString = Shared.ReadFromZeroTerminatedString(binaryReader); 29 | 30 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 31 | 32 | return this; 33 | } 34 | 35 | public override void SetListBytes(int fileVersion, ref List listBytes) 36 | { 37 | sectionIdentifier = Section.String; 38 | 39 | foreach (char i in stringString) 40 | listBytes.Add((byte)i); 41 | 42 | if (stringString.Length % 4 == 0) listBytes.AddRange(new byte[] { 0, 0, 0, 0 }); 43 | if (stringString.Length % 4 == 1) listBytes.AddRange(new byte[] { 0, 0, 0 }); 44 | if (stringString.Length % 4 == 2) listBytes.AddRange(new byte[] { 0, 0 }); 45 | if (stringString.Length % 4 == 3) listBytes.Add(0); 46 | } 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/AtomicSectorStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class AtomicSectorStruct_0001 : RWSection 8 | { 9 | public int matListWindowBase; 10 | public int numTriangles; 11 | public int numVertices; 12 | public Vertex3 boxMaximum; 13 | public Vertex3 boxMinimum; 14 | public int collSectorPresent; 15 | public int unused; 16 | 17 | public Vertex3[] vertexArray; 18 | public Color[] colorArray; 19 | public Vertex2[] uvArray; 20 | public Triangle[] triangleArray; 21 | 22 | public bool isNativeData = false; 23 | 24 | public AtomicSectorStruct_0001 Read(BinaryReader binaryReader) 25 | { 26 | sectionIdentifier = Section.Struct; 27 | sectionSize = binaryReader.ReadInt32(); 28 | renderWareVersion = binaryReader.ReadInt32(); 29 | 30 | long startSectionPosition = binaryReader.BaseStream.Position; 31 | 32 | matListWindowBase = binaryReader.ReadInt32(); 33 | numTriangles = binaryReader.ReadInt32(); 34 | numVertices = binaryReader.ReadInt32(); 35 | boxMaximum = new Vertex3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); 36 | boxMinimum = new Vertex3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); 37 | collSectorPresent = binaryReader.ReadInt32(); 38 | unused = binaryReader.ReadInt32(); 39 | 40 | if (binaryReader.BaseStream.Position == startSectionPosition + sectionSize) 41 | if (numVertices != 0 && numTriangles != 0) 42 | { 43 | isNativeData = true; 44 | return this; 45 | } 46 | 47 | binaryReader.BaseStream.Position = startSectionPosition + 11 * 4; 48 | 49 | vertexArray = new Vertex3[numVertices]; 50 | for (int i = 0; i < numVertices; i++) 51 | { 52 | vertexArray[i].X = binaryReader.ReadSingle(); 53 | vertexArray[i].Y = binaryReader.ReadSingle(); 54 | vertexArray[i].Z = binaryReader.ReadSingle(); 55 | } 56 | 57 | binaryReader.BaseStream.Position = startSectionPosition + 11 * 4 + 12 * numVertices; 58 | 59 | if (!ReadFileMethods.isCollision) 60 | { 61 | int supposedTotalSectionLenght = (11 * 4) + (12 + 4 + 8) * numVertices + 8 * numTriangles; 62 | bool twoVcolorArrays = false; 63 | 64 | if (sectionSize - supposedTotalSectionLenght == numVertices * 4) twoVcolorArrays = true; 65 | else if (sectionSize - supposedTotalSectionLenght == numVertices * 12) twoVcolorArrays = true; 66 | 67 | if (twoVcolorArrays) binaryReader.BaseStream.Position += 4 * numVertices; 68 | 69 | colorArray = new Color[numVertices]; 70 | for (int i = 0; i < numVertices; i++) 71 | { 72 | colorArray[i].R = binaryReader.ReadByte(); 73 | colorArray[i].G = binaryReader.ReadByte(); 74 | colorArray[i].B = binaryReader.ReadByte(); 75 | colorArray[i].A = binaryReader.ReadByte(); 76 | } 77 | 78 | if (twoVcolorArrays) 79 | binaryReader.BaseStream.Position = startSectionPosition + 11 * 4 + 20 * numVertices; 80 | else 81 | binaryReader.BaseStream.Position = startSectionPosition + 11 * 4 + 16 * numVertices; 82 | 83 | uvArray = new Vertex2[numVertices]; 84 | for (int i = 0; i < numVertices; i++) 85 | { 86 | uvArray[i].X = binaryReader.ReadSingle(); 87 | uvArray[i].Y = binaryReader.ReadSingle(); 88 | } 89 | } 90 | 91 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize - 8 * numTriangles; 92 | 93 | if (ReadFileMethods.isShadow) 94 | { 95 | // shadow 96 | triangleArray = new Triangle[numTriangles]; 97 | for (int i = 0; i < numTriangles; i++) 98 | { 99 | triangleArray[i].vertex1 = binaryReader.ReadUInt16(); 100 | triangleArray[i].vertex2 = binaryReader.ReadUInt16(); 101 | triangleArray[i].vertex3 = binaryReader.ReadUInt16(); 102 | triangleArray[i].materialIndex = binaryReader.ReadUInt16(); 103 | } 104 | } 105 | else 106 | { 107 | // heroes 108 | triangleArray = new Triangle[numTriangles]; 109 | for (int i = 0; i < numTriangles; i++) 110 | { 111 | triangleArray[i].materialIndex = binaryReader.ReadUInt16(); 112 | triangleArray[i].vertex1 = binaryReader.ReadUInt16(); 113 | triangleArray[i].vertex2 = binaryReader.ReadUInt16(); 114 | triangleArray[i].vertex3 = binaryReader.ReadUInt16(); 115 | } 116 | } 117 | 118 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 119 | 120 | return this; 121 | } 122 | 123 | public override void SetListBytes(int fileVersion, ref List listBytes) 124 | { 125 | sectionIdentifier = Section.Struct; 126 | 127 | listBytes.AddRange(BitConverter.GetBytes(matListWindowBase)); 128 | listBytes.AddRange(BitConverter.GetBytes(numTriangles)); 129 | listBytes.AddRange(BitConverter.GetBytes(numVertices)); 130 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.X)); 131 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Y)); 132 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Z)); 133 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.X)); 134 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.Y)); 135 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.Z)); 136 | listBytes.AddRange(BitConverter.GetBytes(collSectorPresent)); 137 | listBytes.AddRange(BitConverter.GetBytes(unused)); 138 | 139 | for (int i = 0; i < vertexArray.Length; i++) 140 | { 141 | listBytes.AddRange(BitConverter.GetBytes(vertexArray[i].X)); 142 | listBytes.AddRange(BitConverter.GetBytes(vertexArray[i].Y)); 143 | listBytes.AddRange(BitConverter.GetBytes(vertexArray[i].Z)); 144 | } 145 | 146 | if (!ReadFileMethods.isCollision) 147 | { 148 | for (int i = 0; i < colorArray.Length; i++) 149 | { 150 | listBytes.Add(colorArray[i].R); 151 | listBytes.Add(colorArray[i].G); 152 | listBytes.Add(colorArray[i].B); 153 | listBytes.Add(colorArray[i].A); 154 | } 155 | 156 | for (int i = 0; i < uvArray.Length; i++) 157 | { 158 | listBytes.AddRange(BitConverter.GetBytes(uvArray[i].X)); 159 | listBytes.AddRange(BitConverter.GetBytes(uvArray[i].Y)); 160 | } 161 | } 162 | 163 | if (ReadFileMethods.isShadow) 164 | for (int i = 0; i < triangleArray.Length; i++) 165 | { 166 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].vertex1)); 167 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].vertex2)); 168 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].vertex3)); 169 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].materialIndex)); 170 | } 171 | else 172 | for (int i = 0; i < triangleArray.Length; i++) 173 | { 174 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].materialIndex)); 175 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].vertex1)); 176 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].vertex2)); 177 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i].vertex3)); 178 | } 179 | } 180 | } 181 | } 182 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/AtomicStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public enum AtomicFlags : int 8 | { 9 | None = 0, 10 | CollisionTest = 1, 11 | Render = 4, 12 | CollisionTestAndRender = 5 13 | } 14 | 15 | public class AtomicStruct_0001 : RWSection 16 | { 17 | public int frameIndex; 18 | public int geometryIndex; 19 | public AtomicFlags flags; 20 | public int unused; 21 | 22 | public AtomicStruct_0001 Read(BinaryReader binaryReader) 23 | { 24 | sectionIdentifier = Section.Atomic; 25 | sectionSize = binaryReader.ReadInt32(); 26 | renderWareVersion = binaryReader.ReadInt32(); 27 | 28 | frameIndex = binaryReader.ReadInt32(); 29 | geometryIndex = binaryReader.ReadInt32(); 30 | flags = (AtomicFlags)binaryReader.ReadInt32(); 31 | unused = binaryReader.ReadInt32(); 32 | 33 | return this; 34 | } 35 | 36 | public override void SetListBytes(int fileVersion, ref List listBytes) 37 | { 38 | sectionIdentifier = Section.Struct; 39 | 40 | listBytes.AddRange(BitConverter.GetBytes(frameIndex)); 41 | listBytes.AddRange(BitConverter.GetBytes(geometryIndex)); 42 | listBytes.AddRange(BitConverter.GetBytes((int)flags)); 43 | listBytes.AddRange(BitConverter.GetBytes(unused)); 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/ClumpStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class ClumpStruct_0001 : RWSection 8 | { 9 | public int atomicCount; 10 | public int lightCount; 11 | public int cameraCount; 12 | 13 | public ClumpStruct_0001 Read(BinaryReader binaryReader) 14 | { 15 | sectionIdentifier = Section.Struct; 16 | sectionSize = binaryReader.ReadInt32(); 17 | renderWareVersion = binaryReader.ReadInt32(); 18 | 19 | long startSectionPosition = binaryReader.BaseStream.Position; 20 | 21 | atomicCount = binaryReader.ReadInt32(); 22 | lightCount = binaryReader.ReadInt32(); 23 | cameraCount = binaryReader.ReadInt32(); 24 | 25 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 26 | 27 | return this; 28 | } 29 | 30 | public override void SetListBytes(int fileVersion, ref List listBytes) 31 | { 32 | sectionIdentifier = Section.Struct; 33 | 34 | listBytes.AddRange(BitConverter.GetBytes(atomicCount)); 35 | if (fileVersion == 0x0310) 36 | return; 37 | listBytes.AddRange(BitConverter.GetBytes(lightCount)); 38 | listBytes.AddRange(BitConverter.GetBytes(cameraCount)); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/ColTreeStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class Split 8 | { 9 | public Sector negativeSector; 10 | public Sector positiveSector; 11 | 12 | public Split() 13 | { 14 | negativeSector = new Sector(); 15 | positiveSector = new Sector(); 16 | } 17 | } 18 | 19 | public enum SectorType : byte 20 | { 21 | PositiveX = 0x00, 22 | NegativeX = 0x01, 23 | PositiveY = 0x04, 24 | NegativeY = 0x05, 25 | PositiveZ = 0x08, 26 | NegativeZ = 0x09 27 | } 28 | 29 | public class Sector 30 | { 31 | public SectorType type; 32 | public byte triangleAmount; 33 | public ushort referenceIndex; 34 | public float splitPosition; 35 | 36 | public Vertex3 Min; 37 | public Vertex3 Max; 38 | public List TriangleIndexList; 39 | 40 | public Sector() 41 | { 42 | TriangleIndexList = new List(); 43 | } 44 | } 45 | 46 | public class ColTreeStruct_0001 : RWSection 47 | { 48 | public int useMap; 49 | public Vertex3 boxMinimum; 50 | public Vertex3 boxMaximum; 51 | public int numTriangles; 52 | public int numSplits; 53 | 54 | public Split[] splitArray; 55 | public ushort[] triangleArray; 56 | 57 | public ColTreeStruct_0001 Read(BinaryReader binaryReader) 58 | { 59 | sectionIdentifier = Section.Struct; 60 | sectionSize = binaryReader.ReadInt32(); 61 | renderWareVersion = binaryReader.ReadInt32(); 62 | 63 | useMap = binaryReader.ReadInt32(); 64 | boxMinimum = new Vertex3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); 65 | boxMaximum = new Vertex3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); 66 | numTriangles = binaryReader.ReadInt32(); 67 | numSplits = binaryReader.ReadInt32(); 68 | 69 | splitArray = new Split[numSplits]; 70 | 71 | for (int i = 0; i < numSplits; i++) 72 | { 73 | splitArray[i] = new Split(); 74 | splitArray[i].negativeSector = new Sector 75 | { 76 | type = (SectorType)binaryReader.ReadByte(), 77 | triangleAmount = binaryReader.ReadByte(), 78 | referenceIndex = binaryReader.ReadUInt16(), 79 | splitPosition = binaryReader.ReadSingle() 80 | }; 81 | 82 | splitArray[i].positiveSector = new Sector 83 | { 84 | type = (SectorType)binaryReader.ReadByte(), 85 | triangleAmount = binaryReader.ReadByte(), 86 | referenceIndex = binaryReader.ReadUInt16(), 87 | splitPosition = binaryReader.ReadSingle() 88 | }; 89 | } 90 | 91 | triangleArray = new ushort[numTriangles]; 92 | 93 | for (int i = 0; i < numTriangles; i++) 94 | { 95 | triangleArray[i] = binaryReader.ReadUInt16(); 96 | } 97 | 98 | return this; 99 | } 100 | 101 | public override void SetListBytes(int fileVersion, ref List listBytes) 102 | { 103 | sectionIdentifier = Section.Struct; 104 | 105 | listBytes.AddRange(BitConverter.GetBytes(useMap)); 106 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.X)); 107 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.Y)); 108 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.Z)); 109 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.X)); 110 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Y)); 111 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Z)); 112 | listBytes.AddRange(BitConverter.GetBytes(numTriangles)); 113 | listBytes.AddRange(BitConverter.GetBytes(numSplits)); 114 | 115 | for (int i = 0; i < numSplits; i++) 116 | { 117 | listBytes.Add((byte)splitArray[i].negativeSector.type); 118 | listBytes.Add(splitArray[i].negativeSector.triangleAmount); 119 | listBytes.AddRange(BitConverter.GetBytes(splitArray[i].negativeSector.referenceIndex)); 120 | listBytes.AddRange(BitConverter.GetBytes(splitArray[i].negativeSector.splitPosition)); 121 | 122 | listBytes.Add((byte)splitArray[i].positiveSector.type); 123 | listBytes.Add(splitArray[i].positiveSector.triangleAmount); 124 | listBytes.AddRange(BitConverter.GetBytes(splitArray[i].positiveSector.referenceIndex)); 125 | listBytes.AddRange(BitConverter.GetBytes(splitArray[i].positiveSector.splitPosition)); 126 | } 127 | 128 | if (triangleArray != null) 129 | for (int i = 0; i < numTriangles; i++) 130 | { 131 | listBytes.AddRange(BitConverter.GetBytes(triangleArray[i])); 132 | } 133 | } 134 | } 135 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/FrameListStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public struct Frame 8 | { 9 | public Matrix3x3 rotationMatrix; 10 | public Vertex3 position; 11 | public int parentFrame; 12 | public int unknown; 13 | } 14 | 15 | public class FrameListStruct_0001 : RWSection 16 | { 17 | public List frames; 18 | 19 | public FrameListStruct_0001 Read(BinaryReader binaryReader) 20 | { 21 | sectionIdentifier = Section.Struct; 22 | sectionSize = binaryReader.ReadInt32(); 23 | renderWareVersion = binaryReader.ReadInt32(); 24 | 25 | int frameCount = binaryReader.ReadInt32(); 26 | frames = new List(); 27 | 28 | for (int i = 0; i < frameCount; i++) 29 | frames.Add(new Frame() 30 | { 31 | rotationMatrix = new Matrix3x3 32 | { 33 | M11 = binaryReader.ReadSingle(), 34 | M12 = binaryReader.ReadSingle(), 35 | M13 = binaryReader.ReadSingle(), 36 | M21 = binaryReader.ReadSingle(), 37 | M22 = binaryReader.ReadSingle(), 38 | M23 = binaryReader.ReadSingle(), 39 | M31 = binaryReader.ReadSingle(), 40 | M32 = binaryReader.ReadSingle(), 41 | M33 = binaryReader.ReadSingle() 42 | }, 43 | position = new Vertex3 44 | { 45 | X = binaryReader.ReadSingle(), 46 | Y = binaryReader.ReadSingle(), 47 | Z = binaryReader.ReadSingle() 48 | }, 49 | parentFrame = binaryReader.ReadInt32(), 50 | unknown = binaryReader.ReadInt32() 51 | }); 52 | 53 | return this; 54 | } 55 | 56 | public override void SetListBytes(int fileVersion, ref List listBytes) 57 | { 58 | sectionIdentifier = Section.Struct; 59 | 60 | listBytes.AddRange(BitConverter.GetBytes(frames.Count)); 61 | foreach (Frame i in frames) 62 | { 63 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M11)); 64 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M12)); 65 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M13)); 66 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M21)); 67 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M22)); 68 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M23)); 69 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M31)); 70 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M32)); 71 | listBytes.AddRange(BitConverter.GetBytes(i.rotationMatrix.M33)); 72 | listBytes.AddRange(BitConverter.GetBytes(i.position.X)); 73 | listBytes.AddRange(BitConverter.GetBytes(i.position.Y)); 74 | listBytes.AddRange(BitConverter.GetBytes(i.position.Z)); 75 | listBytes.AddRange(BitConverter.GetBytes(i.parentFrame)); 76 | listBytes.AddRange(BitConverter.GetBytes(i.unknown)); 77 | } 78 | } 79 | } 80 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/GeometryListStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class GeometryListStruct_0001 : RWSection 8 | { 9 | public int numberOfGeometries; 10 | 11 | public GeometryListStruct_0001 Read(BinaryReader binaryReader) 12 | { 13 | sectionIdentifier = Section.Struct; 14 | sectionSize = binaryReader.ReadInt32(); 15 | renderWareVersion = binaryReader.ReadInt32(); 16 | 17 | numberOfGeometries = binaryReader.ReadInt32(); 18 | 19 | return this; 20 | } 21 | 22 | public override void SetListBytes(int fileVersion, ref List listBytes) 23 | { 24 | sectionIdentifier = Section.Struct; 25 | 26 | listBytes.AddRange(BitConverter.GetBytes(numberOfGeometries)); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/GeometryStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public struct MorphTarget 8 | { 9 | public Vertex3 sphereCenter; 10 | public float radius; 11 | public int hasVertices; 12 | public int hasNormals; 13 | 14 | public Vertex3[] vertices; 15 | public Vertex3[] normals; 16 | } 17 | 18 | public class GeometryStruct_0001 : RWSection 19 | { 20 | public GeometryFlags geometryFlags; 21 | public GeometryFlags2 geometryFlags2; 22 | public int numTriangles; 23 | public int numVertices; 24 | public int numMorphTargets; 25 | 26 | public float ambient; 27 | public float specular; 28 | public float diffuse; 29 | 30 | public float sphereCenterX; 31 | public float sphereCenterY; 32 | public float sphereCenterZ; 33 | public float sphereRadius; 34 | public int unknown1; 35 | public int unknown2; 36 | 37 | public Color[] vertexColors; 38 | public Vertex2[] textCoords; 39 | public Triangle[] triangles; 40 | public MorphTarget[] morphTargets; 41 | 42 | public byte[] sectionData; 43 | 44 | public GeometryStruct_0001 Read(BinaryReader binaryReader) 45 | { 46 | sectionIdentifier = Section.Struct; 47 | sectionSize = binaryReader.ReadInt32(); 48 | renderWareVersion = binaryReader.ReadInt32(); 49 | 50 | if (ReadFileMethods.treatStuffAsByteArray) 51 | { 52 | sectionData = binaryReader.ReadBytes(sectionSize); 53 | return this; 54 | } 55 | 56 | long startSectionPosition = binaryReader.BaseStream.Position; 57 | 58 | geometryFlags = (GeometryFlags)binaryReader.ReadInt16(); 59 | geometryFlags2 = (GeometryFlags2)binaryReader.ReadInt16(); 60 | numTriangles = binaryReader.ReadInt32(); 61 | numVertices = binaryReader.ReadInt32(); 62 | numMorphTargets = binaryReader.ReadInt32(); 63 | 64 | if (Shared.UnpackLibraryVersion(renderWareVersion) < 0x34000) 65 | { 66 | ambient = binaryReader.ReadSingle(); 67 | specular = binaryReader.ReadSingle(); 68 | diffuse = binaryReader.ReadSingle(); 69 | } 70 | 71 | if ((geometryFlags2 & GeometryFlags2.isNativeGeometry) != 0) 72 | { 73 | sphereCenterX = binaryReader.ReadSingle(); 74 | sphereCenterY = binaryReader.ReadSingle(); 75 | sphereCenterZ = binaryReader.ReadSingle(); 76 | sphereRadius = binaryReader.ReadSingle(); 77 | unknown1 = binaryReader.ReadInt32(); 78 | unknown2 = binaryReader.ReadInt32(); 79 | 80 | return this; 81 | } 82 | 83 | if ((geometryFlags & GeometryFlags.hasVertexColors) != 0) 84 | { 85 | vertexColors = new Color[numVertices]; 86 | for (int i = 0; i < numVertices; i++) 87 | { 88 | vertexColors[i] = new Color() 89 | { 90 | R = binaryReader.ReadByte(), 91 | G = binaryReader.ReadByte(), 92 | B = binaryReader.ReadByte(), 93 | A = binaryReader.ReadByte() 94 | }; 95 | } 96 | } 97 | 98 | if ((geometryFlags & GeometryFlags.hasTextCoords) != 0) 99 | { 100 | textCoords = new Vertex2[numVertices]; 101 | for (int i = 0; i < numVertices; i++) 102 | { 103 | textCoords[i] = new Vertex2() 104 | { 105 | X = binaryReader.ReadSingle(), 106 | Y = binaryReader.ReadSingle() 107 | }; 108 | } 109 | 110 | if ((geometryFlags & GeometryFlags.hasTextCoords2) != 0) 111 | binaryReader.BaseStream.Position += numVertices * 8; 112 | } 113 | else if ((geometryFlags & GeometryFlags.hasTextCoords2) != 0) 114 | { 115 | textCoords = new Vertex2[numVertices * 2]; 116 | for (int i = 0; i < numVertices * 2; i++) 117 | { 118 | textCoords[i] = new Vertex2() 119 | { 120 | X = binaryReader.ReadSingle(), 121 | Y = binaryReader.ReadSingle() 122 | }; 123 | } 124 | } 125 | 126 | triangles = new Triangle[numTriangles]; 127 | for (int i = 0; i < numTriangles; i++) 128 | { 129 | triangles[i] = new Triangle() 130 | { 131 | vertex2 = binaryReader.ReadUInt16(), 132 | vertex1 = binaryReader.ReadUInt16(), 133 | materialIndex = binaryReader.ReadUInt16(), 134 | vertex3 = binaryReader.ReadUInt16() 135 | }; 136 | } 137 | 138 | morphTargets = new MorphTarget[numMorphTargets]; 139 | for (int i = 0; i < numMorphTargets; i++) 140 | { 141 | MorphTarget m = new MorphTarget(); 142 | 143 | m.sphereCenter.X = binaryReader.ReadSingle(); 144 | m.sphereCenter.Y = binaryReader.ReadSingle(); 145 | m.sphereCenter.Z = binaryReader.ReadSingle(); 146 | m.radius = binaryReader.ReadSingle(); 147 | m.hasVertices = binaryReader.ReadInt32(); 148 | m.hasNormals = binaryReader.ReadInt32(); 149 | 150 | if (m.hasVertices != 0) 151 | { 152 | m.vertices = new Vertex3[numVertices]; 153 | for (int j = 0; j < numVertices; j++) 154 | { 155 | m.vertices[j] = new Vertex3() 156 | { 157 | X = binaryReader.ReadSingle(), 158 | Y = binaryReader.ReadSingle(), 159 | Z = binaryReader.ReadSingle() 160 | }; 161 | } 162 | } 163 | 164 | if (m.vertices == null) 165 | throw new Exception(); 166 | 167 | if (m.hasNormals != 0) 168 | { 169 | m.normals = new Vertex3[numVertices]; 170 | for (int j = 0; j < numVertices; j++) 171 | { 172 | m.normals[j] = new Vertex3() 173 | { 174 | X = binaryReader.ReadSingle(), 175 | Y = binaryReader.ReadSingle(), 176 | Z = binaryReader.ReadSingle() 177 | }; 178 | } 179 | } 180 | 181 | morphTargets[i] = m; 182 | } 183 | 184 | return this; 185 | } 186 | 187 | public override void SetListBytes(int fileVersion, ref List listBytes) 188 | { 189 | sectionIdentifier = Section.Struct; 190 | 191 | if (ReadFileMethods.treatStuffAsByteArray) 192 | { 193 | listBytes.AddRange(sectionData); 194 | return; 195 | } 196 | 197 | listBytes.AddRange(BitConverter.GetBytes((short)geometryFlags)); 198 | listBytes.AddRange(BitConverter.GetBytes((short)geometryFlags2)); 199 | listBytes.AddRange(BitConverter.GetBytes(numTriangles)); 200 | listBytes.AddRange(BitConverter.GetBytes(numVertices)); 201 | listBytes.AddRange(BitConverter.GetBytes(numMorphTargets)); 202 | 203 | if (Shared.UnpackLibraryVersion(fileVersion) < 0x34000) 204 | { 205 | listBytes.AddRange(BitConverter.GetBytes(ambient)); 206 | listBytes.AddRange(BitConverter.GetBytes(specular)); 207 | listBytes.AddRange(BitConverter.GetBytes(diffuse)); 208 | } 209 | 210 | if ((geometryFlags2 & GeometryFlags2.isNativeGeometry) != 0) 211 | { 212 | listBytes.AddRange(BitConverter.GetBytes(sphereCenterX)); 213 | listBytes.AddRange(BitConverter.GetBytes(sphereCenterY)); 214 | listBytes.AddRange(BitConverter.GetBytes(sphereCenterZ)); 215 | listBytes.AddRange(BitConverter.GetBytes(sphereRadius)); 216 | listBytes.AddRange(BitConverter.GetBytes(unknown1)); 217 | listBytes.AddRange(BitConverter.GetBytes(unknown2)); 218 | } 219 | else 220 | { 221 | if ((geometryFlags & GeometryFlags.hasVertexColors) != 0) 222 | { 223 | for (int i = 0; i < numVertices; i++) 224 | { 225 | listBytes.Add(vertexColors[i].R); 226 | listBytes.Add(vertexColors[i].G); 227 | listBytes.Add(vertexColors[i].B); 228 | listBytes.Add(vertexColors[i].A); 229 | } 230 | } 231 | 232 | if ((geometryFlags & GeometryFlags.hasTextCoords) != 0) 233 | { 234 | for (int i = 0; i < numVertices; i++) 235 | { 236 | listBytes.AddRange(BitConverter.GetBytes(textCoords[i].X)); 237 | listBytes.AddRange(BitConverter.GetBytes(textCoords[i].Y)); 238 | } 239 | } 240 | 241 | for (int i = 0; i < numTriangles; i++) 242 | { 243 | listBytes.AddRange(BitConverter.GetBytes(triangles[i].vertex2)); 244 | listBytes.AddRange(BitConverter.GetBytes(triangles[i].vertex1)); 245 | listBytes.AddRange(BitConverter.GetBytes(triangles[i].materialIndex)); 246 | listBytes.AddRange(BitConverter.GetBytes(triangles[i].vertex3)); 247 | } 248 | 249 | for (int i = 0; i < numMorphTargets; i++) 250 | { 251 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].sphereCenter.X)); 252 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].sphereCenter.Y)); 253 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].sphereCenter.Z)); 254 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].radius)); 255 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].hasVertices)); 256 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].hasNormals)); 257 | 258 | if (morphTargets[i].hasVertices != 0) 259 | { 260 | for (int j = 0; j < numVertices; j++) 261 | { 262 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].vertices[j].X)); 263 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].vertices[j].Y)); 264 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].vertices[j].Z)); 265 | } 266 | } 267 | 268 | if (morphTargets[i].hasNormals != 0) 269 | { 270 | for (int j = 0; j < numVertices; j++) 271 | { 272 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].normals[j].X)); 273 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].normals[j].Y)); 274 | listBytes.AddRange(BitConverter.GetBytes(morphTargets[i].normals[j].Z)); 275 | } 276 | } 277 | } 278 | } 279 | } 280 | } 281 | } 282 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/MaterialListStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class MaterialListStruct_0001 : RWSection 8 | { 9 | public int materialCount; 10 | 11 | public MaterialListStruct_0001 Read(BinaryReader binaryReader) 12 | { 13 | sectionIdentifier = Section.Struct; 14 | sectionSize = binaryReader.ReadInt32(); 15 | renderWareVersion = binaryReader.ReadInt32(); 16 | 17 | materialCount = binaryReader.ReadInt32(); 18 | for (int i = 0; i < materialCount; i++) 19 | { 20 | binaryReader.ReadInt32(); 21 | } 22 | 23 | return this; 24 | } 25 | 26 | public override void SetListBytes(int fileVersion, ref List listBytes) 27 | { 28 | sectionIdentifier = Section.Struct; 29 | 30 | listBytes.AddRange(BitConverter.GetBytes(materialCount)); 31 | for (int i = 0; i < materialCount; i++) 32 | { 33 | listBytes.AddRange(BitConverter.GetBytes(-1)); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/MaterialStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class MaterialStruct_0001 : RWSection 8 | { 9 | public int unusedFlags; 10 | public Color color; 11 | public int unusedInt2; 12 | public int isTextured; 13 | public float ambient; 14 | public float specular; 15 | public float diffuse; 16 | 17 | public MaterialStruct_0001 Read(BinaryReader binaryReader) 18 | { 19 | sectionIdentifier = Section.Struct; 20 | sectionSize = binaryReader.ReadInt32(); 21 | renderWareVersion = binaryReader.ReadInt32(); 22 | 23 | unusedFlags = binaryReader.ReadInt32(); 24 | byte R = binaryReader.ReadByte(); 25 | byte G = binaryReader.ReadByte(); 26 | byte B = binaryReader.ReadByte(); 27 | byte A = binaryReader.ReadByte(); 28 | color = new Color() { R = R, G = G, B = B, A = A }; 29 | unusedInt2 = binaryReader.ReadInt32(); 30 | isTextured = binaryReader.ReadInt32(); 31 | ambient = binaryReader.ReadSingle(); 32 | specular = binaryReader.ReadSingle(); 33 | diffuse = binaryReader.ReadSingle(); 34 | 35 | return this; 36 | } 37 | 38 | public override void SetListBytes(int fileVersion, ref List listBytes) 39 | { 40 | sectionIdentifier = Section.Struct; 41 | 42 | listBytes.AddRange(BitConverter.GetBytes(unusedFlags)); 43 | listBytes.AddRange(BitConverter.GetBytes((int)color)); 44 | listBytes.AddRange(BitConverter.GetBytes(unusedInt2)); 45 | listBytes.AddRange(BitConverter.GetBytes(isTextured)); 46 | listBytes.AddRange(BitConverter.GetBytes(ambient)); 47 | listBytes.AddRange(BitConverter.GetBytes(specular)); 48 | listBytes.AddRange(BitConverter.GetBytes(diffuse)); 49 | } 50 | } 51 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/NativeDataStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | 8 | public class NativeDataStruct_0001 : RWSection 9 | { 10 | public NativeDataType nativeDataType; 11 | public NativeDataGC nativeData; 12 | 13 | public byte[] nativeDataData; 14 | 15 | public NativeDataStruct_0001 Read(BinaryReader binaryReader) 16 | { 17 | sectionIdentifier = Section.Struct; 18 | sectionSize = binaryReader.ReadInt32(); 19 | renderWareVersion = binaryReader.ReadInt32(); 20 | 21 | if (ReadFileMethods.treatStuffAsByteArray) 22 | { 23 | nativeDataData = binaryReader.ReadBytes(sectionSize); 24 | return this; 25 | } 26 | 27 | long startSectionPosition = binaryReader.BaseStream.Position; 28 | 29 | nativeDataType = (NativeDataType)binaryReader.ReadInt32(); 30 | switch (nativeDataType) 31 | { 32 | case NativeDataType.GameCube: 33 | try 34 | { 35 | nativeData = new NativeDataGC(binaryReader, false); 36 | } 37 | catch 38 | { 39 | binaryReader.BaseStream.Position = startSectionPosition + 4; 40 | nativeData = new NativeDataGC(binaryReader, true); 41 | } 42 | break; 43 | default: 44 | throw new Exception(); 45 | } 46 | 47 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 48 | 49 | return this; 50 | } 51 | 52 | public override void SetListBytes(int fileVersion, ref List listBytes) 53 | { 54 | sectionIdentifier = Section.Struct; 55 | 56 | if (ReadFileMethods.treatStuffAsByteArray) 57 | { 58 | listBytes.AddRange(nativeDataData); 59 | return; 60 | } 61 | 62 | listBytes.AddRange(BitConverter.GetBytes((int)nativeDataType)); 63 | 64 | switch (nativeDataType) 65 | { 66 | case NativeDataType.GameCube: 67 | listBytes.AddRange(nativeData.GetBytes()); 68 | break; 69 | default: 70 | throw new Exception(); 71 | } 72 | } 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/PlaneStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class PlaneStruct_0001 : RWSection 8 | { 9 | public int type; 10 | public float value; 11 | public int leftIsAtomic; 12 | public int rightIsAtomic; 13 | public float leftValue; 14 | public float rightValue; 15 | 16 | public PlaneStruct_0001 Read(BinaryReader binaryReader) 17 | { 18 | sectionIdentifier = Section.Struct; 19 | sectionSize = binaryReader.ReadInt32(); 20 | renderWareVersion = binaryReader.ReadInt32(); 21 | 22 | type = binaryReader.ReadInt32(); 23 | value = binaryReader.ReadSingle(); 24 | leftIsAtomic = binaryReader.ReadInt32(); 25 | rightIsAtomic = binaryReader.ReadInt32(); 26 | leftValue = binaryReader.ReadSingle(); 27 | rightValue = binaryReader.ReadSingle(); 28 | 29 | return this; 30 | } 31 | 32 | public override void SetListBytes(int fileVersion, ref List listBytes) 33 | { 34 | sectionIdentifier = Section.Struct; 35 | 36 | listBytes.AddRange(BitConverter.GetBytes(type)); 37 | listBytes.AddRange(BitConverter.GetBytes(value)); 38 | listBytes.AddRange(BitConverter.GetBytes(leftIsAtomic)); 39 | listBytes.AddRange(BitConverter.GetBytes(rightIsAtomic)); 40 | listBytes.AddRange(BitConverter.GetBytes(leftValue)); 41 | listBytes.AddRange(BitConverter.GetBytes(rightValue)); 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/TextureDictionaryStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class TextureDictionaryStruct_0001 : RWSection 8 | { 9 | public short textureCount; 10 | public short unknown; 11 | 12 | public TextureDictionaryStruct_0001 Read(BinaryReader binaryReader) 13 | { 14 | sectionIdentifier = Section.Struct; 15 | sectionSize = binaryReader.ReadInt32(); 16 | renderWareVersion = binaryReader.ReadInt32(); 17 | 18 | textureCount = binaryReader.ReadInt16(); 19 | unknown = binaryReader.ReadInt16(); 20 | 21 | return this; 22 | } 23 | 24 | public override void SetListBytes(int fileVersion, ref List listBytes) 25 | { 26 | sectionIdentifier = Section.Struct; 27 | 28 | listBytes.AddRange(BitConverter.GetBytes(textureCount)); 29 | listBytes.AddRange(BitConverter.GetBytes(unknown)); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/TextureNativeStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace RenderWareFile.Sections 7 | { 8 | public struct MipMapEntry 9 | { 10 | public int dataSize; 11 | public byte[] data; 12 | 13 | public MipMapEntry(int dataSize, byte[] data) 14 | { 15 | this.dataSize = dataSize; 16 | this.data = data; 17 | } 18 | } 19 | 20 | public class TextureNativeStruct_0001 : RWSection 21 | { 22 | public int platformType; 23 | public TextureFilterMode filterMode; 24 | public TextureAddressMode addressModeU; // half a byte 25 | public TextureAddressMode addressModeV; // half a byte 26 | public string textureName; 27 | public string alphaName; 28 | public TextureRasterFormat rasterFormatFlags; 29 | public bool hasAlpha; 30 | public short width; 31 | public short height; 32 | public byte bitDepth; 33 | public byte mipMapCount; 34 | public byte type; 35 | public byte compression; 36 | public Color[] palette; 37 | public MipMapEntry[] mipMaps; 38 | 39 | public int gcnUnknown1; 40 | public int gcnUnknown2; 41 | public int gcnUnknown3; 42 | public int gcnUnknown4; 43 | 44 | public String_0002 ps2TextureNameString; 45 | public String_0002 ps2AlphaNameString; 46 | 47 | private int totalMipMapDataSize; 48 | 49 | private byte[] sectionData; 50 | private long startSectionPosition; 51 | 52 | public TextureNativeStruct_0001 Read(BinaryReader binaryReader) 53 | { 54 | sectionIdentifier = Section.Struct; 55 | sectionSize = binaryReader.ReadInt32(); 56 | renderWareVersion = binaryReader.ReadInt32(); 57 | 58 | startSectionPosition = binaryReader.BaseStream.Position; 59 | 60 | platformType = binaryReader.ReadInt32(); 61 | 62 | if (platformType == 8 | platformType == 5) 63 | { 64 | ReadNormalData(binaryReader, (int)startSectionPosition + sectionSize); 65 | } 66 | else if (platformType == 100663296) 67 | { 68 | ReadGameCubeData(binaryReader); 69 | } 70 | else if (platformType == 3298128) 71 | { 72 | ReadPS2Data(binaryReader); 73 | return this; 74 | } 75 | else throw new InvalidDataException("Unsupported texture format: " + platformType.ToString()); 76 | 77 | if (binaryReader.BaseStream.Position != startSectionPosition + sectionSize) 78 | throw new Exception(binaryReader.BaseStream.Position.ToString()); 79 | 80 | return this; 81 | } 82 | 83 | private void ReadNormalData(BinaryReader binaryReader, int endOfSectionPosition) 84 | { 85 | filterMode = (TextureFilterMode)binaryReader.ReadByte(); 86 | byte addressMode = binaryReader.ReadByte(); 87 | addressModeU = (TextureAddressMode)((addressMode & 0xF0) >> 4); 88 | addressModeV = (TextureAddressMode)(addressMode & 0x0F); 89 | binaryReader.BaseStream.Position += 2; 90 | 91 | textureName = ReadString(binaryReader); 92 | alphaName = ReadString(binaryReader); 93 | 94 | rasterFormatFlags = (TextureRasterFormat)binaryReader.ReadInt32(); 95 | hasAlpha = binaryReader.ReadInt32() != 0; 96 | width = binaryReader.ReadInt16(); 97 | height = binaryReader.ReadInt16(); 98 | 99 | bitDepth = binaryReader.ReadByte(); 100 | mipMapCount = binaryReader.ReadByte(); 101 | type = binaryReader.ReadByte(); 102 | compression = binaryReader.ReadByte(); 103 | 104 | if (platformType == 5) 105 | totalMipMapDataSize = binaryReader.ReadInt32(); 106 | 107 | int palleteSize = 108 | ((rasterFormatFlags & TextureRasterFormat.RASTER_PAL4) != 0) ? 0x80 / 4 : 109 | ((rasterFormatFlags & TextureRasterFormat.RASTER_PAL8) != 0) ? 0x400 / 4 : 0; 110 | 111 | if (palleteSize != 0) 112 | { 113 | palette = new Color[palleteSize]; 114 | for (int i = 0; i < palleteSize; i++) 115 | palette[i] = new Color(binaryReader.ReadInt32()); 116 | } 117 | 118 | int passedSize = 0; 119 | mipMaps = new MipMapEntry[mipMapCount]; 120 | for (int i = 0; i < mipMapCount; i++) 121 | { 122 | int dataSize = 0; 123 | 124 | if (platformType == 8) 125 | dataSize = binaryReader.ReadInt32(); 126 | else if (platformType == 5) 127 | dataSize = BiggestPowerOfTwoUnder(totalMipMapDataSize - passedSize); 128 | 129 | byte[] data = binaryReader.ReadBytes(dataSize); 130 | mipMaps[i] = new MipMapEntry(dataSize, data); 131 | 132 | passedSize += dataSize; 133 | } 134 | } 135 | 136 | private void ReadPS2Data(BinaryReader binaryReader) 137 | { 138 | filterMode = (TextureFilterMode)binaryReader.ReadByte(); 139 | byte addressMode = binaryReader.ReadByte(); 140 | addressModeU = (TextureAddressMode)((addressMode & 0xF0) >> 4); 141 | addressModeV = (TextureAddressMode)(addressMode & 0x0F); 142 | binaryReader.BaseStream.Position += 2; 143 | 144 | binaryReader.ReadInt32(); 145 | textureName = new String_0002().Read(binaryReader).stringString; 146 | binaryReader.ReadInt32(); 147 | alphaName = new String_0002().Read(binaryReader).stringString; 148 | 149 | binaryReader.ReadInt32(); 150 | int sizeOfdata = binaryReader.ReadInt32(); 151 | binaryReader.ReadInt32(); 152 | 153 | sectionData = binaryReader.ReadBytes(sizeOfdata); 154 | } 155 | 156 | private int BiggestPowerOfTwoUnder(int number) 157 | { 158 | return (int)Math.Pow(2, (Math.Floor(Math.Log(number, 2)))); 159 | } 160 | 161 | private void ReadGameCubeData(BinaryReader binaryReader) 162 | { 163 | binaryReader.BaseStream.Position += 2; 164 | byte addressMode = binaryReader.ReadByte(); 165 | addressModeU = (TextureAddressMode)((addressMode & 0xF0) >> 4); 166 | addressModeV = (TextureAddressMode)(addressMode & 0x0F); 167 | filterMode = (TextureFilterMode)binaryReader.ReadByte(); 168 | 169 | gcnUnknown1 = Shared.Switch(binaryReader.ReadInt32()); 170 | gcnUnknown2 = Shared.Switch(binaryReader.ReadInt32()); 171 | gcnUnknown3 = Shared.Switch(binaryReader.ReadInt32()); 172 | gcnUnknown4 = Shared.Switch(binaryReader.ReadInt32()); 173 | 174 | textureName = ReadString(binaryReader); 175 | alphaName = ReadString(binaryReader); 176 | 177 | if (ReadFileMethods.treatStuffAsByteArray) 178 | { 179 | sectionData = binaryReader.ReadBytes((int)(sectionSize - (binaryReader.BaseStream.Position - startSectionPosition))); 180 | return; 181 | } 182 | 183 | rasterFormatFlags = (TextureRasterFormat)Shared.Switch(binaryReader.ReadInt32()); 184 | width = Shared.Switch(binaryReader.ReadInt16()); 185 | height = Shared.Switch(binaryReader.ReadInt16()); 186 | 187 | bitDepth = binaryReader.ReadByte(); 188 | mipMapCount = binaryReader.ReadByte(); 189 | type = binaryReader.ReadByte(); 190 | compression = binaryReader.ReadByte(); 191 | 192 | int palleteSize = 193 | ((rasterFormatFlags & TextureRasterFormat.RASTER_PAL4) != 0) ? 0x80 / 4 : 194 | ((rasterFormatFlags & TextureRasterFormat.RASTER_PAL8) != 0) ? 0x400 / 4 : 0; 195 | 196 | if (palleteSize != 0) 197 | { 198 | palette = new Color[palleteSize]; 199 | for (int i = 0; i < palleteSize; i++) 200 | palette[i] = new Color(binaryReader.ReadInt32()); 201 | } 202 | 203 | mipMaps = new MipMapEntry[mipMapCount]; 204 | for (int i = 0; i < mipMapCount; i++) 205 | { 206 | int dataSize = Shared.Switch(binaryReader.ReadInt32()); 207 | byte[] data = binaryReader.ReadBytes(dataSize); 208 | 209 | mipMaps[i] = new MipMapEntry(dataSize, data); 210 | } 211 | } 212 | 213 | private static string ReadString(BinaryReader binaryReader) 214 | { 215 | long posBeforeString = binaryReader.BaseStream.Position; 216 | 217 | List chars = new List(); 218 | char c = binaryReader.ReadChar(); 219 | while (c != '\0') 220 | { 221 | chars.Add(c); 222 | c = binaryReader.ReadChar(); 223 | } 224 | 225 | binaryReader.BaseStream.Position = posBeforeString + 32; 226 | 227 | return new string(chars.ToArray()); 228 | } 229 | 230 | public override void SetListBytes(int fileVersion, ref List listBytes) 231 | { 232 | sectionIdentifier = Section.Struct; 233 | 234 | listBytes.AddRange(BitConverter.GetBytes(platformType)); 235 | 236 | if (platformType == 8 | platformType == 5) 237 | { 238 | SetNormalListBytes(fileVersion, ref listBytes); 239 | } 240 | else if (platformType == 100663296) 241 | { 242 | SetGameCubeListBytes(fileVersion, ref listBytes); 243 | } 244 | else if (platformType == 3298128) 245 | { 246 | SetPS2ListBytes(fileVersion, ref listBytes); 247 | } 248 | else throw new NotImplementedException("Unsupported writing of this platform type"); 249 | } 250 | 251 | private void SetNormalListBytes(int fileVersion, ref List listBytes) 252 | { 253 | listBytes.Add((byte)filterMode); 254 | listBytes.Add((byte)((byte)addressModeV + ((byte)addressModeU << 4))); 255 | listBytes.Add(0); 256 | listBytes.Add(0); 257 | 258 | foreach (char i in textureName) 259 | listBytes.Add((byte)i); 260 | for (int i = textureName.Length; i < 32; i++) 261 | listBytes.Add(0); 262 | foreach (char i in alphaName) 263 | listBytes.Add((byte)i); 264 | for (int i = alphaName.Length; i < 32; i++) 265 | listBytes.Add(0); 266 | 267 | listBytes.AddRange(BitConverter.GetBytes((short)rasterFormatFlags)); 268 | listBytes.Add(0); 269 | listBytes.Add(0); 270 | 271 | listBytes.AddRange(BitConverter.GetBytes(hasAlpha ? 1 : 0)); 272 | listBytes.AddRange(BitConverter.GetBytes(width)); 273 | listBytes.AddRange(BitConverter.GetBytes(height)); 274 | 275 | listBytes.Add(bitDepth); 276 | listBytes.Add(mipMapCount); 277 | listBytes.Add(type); 278 | listBytes.Add(compression); 279 | 280 | if (platformType == 5) 281 | { 282 | totalMipMapDataSize = 0; 283 | foreach (MipMapEntry i in mipMaps) 284 | totalMipMapDataSize += i.dataSize; 285 | 286 | listBytes.AddRange(BitConverter.GetBytes(totalMipMapDataSize)); 287 | } 288 | 289 | if (palette != null) 290 | foreach (Color c in palette) 291 | { 292 | listBytes.Add(c.R); 293 | listBytes.Add(c.G); 294 | listBytes.Add(c.B); 295 | listBytes.Add(c.A); 296 | } 297 | 298 | foreach (MipMapEntry i in mipMaps) 299 | { 300 | if (platformType == 8) 301 | listBytes.AddRange(BitConverter.GetBytes(i.dataSize)); 302 | 303 | foreach (byte j in i.data) 304 | listBytes.Add(j); 305 | } 306 | } 307 | 308 | private void SetPS2ListBytes(int fileVersion, ref List listBytes) 309 | { 310 | listBytes.Add((byte)filterMode); 311 | listBytes.Add((byte)((byte)addressModeV + ((byte)addressModeU << 4))); 312 | listBytes.Add(0); 313 | listBytes.Add(0); 314 | 315 | listBytes.AddRange(new String_0002(textureName).GetBytes(fileVersion)); 316 | listBytes.AddRange(new String_0002(alphaName).GetBytes(fileVersion)); 317 | 318 | listBytes.Add(1); 319 | listBytes.Add(0); 320 | listBytes.Add(0); 321 | listBytes.Add(0); 322 | listBytes.AddRange(BitConverter.GetBytes(sectionData.Length)); 323 | listBytes.AddRange(BitConverter.GetBytes(renderWareVersion)); 324 | listBytes.AddRange(sectionData); 325 | } 326 | 327 | private void SetGameCubeListBytes(int fileVersion, ref List listBytes) 328 | { 329 | listBytes.Add(0); 330 | listBytes.Add(0); 331 | listBytes.Add((byte)((byte)addressModeV + ((byte)addressModeU << 4))); 332 | listBytes.Add((byte)filterMode); 333 | 334 | listBytes.AddRange(BitConverter.GetBytes(gcnUnknown1).Reverse().ToArray()); 335 | listBytes.AddRange(BitConverter.GetBytes(gcnUnknown2).Reverse().ToArray()); 336 | listBytes.AddRange(BitConverter.GetBytes(gcnUnknown3).Reverse().ToArray()); 337 | listBytes.AddRange(BitConverter.GetBytes(gcnUnknown4).Reverse().ToArray()); 338 | 339 | for (int i = 0; i < 32; i++) 340 | { 341 | if (i < textureName.Length) 342 | listBytes.Add((byte)textureName[i]); 343 | else 344 | listBytes.Add(0); 345 | } 346 | 347 | for (int i = 0; i < 32; i++) 348 | { 349 | if (i < alphaName.Length) 350 | listBytes.Add((byte)alphaName[i]); 351 | else 352 | listBytes.Add(0); 353 | } 354 | 355 | if (ReadFileMethods.treatStuffAsByteArray) 356 | { 357 | listBytes.AddRange(sectionData); 358 | return; 359 | } 360 | else throw new NotImplementedException("Can't write GameCube texture as actual data yet."); 361 | } 362 | } 363 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/TextureStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class TextureStruct_0001 : RWSection 8 | { 9 | public TextureFilterMode FilterMode { get; set; } 10 | public TextureAddressMode AddressModeU { get; set; } // half a byte 11 | public TextureAddressMode AddressModeV { get; set; } // half a byte 12 | public ushort UseMipLevels { get; set; } 13 | 14 | public TextureStruct_0001() 15 | { 16 | sectionIdentifier = Section.Struct; 17 | FilterMode = TextureFilterMode.FILTERLINEARMIPLINEAR; 18 | 19 | AddressModeU = TextureAddressMode.TEXTUREADDRESSWRAP; 20 | AddressModeV = TextureAddressMode.TEXTUREADDRESSWRAP; 21 | 22 | UseMipLevels = 1; 23 | } 24 | 25 | public TextureStruct_0001 Read(BinaryReader binaryReader) 26 | { 27 | sectionIdentifier = Section.Struct; 28 | sectionSize = binaryReader.ReadInt32(); 29 | renderWareVersion = binaryReader.ReadInt32(); 30 | 31 | FilterMode = (TextureFilterMode)binaryReader.ReadByte(); 32 | 33 | byte addressMode = binaryReader.ReadByte(); 34 | AddressModeU = (TextureAddressMode)((addressMode & 0xF0) >> 4); 35 | AddressModeV = (TextureAddressMode)(addressMode & 0x0F); 36 | 37 | UseMipLevels = binaryReader.ReadUInt16(); 38 | 39 | return this; 40 | } 41 | 42 | public override void SetListBytes(int fileVersion, ref List listBytes) 43 | { 44 | sectionIdentifier = Section.Struct; 45 | 46 | listBytes.Add((byte)FilterMode); 47 | listBytes.Add((byte)((byte)AddressModeV + ((byte)AddressModeU << 4))); 48 | listBytes.AddRange(BitConverter.GetBytes(UseMipLevels)); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/Structs/WorldStruct_0001.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public enum WorldFlags 8 | { 9 | UseTriangleStrips = 0x00000001, 10 | HasVertexPositions = 0x00000002, 11 | HasOneSetOfTextCoords = 0x00000004, 12 | HasVertexColors = 0x00000008, 13 | HasNormals = 0x00000010, 14 | UseLighting = 0x00000020, 15 | ModulateMaterialColors = 0x00000040, 16 | HasMultipleSetsOfTextCoords = 0x00000080, 17 | IsNativeGeometry = 0x01000000, 18 | IsNativeInstance = 0x02000000, 19 | FlagsMask = 0x000000FF, 20 | NativeFlagsMask = 0x0F000000, 21 | WorldSectorsOverlap = 0x40000000 22 | } 23 | 24 | public class WorldStruct_0001 : RWSection 25 | { 26 | public int rootIsWorldSector; 27 | public Vertex3 inverseOrigin; 28 | public uint numTriangles; 29 | public uint numVertices; 30 | public uint numPlaneSectors; 31 | public uint numAtomicSectors; 32 | public uint colSectorSize; 33 | public WorldFlags worldFlags; 34 | public Vertex3 boxMaximum; 35 | public Vertex3 boxMinimum; 36 | 37 | public WorldStruct_0001 Read(BinaryReader binaryReader) 38 | { 39 | sectionIdentifier = Section.Struct; 40 | sectionSize = binaryReader.ReadInt32(); 41 | renderWareVersion = binaryReader.ReadInt32(); 42 | 43 | long startSectionPosition = binaryReader.BaseStream.Position; 44 | 45 | if (sectionSize == 0x40) 46 | { 47 | rootIsWorldSector = binaryReader.ReadInt32(); 48 | inverseOrigin.X = binaryReader.ReadSingle(); 49 | inverseOrigin.Y = binaryReader.ReadSingle(); 50 | inverseOrigin.Z = binaryReader.ReadSingle(); 51 | numTriangles = binaryReader.ReadUInt32(); 52 | numVertices = binaryReader.ReadUInt32(); 53 | numPlaneSectors = binaryReader.ReadUInt32(); 54 | numAtomicSectors = binaryReader.ReadUInt32(); 55 | colSectorSize = binaryReader.ReadUInt32(); 56 | worldFlags = (WorldFlags)binaryReader.ReadUInt32(); 57 | boxMaximum = new Vertex3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); 58 | boxMinimum = new Vertex3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); 59 | } 60 | else if (sectionSize == 0x34) 61 | { 62 | rootIsWorldSector = binaryReader.ReadInt32(); 63 | inverseOrigin.X = binaryReader.ReadSingle(); 64 | inverseOrigin.Y = binaryReader.ReadSingle(); 65 | inverseOrigin.Z = binaryReader.ReadSingle(); 66 | boxMaximum = new Vertex3(binaryReader.ReadSingle(), binaryReader.ReadSingle(), binaryReader.ReadSingle()); 67 | boxMinimum = boxMaximum; 68 | numTriangles = binaryReader.ReadUInt32(); 69 | numVertices = binaryReader.ReadUInt32(); 70 | numPlaneSectors = binaryReader.ReadUInt32(); 71 | numAtomicSectors = binaryReader.ReadUInt32(); 72 | colSectorSize = binaryReader.ReadUInt32(); 73 | worldFlags = (WorldFlags)binaryReader.ReadUInt32(); 74 | } 75 | 76 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 77 | 78 | return this; 79 | } 80 | 81 | public override void SetListBytes(int fileVersion, ref List listBytes) 82 | { 83 | sectionIdentifier = Section.Struct; 84 | 85 | if (fileVersion == 0x0310) 86 | { 87 | listBytes.AddRange(BitConverter.GetBytes(rootIsWorldSector)); 88 | listBytes.AddRange(BitConverter.GetBytes(inverseOrigin.X)); 89 | listBytes.AddRange(BitConverter.GetBytes(inverseOrigin.Y)); 90 | listBytes.AddRange(BitConverter.GetBytes(inverseOrigin.Z)); 91 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.X)); 92 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Y)); 93 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Z)); 94 | listBytes.AddRange(BitConverter.GetBytes(numTriangles)); 95 | listBytes.AddRange(BitConverter.GetBytes(numVertices)); 96 | listBytes.AddRange(BitConverter.GetBytes(numPlaneSectors)); 97 | listBytes.AddRange(BitConverter.GetBytes(numAtomicSectors)); 98 | listBytes.AddRange(BitConverter.GetBytes(colSectorSize)); 99 | listBytes.AddRange(BitConverter.GetBytes((int)worldFlags)); 100 | } 101 | else 102 | { 103 | listBytes.AddRange(BitConverter.GetBytes(rootIsWorldSector)); 104 | listBytes.AddRange(BitConverter.GetBytes(inverseOrigin.X)); 105 | listBytes.AddRange(BitConverter.GetBytes(inverseOrigin.Y)); 106 | listBytes.AddRange(BitConverter.GetBytes(inverseOrigin.Z)); 107 | listBytes.AddRange(BitConverter.GetBytes(numTriangles)); 108 | listBytes.AddRange(BitConverter.GetBytes(numVertices)); 109 | listBytes.AddRange(BitConverter.GetBytes(numPlaneSectors)); 110 | listBytes.AddRange(BitConverter.GetBytes(numAtomicSectors)); 111 | listBytes.AddRange(BitConverter.GetBytes(colSectorSize)); 112 | listBytes.AddRange(BitConverter.GetBytes((int)worldFlags)); 113 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.X)); 114 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Y)); 115 | listBytes.AddRange(BitConverter.GetBytes(boxMaximum.Z)); 116 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.X)); 117 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.Y)); 118 | listBytes.AddRange(BitConverter.GetBytes(boxMinimum.Z)); 119 | } 120 | } 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/TextureDictionary_0016.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class TextureDictionary_0016 : RWSection 8 | { 9 | public TextureDictionaryStruct_0001 textureDictionaryStruct; 10 | public List textureNativeList; 11 | public Extension_0003 textureDictionaryExtension; 12 | 13 | public TextureDictionary_0016 Read(BinaryReader binaryReader) 14 | { 15 | sectionIdentifier = Section.TextureDictionary; 16 | sectionSize = binaryReader.ReadInt32(); 17 | renderWareVersion = binaryReader.ReadInt32(); 18 | 19 | long startSectionPosition = binaryReader.BaseStream.Position; 20 | 21 | Section textureDictionaryStructSection = (Section)binaryReader.ReadInt32(); 22 | if (textureDictionaryStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.Position.ToString()); 23 | textureDictionaryStruct = new TextureDictionaryStruct_0001().Read(binaryReader); 24 | 25 | textureNativeList = new List(); 26 | 27 | for (int i = 0; i < textureDictionaryStruct.textureCount; i++) 28 | { 29 | Section textureNativeSection = (Section)binaryReader.ReadInt32(); 30 | if (textureNativeSection != Section.TextureNative) throw new Exception(binaryReader.BaseStream.Position.ToString()); 31 | textureNativeList.Add(new TextureNative_0015().Read(binaryReader)); 32 | } 33 | 34 | Section textureDictionaryExtensionSection = (Section)binaryReader.ReadInt32(); 35 | if (textureDictionaryExtensionSection == Section.Extension) 36 | textureDictionaryExtension = new Extension_0003().Read(binaryReader); 37 | 38 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 39 | 40 | return this; 41 | } 42 | 43 | public override void SetListBytes(int fileVersion, ref List listBytes) 44 | { 45 | sectionIdentifier = Section.TextureDictionary; 46 | 47 | listBytes.AddRange(textureDictionaryStruct.GetBytes(fileVersion)); 48 | 49 | foreach (TextureNative_0015 i in textureNativeList) 50 | listBytes.AddRange(i.GetBytes(fileVersion)); 51 | 52 | listBytes.AddRange(textureDictionaryExtension.GetBytes(fileVersion)); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/TextureNative_0015.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class TextureNative_0015 : RWSection 8 | { 9 | public TextureNativeStruct_0001 textureNativeStruct; 10 | public Extension_0003 textureNativeExtension; 11 | 12 | public TextureNative_0015 Read(BinaryReader binaryReader) 13 | { 14 | sectionIdentifier = Section.TextureNative; 15 | sectionSize = binaryReader.ReadInt32(); 16 | renderWareVersion = binaryReader.ReadInt32(); 17 | 18 | try 19 | { 20 | Section textureNativeStructSection = (Section)binaryReader.ReadInt32(); 21 | if (textureNativeStructSection != Section.Struct) 22 | throw new Exception(binaryReader.BaseStream.Position.ToString()); 23 | textureNativeStruct = new TextureNativeStruct_0001(); 24 | textureNativeStruct.Read(binaryReader); 25 | } 26 | catch (Exception ex) 27 | { 28 | throw new Exception(textureNativeStruct.textureName + ": " + ex.Message, ex); 29 | } 30 | 31 | Section textureNativeExtensionSection = (Section)binaryReader.ReadInt32(); 32 | if (textureNativeExtensionSection == Section.Extension) 33 | textureNativeExtension = new Extension_0003().Read(binaryReader); 34 | 35 | return this; 36 | } 37 | 38 | public TextureNative_0015 FromBytes(byte[] data) 39 | { 40 | BinaryReader binaryReader = new BinaryReader(new MemoryStream(data)); 41 | 42 | sectionIdentifier = (Section)binaryReader.ReadInt32(); 43 | if (sectionIdentifier != Section.TextureNative) throw new Exception(binaryReader.BaseStream.Position.ToString()); 44 | 45 | sectionSize = binaryReader.ReadInt32(); 46 | renderWareVersion = binaryReader.ReadInt32(); 47 | 48 | Section textureNativeStructSection = (Section)binaryReader.ReadInt32(); 49 | if (textureNativeStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.Position.ToString()); 50 | textureNativeStruct = new TextureNativeStruct_0001().Read(binaryReader); 51 | 52 | Section textureNativeExtensionSection = (Section)binaryReader.ReadInt32(); 53 | if (textureNativeExtensionSection == Section.Extension) 54 | textureNativeExtension = new Extension_0003().Read(binaryReader); 55 | 56 | return this; 57 | } 58 | 59 | public override void SetListBytes(int fileVersion, ref List listBytes) 60 | { 61 | sectionIdentifier = Section.TextureNative; 62 | 63 | listBytes.AddRange(textureNativeStruct.GetBytes(fileVersion)); 64 | if (textureNativeExtension != null) 65 | listBytes.AddRange(textureNativeExtension.GetBytes(fileVersion)); 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/Texture_0006.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.ComponentModel; 4 | using System.IO; 5 | 6 | namespace RenderWareFile.Sections 7 | { 8 | [TypeConverter(typeof(ExpandableObjectConverter))] 9 | public class Texture_0006 : RWSection 10 | { 11 | public TextureStruct_0001 textureStruct; 12 | public String_0002 diffuseTextureName; 13 | public String_0002 alphaTextureName; 14 | public Extension_0003 textureExtension; 15 | 16 | public Texture_0006() 17 | { 18 | textureStruct = new TextureStruct_0001(); 19 | diffuseTextureName = new String_0002(); 20 | alphaTextureName = new String_0002(); 21 | textureExtension = new Extension_0003(); 22 | } 23 | 24 | public string DiffuseTextureName 25 | { 26 | get => diffuseTextureName.stringString; 27 | set => diffuseTextureName = new String_0002(value); 28 | } 29 | 30 | public string AlphaTextureName 31 | { 32 | get => alphaTextureName.stringString; 33 | set => alphaTextureName = new String_0002(value); 34 | } 35 | 36 | public TextureFilterMode FilterMode 37 | { 38 | get => textureStruct.FilterMode; 39 | set => textureStruct.FilterMode = value; 40 | } 41 | public TextureAddressMode AddressModeU 42 | { 43 | get => textureStruct.AddressModeU; 44 | set => textureStruct.AddressModeU = value; 45 | } 46 | public TextureAddressMode AddressModeV 47 | { 48 | get => textureStruct.AddressModeV; 49 | set => textureStruct.AddressModeV = value; 50 | } 51 | public ushort UseMipLevels 52 | { 53 | get => textureStruct.UseMipLevels; 54 | set => textureStruct.UseMipLevels = value; 55 | } 56 | 57 | public Texture_0006 Read(BinaryReader binaryReader) 58 | { 59 | sectionIdentifier = Section.Texture; 60 | sectionSize = binaryReader.ReadInt32(); 61 | renderWareVersion = binaryReader.ReadInt32(); 62 | 63 | Section textureStructSection = (Section)binaryReader.ReadInt32(); 64 | if (textureStructSection != Section.Struct) throw new Exception(); 65 | textureStruct = new TextureStruct_0001().Read(binaryReader); 66 | 67 | Section diffuseTextureNameSection = (Section)binaryReader.ReadInt32(); 68 | if (diffuseTextureNameSection != Section.String) throw new Exception(); 69 | diffuseTextureName = new String_0002().Read(binaryReader); 70 | 71 | Section alphaTextureNameSection = (Section)binaryReader.ReadInt32(); 72 | if (alphaTextureNameSection != Section.String) throw new Exception(); 73 | alphaTextureName = new String_0002().Read(binaryReader); 74 | 75 | Section textureExtensionSection = (Section)binaryReader.ReadInt32(); 76 | if (textureExtensionSection != Section.Extension) throw new Exception(); 77 | textureExtension = new Extension_0003().Read(binaryReader); 78 | 79 | return this; 80 | } 81 | 82 | public override void SetListBytes(int fileVersion, ref List listBytes) 83 | { 84 | sectionIdentifier = Section.Texture; 85 | 86 | listBytes.AddRange(textureStruct.GetBytes(fileVersion)); 87 | listBytes.AddRange(diffuseTextureName.GetBytes(fileVersion)); 88 | listBytes.AddRange(alphaTextureName.GetBytes(fileVersion)); 89 | listBytes.AddRange(textureExtension.GetBytes(fileVersion)); 90 | } 91 | } 92 | } 93 | -------------------------------------------------------------------------------- /RenderWareFile/Sections/UserDataPLG_011F.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class UserDataPLG_011F : RWSection 8 | { 9 | public byte[] data; 10 | 11 | public int userDataType; 12 | public int unknown2; 13 | public string attribute; 14 | public int unknown3; 15 | public int numTriangles; 16 | public Color[] collisionFlags; 17 | public int unknown4; 18 | public string userData; 19 | public int unknown5; 20 | public int unknown6; 21 | public int unknown7; 22 | 23 | public UserDataPLG_011F Read(BinaryReader binaryReader) 24 | { 25 | sectionIdentifier = Section.UserDataPLG; 26 | sectionSize = binaryReader.ReadInt32(); 27 | renderWareVersion = binaryReader.ReadInt32(); 28 | 29 | data = binaryReader.ReadBytes(sectionSize); 30 | 31 | if (!ReadFileMethods.isCollision) 32 | return this; 33 | 34 | binaryReader.BaseStream.Position -= sectionSize; 35 | 36 | userDataType = binaryReader.ReadInt32(); 37 | 38 | if (userDataType == 0x02) 39 | { 40 | unknown2 = binaryReader.ReadInt32(); 41 | attribute = Shared.ReadFromZeroTerminatedString(binaryReader); 42 | unknown3 = binaryReader.ReadInt32(); 43 | numTriangles = binaryReader.ReadInt32(); 44 | collisionFlags = new Color[numTriangles]; 45 | for (int i = 0; i < numTriangles; i++) 46 | { 47 | collisionFlags[i] = new Color(binaryReader.ReadInt32()); 48 | } 49 | unknown4 = binaryReader.ReadInt32(); 50 | } 51 | 52 | userData = Shared.ReadFromZeroTerminatedString(binaryReader); 53 | unknown5 = binaryReader.ReadInt32(); 54 | unknown6 = binaryReader.ReadInt32(); 55 | unknown7 = binaryReader.ReadInt32(); 56 | 57 | return this; 58 | } 59 | 60 | public override void SetListBytes(int fileVersion, ref List listBytes) 61 | { 62 | sectionIdentifier = Section.UserDataPLG; 63 | 64 | if (!ReadFileMethods.isCollision) 65 | { 66 | listBytes.AddRange(data); 67 | return; 68 | } 69 | 70 | listBytes.AddRange(BitConverter.GetBytes(userDataType)); 71 | listBytes.AddRange(BitConverter.GetBytes(unknown2)); 72 | foreach (char i in attribute) 73 | listBytes.Add((byte)i); 74 | listBytes.Add(0); 75 | listBytes.AddRange(BitConverter.GetBytes(unknown3)); 76 | listBytes.AddRange(BitConverter.GetBytes(numTriangles)); 77 | for (int i = 0; i < numTriangles; i++) 78 | { 79 | listBytes.Add(collisionFlags[i].R); 80 | listBytes.Add(collisionFlags[i].G); 81 | listBytes.Add(collisionFlags[i].B); 82 | listBytes.Add(collisionFlags[i].A); 83 | } 84 | listBytes.AddRange(BitConverter.GetBytes(unknown4)); 85 | foreach (char i in userData) 86 | listBytes.Add((byte)i); 87 | listBytes.Add(0); 88 | listBytes.AddRange(BitConverter.GetBytes(unknown5)); 89 | listBytes.AddRange(BitConverter.GetBytes(unknown6)); 90 | listBytes.AddRange(BitConverter.GetBytes(unknown7)); 91 | } 92 | } 93 | } -------------------------------------------------------------------------------- /RenderWareFile/Sections/World_000B.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | 5 | namespace RenderWareFile.Sections 6 | { 7 | public class World_000B : RWSection 8 | { 9 | public WorldStruct_0001 worldStruct; 10 | public MaterialList_0008 materialList; 11 | public RWSection firstWorldChunk; 12 | public Extension_0003 worldExtension; 13 | 14 | public World_000B Read(BinaryReader binaryReader) 15 | { 16 | sectionIdentifier = Section.World; 17 | sectionSize = binaryReader.ReadInt32(); 18 | renderWareVersion = binaryReader.ReadInt32(); 19 | 20 | long startSectionPosition = binaryReader.BaseStream.Position; 21 | 22 | Section worldStructSection = (Section)binaryReader.ReadInt32(); 23 | if (worldStructSection != Section.Struct) throw new Exception(binaryReader.BaseStream.Position.ToString()); 24 | worldStruct = new WorldStruct_0001().Read(binaryReader); 25 | 26 | Section materialListSection = (Section)binaryReader.ReadInt32(); 27 | if (materialListSection != Section.MaterialList) throw new Exception(); 28 | materialList = new MaterialList_0008().Read(binaryReader); 29 | 30 | Section firstWorldChunkSection = (Section)binaryReader.ReadInt32(); 31 | if (firstWorldChunkSection == Section.AtomicSector) 32 | { 33 | firstWorldChunk = new AtomicSector_0009().Read(binaryReader); 34 | } 35 | else if (firstWorldChunkSection == Section.PlaneSector) 36 | { 37 | firstWorldChunk = new PlaneSector_000A().Read(binaryReader); 38 | } 39 | else throw new Exception(); 40 | 41 | Section worldExtensionSection = (Section)binaryReader.ReadInt32(); 42 | if (worldExtensionSection == Section.Extension) 43 | worldExtension = new Extension_0003().Read(binaryReader); 44 | 45 | binaryReader.BaseStream.Position = startSectionPosition + sectionSize; 46 | 47 | return this; 48 | } 49 | 50 | public override void SetListBytes(int fileVersion, ref List listBytes) 51 | { 52 | sectionIdentifier = Section.World; 53 | 54 | listBytes.AddRange(worldStruct.GetBytes(fileVersion)); 55 | listBytes.AddRange(materialList.GetBytes(fileVersion)); 56 | listBytes.AddRange(firstWorldChunk.GetBytes(fileVersion)); 57 | listBytes.AddRange(worldExtension.GetBytes(fileVersion)); 58 | } 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /RenderWareFile/Shared.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.IO; 4 | using System.Linq; 5 | 6 | namespace RenderWareFile 7 | { 8 | public static class Shared 9 | { 10 | public static int UnpackLibraryVersion(int libid) 11 | { 12 | if ((libid & 0xFFFF0000) != 0) 13 | return (libid >> 14 & 0x3FF00) + 0x30000 | 14 | (libid >> 16 & 0x3F); 15 | return libid << 8; 16 | } 17 | 18 | public static bool DoNotSwitch = false; 19 | 20 | public static float Switch(float f) 21 | { 22 | byte[] a = BitConverter.GetBytes(f); 23 | return BitConverter.ToSingle(new byte[] { a[3], a[2], a[1], a[0] }, 0); 24 | } 25 | 26 | public static int Switch(int f) 27 | { 28 | byte[] a = BitConverter.GetBytes(f); 29 | return BitConverter.ToInt32(new byte[] { a[3], a[2], a[1], a[0] }, 0); 30 | } 31 | 32 | public static short Switch(short f) 33 | { 34 | byte[] a = BitConverter.GetBytes(f); 35 | return BitConverter.ToInt16(new byte[] { a[1], a[0] }, 0); 36 | } 37 | 38 | public static float SwitchToggleable(float f) 39 | { 40 | return DoNotSwitch ? f : Switch(f); 41 | } 42 | 43 | public static int SwitchToggleable(int f) 44 | { 45 | return DoNotSwitch ? f : Switch(f); 46 | } 47 | 48 | public static short SwitchToggleable(short f) 49 | { 50 | return DoNotSwitch ? f : Switch(f); 51 | } 52 | 53 | public static string ReadFromZeroTerminatedString(BinaryReader binaryReader) 54 | { 55 | List charList = new List(); 56 | byte c = binaryReader.ReadByte(); 57 | while (c != 0) 58 | { 59 | charList.Add((char)c); 60 | c = binaryReader.ReadByte(); 61 | } 62 | 63 | return new string(charList.ToArray()); 64 | } 65 | 66 | public static List MaterialList; 67 | } 68 | } 69 | --------------------------------------------------------------------------------