143 lines
3.8 KiB
C#
143 lines
3.8 KiB
C#
using System;
|
|
using Microsoft.Xna.Framework.Graphics;
|
|
|
|
namespace FreedomFighter;
|
|
|
|
/// <summary>
|
|
/// Port of TOmegaBitmapFont: a fixed-cell bitmap font backed by an image list item,
|
|
/// with mutable color/alpha state (the credits animate Alpha on the shared font).
|
|
/// </summary>
|
|
public class BitmapFont
|
|
{
|
|
public string Characters = "";
|
|
public OmegaImage Image = null!;
|
|
public int Red = 255, Green = 255, Blue = 255;
|
|
public int Alpha = 255;
|
|
|
|
public int CharWidth => Image.TileWidth;
|
|
public int CharHeight => Image.TileHeight;
|
|
|
|
public BitmapFont(OmegaImage image, string characters)
|
|
{
|
|
Image = image;
|
|
Characters = characters;
|
|
}
|
|
|
|
public void PrintFast(SpriteBatch sb, float x, float y, char c)
|
|
{
|
|
int idx = Characters.IndexOf(c);
|
|
if (idx < 0) return;
|
|
Image.Draw(sb, x, y, 0, 0, 0, 1, 1, Red, Green, Blue, Math.Clamp(Alpha, 0, 255), idx);
|
|
}
|
|
|
|
public void Print(SpriteBatch sb, float x, float y, string text)
|
|
{
|
|
for (int i = 0; i < text.Length; i++)
|
|
PrintFast(sb, x + i * CharWidth, y, text[i]);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Port of the TGameText helper (GameText.pas): typewriter printing and
|
|
/// fade in/out of text through a bitmap font's shared Alpha.
|
|
/// </summary>
|
|
public class GameText
|
|
{
|
|
string _text;
|
|
int _length;
|
|
int _curChar;
|
|
int _maxLength;
|
|
int _timer;
|
|
int _speed = 10;
|
|
bool _done;
|
|
readonly BitmapFont _font;
|
|
|
|
public GameText(string msg, int rowLength, BitmapFont font)
|
|
{
|
|
_text = msg;
|
|
_length = msg.Length;
|
|
_maxLength = rowLength;
|
|
_font = font;
|
|
}
|
|
|
|
public void SetText(string msg)
|
|
{
|
|
_text = msg;
|
|
_length = msg.Length;
|
|
_curChar = 0;
|
|
_timer = 0;
|
|
}
|
|
|
|
public void SetSpeed(int speed) => _speed = speed;
|
|
public bool IsDone => _done;
|
|
public string GetText() => _text;
|
|
public int GetLength() => _length * _font.CharWidth;
|
|
|
|
// The Pascal original indexed the 1-based string with i = 0..CurChar; index 0 was a no-op.
|
|
void PrintChars(SpriteBatch sb, float x, float y, int upTo)
|
|
{
|
|
for (int i = 1; i <= upTo && i <= _length; i++)
|
|
{
|
|
char c = _text[i - 1];
|
|
if (i <= _maxLength)
|
|
_font.PrintFast(sb, x + i * _font.CharWidth, y, c);
|
|
else
|
|
{
|
|
int tempChar = i;
|
|
while (tempChar > _maxLength) tempChar -= _maxLength;
|
|
_font.PrintFast(sb, x + tempChar * 12, y + (int)Math.Ceiling(i / (double)_maxLength) * 24 - 24, c);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void TypePrint(SpriteBatch sb, float x, float y)
|
|
{
|
|
_done = false;
|
|
PrintChars(sb, x, y, _curChar);
|
|
|
|
if (_curChar < _length)
|
|
{
|
|
_timer++;
|
|
if (_timer > _speed)
|
|
{
|
|
_curChar++;
|
|
if (_curChar <= _length && _curChar >= 1 && _text[_curChar - 1] == ' ')
|
|
_curChar++;
|
|
_timer = 0;
|
|
}
|
|
}
|
|
else
|
|
_done = true;
|
|
}
|
|
|
|
public void FadeIn(SpriteBatch sb, float x, float y, int speed)
|
|
{
|
|
_done = false;
|
|
PrintChars(sb, x, y, _length);
|
|
_timer++;
|
|
if (_timer > speed && _font.Alpha < 255)
|
|
_font.Alpha++;
|
|
else
|
|
_done = true; // original quirk: also "done" while the timer is still counting
|
|
}
|
|
|
|
public void FadeOut(SpriteBatch sb, float x, float y, int speed)
|
|
{
|
|
_done = false;
|
|
PrintChars(sb, x, y, _length);
|
|
_timer++;
|
|
if (_timer > speed && _font.Alpha > 0)
|
|
_font.Alpha--;
|
|
else
|
|
_done = true;
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
_curChar = 0;
|
|
_timer = 0;
|
|
_speed = 10;
|
|
_done = false;
|
|
}
|
|
}
|