Example #1
0
 private static void WriteTextures(ChunkWriter chunkIO, List <WadTexture> textureTable)
 {
     chunkIO.WriteChunkWithChildren(Wad2Chunks.Textures, () =>
     {
         foreach (var texture in textureTable)
         {
             chunkIO.WriteChunkWithChildren(Wad2Chunks.Texture, () =>
             {
                 LEB128.Write(chunkIO.Raw, texture.Image.Width);
                 LEB128.Write(chunkIO.Raw, texture.Image.Height);
                 chunkIO.WriteChunkArrayOfBytes(Wad2Chunks.TextureData, texture.Image.ToByteArray());
             });
         }
     });
 }
Example #2
0
 private static void WriteSpriteSequences(ChunkWriter chunkIO, Wad2 wad, List <WadSprite> spriteTable)
 {
     chunkIO.WriteChunkWithChildren(Wad2Chunks.SpriteSequences, () =>
     {
         foreach (var sequence in wad.SpriteSequences.Values)
         {
             chunkIO.WriteChunkWithChildren(Wad2Chunks.SpriteSequence, () =>
             {
                 LEB128.Write(chunkIO.Raw, sequence.Id.TypeId);
                 foreach (var spr in sequence.Sprites)
                 {
                     chunkIO.WriteChunkInt(Wad2Chunks.SpriteSequenceSpriteIndex, spriteTable.IndexOf(spr));
                 }
             });
         }
     });
 }
Example #3
0
        private static void WriteStatics(ChunkWriter chunkIO, Wad2 wad, List <WadTexture> textureTable)
        {
            chunkIO.WriteChunkWithChildren(Wad2Chunks.Statics, () =>
            {
                foreach (var staticMesh in wad.Statics)
                {
                    chunkIO.WriteChunkWithChildren(Wad2Chunks.Static, () =>
                    {
                        var s = staticMesh.Value;

                        LEB128.Write(chunkIO.Raw, s.Id.TypeId);
                        LEB128.Write(chunkIO.Raw, s.Flags);
                        LEB128.Write(chunkIO.Raw, (short)s.LightingType);

                        WriteMesh(chunkIO, s.Mesh, textureTable);

                        chunkIO.WriteChunkInt(Wad2Chunks.StaticAmbientLight, s.AmbientLight);

                        foreach (var light in s.Lights)
                        {
                            chunkIO.WriteChunkWithChildren(Wad2Chunks.StaticLight, () =>
                            {
                                chunkIO.WriteChunkVector3(Wad2Chunks.StaticLightPosition, light.Position);
                                chunkIO.WriteChunkFloat(Wad2Chunks.StaticLightRadius, light.Radius);
                                chunkIO.WriteChunkFloat(Wad2Chunks.StaticLightIntensity, light.Intensity);
                            });
                        }

                        chunkIO.WriteChunkWithChildren(Wad2Chunks.StaticVisibilityBox, () =>
                        {
                            chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMin, s.VisibilityBox.Minimum);
                            chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMax, s.VisibilityBox.Maximum);
                        });

                        chunkIO.WriteChunkWithChildren(Wad2Chunks.StaticCollisionBox, () =>
                        {
                            chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMin, s.CollisionBox.Minimum);
                            chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMax, s.CollisionBox.Maximum);
                        });

                        //chunkIO.WriteChunkString(Wad2Chunks.StaticName, s.Name);
                    });
                }
            });
        }
Example #4
0
 private static void WriteSprites(ChunkWriter chunkIO, List <WadSprite> spriteTable)
 {
     chunkIO.WriteChunkWithChildren(Wad2Chunks.Sprites, () =>
     {
         for (int i = 0; i < spriteTable.Count; ++i)
         {
             var sprite = spriteTable[i];
             chunkIO.WriteChunkWithChildren(Wad2Chunks.Sprite, () =>
             {
                 LEB128.Write(chunkIO.Raw, sprite.Texture.Image.Width);
                 LEB128.Write(chunkIO.Raw, sprite.Texture.Image.Height);
                 chunkIO.WriteChunkInt(Wad2Chunks.SpriteIndex, i);
                 chunkIO.WriteChunkArrayOfBytes(Wad2Chunks.SpriteData, sprite.Texture.Image.ToByteArray());
                 chunkIO.WriteChunk(Wad2Chunks.SpriteSides, () => {
                     chunkIO.Raw.Write(sprite.Alignment.X0);
                     chunkIO.Raw.Write(sprite.Alignment.Y0);
                     chunkIO.Raw.Write(sprite.Alignment.X1);
                     chunkIO.Raw.Write(sprite.Alignment.Y1);
                 });
             });
         }
     });
 }
Example #5
0
        private bool BuildScripts()
        {
            string scriptPath = _dstPath + "\\Script.dat";

            if (File.Exists(scriptPath))
            {
                File.Delete(scriptPath);
            }

            using (var stream = File.OpenWrite(scriptPath))
            {
                var chunkIO = new ChunkWriter(new byte[] { 0x54, 0x52, 0x35, 0x4D }, new BinaryWriterFast(stream));

                // Main flags
                chunkIO.WriteChunk(Tr5MainFlags, () =>
                {
                    LEB128.Write(chunkIO.Raw, (_loadSave ? 1 : 0));
                    LEB128.Write(chunkIO.Raw, (_playAnyLevel ? 1 : 0));
                    LEB128.Write(chunkIO.Raw, (_flyCheat ? 1 : 0));
                    LEB128.Write(chunkIO.Raw, (_diagnostics ? 1 : 0));
                    LEB128.Write(chunkIO.Raw, _levelFarView);
                    chunkIO.Raw.WriteStringUTF8(_intro);
                });

                // Game strings
                foreach (var stringsObj in _languageStrings)
                {
                    chunkIO.WriteChunk(Tr5MainStrings, () =>
                    {
                        chunkIO.Raw.WriteStringUTF8(stringsObj.Name);
                        LEB128.Write(chunkIO.Raw, stringsObj.Strings.Count);
                        foreach (var str in stringsObj.Strings)
                        {
                            chunkIO.Raw.WriteStringUTF8(str);
                        }
                    });
                }

                // Audio tracks
                chunkIO.WriteChunk(Tr5MainAudioTracks, () =>
                {
                    LEB128.Write(chunkIO.Raw, _tracks.Count);
                    foreach (var track in _tracks)
                    {
                        chunkIO.Raw.WriteStringUTF8(track);
                    }
                });

                // Levels
                foreach (var level in _levels)
                {
                    chunkIO.WriteChunkWithChildren(Tr5MainLevel, () =>
                    {
                        // Level informations
                        chunkIO.WriteChunk(Tr5MainLevelInfo, () =>
                        {
                            chunkIO.Raw.WriteStringUTF8(level.FileName);
                            chunkIO.Raw.WriteStringUTF8(level.LoadScreen);
                            chunkIO.Raw.WriteStringUTF8(level.Background);
                            LEB128.Write(chunkIO.Raw, GetStringIndex(level.Name));
                            LEB128.Write(chunkIO.Raw, level.AudioTrack);
                        });

                        // Level flags
                        chunkIO.WriteChunk(Tr5MainLevelFlags, () =>
                        {
                            LEB128.Write(chunkIO.Raw, (level.Horizon ? 1 : 0));
                            LEB128.Write(chunkIO.Raw, (level.Sky ? 1 : 0));
                            LEB128.Write(chunkIO.Raw, (level.ColAddHorizon ? 1 : 0));
                            LEB128.Write(chunkIO.Raw, (level.Lightning ? 1 : 0));
                            LEB128.Write(chunkIO.Raw, (level.ResetInventory ? 1 : 0));
                            LEB128.Write(chunkIO.Raw, level.LaraType);
                            LEB128.Write(chunkIO.Raw, level.UVRotate);
                            LEB128.Write(chunkIO.Raw, (level.LevelFarView != 0 ? level.LevelFarView : _levelFarView));
                            LEB128.Write(chunkIO.Raw, (level.Rumble ? 1 : 0));
                            LEB128.Write(chunkIO.Raw, (byte)(level.Weather));
                            LEB128.Write(chunkIO.Raw, (level.UnlimitedAir ? 1 : 0));
                        });

                        // Puzzles and various things
                        foreach (var entry in level.Entries)
                        {
                            if (entry.Command.Name == "Puzzle")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelPuzzle, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString()));
                                    for (int j = 2; j < 8; j++)
                                    {
                                        LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString()));
                                    }
                                });
                            }
                            else if (entry.Command.Name == "Key")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelKey, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString()));
                                    for (int j = 2; j < 8; j++)
                                    {
                                        LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString()));
                                    }
                                });
                            }
                            else if (entry.Command.Name == "Pickup")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelPickup, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString()));
                                    for (int j = 2; j < 8; j++)
                                    {
                                        LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString()));
                                    }
                                });
                            }
                            if (entry.Command.Name == "Examine")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelExamine, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[1].ToString()));
                                    for (int j = 2; j < 8; j++)
                                    {
                                        LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString()));
                                    }
                                });
                            }
                            if (entry.Command.Name == "PuzzleCombo")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelPuzzleCombo, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString()));
                                    LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[2].ToString()));
                                    for (int j = 3; j < 9; j++)
                                    {
                                        LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString()));
                                    }
                                });
                            }
                            else if (entry.Command.Name == "KeyCombo")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelKeyCombo, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString()));
                                    LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[2].ToString()));
                                    for (int j = 3; j < 9; j++)
                                    {
                                        LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString()));
                                    }
                                });
                            }
                            else if (entry.Command.Name == "PickupCombo")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelPickupCombo, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString()));
                                    LEB128.Write(chunkIO.Raw, (int)GetStringIndex(entry.Parameters[2].ToString()));
                                    for (int j = 3; j < 9; j++)
                                    {
                                        LEB128.Write(chunkIO.Raw, short.Parse(entry.Parameters[j].ToString()));
                                    }
                                });
                            }
                            else if (entry.Command.Name == "Layer1")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelLayer, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, 1);
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[2].ToString()));
                                    LEB128.Write(chunkIO.Raw, sbyte.Parse(entry.Parameters[3].ToString()));
                                });
                            }
                            else if (entry.Command.Name == "Layer2")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelLayer, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, 2);
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[2].ToString()));
                                    LEB128.Write(chunkIO.Raw, sbyte.Parse(entry.Parameters[3].ToString()));
                                });
                            }
                            else if (entry.Command.Name == "DistantFog")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelLayer, () =>
                                {
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[0].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[1].ToString()));
                                    LEB128.Write(chunkIO.Raw, byte.Parse(entry.Parameters[2].ToString()));
                                    LEB128.Write(chunkIO.Raw, int.Parse(entry.Parameters[3].ToString()));
                                });
                            }
                            else if (entry.Command.Name == "OnLevelStart" ||
                                     entry.Command.Name == "OnLevelFinish" ||
                                     entry.Command.Name == "OnLoadGame" ||
                                     entry.Command.Name == "OnSaveGame" ||
                                     entry.Command.Name == "OnLaraDeath" ||
                                     entry.Command.Name == "OnLevelControl" ||
                                     entry.Command.Name == "OnBeginFrame")
                            {
                                chunkIO.WriteChunk(Tr5MainLevelLuaEvent, () =>
                                {
                                    chunkIO.Raw.WriteStringUTF8(entry.Command.Name);
                                    chunkIO.Raw.WriteStringUTF8(entry.Parameters[0].ToString());
                                });
                            }
                        }
                    });
                }

                // EOF
                chunkIO.Raw.Write((int)0);

                chunkIO.Raw.Flush();
            }

            return(true);
        }
Example #6
0
        private static void WriteObjects(ChunkWriter chunkIO, IEnumerable <ObjectInstance> objects,
                                         Dictionary <Room, int> rooms, LevelSettingsIds levelSettingIds,
                                         Dictionary <ObjectInstance, int> objectInstanceLookup)
        {
            using (var chunkObjects = chunkIO.WriteChunk(Prj2Chunks.Objects, long.MaxValue))
            {
                foreach (var o in objects)
                {
                    if (o is MoveableInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectMovable3, () =>
                        {
                            var instance = (MoveableInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.WadObjectId.TypeId);
                            chunkIO.Raw.Write(instance.Ocb);
                            chunkIO.Raw.Write(instance.Invisible);
                            chunkIO.Raw.Write(instance.ClearBody);
                            chunkIO.Raw.Write(instance.CodeBits);
                            chunkIO.Raw.Write(instance.Color);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectItemLuaId, instance.LuaId);
                        });
                    }
                    else if (o is StaticInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectStatic2, () =>
                        {
                            var instance = (StaticInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.WadObjectId.TypeId);
                            chunkIO.Raw.Write(instance.Color);
                            chunkIO.Raw.Write((int)0); // Unused 32 bit value
                            chunkIO.Raw.Write(instance.Ocb);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectItemLuaId, instance.LuaId);
                        });
                    }
                    else if (o is CameraInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectCamera, LEB128.MaximumSize1Byte))
                        {
                            var instance = (CameraInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.Fixed);
                        }
                    }
                    else if (o is FlybyCameraInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectFlyBy, () =>
                        {
                            var instance = (FlybyCameraInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            chunkIO.Raw.Write(instance.RotationX);
                            chunkIO.Raw.Write(instance.Roll);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.Speed);
                            chunkIO.Raw.Write(instance.Fov);
                            LEB128.Write(chunkIO.Raw, instance.Flags);
                            LEB128.Write(chunkIO.Raw, instance.Number);
                            LEB128.Write(chunkIO.Raw, instance.Sequence);
                            LEB128.Write(chunkIO.Raw, instance.Timer);
                        });
                    }
                    else if (o is SinkInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectSink, LEB128.MaximumSize1Byte))
                        {
                            var instance = (SinkInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            LEB128.Write(chunkIO.Raw, (long?)instance.ScriptId ?? -1);
                            chunkIO.Raw.Write(instance.Strength);
                        }
                    }
                    else if (o is SoundSourceInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectSoundSourceFinal, LEB128.MaximumSize1Byte))
                        {
                            var instance = (SoundSourceInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.SoundId);
                            chunkIO.Raw.Write((int)instance.PlayMode);
                            LEB128.Write(chunkIO.Raw, -1);
                        }
                    }
                    else if (o is LightInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectLight4, LEB128.MaximumSize2Byte))
                        {
                            var instance = (LightInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, (long)instance.Type);
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            chunkIO.Raw.Write(instance.RotationX);
                            chunkIO.Raw.Write(instance.Intensity);
                            chunkIO.Raw.Write(instance.Color);
                            chunkIO.Raw.Write(instance.InnerRange);
                            chunkIO.Raw.Write(instance.OuterRange);
                            chunkIO.Raw.Write(instance.InnerAngle);
                            chunkIO.Raw.Write(instance.OuterAngle);
                            chunkIO.Raw.Write(instance.Enabled);
                            chunkIO.Raw.Write(instance.IsObstructedByRoomGeometry);
                            chunkIO.Raw.Write(instance.IsDynamicallyUsed);
                            chunkIO.Raw.Write(instance.IsStaticallyUsed);
                            chunkIO.Raw.Write(instance.IsUsedForImportedGeometry);
                            chunkIO.Raw.Write((byte)instance.Quality);
                        }
                    }
                    else if (o is PortalInstance && rooms.ContainsKey(((PortalInstance)o).AdjoiningRoom))
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectPortal, LEB128.MaximumSize2Byte))
                        {
                            var instance = (PortalInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, instance.Area.X0);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y0);
                            LEB128.Write(chunkIO.Raw, instance.Area.X1);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y1);
                            LEB128.Write(chunkIO.Raw, rooms[instance.AdjoiningRoom]);
                            chunkIO.Raw.Write((byte)instance.Direction);
                            chunkIO.Raw.Write((byte)instance.Opacity);
                        }
                    }
                    else if (o is GhostBlockInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectGhostBlock, LEB128.MaximumSize2Byte))
                        {
                            var instance = (GhostBlockInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, instance.Area.X0);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y0);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XnZn);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XnZp);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XpZn);
                            LEB128.Write(chunkIO.Raw, instance.Floor.XpZp);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XnZn);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XnZp);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XpZn);
                            LEB128.Write(chunkIO.Raw, instance.Ceiling.XpZp);
                        }
                    }
                    else if (o is VolumeInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectTriggerVolumeTest, LEB128.MaximumSize2Byte))
                        {
                            var instance = (VolumeInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));

                            var shape = instance.Shape();
                            chunkIO.Raw.Write((byte)shape);

                            switch (shape)
                            {
                            case VolumeShape.Box:
                            {
                                var bv = instance as BoxVolumeInstance;
                                chunkIO.Raw.Write(bv.Size);
                                chunkIO.Raw.Write(bv.RotationY);
                                chunkIO.Raw.Write(bv.RotationX);
                            }
                            break;

                            case VolumeShape.Prism:
                            {
                                var pv = instance as PrismVolumeInstance;
                                chunkIO.Raw.Write(pv.Scale);
                                chunkIO.Raw.Write(pv.RotationY);
                            }
                            break;

                            case VolumeShape.Sphere:
                                chunkIO.Raw.Write((instance as SphereVolumeInstance).Scale);
                                break;
                            }

                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write((ushort)instance.Activators);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.Name);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.Environment);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnEnter);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnInside);
                            chunkIO.Raw.WriteStringUTF8(instance.Scripts.OnLeave);
                        }
                    }
                    else if (o is TriggerInstance)
                    {
                        using (var chunk = chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2, LEB128.MaximumSize2Byte))
                        {
                            Action <ITriggerParameter> writeTriggerParameter = (ITriggerParameter parameter) =>
                            {
                                if (parameter is TriggerParameterUshort)
                                {
                                    LEB128.Write(chunkIO.Raw, 0);
                                    LEB128.Write(chunkIO.Raw, ((TriggerParameterUshort)parameter).Key);
                                }
                                else if (parameter is ObjectInstance)
                                {
                                    LEB128.Write(chunkIO.Raw, 1);
                                    LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault((ObjectInstance)parameter));
                                }
                                else if (parameter is Room)
                                {
                                    LEB128.Write(chunkIO.Raw, 2);
                                    LEB128.Write(chunkIO.Raw, rooms.TryGetOrDefault((Room)parameter));
                                }
                                else
                                {
                                    LEB128.Write(chunkIO.Raw, -1);
                                };
                            };

                            var instance = (TriggerInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            LEB128.Write(chunkIO.Raw, instance.Area.X0);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y0);
                            LEB128.Write(chunkIO.Raw, instance.Area.X1);
                            LEB128.Write(chunkIO.Raw, instance.Area.Y1);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2Type, (long)instance.TriggerType);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2TargetType, (long)instance.TargetType);
                            chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Target, () => writeTriggerParameter(instance.Target), 32);
                            chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Timer, () => writeTriggerParameter(instance.Timer), 32);
                            chunkIO.WriteChunk(Prj2Chunks.ObjectTrigger2Extra, () => writeTriggerParameter(instance.Extra), 32);
                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectTrigger2CodeBits, instance.CodeBits);
                            chunkIO.WriteChunkBool(Prj2Chunks.ObjectTrigger2OneShot, instance.OneShot);
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    else if (o is ImportedGeometryInstance)
                    {
                        chunkIO.WriteChunkWithChildren(Prj2Chunks.ObjectImportedGeometry3, () =>
                        {
                            var instance = (ImportedGeometryInstance)o;
                            LEB128.Write(chunkIO.Raw, objectInstanceLookup.TryGetOrDefault(instance, -1));
                            chunkIO.Raw.Write(instance.Position);
                            chunkIO.Raw.Write(instance.RotationY);
                            chunkIO.Raw.Write(instance.RotationX);
                            chunkIO.Raw.Write(instance.Roll);
                            chunkIO.Raw.Write(instance.Scale);
                            LEB128.Write(chunkIO.Raw, instance.Model == null ?
                                         -1 :
                                         levelSettingIds.ImportedGeometries[instance.Model]);

                            chunkIO.WriteChunkInt(Prj2Chunks.ObjectImportedGeometryLightingModel, (int)instance.LightingModel);
                            chunkIO.WriteChunkBool(Prj2Chunks.ObjectImportedGeometrySharpEdges, instance.SharpEdges);
                            chunkIO.WriteChunkBool(Prj2Chunks.ObjectImportedGeometryHidden, instance.Hidden);
                        });
                    }
                    else
                    {
                        logger.Warn("Object " + o + " not supported.");
                    }
                }
                chunkIO.WriteChunkEnd();
            };
        }
Example #7
0
        private static void WriteRooms(ChunkWriter chunkIO, Dictionary <Room, int> rooms, LevelSettingsIds levelSettingIds)
        {
            // Allocate object indices
            var objectInstanceLookup = new Dictionary <ObjectInstance, int>();

            foreach (Room room in rooms.Keys)
            {
                foreach (ObjectInstance objectInstance in room.AnyObjects)
                {
                    objectInstanceLookup.Add(objectInstance, objectInstanceLookup.Count);
                }
            }

            // Save
            using (var chunkRooms = chunkIO.WriteChunk(Prj2Chunks.Rooms, long.MaxValue))
            {
                foreach (Room room in rooms.Keys)
                {
                    using (var chunkRoom = chunkIO.WriteChunk(Prj2Chunks.Room, long.MaxValue))
                    {
                        LEB128.Write(chunkIO.Raw, room.NumXSectors);
                        LEB128.Write(chunkIO.Raw, room.NumZSectors);

                        // Write basic properties
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomIndex, rooms.TryGetOrDefault(room, -1));
                        chunkIO.WriteChunkString(Prj2Chunks.RoomName, room.Name);
                        chunkIO.WriteChunkVector3(Prj2Chunks.RoomPosition, room.Position);
                        chunkIO.WriteChunkArrayOfBytes(Prj2Chunks.RoomTags, System.Text.Encoding.UTF8.GetBytes(string.Join(" ", room.Tags)));

                        // Write sectors
                        using (var chunkRoomSectors = chunkIO.WriteChunk(Prj2Chunks.RoomSectors))
                        {
                            for (int z = 0; z < room.NumZSectors; z++)
                            {
                                for (int x = 0; x < room.NumXSectors; x++)
                                {
                                    using (var chunkSector = chunkIO.WriteChunk(Prj2Chunks.Sector, LEB128.MaximumSize2Byte))
                                    {
                                        chunkIO.Raw.Write(x + z * room.NumXSectors);
                                        var b = room.Blocks[x, z];

                                        long combinedFlag = (b.IsAnyWall ? 1L : 0) | (b.ForceFloorSolid ? 2L : 0) | ((long)b.Flags << 2);
                                        chunkIO.WriteChunkInt(Prj2Chunks.SectorProperties, combinedFlag);
                                        using (var chunkSectorFloor = chunkIO.WriteChunk(Prj2Chunks.SectorFloor, LEB128.MaximumSize1Byte))
                                        {
                                            long flag = (b.Floor.SplitDirectionIsXEqualsZ ? 1L : 0) | ((long)b.Floor.DiagonalSplit << 1);
                                            LEB128.Write(chunkIO.Raw, flag);
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.Floor.GetHeight(edge));
                                            }
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.GetHeight(BlockVertical.Ed, edge));
                                            }
                                        }
                                        using (var chunkSectorCeiling = chunkIO.WriteChunk(Prj2Chunks.SectorCeiling, LEB128.MaximumSize1Byte))
                                        {
                                            long flag = (b.Ceiling.SplitDirectionIsXEqualsZ ? 1L : 0) | ((long)b.Ceiling.DiagonalSplit << 1);
                                            LEB128.Write(chunkIO.Raw, flag);
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.Ceiling.GetHeight(edge));
                                            }
                                            for (BlockEdge edge = 0; edge < BlockEdge.Count; ++edge)
                                            {
                                                LEB128.Write(chunkIO.Raw, b.GetHeight(BlockVertical.Rf, edge));
                                            }
                                        }
                                        for (BlockFace face = 0; face < BlockFace.Count; face++)
                                        {
                                            var texture = b.GetFaceTexture(face);
                                            if (texture.Texture == null)
                                            {
                                                continue;
                                            }

                                            if (texture.Texture is LevelTexture)
                                            {
                                                using (var chunkTextureLevelTexture = chunkIO.WriteChunk(Prj2Chunks.TextureLevelTexture2, LEB128.MaximumSize1Byte))
                                                {
                                                    int textureIndex = levelSettingIds.LevelTextures[(LevelTexture)texture.Texture];

                                                    LEB128.Write(chunkIO.Raw, (long)face);
                                                    chunkIO.Raw.Write(texture.TexCoord0);
                                                    chunkIO.Raw.Write(texture.TexCoord1);
                                                    chunkIO.Raw.Write(texture.TexCoord2);
                                                    chunkIO.Raw.Write(texture.TexCoord3);
                                                    chunkIO.Raw.Write(texture.ParentArea.Start);
                                                    chunkIO.Raw.Write(texture.ParentArea.End);
                                                    LEB128.Write(chunkIO.Raw, (texture.DoubleSided ? 1L : 0) | ((long)texture.BlendMode << 1));
                                                    LEB128.Write(chunkIO.Raw, textureIndex);
                                                }
                                            }
                                            else if (texture.Texture == TextureInvisible.Instance)
                                            {
                                                chunkIO.WriteChunkInt(Prj2Chunks.TextureInvisible, (long)face);
                                            }
                                            else
                                            {
                                                throw new NotSupportedException("Unsupported texture type " + texture.Texture.GetType().Name);
                                            }
                                        }
                                        chunkIO.WriteChunkEnd();
                                    }
                                }
                            }
                            chunkIO.WriteChunkEnd();
                        }

                        // Write room properties
                        chunkIO.WriteChunkVector3(Prj2Chunks.RoomAmbientLight, room.AmbientLight);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagCold, room.FlagCold);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagDamage, room.FlagDamage);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagHorizon, room.FlagHorizon);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagOutside, room.FlagOutside);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagNoLensflare, room.FlagNoLensflare);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomFlagExcludeFromPathFinding, room.FlagExcludeFromPathFinding);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomType, (int)room.Type);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomTypeStrength, room.TypeStrength);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomLightEffect, (int)room.LightEffect);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomLightEffectStrength2, room.LightEffectStrength);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomReverberation, (int)room.Reverberation);
                        chunkIO.WriteChunkInt(Prj2Chunks.RoomLightInterpolationMode, (int)room.LightInterpolationMode);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomLocked, room.Locked);
                        chunkIO.WriteChunkBool(Prj2Chunks.RoomHidden, room.Hidden);
                        if (room.AlternateRoom != null && rooms.ContainsKey(room.AlternateRoom))
                        {
                            using (var chunkRoomAlternate = chunkIO.WriteChunk(Prj2Chunks.RoomAlternate, LEB128.MaximumSize1Byte))
                            {
                                chunkIO.WriteChunkInt(Prj2Chunks.AlternateGroup, room.AlternateGroup);
                                chunkIO.WriteChunkInt(Prj2Chunks.AlternateRoom, rooms[room.AlternateRoom]);
                                chunkIO.WriteChunkEnd();
                            }
                        }

                        // Write room objects
                        WriteObjects(chunkIO, room.AnyObjects, rooms, levelSettingIds, objectInstanceLookup);
                        chunkIO.WriteChunkEnd();
                    }
                }
                chunkIO.WriteChunkEnd();
            }
        }
Example #8
0
        private static LevelSettingsIds WriteLevelSettings(ChunkWriter chunkIO, LevelSettings settings)
        {
            var levelSettingIds = new LevelSettingsIds(settings);

            using (var chunkSettings = chunkIO.WriteChunk(Prj2Chunks.Settings, long.MaxValue))
            {
                chunkIO.WriteChunkString(Prj2Chunks.FontTextureFilePath, settings.FontTextureFilePath ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.SkyTextureFilePath, settings.SkyTextureFilePath ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.Tr5ExtraSpritesFilePath, settings.Tr5ExtraSpritesFilePath ?? "");
                using (var chunkOldWadSoundPaths = chunkIO.WriteChunk(Prj2Chunks.OldWadSoundPaths))
                {
                    chunkIO.WriteChunkEmpty(Prj2Chunks.OldWadSoundUpdateTag1_0_8);
                    foreach (WadSoundPath soundPath in settings.WadSoundPaths)
                    {
                        using (var chunkOldWadSoundPath = chunkIO.WriteChunk(Prj2Chunks.OldWadSoundPath))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.OldWadSoundPathPath, soundPath.Path);
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                chunkIO.WriteChunkString(Prj2Chunks.GameDirectory, settings.GameDirectory ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.GameLevelFilePath, settings.GameLevelFilePath ?? "");
                chunkIO.WriteChunkString(Prj2Chunks.GameExecutableFilePath, settings.GameExecutableFilePath ?? "");
                chunkIO.WriteChunkBool(Prj2Chunks.GameEnableQuickStartFeature, settings.GameEnableQuickStartFeature);
                chunkIO.WriteChunkInt(Prj2Chunks.GameVersion, (long)settings.GameVersion);
                chunkIO.WriteChunkInt(Prj2Chunks.Tr5LaraType, (long)settings.Tr5LaraType);
                chunkIO.WriteChunkInt(Prj2Chunks.Tr5Weather, (long)settings.Tr5WeatherType);
                chunkIO.WriteChunkInt(Prj2Chunks.TexturePadding, (long)settings.TexturePadding);
                chunkIO.WriteChunkBool(Prj2Chunks.RemapAnimatedTextures, settings.RemapAnimatedTextures);
                chunkIO.WriteChunkBool(Prj2Chunks.Dither16BitTextures, settings.Dither16BitTextures);
                chunkIO.WriteChunkBool(Prj2Chunks.AgressiveTexturePacking, settings.AgressiveTexturePacking);
                chunkIO.WriteChunkBool(Prj2Chunks.AgressiveFloordataPacking, settings.AgressiveFloordataPacking);
                chunkIO.WriteChunkVector3(Prj2Chunks.DefaultAmbientLight, settings.DefaultAmbientLight);
                chunkIO.WriteChunkInt(Prj2Chunks.DefaultLightQuality, (long)settings.DefaultLightQuality);
                chunkIO.WriteChunkBool(Prj2Chunks.OverrideLightQuality, settings.OverrideIndividualLightQualitySettings);
                chunkIO.WriteChunkString(Prj2Chunks.ScriptDirectory, settings.ScriptDirectory ?? "");
                chunkIO.WriteChunkInt(Prj2Chunks.SoundSystem, (int)settings.SoundSystem);
                using (var chunkWads = chunkIO.WriteChunk(Prj2Chunks.Wads, long.MaxValue))
                {
                    foreach (ReferencedWad wad in settings.Wads)
                    {
                        using (var chunkWad = chunkIO.WriteChunk(Prj2Chunks.Wad))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.WadPath, wad.Path ?? "");
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkSounds = chunkIO.WriteChunk(Prj2Chunks.SoundsCatalogs, long.MaxValue))
                {
                    foreach (ReferencedSoundsCatalog soundRef in settings.SoundsCatalogs)
                    {
                        using (var chunkSound = chunkIO.WriteChunk(Prj2Chunks.SoundsCatalog))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.SoundsCatalogPath, soundRef.Path ?? "");
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkSelectedSounds = chunkIO.WriteChunk(Prj2Chunks.SelectedSounds, long.MaxValue))
                {
                    foreach (int selectedSound in settings.SelectedSounds)
                    {
                        chunkIO.WriteChunkInt(Prj2Chunks.SelectedSound, selectedSound);
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkTextures = chunkIO.WriteChunk(Prj2Chunks.Textures, long.MaxValue))
                {
                    int index = 0;
                    foreach (LevelTexture texture in settings.Textures)
                    {
                        using (var chunkLevelTexture = chunkIO.WriteChunk(Prj2Chunks.LevelTexture))
                        {
                            chunkIO.WriteChunkInt(Prj2Chunks.LevelTextureIndex, index);
                            chunkIO.WriteChunkString(Prj2Chunks.LevelTexturePath, texture.Path ?? "");
                            chunkIO.WriteChunkString(Prj2Chunks.LevelTextureCustomBumpmapPath, texture.BumpPath ?? "");
                            chunkIO.WriteChunkBool(Prj2Chunks.LevelTextureConvert512PixelsToDoubleRows, texture.Convert512PixelsToDoubleRows);
                            chunkIO.WriteChunkBool(Prj2Chunks.LevelTextureReplaceMagentaWithTransparency, texture.ReplaceMagentaWithTransparency);
                            using (var chunkLevelTextureFootStepSounds = chunkIO.WriteChunk(Prj2Chunks.LevelTextureFootStepSounds))
                            {
                                chunkIO.Raw.Write(texture.FootStepSoundWidth);
                                chunkIO.Raw.Write(texture.FootStepSoundHeight);
                                for (int y = 0; y < texture.FootStepSoundHeight; ++y)
                                {
                                    for (int x = 0; x < texture.FootStepSoundWidth; ++x)
                                    {
                                        chunkIO.Raw.Write((byte)texture.GetFootStepSound(x, y));
                                    }
                                }
                            }
                            using (var chunkLevelTextureBumpmaps = chunkIO.WriteChunk(Prj2Chunks.LevelTextureBumpmaps))
                            {
                                chunkIO.Raw.Write(texture.BumpMappingWidth);
                                chunkIO.Raw.Write(texture.BumpMappingHeight);
                                for (int y = 0; y < texture.BumpMappingHeight; ++y)
                                {
                                    for (int x = 0; x < texture.BumpMappingWidth; ++x)
                                    {
                                        chunkIO.Raw.Write((byte)texture.GetBumpMapLevel(x, y));
                                    }
                                }
                            }
                            chunkIO.WriteChunkEnd();
                        }
                        levelSettingIds.LevelTextures.Add(texture, index++);
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkImportedGeometries = chunkIO.WriteChunk(Prj2Chunks.ImportedGeometries, long.MaxValue))
                {
                    int index = 0;
                    foreach (ImportedGeometry importedGeometry in settings.ImportedGeometries)
                    {
                        using (var chunkImportedGeometry = chunkIO.WriteChunk(Prj2Chunks.ImportedGeometry))
                        {
                            chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryIndex, index);
                            chunkIO.WriteChunkString(Prj2Chunks.ImportedGeometryName, importedGeometry.Info.Name);
                            chunkIO.WriteChunkString(Prj2Chunks.ImportedGeometryPath, importedGeometry.Info.Path);
                            chunkIO.WriteChunkFloat(Prj2Chunks.ImportedGeometryScale, importedGeometry.Info.Scale);
                            chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryPosAxisFlags,
                                                  (importedGeometry.Info.SwapXY ? 1 : 0) |
                                                  (importedGeometry.Info.SwapXZ ? 2 : 0) |
                                                  (importedGeometry.Info.SwapYZ ? 4 : 0) |
                                                  (importedGeometry.Info.FlipX ? 8 : 0) |
                                                  (importedGeometry.Info.FlipY ? 16 : 0) |
                                                  (importedGeometry.Info.FlipZ ? 32 : 0));
                            chunkIO.WriteChunkInt(Prj2Chunks.ImportedGeometryTexAxisFlags, importedGeometry.Info.FlipUV_V ? 4 : 0);
                            chunkIO.WriteChunkBool(Prj2Chunks.ImportedGeometryInvertFaces, importedGeometry.Info.InvertFaces);
                            chunkIO.WriteChunkEnd();
                        }
                        levelSettingIds.ImportedGeometries.Add(importedGeometry, index++);
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkAnimatedTextureSets = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureSets, long.MaxValue))
                {
                    foreach (AnimatedTextureSet set in settings.AnimatedTextureSets)
                    {
                        using (var chunkAnimatedTextureSet = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureSet))
                        {
                            chunkIO.WriteChunkString(Prj2Chunks.AnimatedTextureSetName, set.Name ?? "");
                            chunkIO.WriteChunkInt(Prj2Chunks.AnimatedTextureSetType, (int)set.AnimationType);
                            chunkIO.WriteChunkFloat(Prj2Chunks.AnimatedTextureSetFps, set.Fps);
                            chunkIO.WriteChunkInt(Prj2Chunks.AnimatedTextureSetUvRotate, set.UvRotate);
                            using (var chunkAnimatedTextureFrames = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureFrames))
                            {
                                foreach (AnimatedTextureFrame frame in set.Frames)
                                {
                                    using (var chunkAnimatedTextureFrame = chunkIO.WriteChunk(Prj2Chunks.AnimatedTextureFrame, 120))
                                    {
                                        LEB128.Write(chunkIO.Raw, levelSettingIds.LevelTextures[frame.Texture]);
                                        chunkIO.Raw.Write(frame.TexCoord0);
                                        chunkIO.Raw.Write(frame.TexCoord1);
                                        chunkIO.Raw.Write(frame.TexCoord2);
                                        chunkIO.Raw.Write(frame.TexCoord3);
                                        LEB128.Write(chunkIO.Raw, frame.Repeat);
                                    }
                                }

                                chunkIO.WriteChunkEnd();
                            }
                            chunkIO.WriteChunkEnd();
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkAutoMergeStatics = chunkIO.WriteChunk(Prj2Chunks.AutoMergeStaticMeshes, UInt16.MaxValue))
                {
                    foreach (var entry in settings.AutoStaticMeshMerges)
                    {
                        using  (var chunkAutoMergeEntry = chunkIO.WriteChunk(Prj2Chunks.AutoMergeStaticMeshEntry3))
                        {
                            chunkIO.Raw.Write(entry.meshId);
                            chunkIO.Raw.Write(entry.InterpretShadesAsEffect);
                            chunkIO.Raw.Write(entry.TintAsAmbient);
                            chunkIO.Raw.Write(entry.ClearShades);
                        }
                    }
                    chunkIO.WriteChunkEnd();
                }
                using (var chunkPalette = chunkIO.WriteChunk(Prj2Chunks.Palette, UInt16.MaxValue))
                {
                    chunkIO.Raw.Write((ushort)settings.Palette.Count);
                    foreach (var color in settings.Palette)
                    {
                        chunkIO.Raw.Write(color.R);
                        chunkIO.Raw.Write(color.G);
                        chunkIO.Raw.Write(color.B);
                    }
                    chunkIO.WriteChunkEnd();
                }
                chunkIO.WriteChunkEnd();
            };

            return(levelSettingIds);
        }
Example #9
0
        private static void WriteMoveables(ChunkWriter chunkIO, Wad2 wad, List <WadTexture> textureTable)
        {
            chunkIO.WriteChunkWithChildren(Wad2Chunks.Moveables, () =>
            {
                foreach (var moveable in wad.Moveables)
                {
                    chunkIO.WriteChunkWithChildren(Wad2Chunks.Moveable, () =>
                    {
                        var m = moveable.Value;

                        LEB128.Write(chunkIO.Raw, m.Id.TypeId);

                        foreach (var mesh in m.Meshes)
                        {
                            WriteMesh(chunkIO, mesh, textureTable);
                        }

                        foreach (var b in m.Bones)
                        {
                            chunkIO.WriteChunkWithChildren(Wad2Chunks.MoveableBoneNew, () =>
                            {
                                LEB128.Write(chunkIO.Raw, (byte)b.OpCode);
                                chunkIO.Raw.WriteStringUTF8(b.Name);
                                chunkIO.WriteChunkVector3(Wad2Chunks.MoveableBoneTranslation, b.Translation);
                                chunkIO.WriteChunkInt(Wad2Chunks.MoveableBoneMeshPointer, m.Bones.IndexOf(b));
                            });
                        }

                        foreach (var animation in m.Animations)
                        {
                            chunkIO.WriteChunkWithChildren(Wad2Chunks.Animation2, () =>
                            {
                                LEB128.Write(chunkIO.Raw, animation.StateId);
                                LEB128.Write(chunkIO.Raw, animation.EndFrame);
                                LEB128.Write(chunkIO.Raw, animation.FrameRate);

                                LEB128.Write(chunkIO.Raw, animation.NextAnimation);
                                LEB128.Write(chunkIO.Raw, animation.NextFrame);

                                chunkIO.WriteChunkString(Wad2Chunks.AnimationName, animation.Name);

                                foreach (var kf in animation.KeyFrames)
                                {
                                    chunkIO.WriteChunkWithChildren(Wad2Chunks.KeyFrame, () =>
                                    {
                                        chunkIO.WriteChunkVector3(Wad2Chunks.KeyFrameOffset, kf.Offset);
                                        chunkIO.WriteChunkWithChildren(Wad2Chunks.KeyFrameBoundingBox, () =>
                                        {
                                            chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMin, kf.BoundingBox.Minimum);
                                            chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMax, kf.BoundingBox.Maximum);
                                        });
                                        foreach (var angle in kf.Angles)
                                        {
                                            chunkIO.WriteChunkVector3(Wad2Chunks.KeyFrameAngle, angle.Rotations);
                                        }
                                    });
                                }

                                foreach (var stateChange in animation.StateChanges)
                                {
                                    chunkIO.WriteChunkWithChildren(Wad2Chunks.StateChange, () =>
                                    {
                                        LEB128.Write(chunkIO.Raw, stateChange.StateId);
                                        foreach (var dispatch in stateChange.Dispatches)
                                        {
                                            chunkIO.WriteChunk(Wad2Chunks.Dispatch, () =>
                                            {
                                                LEB128.Write(chunkIO.Raw, dispatch.InFrame);
                                                LEB128.Write(chunkIO.Raw, dispatch.OutFrame);
                                                LEB128.Write(chunkIO.Raw, dispatch.NextAnimation);
                                                LEB128.Write(chunkIO.Raw, dispatch.NextFrame);
                                            });
                                        }
                                    });
                                }

                                foreach (var command in animation.AnimCommands)
                                {
                                    chunkIO.WriteChunkWithChildren(Wad2Chunks.AnimCommand, () =>
                                    {
                                        LEB128.Write(chunkIO.Raw, (ushort)command.Type);
                                        LEB128.Write(chunkIO.Raw, command.Parameter1);
                                        LEB128.Write(chunkIO.Raw, command.Parameter2);
                                        LEB128.Write(chunkIO.Raw, command.Parameter3);
                                        chunkIO.WriteChunkInt(Wad2Chunks.AnimCommandSoundInfo, -1);
                                    });
                                }

                                // New chunk for velocities
                                chunkIO.WriteChunkVector4(Wad2Chunks.AnimationVelocities,
                                                          new System.Numerics.Vector4(animation.StartVelocity,
                                                                                      animation.EndVelocity,
                                                                                      animation.StartLateralVelocity,
                                                                                      animation.EndLateralVelocity));
                            });
                        }
                    });
                }
            });
        }
Example #10
0
        public static void WriteMesh(ChunkWriter chunkIO, WadMesh mesh, List <WadTexture> textureTable)
        {
            chunkIO.WriteChunkWithChildren(Wad2Chunks.Mesh, () =>
            {
                chunkIO.WriteChunkInt(Wad2Chunks.MeshIndex, 0);
                chunkIO.WriteChunkString(Wad2Chunks.MeshName, mesh.Name);

                // Write bounding sphere
                chunkIO.WriteChunkWithChildren(Wad2Chunks.MeshSphere, () =>
                {
                    chunkIO.WriteChunkVector3(Wad2Chunks.MeshSphereCenter, mesh.BoundingSphere.Center);
                    chunkIO.WriteChunkFloat(Wad2Chunks.MeshSphereRadius, mesh.BoundingSphere.Radius);
                });

                // Write bounding box
                chunkIO.WriteChunkWithChildren(Wad2Chunks.MeshBoundingBox, () =>
                {
                    chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMin, mesh.BoundingBox.Minimum);
                    chunkIO.WriteChunkVector3(Wad2Chunks.MeshBoundingBoxMax, mesh.BoundingBox.Maximum);
                });

                // Write positions
                chunkIO.WriteChunkWithChildren(Wad2Chunks.MeshVertexPositions, () =>
                {
                    foreach (var pos in mesh.VerticesPositions)
                    {
                        chunkIO.WriteChunkVector3(Wad2Chunks.MeshVertexPosition, pos);
                    }
                });

                // Write normals
                chunkIO.WriteChunkWithChildren(Wad2Chunks.MeshVertexNormals, () =>
                {
                    foreach (var normal in mesh.VerticesNormals)
                    {
                        chunkIO.WriteChunkVector3(Wad2Chunks.MeshVertexNormal, normal);
                    }
                });

                // Write shades
                chunkIO.WriteChunkWithChildren(Wad2Chunks.MeshVertexShades, () =>
                {
                    foreach (var shade in mesh.VerticesShades)
                    {
                        chunkIO.WriteChunkInt(Wad2Chunks.MeshVertexShade, shade);
                    }
                });

                // Write polygons
                chunkIO.WriteChunkWithChildren(Wad2Chunks.MeshPolygons, () =>
                {
                    foreach (var poly in mesh.Polys)
                    {
                        bool isQuad = poly.Shape == WadPolygonShape.Quad;

                        chunkIO.WriteChunkWithChildren(isQuad ? Wad2Chunks.MeshQuad : Wad2Chunks.MeshTriangle, () =>
                        {
                            LEB128.Write(chunkIO.Raw, poly.Index0);
                            LEB128.Write(chunkIO.Raw, poly.Index1);
                            LEB128.Write(chunkIO.Raw, poly.Index2);
                            if (isQuad)
                            {
                                LEB128.Write(chunkIO.Raw, poly.Index3);
                            }
                            LEB128.Write(chunkIO.Raw, poly.ShineStrength);

                            LEB128.Write(chunkIO.Raw, textureTable.IndexOf(poly.Texture.Texture as WadTexture));
                            chunkIO.Raw.Write(poly.Texture.TexCoord0);
                            chunkIO.Raw.Write(poly.Texture.TexCoord1);
                            chunkIO.Raw.Write(poly.Texture.TexCoord2);
                            if (isQuad)
                            {
                                chunkIO.Raw.Write(poly.Texture.TexCoord3);
                            }
                            LEB128.Write(chunkIO.Raw, (long)poly.Texture.BlendMode);
                            chunkIO.Raw.Write(poly.Texture.DoubleSided);
                        });
                    }
                });
            });
        }