mirror of
https://github.com/galaxyhaxz/devilution
synced 2025-02-22 12:34:59 +00:00
350 lines
6.1 KiB
C++
350 lines
6.1 KiB
C++
|
#include "diablo.h"
|
||
|
|
||
|
int qtexty; // weak
|
||
|
char *qtextptr;
|
||
|
int qtextSpd; // weak
|
||
|
char qtextflag; // weak
|
||
|
int scrolltexty; // weak
|
||
|
int sgLastScroll; // weak
|
||
|
void *pMedTextCels;
|
||
|
void *pTextBoxCels;
|
||
|
|
||
|
const unsigned char mfontframe[127] =
|
||
|
{
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||
|
0, 0, 0, 37, 49, 38, 0, 39, 40, 47,
|
||
|
42, 43, 41, 45, 52, 44, 53, 55, 36, 27,
|
||
|
28, 29, 30, 31, 32, 33, 34, 35, 51, 50,
|
||
|
48, 46, 49, 54, 0, 1, 2, 3, 4, 5,
|
||
|
6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||
|
16, 17, 18, 19, 20, 21, 22, 23, 24, 25,
|
||
|
26, 42, 0, 43, 0, 0, 0, 1, 2, 3,
|
||
|
4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
|
||
|
14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||
|
24, 25, 26, 48, 0, 49, 0
|
||
|
};
|
||
|
const unsigned char mfontkern[56] =
|
||
|
{
|
||
|
5, 15, 10, 13, 14, 10, 9, 13, 11, 5,
|
||
|
5, 11, 10, 16, 13, 16, 10, 15, 12, 10,
|
||
|
14, 17, 17, 22, 17, 16, 11, 5, 11, 11,
|
||
|
11, 10, 11, 11, 11, 11, 15, 5, 10, 18,
|
||
|
15, 8, 6, 6, 7, 10, 9, 6, 10, 10,
|
||
|
5, 5, 5, 5, 11, 12
|
||
|
};
|
||
|
|
||
|
/* data */
|
||
|
|
||
|
int qscroll_spd_tbl[9] = { 2, 4, 6, 8, 0, -1, -2, -3, -4 };
|
||
|
|
||
|
void FreeQuestText()
|
||
|
{
|
||
|
void *v0; // ecx
|
||
|
void *v1; // ecx
|
||
|
|
||
|
v0 = pMedTextCels;
|
||
|
pMedTextCels = 0;
|
||
|
mem_free_dbg(v0);
|
||
|
v1 = pTextBoxCels;
|
||
|
pTextBoxCels = 0;
|
||
|
mem_free_dbg(v1);
|
||
|
}
|
||
|
|
||
|
void InitQuestText()
|
||
|
{
|
||
|
unsigned char *v0; // eax
|
||
|
|
||
|
pMedTextCels = DiabLoad("Data\\MedTextS.CEL", NULL, 'MINI');
|
||
|
v0 = DiabLoad("Data\\TextBox.CEL", NULL, 'MINI');
|
||
|
qtextflag = 0;
|
||
|
pTextBoxCels = v0;
|
||
|
}
|
||
|
|
||
|
void InitQTextMsg(int m)
|
||
|
{
|
||
|
if ( alltext[m].scrlltxt )
|
||
|
{
|
||
|
questlog = 0;
|
||
|
qtextptr = alltext[m].txtstr;
|
||
|
qtextflag = 1;
|
||
|
qtexty = 500;
|
||
|
sgLastScroll = qscroll_spd_tbl[alltext[m].txtspd - 1]; /* double check offset */
|
||
|
scrolltexty = sgLastScroll;
|
||
|
qtextSpd = GetTickCount();
|
||
|
}
|
||
|
PlaySFX(alltext[m].sfxnr);
|
||
|
}
|
||
|
|
||
|
void DrawQTextBack()
|
||
|
{
|
||
|
CelDecodeOnly(88, 487, (BYTE *)pTextBoxCels, 1, 591);
|
||
|
|
||
|
/// ASSERT: assert(gpBuffer);
|
||
|
|
||
|
#ifdef USE_ASM
|
||
|
__asm {
|
||
|
mov edi, gpBuffer
|
||
|
add edi, SCREENXY(27, 324)
|
||
|
xor eax, eax
|
||
|
mov edx, 297 / 2
|
||
|
label1:
|
||
|
mov ecx, 585 / 2
|
||
|
label2:
|
||
|
stosb
|
||
|
inc edi
|
||
|
loop label2
|
||
|
stosb
|
||
|
sub edi, 768 + 585
|
||
|
mov ecx, 585 / 2
|
||
|
label3:
|
||
|
inc edi
|
||
|
stosb
|
||
|
loop label3
|
||
|
sub edi, 768 + (585 - 1)
|
||
|
dec edx
|
||
|
jnz label1
|
||
|
mov ecx, 585 / 2
|
||
|
label4:
|
||
|
stosb
|
||
|
inc edi
|
||
|
loop label4
|
||
|
stosb
|
||
|
}
|
||
|
#else
|
||
|
int wdt, hgt;
|
||
|
BYTE *dst;
|
||
|
|
||
|
dst = &gpBuffer[SCREENXY(27, 324)];
|
||
|
|
||
|
for(hgt = 297 / 2; hgt != 0; hgt--) {
|
||
|
for(wdt = 585 / 2; wdt != 0; wdt--) {
|
||
|
dst[0] = 0;
|
||
|
dst += 2;
|
||
|
}
|
||
|
*dst = 0;
|
||
|
dst -= 768 + (585 - 1);
|
||
|
for(wdt = 585 / 2; wdt != 0; wdt--) {
|
||
|
dst[1] = 0;
|
||
|
dst += 2;
|
||
|
}
|
||
|
dst -= 768 + (585 - 1);
|
||
|
}
|
||
|
for(wdt = 585 / 2; wdt != 0; wdt--) {
|
||
|
dst[0] = 0;
|
||
|
dst += 2;
|
||
|
}
|
||
|
*dst = 0;
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void PrintQTextChr(int sx, int sy, BYTE *pCelBuff, int nCel)
|
||
|
{
|
||
|
BYTE *dst, *pStart, *pEnd, *end;
|
||
|
|
||
|
/// ASSERT: assert(gpBuffer);
|
||
|
|
||
|
dst = &gpBuffer[sx + PitchTbl[sy]];
|
||
|
pStart = &gpBuffer[PitchTbl[209]];
|
||
|
pEnd = &gpBuffer[PitchTbl[469]];
|
||
|
|
||
|
#ifdef USE_ASM
|
||
|
__asm {
|
||
|
mov ebx, pCelBuff
|
||
|
mov eax, nCel
|
||
|
shl eax, 2
|
||
|
add ebx, eax
|
||
|
mov eax, [ebx+4]
|
||
|
sub eax, [ebx]
|
||
|
mov end, eax
|
||
|
mov esi, pCelBuff
|
||
|
add esi, [ebx]
|
||
|
mov edi, dst
|
||
|
mov ebx, end
|
||
|
add ebx, esi
|
||
|
label1:
|
||
|
mov edx, 22
|
||
|
label2:
|
||
|
xor eax, eax
|
||
|
lodsb
|
||
|
or al, al
|
||
|
js label7
|
||
|
sub edx, eax
|
||
|
cmp edi, pStart
|
||
|
jb label5
|
||
|
cmp edi, pEnd
|
||
|
ja label5
|
||
|
mov ecx, eax
|
||
|
shr ecx, 1
|
||
|
jnb label3
|
||
|
movsb
|
||
|
jecxz label6
|
||
|
label3:
|
||
|
shr ecx, 1
|
||
|
jnb label4
|
||
|
movsw
|
||
|
jecxz label6
|
||
|
label4:
|
||
|
rep movsd
|
||
|
jmp label6
|
||
|
label5:
|
||
|
add esi, eax
|
||
|
add edi, eax
|
||
|
label6:
|
||
|
or edx, edx
|
||
|
jz label8
|
||
|
jmp label2
|
||
|
label7:
|
||
|
neg al
|
||
|
add edi, eax
|
||
|
sub edx, eax
|
||
|
jnz label2
|
||
|
label8:
|
||
|
sub edi, 768 + 22
|
||
|
cmp ebx, esi
|
||
|
jnz label1
|
||
|
}
|
||
|
#else
|
||
|
int i;
|
||
|
BYTE width;
|
||
|
BYTE *src;
|
||
|
DWORD *pFrameTable;
|
||
|
|
||
|
pFrameTable = (DWORD *)&pCelBuff[4 * nCel];
|
||
|
src = &pCelBuff[pFrameTable[0]];
|
||
|
end = &src[pFrameTable[1] - pFrameTable[0]];
|
||
|
|
||
|
for(; src != end; dst -= 768 + 22) {
|
||
|
for(i = 22; i;) {
|
||
|
width = *src++;
|
||
|
if(!(width & 0x80)) {
|
||
|
i -= width;
|
||
|
if(dst >= pStart && dst <= pEnd) {
|
||
|
if(width & 1) {
|
||
|
dst[0] = src[0];
|
||
|
src++;
|
||
|
dst++;
|
||
|
}
|
||
|
width >>= 1;
|
||
|
if(width & 1) {
|
||
|
dst[0] = src[0];
|
||
|
dst[1] = src[1];
|
||
|
src += 2;
|
||
|
dst += 2;
|
||
|
}
|
||
|
width >>= 1;
|
||
|
for(; width; width--) {
|
||
|
dst[0] = src[0];
|
||
|
dst[1] = src[1];
|
||
|
dst[2] = src[2];
|
||
|
dst[3] = src[3];
|
||
|
src += 4;
|
||
|
dst += 4;
|
||
|
}
|
||
|
} else {
|
||
|
src += width;
|
||
|
dst += width;
|
||
|
}
|
||
|
} else {
|
||
|
width = -(char)width;
|
||
|
dst += width;
|
||
|
i -= width;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
void DrawQText()
|
||
|
{
|
||
|
int i, l, w, tx, ty;
|
||
|
BYTE c;
|
||
|
char *p, *pnl, *s;
|
||
|
char tempstr[128];
|
||
|
BOOL doneflag;
|
||
|
DWORD currTime;
|
||
|
|
||
|
DrawQTextBack();
|
||
|
|
||
|
p = qtextptr;
|
||
|
pnl = NULL;
|
||
|
tx = 112;
|
||
|
ty = qtexty;
|
||
|
|
||
|
doneflag = FALSE;
|
||
|
while(!doneflag) {
|
||
|
w = 0;
|
||
|
s = p;
|
||
|
l = 0;
|
||
|
while(*s != '\n' && *s != '|' && w < 543) {
|
||
|
c = gbFontTransTbl[(BYTE)*s];
|
||
|
s++;
|
||
|
if(c != '\0') {
|
||
|
tempstr[l] = c;
|
||
|
w += mfontkern[mfontframe[c]] + 2;
|
||
|
} else {
|
||
|
l--;
|
||
|
}
|
||
|
l++;
|
||
|
}
|
||
|
tempstr[l] = '\0';
|
||
|
if(*s == '|') {
|
||
|
tempstr[l] = '\0';
|
||
|
doneflag = TRUE;
|
||
|
} else if(*s != '\n') {
|
||
|
while(tempstr[l] != ' ' && l > 0) {
|
||
|
tempstr[l] = '\0';
|
||
|
l--;
|
||
|
}
|
||
|
}
|
||
|
for(i = 0; tempstr[i]; i++) {
|
||
|
p++;
|
||
|
c = mfontframe[gbFontTransTbl[(BYTE)tempstr[i]]];
|
||
|
if(*p == '\n') {
|
||
|
p++;
|
||
|
}
|
||
|
if(c != 0) {
|
||
|
PrintQTextChr(tx, ty, (BYTE *)pMedTextCels, c);
|
||
|
}
|
||
|
tx += mfontkern[c] + 2;
|
||
|
}
|
||
|
if(pnl == NULL) {
|
||
|
pnl = p;
|
||
|
}
|
||
|
tx = 112;
|
||
|
ty += 38;
|
||
|
if(ty > 501) {
|
||
|
doneflag = TRUE;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
currTime = GetTickCount();
|
||
|
while(1) {
|
||
|
if(sgLastScroll <= 0) {
|
||
|
qtexty--;
|
||
|
qtexty += sgLastScroll;
|
||
|
} else {
|
||
|
scrolltexty--;
|
||
|
if(scrolltexty != 0) {
|
||
|
qtexty--;
|
||
|
}
|
||
|
}
|
||
|
if(scrolltexty == 0) {
|
||
|
scrolltexty = sgLastScroll;
|
||
|
}
|
||
|
if(qtexty <= 209) {
|
||
|
qtexty += 38;
|
||
|
qtextptr = pnl;
|
||
|
if(*pnl == '|') {
|
||
|
qtextflag = 0;
|
||
|
}
|
||
|
break;
|
||
|
}
|
||
|
qtextSpd += 50;
|
||
|
if(currTime - qtextSpd >= 0x7FFFFFFF) {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|