Dark Bit Factory & Gravity
PROGRAMMING => C / C++ /C# => Topic started by: mammon on March 01, 2017
-
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 :)
/// <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);
}
}
-
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.