960 lines
20 KiB
C++
960 lines
20 KiB
C++
|
/** @file text.cpp
|
||
|
@brief
|
||
|
This file contains dialogues processing.
|
||
|
It contains text and font functions.
|
||
|
|
||
|
TwinEngine: a Little Big Adventure engine
|
||
|
|
||
|
Copyright (C) 2013 The TwinEngine team
|
||
|
Copyright (C) 2008-2013 Prequengine team
|
||
|
Copyright (C) 2002-2007 The TwinEngine team
|
||
|
|
||
|
This program is free software; you can redistribute it and/or
|
||
|
modify it under the terms of the GNU General Public License
|
||
|
as published by the Free Software Foundation; either version 2
|
||
|
of the License, or (at your option) any later version.
|
||
|
|
||
|
This program is distributed in the hope that it will be useful,
|
||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
GNU General Public License for more details.
|
||
|
|
||
|
You should have received a copy of the GNU General Public License
|
||
|
along with this program; if not, write to the Free Software
|
||
|
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
*/
|
||
|
|
||
|
#include <math.h>
|
||
|
|
||
|
#include "text.h"
|
||
|
#include "main.h"
|
||
|
#include "hqrdepack.h"
|
||
|
#include "resources.h"
|
||
|
#include "sdlengine.h"
|
||
|
#include "menu.h"
|
||
|
#include "interface.h"
|
||
|
#include "lbaengine.h"
|
||
|
#include "keyboard.h"
|
||
|
#include "screens.h"
|
||
|
#include "renderer.h"
|
||
|
#include "sound.h"
|
||
|
|
||
|
// RECHECK THIS LATER
|
||
|
int32 currentBankIdx = -1; // textVar1
|
||
|
uint8 textVar2[256];
|
||
|
uint8 textVar3;
|
||
|
|
||
|
/** Dialogue text pointer */
|
||
|
uint8 *dialTextPtr; // bufText
|
||
|
/** Dialogue entry order pointer */
|
||
|
uint8 *dialOrderPtr; // bufOrder
|
||
|
/** Number of dialogues text entries */
|
||
|
int16 numDialTextEntries;
|
||
|
|
||
|
// TODO: refactor this
|
||
|
int32 wordSizeChar;
|
||
|
int32 wordSizePixel;
|
||
|
|
||
|
int16 spaceChar = 0x20;
|
||
|
|
||
|
/** FLA movie extension */
|
||
|
#define VOX_EXT ".vox"
|
||
|
/** Common movie directory */
|
||
|
#define VOX_DIR "vox/"
|
||
|
|
||
|
int8 * LanguagePrefixTypes[] = {
|
||
|
"EN_",
|
||
|
"FR_",
|
||
|
"DE_",
|
||
|
"SP_",
|
||
|
"IT_"
|
||
|
};
|
||
|
|
||
|
int8 * LanguageSufixTypes[] = {
|
||
|
"sys",
|
||
|
"cre",
|
||
|
"gam",
|
||
|
"000",
|
||
|
"001",
|
||
|
"002",
|
||
|
"003",
|
||
|
"004",
|
||
|
"005",
|
||
|
"006",
|
||
|
"007",
|
||
|
"008",
|
||
|
"009",
|
||
|
"010",
|
||
|
"011"
|
||
|
};
|
||
|
|
||
|
|
||
|
void initVoxBank(int32 bankIdx) {
|
||
|
// get the correct vox hqr file
|
||
|
memset(currentVoxBankFile, 0, sizeof(int8));
|
||
|
sprintf(currentVoxBankFile, VOX_DIR);
|
||
|
strcat(currentVoxBankFile, LanguagePrefixTypes[cfgfile.LanguageId]);
|
||
|
strcat(currentVoxBankFile, LanguageSufixTypes[bankIdx]);
|
||
|
strcat(currentVoxBankFile, VOX_EXT);
|
||
|
|
||
|
// TODO check the rest to reverse
|
||
|
}
|
||
|
|
||
|
|
||
|
int32 initVoxToPlay(int32 index) { // setVoxFileAtDigit
|
||
|
int32 i = 0;
|
||
|
int32 currIdx = 0;
|
||
|
int32 orderIdx = 0;
|
||
|
|
||
|
int16 *localOrderBuf = (int16 *) dialOrderPtr;
|
||
|
|
||
|
voxHiddenIndex = 0;
|
||
|
hasHiddenVox = 0;
|
||
|
|
||
|
// choose right text from order index
|
||
|
for (i = 0; i < numDialTextEntries; i++) {
|
||
|
orderIdx = *(localOrderBuf++);
|
||
|
if (orderIdx == index) {
|
||
|
currIdx = i;
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
currDialTextEntry = currIdx;
|
||
|
|
||
|
playVoxSample(currDialTextEntry);
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
int32 playVox(int32 index) {
|
||
|
if (cfgfile.LanguageCDId && index) {
|
||
|
if (hasHiddenVox && !isSamplePlaying(index)) {
|
||
|
playVoxSample(index);
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32 playVoxSimple(int32 index) {
|
||
|
if (cfgfile.LanguageCDId && index) {
|
||
|
playVox(index);
|
||
|
|
||
|
if (isSamplePlaying(index)) {
|
||
|
return 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
void stopVox(int32 index) {
|
||
|
hasHiddenVox = 0;
|
||
|
stopSample(index);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/** Initialize dialogue
|
||
|
@param bankIdx Text bank index*/
|
||
|
void initTextBank(int32 bankIdx) { // InitDial
|
||
|
int32 langIdx;
|
||
|
int32 hqrSize;
|
||
|
|
||
|
// don't load if we already have the dialogue text bank loaded
|
||
|
if (bankIdx == currentBankIdx)
|
||
|
return;
|
||
|
|
||
|
currentBankIdx = bankIdx;
|
||
|
// RECHECK THIS LATER
|
||
|
textVar2[0] = textVar3;
|
||
|
|
||
|
// get index according with language
|
||
|
langIdx = (cfgfile.LanguageId * 14) * 2 + bankIdx * 2;
|
||
|
|
||
|
hqrSize = hqrGetallocEntry(&dialOrderPtr, HQR_TEXT_FILE, langIdx);
|
||
|
|
||
|
numDialTextEntries = hqrSize / 2;
|
||
|
|
||
|
hqrSize = hqrGetallocEntry(&dialTextPtr, HQR_TEXT_FILE, ++langIdx);
|
||
|
|
||
|
if (cfgfile.LanguageCDId) {
|
||
|
initVoxBank(bankIdx);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Draw a certain character in the screen
|
||
|
@param x X coordinate in screen
|
||
|
@param y Y coordinate in screen
|
||
|
@param character ascii character to display */
|
||
|
void drawCharacter(int32 x, int32 y, uint8 character) { // drawCharacter
|
||
|
uint8 sizeX;
|
||
|
uint8 sizeY;
|
||
|
uint8 param1;
|
||
|
uint8 param2;
|
||
|
uint8 *data;
|
||
|
uint8 *screen;
|
||
|
|
||
|
// int temp=0;
|
||
|
int32 toNextLine;
|
||
|
uint8 index;
|
||
|
|
||
|
// char color;
|
||
|
uint8 usedColor;
|
||
|
uint8 number;
|
||
|
uint8 jump;
|
||
|
|
||
|
int32 i;
|
||
|
|
||
|
int32 tempX;
|
||
|
int32 tempY;
|
||
|
|
||
|
data = fontPtr + *((int16 *)(fontPtr + character * 4));
|
||
|
|
||
|
dialTextSize = sizeX = *(data++);
|
||
|
sizeY = *(data++);
|
||
|
|
||
|
param1 = *(data++);
|
||
|
param2 = *(data++);
|
||
|
|
||
|
x += param1;
|
||
|
y += param2;
|
||
|
|
||
|
usedColor = dialTextColor;
|
||
|
|
||
|
screen = frontVideoBuffer + screenLookupTable[y] + x;
|
||
|
|
||
|
tempX = x;
|
||
|
tempY = y;
|
||
|
|
||
|
toNextLine = SCREEN_WIDTH - sizeX;
|
||
|
|
||
|
do {
|
||
|
index = *(data++);
|
||
|
do {
|
||
|
jump = *(data++);
|
||
|
screen += jump;
|
||
|
tempX += jump;
|
||
|
if (--index == 0) {
|
||
|
screen += toNextLine;
|
||
|
tempY++;
|
||
|
tempX = x;
|
||
|
sizeY--;
|
||
|
if (sizeY <= 0) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
} else {
|
||
|
number = *(data++);
|
||
|
for (i = 0; i < number; i++) {
|
||
|
if (tempX >= SCREEN_TEXTLIMIT_LEFT && tempX < SCREEN_TEXTLIMIT_RIGHT && tempY >= SCREEN_TEXTLIMIT_TOP && tempY < SCREEN_TEXTLIMIT_BOTTOM)
|
||
|
frontVideoBuffer[SCREEN_WIDTH*tempY + tempX] = usedColor;
|
||
|
|
||
|
screen++;
|
||
|
tempX++;
|
||
|
}
|
||
|
|
||
|
if (--index == 0) {
|
||
|
screen += toNextLine;
|
||
|
tempY++;
|
||
|
tempX = x;
|
||
|
|
||
|
sizeY--;
|
||
|
if (sizeY <= 0) {
|
||
|
return;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} while (1);
|
||
|
} while (1);
|
||
|
|
||
|
}
|
||
|
|
||
|
/** Draw character with shadow
|
||
|
@param x X coordinate in screen
|
||
|
@param y Y coordinate in screen
|
||
|
@param character ascii character to display
|
||
|
@param color character color */
|
||
|
void drawCharacterShadow(int32 x, int32 y, uint8 character, int32 color) { // drawDoubleLetter
|
||
|
int32 left, top, right, bottom;
|
||
|
|
||
|
if (character != 0x20)
|
||
|
{
|
||
|
// shadow color
|
||
|
setFontColor(0);
|
||
|
drawCharacter(x + 2, y + 4, character);
|
||
|
|
||
|
// text color
|
||
|
setFontColor(color);
|
||
|
drawCharacter(x, y, character);
|
||
|
|
||
|
left = x;
|
||
|
top = y;
|
||
|
// FIXME: get right font size
|
||
|
right = x + 32;
|
||
|
bottom = y + 38;
|
||
|
|
||
|
copyBlockPhys(left, top, right, bottom);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/** Display a certain dialogue text in the screen
|
||
|
@param x X coordinate in screen
|
||
|
@param y Y coordinate in screen
|
||
|
@param dialogue ascii text to display */
|
||
|
void drawText(int32 x, int32 y, int8 *dialogue) { // Font
|
||
|
uint8 currChar;
|
||
|
|
||
|
if (fontPtr == 0) // if the font is not defined
|
||
|
return;
|
||
|
|
||
|
do {
|
||
|
currChar = (uint8) * (dialogue++); // read the next char from the string
|
||
|
|
||
|
if (currChar == 0) // if the char is 0x0, -> end of string
|
||
|
break;
|
||
|
|
||
|
if (currChar == 0x20) // if it's a space char
|
||
|
x += dialCharSpace;
|
||
|
else {
|
||
|
dialTextSize = *(fontPtr + (*((int16 *)(fontPtr + currChar * 4)))); // get the length of the character
|
||
|
drawCharacter(x, y, currChar); // draw the character on screen
|
||
|
// add the length of the space between 2 characters
|
||
|
x += dialSpaceBetween;
|
||
|
// add the length of the current character
|
||
|
x += dialTextSize;
|
||
|
}
|
||
|
} while (1);
|
||
|
}
|
||
|
|
||
|
/** Gets dialogue text width size
|
||
|
@param dialogue ascii text to display */
|
||
|
int32 getTextSize(int8 *dialogue) { // SizeFont
|
||
|
uint8 currChar;
|
||
|
dialTextSize = 0;
|
||
|
|
||
|
do {
|
||
|
currChar = (uint8) * (dialogue++);
|
||
|
|
||
|
if (currChar == 0)
|
||
|
break;
|
||
|
|
||
|
if (currChar == 0x20) {
|
||
|
dialTextSize += dialCharSpace;
|
||
|
} else {
|
||
|
dialTextSize += dialSpaceBetween;
|
||
|
dialTextSize += *(fontPtr + *((int16 *)(fontPtr + currChar * 4)));
|
||
|
}
|
||
|
} while (1);
|
||
|
|
||
|
return (dialTextSize);
|
||
|
}
|
||
|
|
||
|
void initDialogueBox() { // InitDialWindow
|
||
|
blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8*)workVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8*)frontVideoBuffer);
|
||
|
|
||
|
if (newGameVar4 != 0) {
|
||
|
drawBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
|
||
|
drawTransparentBox(dialTextBoxLeft + 1, dialTextBoxTop + 1, dialTextBoxRight - 1, dialTextBoxBottom - 1, 3);
|
||
|
}
|
||
|
|
||
|
copyBlockPhys(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
|
||
|
printText8Var3 = 0;
|
||
|
blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8*)frontVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8*)workVideoBuffer);
|
||
|
}
|
||
|
|
||
|
void initInventoryDialogueBox() { // SecondInitDialWindow
|
||
|
blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8*)workVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8*)frontVideoBuffer);
|
||
|
copyBlockPhys(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
|
||
|
printText8Var3 = 0;
|
||
|
}
|
||
|
|
||
|
// TODO: refactor this code
|
||
|
void initText(int32 index) { // initText
|
||
|
printTextVar13 = 0;
|
||
|
|
||
|
if (!getText(index)) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
printText8Ptr1 = buf1;
|
||
|
printText8Ptr2 = buf2;
|
||
|
|
||
|
printTextVar13 = 1;
|
||
|
|
||
|
printText8Var1 = 0;
|
||
|
buf1[0] = 0;
|
||
|
buf2[0] = 0;
|
||
|
printText8Var2 = index;
|
||
|
printText8Var3 = 0;
|
||
|
TEXT_CurrentLetterX = dialTextBoxLeft + 8;
|
||
|
printText8Var5 = 0;
|
||
|
printText8Var6 = 0;
|
||
|
TEXT_CurrentLetterY = dialTextBoxTop + 8;
|
||
|
printText8Var8 = currDialTextPtr;
|
||
|
|
||
|
// lba font is get while engine start
|
||
|
setFontParameters(2, 7);
|
||
|
}
|
||
|
|
||
|
void initProgressiveTextBuffer() {
|
||
|
int32 i = 0;
|
||
|
|
||
|
buf2[0] = 0;
|
||
|
|
||
|
while (i < dialTextBufferSize) {
|
||
|
strcat((char*)buf2, " ");
|
||
|
i++;
|
||
|
};
|
||
|
|
||
|
printText8Ptr2 = buf2;
|
||
|
addLineBreakX = 16;
|
||
|
printText8Var1 = 0;
|
||
|
}
|
||
|
|
||
|
void printText8Sub4(int16 a, int16 b, int16 c) {
|
||
|
int32 temp;
|
||
|
int32 counter2 = 0;
|
||
|
int32 var1;
|
||
|
int32 var2;
|
||
|
|
||
|
if (printText8Var3 < 32) {
|
||
|
temp = printText8Var3 * 3;
|
||
|
pt8s4[temp] = c;
|
||
|
pt8s4[temp+1] = a;
|
||
|
pt8s4[temp+2] = b;
|
||
|
|
||
|
printText8Var3++;
|
||
|
} else {
|
||
|
while (counter2 < 31) {
|
||
|
var1 = (counter2 + 1) * 3;
|
||
|
var2 = counter2 * 3;
|
||
|
pt8s4[var2] = pt8s4[var1];
|
||
|
pt8s4[var2+1] = pt8s4[var1+1];
|
||
|
pt8s4[var2+2] = pt8s4[var1+2];
|
||
|
counter2++;
|
||
|
};
|
||
|
pt8s4[93] = c;
|
||
|
pt8s4[94] = a;
|
||
|
pt8s4[95] = b;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
void getWordSize(uint8 *arg1, uint8 *arg2) {
|
||
|
int32 temp = 0;
|
||
|
uint8 *arg2Save = arg2;
|
||
|
|
||
|
while (*arg1 != 0 && *arg1 != 1 && *arg1 != 0x20) {
|
||
|
temp++;
|
||
|
*arg2++ = *arg1++;
|
||
|
}
|
||
|
|
||
|
wordSizeChar = temp;
|
||
|
*arg2 = 0;
|
||
|
wordSizePixel = getTextSize((int8*)arg2Save);
|
||
|
}
|
||
|
|
||
|
void processTextLine() {
|
||
|
int16 var4;
|
||
|
uint8 *buffer;
|
||
|
uint8 *temp;
|
||
|
|
||
|
buffer = printText8Var8;
|
||
|
dialCharSpace = 7;
|
||
|
var4 = 1;
|
||
|
|
||
|
addLineBreakX = 0;
|
||
|
printText8PrepareBufferVar2 = 0;
|
||
|
buf2[0] = 0;
|
||
|
|
||
|
for (;;)
|
||
|
{
|
||
|
if (*buffer == 0x20) {
|
||
|
buffer++;
|
||
|
continue;
|
||
|
}
|
||
|
|
||
|
if (*buffer != 0) {
|
||
|
printText8Var8 = buffer;
|
||
|
getWordSize(buffer, buf1);
|
||
|
if (addLineBreakX + dialCharSpace + wordSizePixel < dialTextBoxParam2) {
|
||
|
temp = buffer + 1;
|
||
|
if (*buffer == 1) {
|
||
|
var4 = 0;
|
||
|
buffer = temp;
|
||
|
} else {
|
||
|
if (*buf1 == 0x40) {
|
||
|
var4 = 0;
|
||
|
buffer = temp;
|
||
|
if (addLineBreakX == 0) {
|
||
|
addLineBreakX = 7;
|
||
|
*((int16 *)buf2) = spaceChar;
|
||
|
}
|
||
|
if (buf1[1] == 0x50) {
|
||
|
printText8Var1 = dialTextBoxParam1;
|
||
|
buffer++;
|
||
|
}
|
||
|
} else {
|
||
|
buffer += wordSizeChar;
|
||
|
printText8Var8 = buffer;
|
||
|
strcat((char*)buf2, (char*)buf1);
|
||
|
strcat((char*)buf2, " "); // not 100% accurate
|
||
|
printText8PrepareBufferVar2++;
|
||
|
|
||
|
addLineBreakX += wordSizePixel + dialCharSpace;
|
||
|
if (*printText8Var8 != 0) {
|
||
|
printText8Var8++;
|
||
|
continue;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
if (printText8PrepareBufferVar2 != 0)
|
||
|
printText8PrepareBufferVar2--;
|
||
|
|
||
|
if (*printText8Var8 != 0 && var4 == 1) {
|
||
|
dialCharSpace += (dialTextBoxParam2 - addLineBreakX) / printText8PrepareBufferVar2;
|
||
|
printText10Var1 = dialTextBoxParam2 - addLineBreakX - dialTextBoxParam2 - addLineBreakX; // stupid... recheck
|
||
|
}
|
||
|
|
||
|
printText8Var8 = buffer;
|
||
|
|
||
|
printText8Ptr2 = buf2;
|
||
|
|
||
|
}
|
||
|
|
||
|
// draw next page arrow polygon
|
||
|
void printText10Sub() { // printText10Sub()
|
||
|
vertexCoordinates[0] = dialTextStopColor;
|
||
|
vertexCoordinates[1] = dialTextBoxRight - 3;
|
||
|
vertexCoordinates[2] = dialTextBoxBottom - 24;
|
||
|
vertexCoordinates[3] = dialTextStopColor;
|
||
|
vertexCoordinates[4] = dialTextBoxRight - 24;
|
||
|
vertexCoordinates[5] = dialTextBoxBottom - 3;
|
||
|
vertexCoordinates[6] = dialTextStartColor;
|
||
|
vertexCoordinates[7] = vertexCoordinates[1];
|
||
|
vertexCoordinates[8] = vertexCoordinates[5];
|
||
|
|
||
|
polyRenderType = 0; // POLYGONTYPE_FLAT
|
||
|
numOfVertex = 3;
|
||
|
|
||
|
if (computePolygons())
|
||
|
{
|
||
|
renderPolygons(polyRenderType, dialTextStopColor);
|
||
|
}
|
||
|
|
||
|
copyBlockPhys(dialTextBoxRight - 24, dialTextBoxBottom - 24, dialTextBoxRight - 3, dialTextBoxBottom - 3);
|
||
|
}
|
||
|
|
||
|
void printText10Sub2() { // printText10Sub2()
|
||
|
int32 currentLetter;
|
||
|
int32 currentIndex;
|
||
|
int32 counter;
|
||
|
int32 counter2;
|
||
|
int16 *ptr;
|
||
|
|
||
|
currentLetter = printText8Var3;
|
||
|
currentLetter--;
|
||
|
|
||
|
currentIndex = currentLetter * 3;
|
||
|
|
||
|
ptr = pt8s4 + currentIndex;
|
||
|
|
||
|
sdldelay(15);
|
||
|
|
||
|
counter = printText8Var3;
|
||
|
counter2 = dialTextStartColor;
|
||
|
|
||
|
while (--counter >= 0) {
|
||
|
setFontColor(counter2);
|
||
|
drawCharacterShadow(*(ptr + 1), *(ptr + 2), (uint8)*ptr, counter2);
|
||
|
counter2 -= dialTextStepSize;
|
||
|
if (counter2 > dialTextStopColor)
|
||
|
counter2 = dialTextStopColor;
|
||
|
ptr -= 3;
|
||
|
};
|
||
|
|
||
|
}
|
||
|
|
||
|
void TEXT_GetLetterSize(uint8 character, int32 *pLetterWidth, int32 *pLetterHeight, uint8 * pFont) { // TEXT_GetLetterSize
|
||
|
uint8 *temp;
|
||
|
|
||
|
temp = (uint8*) (pFont + *((int16 *)(pFont + character * 4)));
|
||
|
*pLetterWidth = *(temp);
|
||
|
*pLetterHeight = *(temp + 1);
|
||
|
}
|
||
|
|
||
|
// TODO: refactor this code
|
||
|
int printText10() { // printText10()
|
||
|
int32 charWidth, charHeight; // a, b
|
||
|
|
||
|
if (printTextVar13 == 0) {
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
if (*(printText8Ptr2) == 0) {
|
||
|
if (printText8Var5 != 0) {
|
||
|
if (newGameVar5 != 0) {
|
||
|
printText10Sub();
|
||
|
}
|
||
|
printTextVar13 = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
if (printText8Var6 != 0) {
|
||
|
blitBox(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom, (int8*)workVideoBuffer, dialTextBoxLeft, dialTextBoxTop, (int8*)frontVideoBuffer);
|
||
|
copyBlockPhys(dialTextBoxLeft, dialTextBoxTop, dialTextBoxRight, dialTextBoxBottom);
|
||
|
printText8Var3 = 0;
|
||
|
printText8Var6 = 0;
|
||
|
TEXT_CurrentLetterX = dialTextBoxLeft + 8;
|
||
|
TEXT_CurrentLetterY = dialTextBoxTop + 8;
|
||
|
}
|
||
|
if (*(printText8Var8) == 0) {
|
||
|
initProgressiveTextBuffer();
|
||
|
printText8Var5 = 1;
|
||
|
return 1;
|
||
|
}
|
||
|
processTextLine();
|
||
|
}
|
||
|
|
||
|
// RECHECK this later
|
||
|
if (*(printText8Ptr2) == 0) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
printText8Sub4(TEXT_CurrentLetterX, TEXT_CurrentLetterY, *printText8Ptr2);
|
||
|
printText10Sub2();
|
||
|
TEXT_GetLetterSize(*printText8Ptr2, &charWidth, &charHeight, (uint8*)fontPtr);
|
||
|
|
||
|
if (*(printText8Ptr2) != 0x20) {
|
||
|
TEXT_CurrentLetterX += charWidth + 2;
|
||
|
} else {
|
||
|
if (printText10Var1 != 0) {
|
||
|
TEXT_CurrentLetterX++;
|
||
|
printText10Var1--;
|
||
|
}
|
||
|
TEXT_CurrentLetterX += dialCharSpace;
|
||
|
}
|
||
|
|
||
|
// next character
|
||
|
printText8Ptr2++;
|
||
|
|
||
|
if (*(printText8Ptr2) != 0)
|
||
|
return 1;
|
||
|
|
||
|
TEXT_CurrentLetterY += 38;
|
||
|
TEXT_CurrentLetterX = dialTextBoxLeft + 8;
|
||
|
|
||
|
if (printText8Var6 == 1 && printText8Var5 == 0) {
|
||
|
printText10Sub();
|
||
|
return 2;
|
||
|
}
|
||
|
|
||
|
printText8Var1++;
|
||
|
if (printText8Var1 < dialTextBoxParam1) {
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
initProgressiveTextBuffer();
|
||
|
printText8Var6 = 1;
|
||
|
|
||
|
if (*(printText8Var8) == 0) {
|
||
|
printText8Var5 = 1;
|
||
|
}
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
// TODO: refactor this code
|
||
|
void drawTextFullscreen(int32 index) { // printTextFullScreen
|
||
|
int32 printedText;
|
||
|
int32 skipText = 0;
|
||
|
|
||
|
saveClip();
|
||
|
resetClip();
|
||
|
copyScreen(frontVideoBuffer, workVideoBuffer);
|
||
|
|
||
|
// get right VOX entry index
|
||
|
if (cfgfile.LanguageCDId) {
|
||
|
initVoxToPlay(index);
|
||
|
}
|
||
|
|
||
|
// if we don't display text, than still plays vox file
|
||
|
if (cfgfile.FlagDisplayText) {
|
||
|
initText(index);
|
||
|
initDialogueBox();
|
||
|
|
||
|
do {
|
||
|
readKeys();
|
||
|
printedText = printText10();
|
||
|
playVox(currDialTextEntry);
|
||
|
|
||
|
if (printedText == 2) {
|
||
|
do {
|
||
|
readKeys();
|
||
|
if (skipIntro == 0 && skippedKey == 0 && pressedKey == 0) {
|
||
|
break;
|
||
|
}
|
||
|
playVox(currDialTextEntry);
|
||
|
sdldelay(1);
|
||
|
} while(1);
|
||
|
|
||
|
do {
|
||
|
readKeys();
|
||
|
if (skipIntro != 0 || skippedKey != 0 || pressedKey != 0) {
|
||
|
break;
|
||
|
}
|
||
|
playVox(currDialTextEntry);
|
||
|
sdldelay(1);
|
||
|
} while(1);
|
||
|
}
|
||
|
|
||
|
if (skipIntro == 1) {
|
||
|
skipText = 1;
|
||
|
}
|
||
|
|
||
|
if (!printedText && !isSamplePlaying(currDialTextEntry)) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
sdldelay(1);
|
||
|
} while(!skipText);
|
||
|
|
||
|
hasHiddenVox = 0;
|
||
|
|
||
|
if (cfgfile.LanguageCDId && isSamplePlaying(currDialTextEntry)) {
|
||
|
stopVox(currDialTextEntry);
|
||
|
}
|
||
|
|
||
|
printTextVar13 = 0;
|
||
|
|
||
|
if (printedText != 0) {
|
||
|
loadClip();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if (skipText != 0) {
|
||
|
loadClip();
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
// RECHECK this later
|
||
|
// wait displaying text
|
||
|
do {
|
||
|
readKeys();
|
||
|
sdldelay(1);
|
||
|
} while(skipIntro || skippedKey || pressedKey);
|
||
|
|
||
|
// RECHECK this later
|
||
|
// wait key to display next text
|
||
|
do {
|
||
|
readKeys();
|
||
|
if (skipIntro != 0) {
|
||
|
loadClip();
|
||
|
return;
|
||
|
}
|
||
|
if (skippedKey != 0) {
|
||
|
loadClip();
|
||
|
return;
|
||
|
}
|
||
|
sdldelay(1);
|
||
|
} while(!pressedKey);
|
||
|
} else { // RECHECK THIS
|
||
|
while (playVox(currDialTextEntry) && skipIntro != 1 );
|
||
|
hasHiddenVox = 0;
|
||
|
voxHiddenIndex = 0;
|
||
|
}
|
||
|
|
||
|
if (cfgfile.LanguageCDId && isSamplePlaying(currDialTextEntry)) {
|
||
|
stopVox(currDialTextEntry);
|
||
|
}
|
||
|
|
||
|
loadClip();
|
||
|
}
|
||
|
|
||
|
void setFont(uint8 *font, int32 spaceBetween, int32 charSpace) {
|
||
|
fontPtr = font;
|
||
|
dialCharSpace = charSpace;
|
||
|
dialSpaceBetween = spaceBetween;
|
||
|
}
|
||
|
|
||
|
/** Set font type parameters
|
||
|
@param spaceBetween number in pixels of space between characters
|
||
|
@param charSpace number in pixels of the character space */
|
||
|
void setFontParameters(int32 spaceBetween, int32 charSpace) {
|
||
|
dialSpaceBetween = spaceBetween;
|
||
|
dialCharSpace = charSpace;
|
||
|
}
|
||
|
|
||
|
/** Set the font cross color
|
||
|
@param color color number to choose */
|
||
|
void setFontCrossColor(int32 color) { // TestCoulDial
|
||
|
dialTextStepSize = -1;
|
||
|
dialTextBufferSize = 14;
|
||
|
dialTextStartColor = color << 4;
|
||
|
dialTextStopColor = (color << 4) + 12;
|
||
|
}
|
||
|
|
||
|
/** Set the font color
|
||
|
@param color color number to choose */
|
||
|
void setFontColor(int32 color) {
|
||
|
dialTextColor = color;
|
||
|
}
|
||
|
|
||
|
/** Set font color parameters to process cross color display
|
||
|
@param stopColor color number to stop
|
||
|
@param startColor color number to start
|
||
|
@param stepSize step size to change between those colors */
|
||
|
void setTextCrossColor(int32 stopColor, int32 startColor, int32 stepSize) {
|
||
|
dialTextStartColor = startColor;
|
||
|
dialTextStopColor = stopColor;
|
||
|
dialTextStepSize = stepSize;
|
||
|
dialTextBufferSize = ((startColor - stopColor) + 1) / stepSize;
|
||
|
}
|
||
|
|
||
|
/** Get dialogue text into text buffer
|
||
|
@param index dialogue index */
|
||
|
int32 getText(int32 index) { // findString
|
||
|
int32 currIdx = 0;
|
||
|
int32 orderIdx = 0;
|
||
|
int32 numEntries;
|
||
|
int32 ptrCurrentEntry;
|
||
|
int32 ptrNextEntry;
|
||
|
|
||
|
int16 *localTextBuf = (int16 *) dialTextPtr;
|
||
|
int16 *localOrderBuf = (int16 *) dialOrderPtr;
|
||
|
|
||
|
numEntries = numDialTextEntries;
|
||
|
|
||
|
// choose right text from order index
|
||
|
do {
|
||
|
orderIdx = *(localOrderBuf++);
|
||
|
if (orderIdx == index)
|
||
|
break;
|
||
|
currIdx++;
|
||
|
} while (currIdx < numDialTextEntries);
|
||
|
|
||
|
if (currIdx >= numEntries)
|
||
|
return 0;
|
||
|
|
||
|
ptrCurrentEntry = localTextBuf[currIdx];
|
||
|
ptrNextEntry = localTextBuf[currIdx + 1];
|
||
|
|
||
|
currDialTextPtr = (dialTextPtr + ptrCurrentEntry);
|
||
|
currDialTextSize = ptrNextEntry - ptrCurrentEntry;
|
||
|
numDialTextEntries = numEntries;
|
||
|
|
||
|
// RECHECK: this was added for vox playback
|
||
|
currDialTextEntry = currIdx;
|
||
|
|
||
|
return 1;
|
||
|
}
|
||
|
|
||
|
/** Copy dialogue text
|
||
|
@param src source text buffer
|
||
|
@param dst destination text buffer
|
||
|
@param size text size */
|
||
|
void copyText(int8 *src, int8 *dst, int32 size) { // copyStringToString
|
||
|
int32 i;
|
||
|
for (i = 0; i < size; i++)
|
||
|
*(dst++) = *(src++);
|
||
|
}
|
||
|
|
||
|
/** Gets menu dialogue text
|
||
|
@param index text index to display
|
||
|
@param dialogue dialogue text buffer to display */
|
||
|
void getMenuText(int32 index, int8 *text) { // GetMultiText
|
||
|
if (index == currMenuTextIndex) {
|
||
|
if (currMenuTextBank == currentTextBank) {
|
||
|
strcpy(text, currMenuTextBuffer);
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
if (!getText(index)) {
|
||
|
// if doesn't have text
|
||
|
text[0] = 0;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
if ((currDialTextSize - 1) > 0xFF)
|
||
|
currDialTextSize = 0xFF;
|
||
|
|
||
|
copyText((int8 *) currDialTextPtr, text, currDialTextSize);
|
||
|
currDialTextSize++;
|
||
|
copyText(text, currMenuTextBuffer, currDialTextSize);
|
||
|
|
||
|
currMenuTextIndex = index;
|
||
|
currMenuTextBank = currentTextBank;
|
||
|
}
|
||
|
|
||
|
void textClipFull() { // newGame2
|
||
|
dialTextBoxLeft = 8;
|
||
|
dialTextBoxTop = 8;
|
||
|
dialTextBoxRight = 631;
|
||
|
|
||
|
dialTextBoxBottom = 471;
|
||
|
dialTextBoxParam1 = 11;
|
||
|
dialTextBoxParam2 = 607;
|
||
|
}
|
||
|
|
||
|
void textClipSmall() { // newGame4
|
||
|
dialTextBoxLeft = 16;
|
||
|
dialTextBoxTop = 334;
|
||
|
dialTextBoxRight = 623;
|
||
|
dialTextBoxBottom = 463;
|
||
|
dialTextBoxParam1 = 3;
|
||
|
dialTextBoxParam2 = 591;
|
||
|
}
|
||
|
|
||
|
void drawAskQuestion(int32 index) { // MyDial
|
||
|
int32 textStatus = 1;
|
||
|
|
||
|
// get right VOX entry index
|
||
|
if (cfgfile.LanguageCDId) {
|
||
|
initVoxToPlay(index);
|
||
|
}
|
||
|
|
||
|
initText(index);
|
||
|
initDialogueBox();
|
||
|
|
||
|
do {
|
||
|
readKeys();
|
||
|
textStatus = printText10();
|
||
|
|
||
|
if (textStatus == 2) {
|
||
|
do {
|
||
|
readKeys();
|
||
|
playVox(currDialTextEntry);
|
||
|
sdldelay(1);
|
||
|
} while(skipIntro || skippedKey || pressedKey);
|
||
|
|
||
|
do {
|
||
|
readKeys();
|
||
|
playVox(currDialTextEntry);
|
||
|
sdldelay(1);
|
||
|
} while(!skipIntro && !skippedKey && !pressedKey);
|
||
|
}
|
||
|
|
||
|
sdldelay(1);
|
||
|
} while(textStatus);
|
||
|
|
||
|
if (cfgfile.LanguageCDId) {
|
||
|
while(playVoxSimple(currDialTextEntry));
|
||
|
|
||
|
hasHiddenVox = 0;
|
||
|
voxHiddenIndex = 0;
|
||
|
|
||
|
if(isSamplePlaying(currDialTextEntry)) {
|
||
|
stopVox(currDialTextEntry);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
printTextVar13 = 0;
|
||
|
}
|