示例#1
0
        public static void ExportGM(
            string fileName,
            List <IBox> boxes,
            GTMP.GMFile.GMMetadata metadata,
            byte[] gmllData
            )
        {
            List <Box>        bigBoxes;
            List <IconImgBox> icons;

            SeparateBoxes(boxes, out bigBoxes, out icons);
            DebugLogger.Log(
                "Project",
                "Exporting as GMFile to {0} with {1} boxes, {2} item boxes, metadata ({3}), and gmllData of {4} bytes",
                fileName,
                bigBoxes.Count,
                icons.Count,
                metadata.ToString(),
                (gmllData == null) ? -1 : gmllData.Length
                );
            // this can be possible is the user just starts drawing boxes and wants to export that
            // without loading an associated image
            if (gmllData == null)
            {
                // 4 - "GMLL"
                // 4 - int for number of positions
                // 0 - position data length
                // 32 * 16 * 2 = 32 palettes of 16 2-byte colour
                // 4 - int for number of tiles
                // 0 - bytes of tile pixel data
                gmllData = new byte[4 + 4 + 0 + (32 * 16 * 2) + 4 + 0];
                Array.Copy(Encoding.ASCII.GetBytes("GMLL"), gmllData, 4);
            }
            try
            {
                using (MemoryStream ms = new MemoryStream(15000))
                    using (BinaryWriter bw = new BinaryWriter(ms))
                    {
                        // the game files never have more than four iconimgs
                        // in one box group, it seems to handle more than that
                        // perfectly fine, so we make slightly smaller files by not
                        // splitting them up like that
                        int numIcons    = icons.Count;
                        int numBigBoxes = bigBoxes.Count;
                        //int curIcon = 0;
                        //int curBigBox = 0;
                        //int boxGroups = numIcons / 4;

                        bw.Write(Encoding.ASCII.GetBytes("GM\x3\x0"));
                        bw.Write(numIcons > 0 ? 1 : 0); // 0x4

                        if (numIcons > 0)
                        {
                            bw.Write(numIcons);
                            foreach (IconImgBox icon in icons)
                            {
                                icon.Serialize(bw);
                            }
                        }

                        // if anybody ever wants to write files with the 4 iconimg per group
                        // here it is, don't forget to comment out the above, or it won't work right
                        // if(numIcons > 0)
                        //{
                        //do
                        //{
                        //    int iconsToWrite = Math.Min(4, numIcons);
                        //    int bigBoxesToWrite = Math.Min(4, numBigBoxes);
                        //    bw.Write((ushort)iconsToWrite);
                        //    bw.Write((ushort)bigBoxesToWrite);
                        //    for (int i = 0; i < iconsToWrite; ++i)
                        //    {
                        //        icons[0].Serialize(bw);
                        //        icons.RemoveAt(0);
                        //    }
                        //    for(int i = 0; i < bigBoxesToWrite; ++i)
                        //    {
                        //        bigBoxes[0].Serialise(bw);
                        //        bigBoxes.RemoveAt(0);
                        //    }
                        //    numIcons -= iconsToWrite;
                        //    numBigBoxes -= bigBoxesToWrite;
                        //}
                        //while (numIcons != 0);
                        //}

                        bw.Write(numBigBoxes);

                        // if any box is a CarDisplay, set flag 2 in the metadata flags
                        // check for more than one box with the default cursor position attribute
                        // don't care of there aren't any
                        int numCars        = 0;
                        int defaultCursors = 0;
                        foreach (Box b in bigBoxes)
                        {
                            if (b.Contents == GTMP.GMFile.BoxItem.CarDisplay)
                            {
                                if (++numCars > 1)
                                {
                                    throw new InvalidBoxStateException("The game will not render more than 1 CarDisplay box", b);
                                }
                            }
                            if ((b.BehaviourAttributes & GTMP.GMFile.InfoBoxAttributes.DefaultCursorPos) != 0)
                            {
                                if (++defaultCursors > 1)
                                {
                                    throw new InvalidBoxStateException("More than one box has the DefaultCursorPos BehaviourAttribute set", b);
                                }
                            }
                            b.Serialize(bw);
                        }

                        int screenBehaviour = (numCars != 0) ? 2 : 0;
                        if (metadata.BackLinkToPreviousScreen)
                        {
                            screenBehaviour = 3;
                        }
                        bw.Write((sbyte)metadata.ManufacturerID);
                        bw.Write((byte)screenBehaviour);
                        bw.Write((ushort)metadata.ScreenType);
                        bw.Write(metadata.BackLink);
                        bw.Write((int)metadata.BackgroundIndex);
                        bw.Write(gmllData);
                        bw.Flush();

                        ms.Position = 0;
#if DEBUG
                        File.WriteAllBytes(@"T:\uncompressedgm.gm", ms.ToArray());
#endif
                        MemoryStream compressed      = Compress.GZipCompressStream(ms);
                        byte[]       compressedBytes = compressed.ToArray();
                        File.WriteAllBytes(fileName, compressedBytes);
                    }
            }
            catch (InvalidBoxStateException ibse)
            {
                MainForm.DisplayMsgBox(
                    System.Windows.Forms.MessageBoxButtons.OK,
                    System.Windows.Forms.MessageBoxIcon.Error,
                    ibse.Message
                    );
            }
        }