Beispiel #1
0
        static int Main(string[] astrArgs)
        {
            string    strOutputDir = null;
            ArrayList alFiles      = new ArrayList();
            bool      fForce       = false;

            if (astrArgs.Length < 1)
            {
                Console.WriteLine("amx2zamx usage:\namx2zamx <file.amx ...> [-o output dir]");
                return(-1);
            }

            for (int i = 0; i < astrArgs.Length; i++)
            {
                string str = astrArgs[i];

                if (str == "-o")
                {
                    strOutputDir = astrArgs[++i];
                    continue;
                }
                else if (str == "-f")
                {
                    fForce = true;
                    continue;
                }

                string strRoot = Path.GetPathRoot(str);
                if (strRoot == "")
                {
                    strRoot = ".";
                }
                string   strFile   = Path.GetFileName(str);
                string[] astrFiles = Directory.GetFiles(strRoot, strFile);
                if (astrFiles.Length == 0)
                {
                    Console.WriteLine("Warning: nothing matches {0}", str);
                    continue;
                }

                alFiles.AddRange(astrFiles);
            }

            foreach (string strFile in alFiles)
            {
                if (Path.GetExtension(strFile).ToLower() != ".amx")
                {
                    Console.WriteLine("Warning: ignoring {0}", strFile);
                    continue;
                }

                AnimDoc doc = AnimDoc.Load(strFile);

                string strOutFile = Path.GetFileName(strFile);
                strOutFile = Path.ChangeExtension(strOutFile, ".zamx");
                if (strOutputDir != null)
                {
                    strOutFile = Path.Combine(strOutputDir, strOutFile);
                }

                if (File.Exists(strOutFile) && !fForce)
                {
                    Console.WriteLine("Warning: {0} already exists, skipping", strOutFile);
                    continue;
                }

                Console.WriteLine("writing {0}", strOutFile);
                doc.Save(strOutFile);
            }

            return(0);
        }
Beispiel #2
0
        static void ShrinkWrap(AnimDoc doc)
        {
            Color      clrTransparent = Color.FromArgb(0xff, 0, 0xff);
            SolidBrush brTransparent  = new SolidBrush(clrTransparent);

            foreach (XBitmap xbm in doc.XBitmapSet)
            {
                Bitmap bm = xbm.Bitmap;

                // OPT: this could be made faster by doing four independent edge scans

                int xL = bm.Width;
                int xR = 0;
                int yT = bm.Height;
                int yB = 0;
                for (int y = 0; y < bm.Height; y++)
                {
                    for (int x = 0; x < bm.Width; x++)
                    {
                        Color clr = bm.GetPixel(x, y);
                        if (clr != clrTransparent)
                        {
                            xL = Math.Min(xL, x);
                            xR = Math.Max(xR, x);
                            yT = Math.Min(yT, y);
                            yB = Math.Max(yB, y);
                        }
                    }
                }
                int cx = xR - xL + 1;
                int cy = yB - yT + 1;

                Bitmap bmT = new Bitmap(cx, cy, PixelFormat.Format24bppRgb);
                using (Graphics g = Graphics.FromImage(bmT)) {
                    Rectangle rcT = new Rectangle(xL, yT, cx, cy);
                    g.DrawImage(bm, 0, 0, rcT, GraphicsUnit.Pixel);
                }

                xbm.Bitmap = bmT;

                // Don't need this anymore

                bm.Dispose();

                // If the upper-left corner of the bitmap has been adjusted
                // we must adjust the origins of all Frames referencing it.

                if (xL != 0 || yT != 0)
                {
                    foreach (Strip stp in doc.StripSet)
                    {
                        foreach (Frame fr in stp)
                        {
                            foreach (BitmapPlacer plc in fr.BitmapPlacers)
                            {
                                if (plc.XBitmap == xbm)
                                {
                                    plc.X -= xL;
                                    plc.Y -= yT;
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #3
0
        static int Main(string[] astrArgs)
        {
            if (astrArgs.Length < 3 || astrArgs.Length > 10)
            {
                Console.WriteLine("Usage:\nacrunch [-scale N] [-save] [-noscaleicon] [-noshrinkwrap] [-highlight <cxTile>] [-stats] <palette.pal> <input.amx> <outdir>\n");
                return(-1);
            }

            double nScale         = 1.0;
            bool   fSave          = false;
            bool   fNoShrinkWrap  = false;
            bool   fDumpStats     = false;
            bool   fScaleIcon     = true;
            bool   fMakeHighlight = true;
            int    cxTile         = 0;

            int iarg = 0;

            while (astrArgs[iarg][0] == '-')
            {
                switch (astrArgs[iarg])
                {
                case "-scale":
                    nScale = double.Parse(astrArgs[++iarg]);
                    break;

                case "-noscaleicon":
                    fScaleIcon = false;
                    break;

                case "-save":
                    fSave = true;
                    break;

                case "-noshrinkwrap":
                    fNoShrinkWrap = true;
                    break;

                case "-stats":
                    fDumpStats = true;
                    break;

                case "-highlight":
                    fMakeHighlight = true;
                    cxTile         = Int32.Parse(astrArgs[++iarg]);
                    break;
                }

                iarg++;
            }

            // Read in the palette

            string  strFilePal = astrArgs[iarg++];
            Palette pal        = new Palette(strFilePal);

            if (pal == null)
            {
                Console.WriteLine("Error: unable to read the palette file {0}\n", strFilePal);
                return(-1);
            }

            // Read in the animation file (.amx)

            string  strFileAmx = astrArgs[iarg++];
            AnimDoc doc        = AnimDoc.Load(strFileAmx);

            if (doc == null)
            {
                Console.WriteLine("Error: unable to read animation file {0}\n", strFileAmx);
                return(-1);
            }

            // Get directory

            string strDir = astrArgs[iarg++];

            // Reduce the Bitmaps down to the tightest rectangular boundary around the
            // non-transparent pixels.

            if (!fNoShrinkWrap)
            {
                ShrinkWrap(doc);
            }

            // Make highlight if asked. This uses existing images, so do this
            // before scaling.

            Strip stpHighlight = null;

            if (fMakeHighlight)
            {
                stpHighlight = MakeHighlightStrip(doc, cxTile, pal);
            }

            // Scale if asked

            if (nScale != 1.0)
            {
                Scale(doc, nScale, pal, fScaleIcon);
            }

            // Add in highlight strip

            if (stpHighlight != null)
            {
                doc.StripSet.Add(stpHighlight);
                foreach (Frame fr in stpHighlight)
                {
                    foreach (BitmapPlacer plc in fr.BitmapPlacers)
                    {
                        doc.XBitmapSet.Add(plc.XBitmap);
                    }
                }
            }

            // If dump stats, we're *only* dumping stats

            if (fDumpStats)
            {
                DumpStats(doc);
                return(0);
            }

            // Write the runtime animation file (.anir) and crunched bitmaps

            if (fSave)
            {
                doc.Save(strDir + Path.DirectorySeparatorChar + Path.GetFileName(strFileAmx));
            }
            else
            {
                doc.WriteAnir(pal, strDir, Path.GetFileNameWithoutExtension(strFileAmx));
            }
            return(0);
        }
Beispiel #4
0
        static void Scale(AnimDoc doc, double nScale, Palette palFixed, bool fScaleIcon)
        {
            if (nScale >= 1.5)
            {
                doc.Hires = true;
            }

            // If not scaling icon, make a clone of it so it doesn't get scaled,
            // then after scaling set this clone back in.

            Strip stpIcon      = doc.StripSet["icon"];
            Strip stpIconClone = null;

            if (!fScaleIcon && stpIcon != null)
            {
                stpIconClone = (Strip)stpIcon.Clone();
            }

            // Scale all the bitmaps

            foreach (XBitmap xbm in doc.XBitmapSet)
            {
                // Scale

                xbm.Bitmap = TBitmapTools.ScaleBitmap(xbm.Bitmap, nScale, palFixed);

                // Scale the points in the frames that use this bitmap

                foreach (Strip stp in doc.StripSet)
                {
                    foreach (Frame fr in stp)
                    {
                        foreach (BitmapPlacer plc in fr.BitmapPlacers)
                        {
                            if (plc.XBitmap == xbm)
                            {
                                plc.X = (int)Math.Round(plc.X * nScale);
                                plc.Y = (int)Math.Round(plc.Y * nScale);
                            }
                        }
                    }
                }
            }

            // Scale all special points too

            foreach (Strip stp in doc.StripSet)
            {
                foreach (Frame fr in stp)
                {
                    Point pt = new Point();
                    pt.X            = (int)Math.Round(fr.SpecialPoint.X * nScale);
                    pt.Y            = (int)Math.Round(fr.SpecialPoint.Y * nScale);
                    fr.SpecialPoint = pt;
                }
            }

            // Put the strip icon back in if it shouldn't be scaled

            if (!fScaleIcon && stpIconClone != null)
            {
                // Patch in the clone and add the images to the XBitmapSet
                // (they are not added auto-magically).

                doc.StripSet[doc.StripSet.IndexOf(stpIcon)] = stpIconClone;
                foreach (Frame fr in stpIconClone)
                {
                    foreach (BitmapPlacer plc in fr.BitmapPlacers)
                    {
                        doc.XBitmapSet.Add(plc.XBitmap);
                    }
                }
            }
        }
Beispiel #5
0
        static Strip MakeHighlightStrip(AnimDoc doc, int cxTile,
                                        Palette palFixed)
        {
            Strip stpHelp = doc.StripSet["help"];

            if (stpHelp == null)
            {
                return(null);
            }

            // This does a deep copy
            Strip stpHighlight = (Strip)stpHelp.Clone();

            stpHighlight.Name = "highlight";

            // Figure out the scaling. It would be better to pass this in as
            // a parameter.

            Frame     frT     = stpHighlight[0];
            Rectangle rcUnion = new Rectangle();

            foreach (BitmapPlacer plc in frT.BitmapPlacers)
            {
                Rectangle rc = new Rectangle();
                rc.X      = -plc.X;
                rc.Y      = -plc.Y;
                rc.Width  = plc.XBitmap.Width;
                rc.Height = plc.XBitmap.Height;
                if (rcUnion.IsEmpty)
                {
                    rcUnion = rc;
                }
                else
                {
                    rcUnion = Rectangle.Union(rcUnion, rc);
                }
            }

            // Needs to be 4 tiles high. Keep aspect ratio

            int cy = rcUnion.Height;

            if (cy < cxTile * 4)
            {
                cy = cxTile * 4;
            }
            double nScale = 1.0;

            if (cy > rcUnion.Height)
            {
                nScale = (double)cy / (double)rcUnion.Height;
            }

            // Scale

            if (nScale != 1.0)
            {
                foreach (Frame fr in stpHighlight)
                {
                    foreach (BitmapPlacer plc in fr.BitmapPlacers)
                    {
                        plc.XBitmap.Bitmap = TBitmapTools.ScaleBitmap(
                            plc.XBitmap.Bitmap, nScale, palFixed);
                        plc.X = (int)Math.Round(plc.X * nScale);
                        plc.Y = (int)Math.Round(plc.Y * nScale);
                    }

                    Point pt = new Point();
                    pt.X            = (int)Math.Round(fr.SpecialPoint.X * nScale);
                    pt.Y            = (int)Math.Round(fr.SpecialPoint.Y * nScale);
                    fr.SpecialPoint = pt;
                }
            }

            return(stpHighlight);
        }