예제 #1
0
        public static void WriteList(BBData data, BBData[] datas)
        {
            var bb = data.Buffer;

            bb.Write(datas.Length);

            var allOffs = data.OffsetOffsets.ToList();

            var offAcc = bb.Position + datas.Length * sizeof(int); // after all offsets

            for (int i = 0; i < datas.Length; i++)
            {
                allOffs.Add(bb.Position);
                bb.Write(offAcc);

                offAcc += datas[i].Buffer.Size;
            }

            for (int i = 0; i < datas.Length; i++)
            {
                Write(bb, datas[i]);
                allOffs.AddRange(datas[i].OffsetOffsets); // updated by Write
            }

            data.OffsetOffsets = allOffs.ToArray();
        }
예제 #2
0
        public static void WriteFont(BBData data, FontInfo fi, StringsChunkBuilder strings, int[] texPagOffsets)
        {
            var fe = new FontEntry
            {
                CodeName     = fi.CodeName == null ? 0 : strings.GetOffset(fi.CodeName),
                SystemName   = strings.GetOffset(fi.SystemName),
                EmSize       = fi.EmSize,
                Bold         = fi.IsBold ? DwordBool.True : DwordBool.False,
                Italic       = fi.IsItalic ? DwordBool.True : DwordBool.False,
                _ignore0     = fi.Characters[0].Character,
                Charset      = fi.Charset,
                AntiAliasing = fi.AntiAliasing,
                TPagOffset   = (uint)texPagOffsets[fi.TexPagId],
                Scale        = fi.Scale
            };

            foreach (var character in fi.Characters)
            {
                if (character.Character > fe._ignore1)
                {
                    fe._ignore1 = character.Character;
                }
            }
            data.Buffer.Write(fe);

            data.Buffer.Position -= 8;

            WriteList(data, fi.Characters, WriteFontCharEntry);
        }
예제 #3
0
        private static void WriteSound(BBData data, SoundInfo si, StringsChunkBuilder strings, string[] audioGroups)
        {
            var se = new SoundEntry
            {
                NameOffset = si.Name == null ? 0 : strings.GetOffset(si.Name),
                TypeOffset = si.Type == null ? 0 : strings.GetOffset(si.Type),
                FileOffset = si.File == null ? 0 : strings.GetOffset(si.File),

                Volume = si.VolumeMod,
                Pitch  = si.PitchMod,

                GroupID = (si.Group == null || si.Group.Length == 0) ? 0 : Array.IndexOf(audioGroups, si.Group),
                AudioID = si.AudioID,
                Flags   = SoundEntryFlags.Normal
            };

            if (si.IsEmbedded)
            {
                se.Flags |= SoundEntryFlags.Embedded;
            }
            if (si.IsCompressed)
            {
                se.Flags |= SoundEntryFlags.Compressed;
            }

            data.Buffer.Write(se);
        }
예제 #4
0
        public static void WriteTextures(BBData data, TextureInfo[] textures)
        {
            BBData[] datas = new BBData[textures.Length];

            for (int i = 0; i < textures.Length; i++)
            {
                BBData texturedata = new BBData(new BinBuffer(), new int[0]);
                //texturedata.Buffer.Write(1); // TextureEntry._pad for 2.0
                texturedata.Buffer.Write(0); // TextureEntry._pad
                texturedata.Buffer.Write(0); // TextureEntry.Offset
                datas[i] = texturedata;
            }

            int[] offsets = WriteList(data, datas);

            int[] secondaryOffsets = new int[textures.Length];
            for (int i = 0; i < textures.Length; i++)
            {
                Pad(data, 0x80, 8);
                var p = data.Buffer.Position;
                data.Buffer.Position = offsets[i] + 4; // 8 on 2.0
                secondaryOffsets[i]  = data.Buffer.Position;
                data.Buffer.Write(p);
                data.Buffer.Position = p;
                data.Buffer.Write(textures[i].PngData);
            }
            data.OffsetOffsets = data.OffsetOffsets.Concat(secondaryOffsets).ToArray();

            Pad(data, 8, 0);
        }
예제 #5
0
        public static void WriteRefDefs(BBData data, ReferenceDef[] variables,
                                        StringsChunkBuilder strings,
                                        bool IsOldBCVersion, bool isFunction,
                                        out int[] stringOffsetOffsets, out int[] codeOffsetOffsets)
        {
            if (!IsOldBCVersion && isFunction)
            {
                data.Buffer.Write(variables.Length);
            }
            stringOffsetOffsets = new int[variables.Length];
            var codeOffsetOffsetsList = new List <int>(variables.Length);

            for (int i = 0; i < variables.Length; i++)
            {
                if (IsOldBCVersion || isFunction)
                {
                    stringOffsetOffsets[i] = data.Buffer.Position + (int)Marshal.OffsetOf(typeof(RefDefEntry), "NameOffset") + 8;
                    if (variables[i].FirstOffset != 0xFFFFFFFF)
                    {
                        codeOffsetOffsetsList.Add(data.Buffer.Position + (int)Marshal.OffsetOf(typeof(RefDefEntry), "FirstAddress") + 8);
                    }
                    WriteRefDef(data, variables[i], strings);
                }
                else
                {
                    stringOffsetOffsets[i] = data.Buffer.Position + (int)Marshal.OffsetOf(typeof(RefDefEntryWithOthers), "NameOffset") + 8;
                    if (variables[i].FirstOffset != 0xFFFFFFFF)
                    {
                        codeOffsetOffsetsList.Add(data.Buffer.Position + (int)Marshal.OffsetOf(typeof(RefDefEntryWithOthers), "FirstAddress") + 8);
                    }
                    WriteRefDefWithOthers(data, variables[i], strings);
                }
            }
            codeOffsetOffsets = codeOffsetOffsetsList.ToArray();
        }
예제 #6
0
        private static void WriteShader(BBData data, ShaderInfo si, StringsChunkBuilder strings)
        {
            var se = new ShaderEntry
            {
                Name           = strings.GetOffset(si.Name),
                Type           = si.Type.Encode(),
                AttributeCount = (uint)si.Attributes.Length
            };

            unsafe
            {
                se.GLSL_ES.VertexSource   = strings.GetOffset(si.Code.GLSL_ES.VertexShader);
                se.GLSL_ES.FragmentSource = strings.GetOffset(si.Code.GLSL_ES.FragmentShader);
                se.GLSL.VertexSource      = strings.GetOffset(si.Code.GLSL.VertexShader);
                se.GLSL.FragmentSource    = strings.GetOffset(si.Code.GLSL.FragmentShader);
                se.HLSL9.VertexSource     = strings.GetOffset(si.Code.HLSL9.VertexShader);
                se.HLSL9.FragmentSource   = strings.GetOffset(si.Code.HLSL9.FragmentShader);
            }
            var tmp = new BinBuffer();

            tmp.Write(se);
            data.Buffer.Write(tmp, 0, tmp.Size - 4, 0); // TODO
            foreach (var attr in si.Attributes)
            {
                data.Buffer.Write(strings.GetOffset(attr));
            }
            data.Buffer.Write(2); // TODO: ShaderEntry2
            for (int i = 0; i < 12; i++)
            {
                data.Buffer.Write(0);
            }
        }
예제 #7
0
        public static void WriteSprites(BBData data,
                                        SpriteInfo[] sprites,
                                        StringsChunkBuilder strings,
                                        int[] texPagOffsets,
                                        out int[] stringOffsetOffsets,
                                        out int[] texpOffsetOffsetsArray)
        {
            int[] offsets = WriteList(data, sprites, WriteSprite, strings, texPagOffsets);
            stringOffsetOffsets = new int[sprites.Length];
            var texpOffsetOffsetsList = new List <int>();

            for (int i = 0; i < sprites.Length; i++)
            {
                stringOffsetOffsets[i] = offsets[i] + (int)Marshal.OffsetOf(typeof(SpriteEntry), "Name") + 8;
                var si = sprites[i];
                if (si.TextureIndices != null)
                {
                    var texIdxOffs = offsets[i] + 12;
                    if (si.Version < 2)
                    {
                        texIdxOffs += (int)Marshal.OffsetOf(typeof(SpriteEntry), "Textures");
                    }
                    else
                    {
                        texIdxOffs += (int)Marshal.OffsetOf(typeof(SpriteEntry2), "Textures");
                    }
                    for (int j = 0; j < si.TextureIndices.Length; j++)
                    {
                        texpOffsetOffsetsList.Add(texIdxOffs + j * sizeof(int));
                    }
                }
            }
            texpOffsetOffsetsArray = texpOffsetOffsetsList.ToArray();
        }
예제 #8
0
 public static void WriteIffWad(BBData data, IDictionary <SectionHeaders, BBData> chunks)
 {
     foreach (var kvp in chunks)
     {
         WriteChunk(data, kvp.Key, kvp.Value);
     }
 }
예제 #9
0
        public static void WriteFonts(BBData data,
                                      FontInfo[] fonts,
                                      StringsChunkBuilder strings,
                                      int[] texPagOffsets,
                                      out int[] stringOffsetOffsets,
                                      out int[] texpOffsetOffsets)
        {
            int[] offsets = WriteList(data, fonts, WriteFont, strings, texPagOffsets);

            stringOffsetOffsets = new int[fonts.Length * 2];
            texpOffsetOffsets   = new int[fonts.Length];

            for (int i = 0; i < fonts.Length; i++)
            {
                stringOffsetOffsets[i * 2]     = offsets[i] + (int)Marshal.OffsetOf(typeof(FontEntry), "CodeName") + 8;
                stringOffsetOffsets[i * 2 + 1] = offsets[i] + (int)Marshal.OffsetOf(typeof(FontEntry), "SystemName") + 8;
                texpOffsetOffsets[i]           = offsets[i] + (int)Marshal.OffsetOf(typeof(FontEntry), "TPagOffset") + 8;
            }

            // pad?
            for (int i = 0; i < 0x80; i++)
            {
                data.Buffer.Write((ushort)i);
            }
            for (int i = 0; i < 0x80; i++)
            {
                data.Buffer.Write((ushort)0x3F);
            }
        }
예제 #10
0
        public static int[] WriteRooms(BBData data, RoomInfo[] rooms, StringsChunkBuilder strings)
        {
            int[] offsets             = WriteList(data, rooms, WriteRoom, strings);
            var   stringOffsetOffsets = new List <int>();

            for (int i = 0; i < rooms.Length; i++)
            {
                stringOffsetOffsets.Add(offsets[i] + (int)Marshal.OffsetOf(typeof(RoomEntry), "Name") + 8);
                if (rooms[i].Caption != null)
                {
                    stringOffsetOffsets.Add(offsets[i] + (int)Marshal.OffsetOf(typeof(RoomEntry), "Caption") + 8);
                }
                if (rooms[i].ObjInst != null)
                {
                    data.Buffer.Position  = offsets[i];
                    data.Buffer.Position += (int)Marshal.OffsetOf(typeof(RoomEntry), "MetresPerPixel") + 4;
                    int listoff = data.Buffer.ReadInt32();
                    data.Buffer.Position = listoff;
                    listoff += 4;
                    int count = data.Buffer.ReadInt32();
                    for (int j = 0; j < count; j++)
                    {
                        data.Buffer.Position = listoff + j * 4;
                        int off = data.Buffer.ReadInt32();
                        stringOffsetOffsets.Add(off + (int)Marshal.OffsetOf(typeof(RoomObjInstEntry), "Name") + 8);
                    }
                }
            }
            return(stringOffsetOffsets.ToArray());
        }
예제 #11
0
        public static void WriteChunk(BBData data, SectionHeaders chunk, BBData inner)
        {
            var bb = data.Buffer;

            bb.Write((uint)chunk);

            Write(bb, inner);
        }
예제 #12
0
 private static void WriteBackground(BBData data, BackgroundInfo bi, StringsChunkBuilder strings, int[] texPagOffsets)
 {
     data.Buffer.Write(new BgEntry
     {
         Name          = strings.GetOffset(bi.Name),
         TextureOffset = bi.TexPageIndex.HasValue ? (uint)texPagOffsets[bi.TexPageIndex.Value] : 0
     });
 }
예제 #13
0
 private static void WriteScript(BBData data, ScriptInfo si, StringsChunkBuilder strings)
 {
     data.Buffer.Write(new ScriptEntry
     {
         Name   = strings.GetOffset(si.Name),
         CodeId = si.CodeId
     });
 }
예제 #14
0
 private static void WriteRefDef(BBData data, ReferenceDef rd, StringsChunkBuilder strings)
 {
     data.Buffer.Write(new RefDefEntry
     {
         NameOffset   = strings.GetOffset(rd.Name),
         Occurrences  = rd.Occurrences,
         FirstAddress = rd.FirstOffset
     });
 }
예제 #15
0
        public static void Pad(BBData data, int amount, int offset)
        {
            var pad = (amount - 1) - ((data.Buffer.Position + offset - 1) % amount);

            for (int j = 0; j < pad; j++)
            {
                data.Buffer.WriteByte(0);
            }
        }
예제 #16
0
 private static void WriteFontCharEntry(BBData data, FontCharacter fc)
 {
     data.Buffer.Write(new FontCharEntry
     {
         Character   = fc.Character,
         TexPagFrame = fc.TPagFrame,
         Shift       = fc.Shift,
         Offset      = fc.Offset
     });
 }
예제 #17
0
 private static void WriteRefDefWithOthers(BBData data, ReferenceDef rd, StringsChunkBuilder strings)
 {
     data.Buffer.Write(new RefDefEntryWithOthers
     {
         NameOffset   = strings.GetOffset(rd.Name),
         InstanceType = (int)rd.InstanceType,
         _pad1        = rd.unknown2,
         Occurrences  = rd.Occurrences,
         FirstAddress = rd.FirstOffset
     });
 }
예제 #18
0
        public static int[] WritePaths(BBData data, PathInfo[] paths, StringsChunkBuilder strings)
        {
            int[] offsets             = WriteList(data, paths, WritePath, strings);
            var   stringOffsetOffsets = new int[paths.Length];

            for (int i = 0; i < paths.Length; i++)
            {
                stringOffsetOffsets[i] = offsets[i] + (int)Marshal.OffsetOf(typeof(PathEntry), "Name") + 8;
            }
            return(stringOffsetOffsets);
        }
예제 #19
0
        public static int[] WriteAudioGroups(BBData data, string[] audioGroups, StringsChunkBuilder strings)
        {
            int[] offsets             = WriteList(data, audioGroups, (groupdata, group) => groupdata.Buffer.Write(strings.GetOffset(group)));
            var   stringOffsetOffsets = new int[audioGroups.Length];

            for (int i = 0; i < audioGroups.Length; i++)
            {
                stringOffsetOffsets[i] = offsets[i] + 8;
            }
            return(stringOffsetOffsets.ToArray());
        }
예제 #20
0
        public static int[] WriteScripts(BBData data, ScriptInfo[] scripts, StringsChunkBuilder strings)
        {
            int[] offsets             = WriteList(data, scripts, WriteScript, strings);
            var   stringOffsetOffsets = new int[scripts.Length];

            for (int i = 0; i < scripts.Length; i++)
            {
                stringOffsetOffsets[i] = offsets[i] + (int)Marshal.OffsetOf(typeof(ScriptEntry), "Name") + 8;
            }
            return(stringOffsetOffsets);
        }
예제 #21
0
        private static void WriteTexturePage(BBData data, TexturePageInfo tpi)
        {
            var tpe = new TexPageEntry
            {
                Source        = tpi.Source,
                Dest          = tpi.Destination,
                Size          = tpi.Size,
                SpritesheetId = (ushort)tpi.SpritesheetId
            };

            data.Buffer.Write(tpe);
        }
예제 #22
0
        private static void WriteRoomView(BBData data, RoomView rv)
        {
            data.Buffer.Write(new RoomViewEntry
            {
                IsEnabled = rv.IsEnabled ? DwordBool.True : DwordBool.False,
                Port      = rv.Port,
                View      = rv.View,
                Border    = rv.Border,
                Speed     = rv.Speed,

                ObjectId = rv.ObjectId ?? 0xFFFFFFFF
            });
        }
예제 #23
0
        private static void WriteRoomTile(BBData data, RoomTile rt)
        {
            data.Buffer.Write(new RoomTileEntry
            {
                DefIndex  = rt.DefIndex ?? 0xFFFFFFFF,
                Position  = rt.Position,
                SourcePos = rt.SourcePosition,
                Size      = rt.Size,
                Scale     = rt.Scale,
                Colour    = rt.Colour,

                TileDepth  = rt.Depth,
                InstanceID = rt.InstanceID
            });
        }
예제 #24
0
        private static void WriteRoomObj(BBData data, RoomObject ro)
        {
            data.Buffer.Write(new RoomObjEntry
            {
                DefIndex = ro.DefIndex ?? 0xFFFFFFFF,
                Position = ro.Position,
                Scale    = ro.Scale,
                Colour   = ro.Colour,
                Rotation = ro.Rotation,

                InstanceID   = ro.InstanceID,
                CreateCodeID = ro.CreateCodeID
            });
            data.Buffer.Write(0xFFFFFFFF);
        }
예제 #25
0
        private static void WriteRoomBg(BBData data, RoomBackground rb)
        {
            data.Buffer.Write(new RoomBgEntry
            {
                IsEnabled    = rb.IsEnabled ? DwordBool.True : DwordBool.False,
                IsForeground = rb.IsForeground ? DwordBool.True : DwordBool.False,
                Position     = rb.Position,
                TileX        = rb.TileX ? DwordBool.True : DwordBool.False,
                TileY        = rb.TileY ? DwordBool.True : DwordBool.False,
                Speed        = rb.Speed,
                Stretch      = rb.StretchSprite ? DwordBool.True : DwordBool.False,

                DefIndex = rb.BgIndex ?? 0xFFFFFFFF
            });
        }
예제 #26
0
        static void UpdateOffsets(BBData data, int parentOffset)
        {
            var offs = data.OffsetOffsets;
            var bb   = data.Buffer;

            for (int i = 0; i < offs.Length; i++)
            {
                bb.Position = offs[i];
                var o = bb.ReadInt32();
                bb.Position -= sizeof(int);
                bb.Write(o + parentOffset);
                offs[i] += parentOffset;
            }

            data.Buffer        = bb;
            data.OffsetOffsets = offs;
        }
예제 #27
0
 private static void WriteRoomObjInst(BBData data, RoomObjInst roi, StringsChunkBuilder strings)
 {
     data.Buffer.Write(new RoomObjInstEntry
     {
         Index     = roi.Index,
         Unk1      = roi.Unk1,
         Depth     = roi.Depth,
         Unk3      = roi.Unk3,
         InstCount = (uint)roi.Instances.Length,
         Name      = strings.GetOffset(roi.Name)
     });
     data.Buffer.Position -= 4;
     foreach (var id in roi.Instances)
     {
         data.Buffer.Write(id);
     }
 }
예제 #28
0
        public static int[] WriteOptions(BBData data, OptionInfo opt, StringsChunkBuilder strings)
        {
            var ret = new SectionOptions();
            var stringOffsetOffsets = new List <int>();

            unsafe
            {
                for (int i = 0; i < 2; i++)
                {
                    ret._pad0[i] = opt._pad0[i];
                }
                for (int i = 0; i < 0xC; i++)
                {
                    ret._pad1[i] = opt._pad1[i];
                }
            }
            ret.GEN8FlagsDup = opt.InfoFlags;

            if (opt.Constants == null)
            {
                ret.ConstMap.Count = 0;
            }
            else
            {
                ret.ConstMap.Count = (uint)opt.Constants.Count;
            }

            var tmp = new BinBuffer();

            tmp.Write(ret);
            data.Buffer.Write(tmp, 0, tmp.Size - 12, 8);

            if (opt.Constants != null)
            {
                foreach (var kvp in opt.Constants)
                {
                    stringOffsetOffsets.Add(data.Buffer.Position + 8);
                    data.Buffer.Write(strings.GetOffset(kvp.Key));
                    stringOffsetOffsets.Add(data.Buffer.Position + 8);
                    data.Buffer.Write(strings.GetOffset(kvp.Value));
                }
            }

            return(stringOffsetOffsets.ToArray());
        }
예제 #29
0
        public static void WriteAudio(BBData data, AudioInfo[] waves, int offset)
        {
            BBData[] datas = new BBData[waves.Length];

            for (int i = 0; i < waves.Length; i++)
            {
                BBData audiodata = new BBData(new BinBuffer(), new int[0]);
                audiodata.Buffer.Write(waves[i].Wave.Length); // AudioEntry.Length
                audiodata.Buffer.Write(waves[i].Wave);
                if (i != waves.Length - 1)
                {
                    Pad(audiodata, 0x4, i == 0 ? 8 + offset : 0);
                }
                datas[i] = audiodata;
            }

            WriteList(data, datas);
        }
예제 #30
0
        public static int[] WriteShaders(BBData data, ShaderInfo[] shaders, StringsChunkBuilder strings)
        {
            int[] offsets             = WriteList(data, shaders, WriteShader, strings);
            var   stringOffsetOffsets = new List <int>(shaders.Length);

            for (int i = 0; i < shaders.Length; i++)
            {
                stringOffsetOffsets.Add(offsets[i] + (int)Marshal.OffsetOf(typeof(ShaderEntry), "Name") + 8);
                for (int j = 0; j < 6; j++)
                {
                    stringOffsetOffsets.Add(offsets[i] + (int)Marshal.OffsetOf(typeof(ShaderEntry), "GLSL_ES") + 8 + j * sizeof(uint));
                }
                for (int j = 0; j < shaders[i].Attributes.Length; j++)
                {
                    stringOffsetOffsets.Add(offsets[i] + (int)Marshal.OffsetOf(typeof(ShaderEntry), "Attributes") + 8 + j * sizeof(uint));
                }
            }
            return(stringOffsetOffsets.ToArray());
        }