protected virtual void Charset()
{
byte[] subtitleBuffer = new byte[200];
var subtitleLine = 0;
Point subtitlePos = new Point();
if (Game.Version >= 7)
{
((ScummEngine7)this).ProcessSubtitleQueue();
}
if (_haveMsg == 0)
return;
if (Game.Version >= 4 && Game.Version <= 6)
{
// Do nothing while the camera is moving
if ((_camera.DestinationPosition.X / 8) != (_camera.CurrentPosition.X / 8) || _camera.CurrentPosition.X != _camera.LastPosition.X)
return;
}
Actor a = null;
if (TalkingActor != 0xFF)
a = Actors[TalkingActor];
if (a != null && _string[0].Overhead)
{
int s;
_string[0].Position = new Point(
(short)(a.Position.X - MainVirtScreen.XStart),
(short)(a.Position.Y - a.Elevation - ScreenTop));
if (_game.Version <= 5)
{
if (_variables[VariableTalkStringY.Value] < 0)
{
s = (a.ScaleY * _variables[VariableTalkStringY.Value]) / 0xFF;
_string[0].Position = _string[0].Position.Offset(0, (short)(((_variables[VariableTalkStringY.Value] - s) / 2) + s));
}
else
{
_string[0].Position = new Point(_string[0].Position.X, (short)_variables[VariableTalkStringY.Value]);
}
}
else
{
s = a.ScaleX * a.TalkPosition.X / 0xFF;
var x = _string[0].Position.X + ((a.TalkPosition.X - s) / 2) + s;
s = a.ScaleY * a.TalkPosition.Y / 0xFF;
var y = _string[0].Position.Y + ((a.TalkPosition.Y - s) / 2) + s;
if (y > ScreenHeight - 40)
y = ScreenHeight - 40;
_string[0].Position = new Point((short)x, (short)y);
}
if (_string[0].Position.Y < 1)
_string[0].Position = new Point(_string[0].Position.X, 1);
if (_string[0].Position.X < 80)
_string[0].Position = new Point(80, _string[0].Position.Y);
if (_string[0].Position.X > ScreenWidth - 80)
_string[0].Position = new Point((short)(ScreenWidth - 80), _string[0].Position.Y);
}
_charset.Top = _string[0].Position.Y + ScreenTop;
_charset.StartLeft = _charset.Left = _string[0].Position.X;
_charset.Right = _string[0].Right;
_charset.Center = _string[0].Center;
_charset.SetColor(_charsetColor);
if (a != null && a.Charset != 0)
_charset.SetCurID(a.Charset);
else
_charset.SetCurID(_string[0].Charset);
if (_game.Version >= 5)
Array.Copy(_charsetData[_charset.GetCurId()], CharsetColorMap, 4);
if (_keepText && Game.Platform == Platform.FMTowns)
_charset.Str = _curStringRect;
if (_talkDelay != 0)
return;
if ((Game.Version <= 6 && _haveMsg == 1) ||
(Game.Version == 7 && _haveMsg != 1))
{
if ((Sound.SfxMode & 2) == 0)
StopTalk();
return;
}
if (a != null && !_string[0].NoTalkAnim)
{
a.RunTalkScript(a.TalkStartFrame);
_useTalkAnims = true;
}
_talkDelay = VariableDefaultTalkDelay.HasValue ? Variables[VariableDefaultTalkDelay.Value] : 60;
if (!_keepText)
{
if (Game.Version >= 7)
{
((ScummEngine7)this).ClearSubtitleQueue();
_nextLeft = _string[0].Position.X;
_nextTop = _string[0].Position.Y + ScreenTop;
}
else
{
if (_game.Platform == Platform.FMTowns)
TownsRestoreCharsetBg();
else
RestoreCharsetBg();
}
}
if (Game.Version > 3)
{
int maxWidth = _charset.Right - _string[0].Position.X - 1;
if (_charset.Center)
{
if (maxWidth > _nextLeft)
maxWidth = _nextLeft;
maxWidth *= 2;
}
_charset.AddLinebreaks(0, _charsetBuffer, _charsetBufPos, maxWidth);
}
if (_charset.Center)
{
_nextLeft -= _charset.GetStringWidth(0, _charsetBuffer, _charsetBufPos) / 2;
if (_nextLeft < 0)
_nextLeft = Game.Version >= 6 ? _string[0].Position.X : 0;
}
_charset.DisableOffsX = _charset.FirstChar = !_keepText;
int c = 0;
while (HandleNextCharsetCode(a, ref c))
{
if (c == 0)
{
// End of text reached, set _haveMsg accordingly
_haveMsg = (_game.Version >= 7) ? 2 : 1;
_keepText = false;
break;
}
if (c == 13)
{
if (Game.Version >= 7 && subtitleLine != 0)
{
((ScummEngine7)this).AddSubtitleToQueue(subtitleBuffer, 0, subtitlePos, _charsetColor, (byte)_charset.GetCurId());
subtitleLine = 0;
}
if (!NewLine())
break;
continue;
}
// Handle line overflow for V3. See also bug #1306269.
if (_game.Version == 3 && _nextLeft >= ScreenWidth)
{
_nextLeft = ScreenWidth;
}
// Handle line breaks for V1-V2
if (_game.Version <= 2 && _nextLeft >= ScreenWidth)
{
if (!NewLine())
break; // FIXME: Is this necessary? Only would be relevant for v0 games
}
_charset.Left = _nextLeft;
_charset.Top = _nextTop;
if (Game.Version >= 7)
{
if (subtitleLine == 0)
{
subtitlePos.X = (short)_charset.Left;
// BlastText position is relative to the top of the screen, adjust y-coordinate
subtitlePos.Y = (short)(_charset.Top - ScreenTop);
}
subtitleBuffer[subtitleLine++] = (byte)c;
subtitleBuffer[subtitleLine] = 0;
}
else
{
_charset.PrintChar(c, false);
}
_nextLeft = _charset.Left;
_nextTop = _charset.Top;
if (_game.Version <= 2)
{
_talkDelay += _defaultTalkDelay;
Variables[VariableCharCount.Value]++;
}
else
{
_talkDelay += _variables[VariableCharIncrement.Value];
}
}
if (_game.Platform == Platform.FMTowns && (c == 0 || c == 2 || c == 3))
_curStringRect = _charset.Str;
if (Game.Version >= 7 && subtitleLine != 0)
{
((ScummEngine7)this).AddSubtitleToQueue(subtitleBuffer, 0, subtitlePos, _charsetColor, (byte)_charset.GetCurId());
}
}