Author Topic: [C#] SineWaveScroller w/Bitmap Font Support  (Read 836 times)

0 Members and 1 Guest are viewing this topic.

Offline mammon

  • ZX 81
  • *
  • Posts: 4
  • Karma: 1
  • Y = x (G^P)
    • View Profile
This code has been partially converted from various sources, but eventually I ended up with having to code my own custom bitmap-font parser to get it to work properly - I hope everyone finds this useful :)
Code: [Select]
    /// <summary>
    /// String Alignment Options
    /// </summary>
    public enum StringAlignment
    {
        /// <summary>
        /// Sets the alignment all to the left
        /// </summary>
        Left,
        /// <summary>
        /// Sets the alignment all to the middle
        /// </summary>
        Middle,
        /// <summary>
        /// Sets the alignment all to the right
        /// </summary>
        Right,
        /// <summary>
        /// Sets the alignment all to the set number
        /// </summary>
        Custom
    }
    /// <summary>
    /// Structure of the Font
    /// </summary>
    public struct Spritefont
    {
        /// <summary>
        /// The exact string of the alphabet
        /// </summary>
        public string Alphabet;
        /// <summary>
        /// The bitmap of the font to use
        /// </summary>
        public Bitmap FontImage;
        /// <summary>
        /// Height of each individual character
        /// </summary>
        public int CharHeight;
        /// <summary>
        /// Width of each individual character
        /// </summary>
        public int CharWidth;
    }
    /// <summary>
    /// Structure of the mapped alphabet
    /// </summary>
    public struct BitmapAlphabet
    {
        /// <summary>
        /// Mapped image of letter
        /// </summary>
        public Bitmap LetterPic;
        /// <summary>
        /// Mapped character of letter
        /// </summary>
        public char Letter;
    }
    /// <summary>
    /// Classic oldschool sinewave text-scroller
    /// </summary>
    /// <author>
    /// mammon
    /// </author>
    public class clsSineWaveScroller
    {
        int sinemultiplier1 = 70;
        int sinemultiplier2 = 70;

        float[] sinearray1 = new float[360];
        float[] sinearray2 = new float[360];

        float[] nTextScroller;
        float X_POS, Y_POS, x_pos_tracker;

        PictureBox myPicBox;
        Spritefont myFont;
        string textToScroll;
        BitmapAlphabet[] sAlphabet;
        bool isBitmapFontUsed = false;

        /// <summary>
        /// Sets the spritefont...
        /// </summary>
        /// <param name="nyFont">The bitmap font to use</param>
        public void SetMyFont(Spritefont nyFont)
        {
            myFont = nyFont;
            isBitmapFontUsed = true;
            InitiateFont();
        }
        /// <summary>
        /// Initiates the SineWave-TextScroller effect...
        /// </summary>
        /// <param name="cPicBox">PictureBox where the effect will be drawn...</param>
        /// <param name="sSpritFont">The bitmap font to use...</param>
        /// <param name="toScroll">The string to scroll...</param>
        public clsSineWaveScroller(PictureBox cPicBox, Spritefont sSpritFont, string toScroll)
        {
            textToScroll = toScroll;
            myPicBox = cPicBox;

            InitiateSineWave();
            SetMyFont(sSpritFont);
        }
        /// <summary>
        /// Initiates the SineWave TextScroller effect...
        /// </summary>
        /// <param name="cPicBox">PictureBox where the effect will be drawn...</param>
        /// <param name="toScroll">The string to scroll...</param>
        public clsSineWaveScroller(PictureBox cPicBox, string toScroll)
        {
            textToScroll = toScroll;
            myPicBox = cPicBox;
            InitiateSineWave();
        }
        /// <summary>
        /// Draws the sinewave-textscroller upon the provided Graphics field...
        /// </summary>
        /// <param name="gfx">Graphics field to write the sinewave-textscroller to...</param>
        public void DrawScroller(Graphics gfx)
        {
            DrawText(gfx);
        }
        /// <summary>
        /// Draws a simple string to the Graphics field...
        /// </summary>
        /// <param name="toWrite">The string to write...</param>
        /// <param name="strAlign">Alignment of the string...</param>
        /// <param name="gfx">Graphics field to write the string to...</param>
        /// <param name="customAlign">[OPTIONAL] Custom number to align to...</param>
        public void DrawStaticString(string toWrite, StringAlignment strAlign, Graphics gfx, [Optional]int customAlign)
        {
            gfx.FillRectangle(new LinearGradientBrush(myPicBox.ClientRectangle, Color.DarkSlateGray, Color.DarkViolet, LinearGradientMode.Vertical), myPicBox.ClientRectangle);
            var xposx = 0;
            var middle = myPicBox.Width / 2 - (myFont.CharWidth * (toWrite.Length / 2)) - myFont.CharWidth;
            var right = myPicBox.Width - (myFont.CharWidth * toWrite.Length) - myFont.CharWidth;
            for (int x = 0; x < toWrite.Length; x++)
            {
                switch (strAlign)
                {
                    case StringAlignment.Middle:
                        xposx = (x * myFont.CharWidth) + middle;
                        break;
                    case StringAlignment.Left:
                        xposx = (x * myFont.CharWidth);
                        break;
                    case StringAlignment.Right:
                        xposx = (x * myFont.CharWidth) + right;
                        break;
                    case StringAlignment.Custom:
                        xposx = (x * myFont.CharWidth) + customAlign;
                        break;
                }
                gfx.DrawImage(sAlphabet.Single(xx => xx.Letter == toWrite.ToUpper()[x]).LetterPic, xposx, 2);
            }

        }
        void InitiateSineWave()
        {
            nTextScroller = new float[textToScroll.Length];
            for (int i = 0; i < textToScroll.Length; i++)
                nTextScroller[i] = i;

            x_pos_tracker = this.myPicBox.Right;
            for (int i = 0; i < 360; i++)
            {
                sinearray1[i] = sinemultiplier1 + ((float)Math.Sin(DegToRad(i)) * sinemultiplier1);
                sinearray2[i] = sinemultiplier2 + ((float)Math.Sin(DegToRad(i)) * sinemultiplier2);
            }
        }
        void InitiateFont()
        {
            sAlphabet = new BitmapAlphabet[myFont.Alphabet.Length];
            for (var a = 0; a < sAlphabet.Length; a++)
            {
                sAlphabet[a].Letter = myFont.Alphabet[a];
                sAlphabet[a].LetterPic = GetCharacter(myFont.Alphabet[a]);
            }

            sinemultiplier1 = myPicBox.Height / 4 - myFont.CharHeight;
            sinemultiplier2 = myPicBox.Height / 4 - myFont.CharHeight;
        }
        void DrawText(Graphics gfx)
        {
            if (x_pos_tracker + textToScroll.Length * myFont.CharWidth > 0)
                x_pos_tracker--;
            else
                x_pos_tracker = this.myPicBox.Right;

            gfx.FillRectangle(Brushes.Transparent, this.myPicBox.ClientRectangle);
            for (int x = 0; x < textToScroll.Length; x++)
            {
                X_POS = (x * myFont.CharWidth) + x_pos_tracker;
                if (nTextScroller[x] < sinearray1.Length)
                    Y_POS = sinearray1[(int)nTextScroller[x]];
                else
                {
                    nTextScroller[x] = 0;
                    Y_POS = sinearray1[(int)nTextScroller[x]];
                }
                nTextScroller[x]++;
                if (isBitmapFontUsed)
                    gfx.DrawImage(sAlphabet.First(xx => xx.Letter == textToScroll.ToUpper()[x]).LetterPic, new PointF(X_POS, Y_POS));
                else
                    gfx.DrawString(textToScroll[x].ToString(), new Font(SystemFonts.DialogFont, FontStyle.Regular), Brushes.Blue, new PointF(X_POS, Y_POS));
            }
        }
        #region Version 1.1 BMPFontParser
        Bitmap GetCharacter(char c)
        {
            var myAlphabet = myFont.Alphabet;

            var i = 0;
            var myBmp = myFont.FontImage;
            var charBmp = new Bitmap(myFont.CharWidth, myFont.CharHeight);
            myBmp.MakeTransparent();
            var g = Graphics.FromImage(myBmp);

            if (myAlphabet.Contains(c))
            {
                for (i = 0; i < myAlphabet.Length && (myAlphabet[i] != c); i++) ;
                var w = myBmp.Width; var h = myBmp.Height;
                var xpos = 0; var ypos = 0;

                for (var x = 0; x < myAlphabet.Length; x++)
                {
                    if (xpos >= w)
                    {
                        xpos = 0;
                        ypos += myFont.CharHeight;
                    }
                    if (myAlphabet[x] == c)
                    {
                        charBmp = GetCharacter(myBmp, new Rectangle(xpos, ypos, myFont.CharWidth, myFont.CharHeight));
                        return charBmp;
                    }
                    xpos += myFont.CharWidth;
                }
            }
            else
                charBmp = new Bitmap(myFont.CharWidth, myFont.CharHeight);

            return charBmp;
        }
        #endregion
        Bitmap GetCharacter(Bitmap source, Rectangle section)
        {
            var bmp = new Bitmap(section.Width, section.Height);

            var g = Graphics.FromImage(bmp);
            g.DrawImage(source, 0, 0, section, GraphicsUnit.Pixel);

            return bmp;
        }
        float DegToRad(float degrees)
        {
            return ((degrees * (float)Math.PI) / 90);
        }
    }
« Last Edit: March 28, 2017 by mammon »
"Attempt the absurd, to achieve the impossible!"

Offline boogop

  • C= 64
  • **
  • Posts: 66
  • Karma: 42
    • View Profile
Re: [C#] SineWaveScroller w/Bitmap Font Support
« Reply #1 on: March 01, 2017 »
Nice to see work in c#! I've gotten a lot of mileage out of it and have done all my DBF compo entries in it. I use the FastBitmap class which allows direct pixel-pushing to the graphics object, which in my thirst for punishment I enjoy.
Challenge Trophies Won: