private void StdSpeak(Compact target, uint textNum, uint animNum)
{
animNum += (uint)(target.Core.megaSet / NEXT_MEGA_SET);
animNum &= 0xFF;
var talkTable = new UShortAccess(_skyCompact.FetchCptRaw((ushort)CptIds.TalkTableList), 0);
target.Core.grafixProgId = talkTable[(int)animNum];
target.Core.grafixProgPos = 0;
var animPtr = _skyCompact.GetGrafixPtr(target);
if (animPtr != null)
{
target.Core.offset = animPtr[0]; animPtr.Offset += 2;
target.Core.getToFlag = animPtr[0]; animPtr.Offset += 2;
target.Core.grafixProgPos += 2;
}
else
{
target.Core.grafixProgId = 0;
}
bool speechFileFound = false;
if (SkyEngine.IsCDVersion)
{
speechFileFound = _skySound.StartSpeech((ushort)textNum);
}
// Set the focus region to that area
// Calculate the point where the character is
int x = target.Core.xcood - TOP_LEFT_X;
int y = target.Core.ycood - TOP_LEFT_Y;
// TODO: Make the box size change based on the object that has the focus
_skyScreen.SetFocusRectangle(new Rect(x, y, 192, 128));
if (SystemVars.Instance.SystemFlags.HasFlag(SystemFlags.AllowText) || !speechFileFound)
{
// form the text sprite, if player wants subtitles or
// if we couldn't find the speech file
var textInfo = _skyText.LowTextManager(textNum, FIXED_TEXT_WIDTH, 0, (byte)target.Core.spColor, true);
var textCompact = _skyCompact.FetchCpt(textInfo.CompactNum);
target.Core.spTextId = textInfo.CompactNum; //So we know what text to kill
var textGfxHeader = ServiceLocator.Platform.ToStructure <DataFileHeader>(textInfo.TextData, 0);
textCompact.Core.screen = target.Core.screen; //put it on our screen
if (_scriptVariables[SCREEN] == target.Core.screen)
{ // Only use coordinates if we are on the current screen
//talking on-screen
//create the x coordinate for the speech text
//we need the talkers sprite information
var targetGfx = SkyEngine.ItemList[target.Core.frame >> 6];
var header = ServiceLocator.Platform.ToStructure <DataFileHeader>(targetGfx, 0);
ushort xPos = (ushort)(target.Core.xcood + header.s_offset_x);
ushort width = (ushort)(header.s_width >> 1);
xPos += (ushort)(width - FIXED_TEXT_WIDTH / 2); //middle of talker
if (xPos < TOP_LEFT_X)
{
xPos = TOP_LEFT_X;
}
width = (ushort)(xPos + FIXED_TEXT_WIDTH);
if (TOP_LEFT_X + FULL_SCREEN_WIDTH <= width)
{
xPos = TOP_LEFT_X + FULL_SCREEN_WIDTH;
xPos -= FIXED_TEXT_WIDTH;
}
textCompact.Core.xcood = xPos;
ushort yPos = (ushort)(target.Core.ycood + (header.s_offset_y - 6 - textGfxHeader.s_height));
if (yPos < TOP_LEFT_Y)
{
yPos = TOP_LEFT_Y;
}
textCompact.Core.ycood = yPos;
}
else
{
//talking off-screen
target.Core.spTextId = 0; //don't kill any text 'cos none was made
textCompact.Core.status = 0; //don't display text
}
// In CD version, we're doing the timing by checking when the VOC has stopped playing.
// Setting spTime to 10 thus means that we're doing a pause of 10 gamecycles between
// each sentence.
if (speechFileFound)
{
target.Core.spTime = 10;
}
else
{
target.Core.spTime = (ushort)(_skyText.NumLetters + 5);
}
}
else
{
target.Core.spTime = 10;
target.Core.spTextId = 0;
}
target.Core.logic = L_TALK;
}