Ejemplo n.º 1
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);
        }
Ejemplo n.º 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);
        }
Ejemplo n.º 3
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);
            }
        }
Ejemplo n.º 4
0
 private static void WriteScript(BBData data, ScriptInfo si, StringsChunkBuilder strings)
 {
     data.Buffer.Write(new ScriptEntry
     {
         Name   = strings.GetOffset(si.Name),
         CodeId = si.CodeId
     });
 }
Ejemplo n.º 5
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
     });
 }
Ejemplo n.º 6
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());
        }
Ejemplo n.º 7
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
     });
 }
Ejemplo n.º 8
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
     });
 }
Ejemplo n.º 9
0
        public static int[] WriteFunctionLocals(BBData data, FunctionLocalsInfo[] functions, StringsChunkBuilder strings)
        {
            var stringOffsetOffsets = new List <int>();

            data.Buffer.Write(functions.Length);

            foreach (var func in functions)
            {
                data.Buffer.Write((uint)func.LocalNames.Length);
                stringOffsetOffsets.Add(data.Buffer.Position + 8);
                data.Buffer.Write(strings.GetOffset(func.FunctionName));
                for (uint i = 0; i < func.LocalNames.Length; i++)
                {
                    stringOffsetOffsets.Add(data.Buffer.Position + 12);
                    data.Buffer.Write(new FunctionLocalEntry
                    {
                        Index = i,
                        Name  = strings.GetOffset(func.LocalNames[i])
                    });
                }
            }

            return(stringOffsetOffsets.ToArray());
        }
Ejemplo n.º 10
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);
     }
 }
Ejemplo n.º 11
0
        private static void WritePath(BBData data, PathInfo pi, StringsChunkBuilder strings)
        {
            var tmp = new BinBuffer();

            tmp.Write(new PathEntry
            {
                Name      = strings.GetOffset(pi.Name),
                IsSmooth  = pi.IsSmooth ? DwordBool.True : DwordBool.False,
                IsClosed  = pi.IsClosed ? DwordBool.True : DwordBool.False,
                Precision = pi.Precision,

                PointCount = (uint)pi.Points.Length
            });
            data.Buffer.Write(tmp, 0, tmp.Size - 12, 0);

            foreach (var pt in pi.Points)
            {
                data.Buffer.Write(pt);
            }
        }
Ejemplo n.º 12
0
        private static void WriteSprite(BBData data, SpriteInfo si, StringsChunkBuilder strings, int[] texPagOffsets)
        {
            var se = new SpriteEntry
            {
                Name     = strings.GetOffset(si.Name),
                Size     = si.Size,
                Bounding = si.Bounding,
                BBoxMode = si.BBoxMode,
                Origin   = si.Origin,

                SeparateColMasks = si.SeparateColMasks ? DwordBool.True : DwordBool.False
            };

            var tmp = new BinBuffer();

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

            if (si.Version >= 2)
            {
                var se2 = new SpriteEntry2();
                unsafe
                {
                    se2._pad2[0] = -1;
                    se2._pad2[1] = 1;
                    se2._pad2[2] = 0;
                }
                se2.funk = si.UnknownFloat;
                tmp      = new BinBuffer();
                tmp.Write(se2);
                data.Buffer.Write(tmp, 0, 0x14, 0x38);
            }

            if (si.TextureIndices == null)
            {
                data.Buffer.Write(0xFFFFFFFF);
            }
            else
            {
                data.Buffer.Write(si.TextureIndices.Length);
                foreach (var ti in si.TextureIndices)
                {
                    data.Buffer.Write(texPagOffsets[ti]);
                }

                if (si.CollisionMasks == null)
                {
                    data.Buffer.Write(0xFFFFFFFF);
                }
                else
                {
                    data.Buffer.Write((uint)si.CollisionMasks.Length);
                    foreach (var mask in si.CollisionMasks)
                    {
                        int w = mask.GetLength(0);
                        for (int y = 0; y < mask.GetLength(1); y++)
                        {
                            for (int x = 0; x < w; x += 8)
                            {
                                byte b = 0;
                                if (x < w && mask[x, y])
                                {
                                    b |= 0b00000001;
                                }
                                if (x + 1 < w && mask[x + 1, y])
                                {
                                    b |= 0b00000010;
                                }
                                if (x + 2 < w && mask[x + 2, y])
                                {
                                    b |= 0b00000100;
                                }
                                if (x + 3 < w && mask[x + 3, y])
                                {
                                    b |= 0b00001000;
                                }
                                if (x + 4 < w && mask[x + 4, y])
                                {
                                    b |= 0b00010000;
                                }
                                if (x + 5 < w && mask[x + 5, y])
                                {
                                    b |= 0b00100000;
                                }
                                if (x + 6 < w && mask[x + 6, y])
                                {
                                    b |= 0b01000000;
                                }
                                if (x + 7 < w && mask[x + 7, y])
                                {
                                    b |= 0b10000000;
                                }
                                data.Buffer.Write(b);
                            }
                        }
                    }
                }
            }
            Pad(data, 4, 0);
        }
Ejemplo n.º 13
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());
        }
Ejemplo n.º 14
0
        private static void WriteObject(BBData data, ObjectInfo oi, StringsChunkBuilder strings)
        {
            var oe = new ObjectEntry
            {
                Name        = strings.GetOffset(oi.Name),
                SpriteIndex = oi.SpriteIndex,
                Visible     = oi.IsVisible ? DwordBool.True : DwordBool.False,
                Solid       = oi.IsSolid ? DwordBool.True : DwordBool.False,
                Depth       = oi.Depth,
                Persistent  = oi.IsPersistent ? DwordBool.True : DwordBool.False,

                ParentId = oi.ParentId == null ? -100 : (int)oi.ParentId,
                MaskId   = oi.TexMaskId == null ? -1 : (int)oi.TexMaskId,

                HasPhysics     = oi.Physics != null ? DwordBool.True : DwordBool.False,
                IsSensor       = oi.IsSensor ? DwordBool.True : DwordBool.False,
                CollisionShape = oi.CollisionShape
            };

            oe.Physics = oi.Physics ?? new ObjectPhysics
            {
                Density        = 0.5f,
                Restitution    = 0.1f,
                Group          = 0,
                LinearDamping  = 0.1f,
                AngularDamping = 0.1f,
                Unknown0       = 0,
                Friction       = 0.2f,
                Unknown1       = 1,
                Kinematic      = 0
            };

            for (int i = 0; i < oi.OtherFloats.Length; i++)
            {
                unsafe
                {
                    oe.Rest.MoreFloats[i] = oi.OtherFloats[i];
                }
            }

            var hasMore = oi.OtherFloats.Length > 0;

            if (hasMore)
            {
                BinBuffer tmp = new BinBuffer();
                tmp.Write(oe);
                data.Buffer.Write(tmp.AsByteArray(), 0, (int)Marshal.OffsetOf(typeof(ObjectEntry), "Rest") + (int)Marshal.OffsetOf(typeof(ObjectRest), "ShapePoints_IfMoreFloats"));
            }
            else
            {
                BinBuffer tmp = new BinBuffer();
                tmp.Write(oe);
                data.Buffer.Write(tmp.AsByteArray(), 0, (int)Marshal.OffsetOf(typeof(ObjectEntry), "Rest") + (int)Marshal.OffsetOf(typeof(ObjectRest), "ShapePoints"));
            }
            WriteList(data, oi.ShapePoints, (shapePointData, shapePoint) =>
                      WriteList(shapePointData, shapePoint, (pointPointData, pointPoint) =>
            {
                pointPointData.Buffer.Write(pointPoint[0]);
                pointPointData.Buffer.Write(pointPoint[1]); // probably count
                pointPointData.OffsetOffsets = new int[] { pointPointData.Buffer.Position };
                pointPointData.Buffer.Write(12);            // probably offset
                for (int i = 3; i < pointPoint.Length; i++)
                {
                    pointPointData.Buffer.Write(pointPoint[i]);
                }
            })
                      );
        }
Ejemplo n.º 15
0
        public static int[] WriteGeneral(BBData data, GeneralInfo ge, RoomInfo[] rooms, StringsChunkBuilder strings)
        {
            var ret = new SectionGeneral
            {
                Debug             = ge.IsDebug,
                FilenameOffset    = strings.GetOffset(ge.FileName),
                ConfigOffset      = strings.GetOffset(ge.Configuration),
                NameOffset        = strings.GetOffset(ge.Name),
                DisplayNameOffset = strings.GetOffset(ge.DisplayName),
                GameID            = ge.GameID,
                WindowSize        = ge.WindowSize,
                BytecodeVersion   = (Int24)ge.BytecodeVersion,
                Major             = ge.Version.Major,
                Minor             = ge.Version.Minor,
                Release           = ge.Version.Build,
                Build             = ge.Version.Revision,

                Info          = ge.InfoFlags,
                ActiveTargets = ge.ActiveTargets,
                AppID         = ge.SteamAppID,

                LastObj  = 0,
                LastTile = 0
            };
            var stringOffsetOffsets = new int[]
            {
                (int)Marshal.OffsetOf(typeof(SectionGeneral), "FilenameOffset") - 3,
                (int)Marshal.OffsetOf(typeof(SectionGeneral), "ConfigOffset") - 3,
                (int)Marshal.OffsetOf(typeof(SectionGeneral), "NameOffset") - 3,
                (int)Marshal.OffsetOf(typeof(SectionGeneral), "DisplayNameOffset") - 3
            };

            foreach (var room in rooms)
            {
                foreach (var obj in room.Objects)
                {
                    if (obj.InstanceID > ret.LastObj)
                    {
                        ret.LastObj = obj.InstanceID;
                    }
                }
                foreach (var tile in room.Tiles)
                {
                    if (tile.InstanceID > ret.LastTile)
                    {
                        ret.LastTile = tile.InstanceID;
                    }
                }
            }
            ret.LastObj++;
            ret.LastTile++;

            for (int i = 0; i < 4; i++)
            {
                unsafe
                {
                    ret._unknown[i] = ge.unknown[i];
                }
            }

            unsafe
            {
                Marshal.Copy(ge.LicenseMD5Hash, 0, (IntPtr)ret.MD5, 0x10);
            }

            ret.CRC32 = ge.LicenceCRC32;

            ret.Timestamp = (ulong)(ge.Timestamp.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;

            if (ge.WeirdNumbers == null)
            {
                ret.NumberCount = 0;
            }
            else
            {
                ret.NumberCount = (uint)ge.WeirdNumbers.Length;
            }

            var tmp = new BinBuffer();

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

            for (int i = 0; i < ret.NumberCount; i++)
            {
                data.Buffer.Write(ge.WeirdNumbers[i]);
            }

            // TODO for 2.0: some lengthy checksum/hash at the end?
            // exits after launch if GEN8 is modified at all,
            // doesn't launch if the extra stuff is missing
            //for (int i = 0; i < 16; i++)
            //    data.Buffer.Write(0x3F3F3F3F);

            return(stringOffsetOffsets);
        }
Ejemplo n.º 16
0
        private static void WriteRoom(BBData data, RoomInfo ri, StringsChunkBuilder strings)
        {
            var re = new RoomEntry
            {
                Name       = strings.GetOffset(ri.Name),
                Caption    = ri.Caption == null ? 0 : strings.GetOffset(ri.Caption),
                Size       = ri.Size,
                Speed      = ri.Speed,
                Persistent = ri.IsPersistent ? DwordBool.True : DwordBool.False,
                Colour     = ri.Colour,

                DrawBackgroundColour = ri.DrawBackgroundColour ? DwordBool.True : DwordBool.False,
                _unknown             = ri._unknown,

                Flags = 0,

                World          = ri.World,
                Bounding       = ri.Bounding,
                Gravity        = ri.Gravity,
                MetresPerPixel = ri.MetresPerPixel
            };

            if (ri.EnableViews)
            {
                re.Flags |= RoomEntryFlags.EnableViews;
            }
            if (ri.ShowColour)
            {
                re.Flags |= RoomEntryFlags.ShowColour;
            }
            if (ri.ClearDisplayBuffer)
            {
                re.Flags |= RoomEntryFlags.ClearDisplayBuffer;
            }
            if (ri.UnknownFlag)
            {
                re.Flags |= RoomEntryFlags.Unknown;
            }

            var bgOffsetOffset      = (int)Marshal.OffsetOf(typeof(RoomEntry), "BgOffset");
            var viewOffsetOffset    = (int)Marshal.OffsetOf(typeof(RoomEntry), "ViewOffset");
            var objOffsetOffset     = (int)Marshal.OffsetOf(typeof(RoomEntry), "ObjOffset");
            var tileOffsetOffset    = (int)Marshal.OffsetOf(typeof(RoomEntry), "TileOffset");
            int objInstOffsetOffset = (int)Marshal.OffsetOf(typeof(RoomEntry), "MetresPerPixel") + 4;

            data.Buffer.Write(re);
            data.OffsetOffsets = new int[] { bgOffsetOffset, viewOffsetOffset, objOffsetOffset, tileOffsetOffset };

            if (ri.ObjInst != null)
            {
                data.Buffer.Write(0);
                data.OffsetOffsets = data.OffsetOffsets.Concat(new int[] { objInstOffsetOffset }).ToArray();
            }

            data.Buffer.Position = bgOffsetOffset;
            data.Buffer.Write(data.Buffer.Size);
            data.Buffer.Position = data.Buffer.Size;
            WriteList(data, ri.Backgrounds, WriteRoomBg);

            data.Buffer.Position = viewOffsetOffset;
            data.Buffer.Write(data.Buffer.Size);
            data.Buffer.Position = data.Buffer.Size;
            WriteList(data, ri.Views, WriteRoomView);

            data.Buffer.Position = objOffsetOffset;
            data.Buffer.Write(data.Buffer.Size);
            data.Buffer.Position = data.Buffer.Size;
            WriteList(data, ri.Objects, WriteRoomObj);

            data.Buffer.Position = tileOffsetOffset;
            data.Buffer.Write(data.Buffer.Size);
            data.Buffer.Position = data.Buffer.Size;
            WriteList(data, ri.Tiles, WriteRoomTile);

            if (ri.ObjInst != null)
            {
                data.Buffer.Position = objInstOffsetOffset;
                data.Buffer.Write(data.Buffer.Size);
                data.Buffer.Position = data.Buffer.Size;
                WriteList(data, ri.ObjInst, WriteRoomObjInst, strings);
            }

            // Unknown stuff for 2.0
            //for (int i = 0; i < 8; i++)
            //    data.Buffer.Write(0x3F3F3F3F);
        }