mirror of
https://github.com/jmarshall23/Hellfire.git
synced 2026-08-12 16:00:51 +02:00
4048 lines
94 KiB
C++
4048 lines
94 KiB
C++
/*-----------------------------------------------------------------------**
|
|
** Diablo
|
|
**
|
|
** Engine file
|
|
**
|
|
** (C)1995 Condor, Inc. All rights reserved.
|
|
**
|
|
**-----------------------------------------------------------------------**
|
|
** $Header: /Diablo/ENGINE.CPP 2 1/22/97 2:32p Dgartner $
|
|
**-----------------------------------------------------------------------*/
|
|
|
|
#include "diablo.h"
|
|
#pragma hdrstop
|
|
#include "resource.h"
|
|
#include "storm/h/storm.h"
|
|
#include "engine.h"
|
|
#include "lighting.h"
|
|
#include "scrollrt.h"
|
|
#include "debug.h"
|
|
#include "gendung.h"
|
|
#include "palette.h"
|
|
|
|
//******************************************************************
|
|
// extern
|
|
//******************************************************************
|
|
void ErrorDlg(int nDlgId,DWORD dwErr,const char * pszFile,int nLine);
|
|
|
|
extern "C" {
|
|
extern BYTE gbLevelTileEnhanceActive;
|
|
extern BYTE gbLevelUnitContrastTable[];
|
|
extern BYTE gbLevelUnitLumaTable[];
|
|
extern BYTE gbLevelUnitSharpenLightTable[];
|
|
extern BYTE gbLevelUnitAoTable[];
|
|
}
|
|
|
|
|
|
//******************************************************************
|
|
// Registration info
|
|
//******************************************************************
|
|
#include "regconst.h"
|
|
char sgszRegSig1[REG_LEN] = "REGISTRATION_BLOCK";
|
|
|
|
|
|
//******************************************************************
|
|
// random numbers
|
|
//******************************************************************
|
|
static long sglGameSeed;
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Decode RLE data without lighting
|
|
**-----------------------------------------------------------------------*/
|
|
void DecodeFullCel (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth)
|
|
{
|
|
long nBufferW;
|
|
app_assert(pDecodeTo != NULL);
|
|
app_assert(pRLEBytes != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pDecodeTo == NULL || pRLEBytes == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
__asm {
|
|
mov esi,dword ptr [pRLEBytes] // Source
|
|
mov edi,dword ptr [pDecodeTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nWidth]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [lRLECount]
|
|
add ebx,esi
|
|
|
|
_T1Lp1: mov edx,dword ptr [nWidth]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
sub edx,eax
|
|
mov ecx,eax
|
|
shr ecx,1
|
|
jnc _T1w
|
|
movsb
|
|
jecxz _T1x
|
|
_T1w: shr ecx,1
|
|
jnc _T1Lp3
|
|
movsw
|
|
jecxz _T1x
|
|
_T1Lp3: rep movsd
|
|
_T1x: or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawCel (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
pTo = gpBuffer + nBuffWTbl[yp] + xp;
|
|
DecodeFullCel (pTo, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawCelP (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(pBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL || pBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
DecodeFullCel (pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawSlabCel (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
DecodeFullCel(pTo, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawSlabCelP (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(pBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL || pBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
DecodeFullCel(pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Decode RLE data with light translation
|
|
**-----------------------------------------------------------------------*/
|
|
void DecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth)
|
|
{
|
|
long nBufferW, nL;
|
|
app_assert(pDecodeTo != NULL);
|
|
app_assert(pRLEBytes != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pDecodeTo == NULL || pRLEBytes == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
__asm {
|
|
mov eax,dword ptr [nLVal];
|
|
shl eax,8
|
|
add eax,dword ptr [pLightTbl];
|
|
mov dword ptr [nL],eax
|
|
|
|
mov esi,dword ptr [pRLEBytes] // Source
|
|
mov edi,dword ptr [pDecodeTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nWidth]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [lRLECount]
|
|
add ebx,esi
|
|
|
|
_T1Lp1: mov edx,dword ptr [nWidth]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
push ebx
|
|
mov ebx,dword ptr [nL]
|
|
sub edx,eax
|
|
mov ecx,eax
|
|
|
|
push edx
|
|
call xbytes
|
|
pop edx
|
|
|
|
pop ebx
|
|
or edx,edx
|
|
jnz _T1Lp2
|
|
jmp _T1Nxt
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
|
|
jmp _done
|
|
xbytes:
|
|
|
|
shr cl,1
|
|
jnc xwords
|
|
|
|
mov dl, [esi]
|
|
mov dl, [ebx+edx]
|
|
mov [edi],dl
|
|
|
|
add esi,1
|
|
add edi,1
|
|
|
|
xwords:
|
|
shr cl,1
|
|
jnc xquads
|
|
|
|
mov dl, [esi]
|
|
mov ch, [ebx+edx]
|
|
|
|
mov [edi],ch
|
|
mov dl, [esi+1]
|
|
|
|
mov ch, [ebx+edx]
|
|
mov [edi+1],ch
|
|
|
|
add esi,2
|
|
add edi,2
|
|
|
|
xquads:
|
|
test cl,cl
|
|
jz _xend
|
|
|
|
xnext:
|
|
mov eax, [esi]
|
|
add esi,4
|
|
|
|
mov dl,al
|
|
mov ch,[ebx+edx]
|
|
|
|
mov dl,ah
|
|
ror eax,16
|
|
mov [edi],ch
|
|
|
|
mov ch,[ebx+edx]
|
|
|
|
mov dl,al
|
|
mov [edi+1],ch
|
|
|
|
mov ch,[ebx+edx]
|
|
|
|
mov dl,ah
|
|
mov [edi+2],ch
|
|
|
|
mov ch,[ebx+edx]
|
|
mov [edi+3],ch
|
|
|
|
add edi,4
|
|
|
|
dec cl
|
|
jnz xnext
|
|
|
|
_xend:
|
|
ret
|
|
|
|
_done:
|
|
} // end of asm block
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Decode RLE data with light translation and transparency
|
|
**-----------------------------------------------------------------------*/
|
|
void TDecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth)
|
|
{
|
|
long nBufferW, nL, LineVal;
|
|
app_assert(pDecodeTo != NULL);
|
|
app_assert(pRLEBytes != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pDecodeTo == NULL || pRLEBytes == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
__asm {
|
|
mov eax,dword ptr [nLVal];
|
|
shl eax,8
|
|
add eax,dword ptr [pLightTbl];
|
|
mov dword ptr [nL],eax
|
|
|
|
mov esi,dword ptr [pRLEBytes] // Source
|
|
mov edi,dword ptr [pDecodeTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nWidth]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [lRLECount]
|
|
add ebx,esi
|
|
|
|
mov eax,edi
|
|
and eax,1
|
|
mov dword ptr [LineVal],eax
|
|
|
|
_T1Lp1: mov edx,dword ptr [nWidth]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
push ebx
|
|
mov ebx,dword ptr [nL]
|
|
sub edx,eax
|
|
mov ecx,eax
|
|
mov eax,edi
|
|
and eax,1
|
|
cmp eax,dword ptr [LineVal]
|
|
jnz _T1Od
|
|
shr ecx,1
|
|
jnc _T1w
|
|
inc esi
|
|
inc edi
|
|
jecxz _T1x
|
|
jmp _T1w2
|
|
_T1w: shr ecx,1
|
|
jnc _T1Lp3
|
|
inc esi
|
|
inc edi
|
|
lodsb
|
|
xlatb
|
|
stosb
|
|
jecxz _T1x
|
|
_T1Lp3: lodsd
|
|
inc edi
|
|
ror eax,8
|
|
xlatb
|
|
stosb
|
|
ror eax,16
|
|
inc edi
|
|
xlatb
|
|
stosb
|
|
loop _T1Lp3
|
|
jmp _T1x
|
|
|
|
_T1Od: shr ecx,1
|
|
jnc _T1w2
|
|
lodsb
|
|
xlatb
|
|
stosb
|
|
jecxz _T1x
|
|
jmp _T1w
|
|
_T1w2: shr ecx,1
|
|
jnc _T1Lp4
|
|
lodsb
|
|
xlatb
|
|
stosb
|
|
inc esi
|
|
inc edi
|
|
jecxz _T1x
|
|
_T1Lp4: lodsd
|
|
xlatb
|
|
stosb
|
|
inc edi
|
|
ror eax,16
|
|
xlatb
|
|
stosb
|
|
inc edi
|
|
loop _T1Lp4
|
|
|
|
_T1x: pop ebx
|
|
or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
mov eax,dword ptr [LineVal]
|
|
inc eax
|
|
and eax,1
|
|
mov dword ptr [LineVal],eax
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawCelL (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
pTo = gpBuffer + nBuffWTbl[yp] + xp;
|
|
if (nLVal)
|
|
DecodeFullCelL (pTo, pFrom, RLELen, nCelW);
|
|
else
|
|
DecodeFullCel (pTo, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
/*
|
|
void DrawCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(pBuff != NULL);
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
if (nLVal)
|
|
DecodeFullCelL (pBuff, pFrom, RLELen, nCelW);
|
|
else
|
|
DecodeFullCel (pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
*/
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawSlabCelL (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
if (nLVal)
|
|
DecodeFullCelL (pTo, pFrom, RLELen, nCelW);
|
|
else
|
|
DecodeFullCel (pTo, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
/*
|
|
void DrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(pBuff != NULL);
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
if (nLVal)
|
|
DecodeFullCelL (pBuff, pFrom, RLELen, nCelW);
|
|
else
|
|
DecodeFullCel (pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
*/
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer. with transparency
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void TDrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(pBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL || pBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
if (nTrans)
|
|
TDecodeFullCelL (pBuff, pFrom, RLELen, nCelW);
|
|
else if (nLVal)
|
|
DecodeFullCelL (pBuff, pFrom, RLELen, nCelW);
|
|
else
|
|
DecodeFullCel (pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer. With infared vision
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawSlabCelI (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
long nBufferW, nL, ltaboff;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
__asm {
|
|
mov eax,dword ptr [pLightTbl]
|
|
add eax,dword ptr [ltaboff]
|
|
mov dword ptr [nL],eax
|
|
|
|
mov esi,dword ptr [pFrom] // Source
|
|
mov edi,dword ptr [pTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nCelW]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [RLELen]
|
|
add ebx,esi
|
|
_T1Lp1:
|
|
mov edx,dword ptr [nCelW]
|
|
_T1Lp2:
|
|
xor eax,eax // Load control byte
|
|
mov al,[esi]
|
|
inc esi
|
|
test al,al
|
|
js _T1J
|
|
|
|
push ebx
|
|
mov ebx,dword ptr [nL]
|
|
sub edx,eax
|
|
mov ecx,eax
|
|
Bytes:
|
|
mov al,[esi]
|
|
inc esi
|
|
mov al,[ebx+eax]
|
|
mov [edi],al
|
|
dec ecx
|
|
lea edi,[edi+1]
|
|
jnz Bytes
|
|
|
|
pop ebx
|
|
test edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
_T1J:
|
|
neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt:
|
|
sub edi,dword ptr [nBufferW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Decode RLE data without lighting, with clipping
|
|
**-----------------------------------------------------------------------*/
|
|
void CDecodeFullCel (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth)
|
|
{
|
|
long nBufferW;
|
|
app_assert(pDecodeTo != NULL);
|
|
app_assert(pRLEBytes != NULL);
|
|
app_assert(gpBuffer);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pDecodeTo == NULL || pRLEBytes == NULL || gpBuffer == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
__asm {
|
|
mov esi,dword ptr [pRLEBytes] // Source
|
|
mov edi,dword ptr [pDecodeTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nWidth]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [lRLECount]
|
|
add ebx,esi
|
|
|
|
_T1Lp1: mov edx,dword ptr [nWidth]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
sub edx,eax
|
|
cmp edi,dword ptr [glClipY]
|
|
jb _T1C1
|
|
add esi,eax
|
|
add edi,eax
|
|
jmp _T1x
|
|
_T1C1: mov ecx,eax
|
|
shr ecx,1
|
|
jnc _T1w
|
|
movsb
|
|
jecxz _T1x
|
|
_T1w: shr ecx,1
|
|
jnc _T1Lp3
|
|
movsw
|
|
jecxz _T1x
|
|
_T1Lp3: rep movsd
|
|
_T1x: or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
**-----------------------------------------------------------------------*/
|
|
void CDrawSlabCel (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
CDecodeFullCel(pTo, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
**-----------------------------------------------------------------------*/
|
|
void CDrawSlabCelP (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(pBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL || pBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = *(WORD*)(pFrom + oend);
|
|
if (oend == 8)
|
|
offval2 = 0;
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
CDecodeFullCel (pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Decode RLE data with light translation and with clipping
|
|
**-----------------------------------------------------------------------*/
|
|
void CDecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth)
|
|
{
|
|
long nBufferW, nL;
|
|
app_assert(pDecodeTo != NULL);
|
|
app_assert(pRLEBytes != NULL);
|
|
|
|
app_assert(gpBuffer);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pDecodeTo == NULL || pRLEBytes == NULL || gpBuffer == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
__asm {
|
|
mov eax,dword ptr [nLVal];
|
|
shl eax,8
|
|
add eax,dword ptr [pLightTbl];
|
|
mov dword ptr [nL],eax
|
|
|
|
mov esi,dword ptr [pRLEBytes] // Source
|
|
mov edi,dword ptr [pDecodeTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nWidth]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [lRLECount]
|
|
add ebx,esi
|
|
|
|
_T1Lp1: mov edx,dword ptr [nWidth]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
push ebx
|
|
mov ebx,dword ptr [nL]
|
|
sub edx,eax
|
|
cmp edi,dword ptr [glClipY]
|
|
jb _T1C1
|
|
add esi,eax
|
|
add edi,eax
|
|
jmp _T1x
|
|
_T1C1: mov ecx,eax
|
|
|
|
push edx
|
|
call xbytes
|
|
pop edx
|
|
|
|
_T1x: pop ebx
|
|
or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
|
|
jmp _done
|
|
|
|
xbytes:
|
|
|
|
shr cl,1
|
|
jnc xwords
|
|
|
|
mov dl, [esi]
|
|
mov dl, [ebx+edx]
|
|
mov [edi],dl
|
|
|
|
add esi,1
|
|
add edi,1
|
|
|
|
xwords:
|
|
shr cl,1
|
|
jnc xquads
|
|
|
|
mov dl, [esi]
|
|
mov ch, [ebx+edx]
|
|
|
|
mov [edi],ch
|
|
mov dl, [esi+1]
|
|
|
|
mov ch, [ebx+edx]
|
|
mov [edi+1],ch
|
|
|
|
add esi,2
|
|
add edi,2
|
|
|
|
xquads:
|
|
test cl,cl
|
|
jz _xend
|
|
|
|
xnext:
|
|
mov eax, [esi]
|
|
add esi,4
|
|
|
|
mov dl,al
|
|
mov ch,[ebx+edx]
|
|
|
|
mov dl,ah
|
|
ror eax,16
|
|
mov [edi],ch
|
|
|
|
mov ch,[ebx+edx]
|
|
|
|
mov dl,al
|
|
mov [edi+1],ch
|
|
|
|
mov ch,[ebx+edx]
|
|
|
|
mov dl,ah
|
|
mov [edi+2],ch
|
|
|
|
mov ch,[ebx+edx]
|
|
mov [edi+3],ch
|
|
|
|
add edi,4
|
|
|
|
dec cl
|
|
jnz xnext
|
|
|
|
_xend:
|
|
ret
|
|
_done:
|
|
} // end of asm block
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Decode RLE data with light translation and with clipping and transparency
|
|
**-----------------------------------------------------------------------*/
|
|
void TCDecodeFullCelL (BYTE *pDecodeTo, BYTE *pRLEBytes, long lRLECount, long nWidth)
|
|
{
|
|
long nBufferW, nL, LineVal;
|
|
app_assert(pDecodeTo != NULL);
|
|
app_assert(pRLEBytes != NULL);
|
|
|
|
app_assert(gpBuffer);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pDecodeTo == NULL || pRLEBytes == NULL || gpBuffer == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
__asm {
|
|
mov eax,dword ptr [nLVal];
|
|
shl eax,8
|
|
add eax,dword ptr [pLightTbl];
|
|
mov dword ptr [nL],eax
|
|
|
|
mov esi,dword ptr [pRLEBytes] // Source
|
|
mov edi,dword ptr [pDecodeTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nWidth]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [lRLECount]
|
|
add ebx,esi
|
|
|
|
mov eax,edi
|
|
and eax,1
|
|
mov dword ptr [LineVal],eax
|
|
|
|
_T1Lp1: mov edx,dword ptr [nWidth]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
push ebx
|
|
mov ebx,dword ptr [nL]
|
|
sub edx,eax
|
|
cmp edi,dword ptr [glClipY]
|
|
jb _T1C1
|
|
add esi,eax
|
|
add edi,eax
|
|
jmp _T1x
|
|
_T1C1: mov ecx,eax
|
|
mov eax,edi
|
|
and eax,1
|
|
cmp eax,dword ptr [LineVal]
|
|
jnz _T1Od
|
|
shr ecx,1
|
|
jnc _T1w
|
|
inc esi
|
|
inc edi
|
|
jecxz _T1x
|
|
jmp _T1w2
|
|
_T1w: shr ecx,1
|
|
jnc _T1Lp3
|
|
inc esi
|
|
inc edi
|
|
lodsb
|
|
xlatb
|
|
stosb
|
|
jecxz _T1x
|
|
_T1Lp3: lodsd
|
|
inc edi
|
|
ror eax,8
|
|
xlatb
|
|
stosb
|
|
ror eax,16
|
|
inc edi
|
|
xlatb
|
|
stosb
|
|
loop _T1Lp3
|
|
jmp _T1x
|
|
|
|
_T1Od: shr ecx,1
|
|
jnc _T1w2
|
|
lodsb
|
|
xlatb
|
|
stosb
|
|
jecxz _T1x
|
|
jmp _T1w
|
|
_T1w2: shr ecx,1
|
|
jnc _T1Lp4
|
|
lodsb
|
|
xlatb
|
|
stosb
|
|
inc esi
|
|
inc edi
|
|
jecxz _T1x
|
|
_T1Lp4: lodsd
|
|
xlatb
|
|
stosb
|
|
inc edi
|
|
ror eax,16
|
|
xlatb
|
|
stosb
|
|
inc edi
|
|
loop _T1Lp4
|
|
|
|
_T1x: pop ebx
|
|
or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
mov eax,dword ptr [LineVal]
|
|
inc eax
|
|
and eax,1
|
|
mov dword ptr [LineVal],eax
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void CDrawSlabCelL (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = *(WORD*)(pFrom + oend);
|
|
if (oend == 8)
|
|
offval2 = 0;
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
if (nLVal)
|
|
CDecodeFullCelL(pTo, pFrom, RLELen, nCelW);
|
|
else
|
|
CDecodeFullCel(pTo, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
/*
|
|
void CDrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = *(WORD*)(pFrom + oend);
|
|
if (oend == 8)
|
|
offval2 = 0;
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
if (nLVal)
|
|
CDecodeFullCelL (pBuff, pFrom, RLELen, nCelW);
|
|
else
|
|
CDecodeFullCel (pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
*/
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer.
|
|
**
|
|
** *pBuff = pointer to destination x,y in offscreen buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void TCDrawSlabCelPL (BYTE *pBuff, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = *(WORD*)(pFrom + oend);
|
|
if (oend == 8)
|
|
offval2 = 0;
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
if (nTrans)
|
|
TCDecodeFullCelL (pBuff, pFrom, RLELen, nCelW);
|
|
else if (nLVal)
|
|
CDecodeFullCelL (pBuff, pFrom, RLELen, nCelW);
|
|
else
|
|
CDecodeFullCel (pBuff, pFrom, RLELen, nCelW);
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a 5 offset slab cel in a cel file RAM buffer. With infared vision and clipping
|
|
**
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void CDrawSlabCelI (long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
long nBufferW, nL, ltaboff;
|
|
|
|
app_assert(gpBuffer);
|
|
app_assert(pCelBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
pFrom = pCelBuff + *((DWORD*)pCelBuff + nCel);
|
|
offval = *(WORD*)(pFrom + ostart);
|
|
if (!offval)
|
|
return;
|
|
RLELen = *((DWORD*)pCelBuff + nCel+1) - *((DWORD*)pCelBuff + nCel);
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pFrom + oend);
|
|
RLELen = offval2 ? offval2 - offval : RLELen - offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
nL = (long)(pLightTbl + ltaboff);
|
|
nBufferW = 768 + nCelW; // Increase width
|
|
__asm {
|
|
mov esi,[pFrom] // Source
|
|
mov edi,[pTo] // Dest
|
|
|
|
mov ecx,[RLELen]
|
|
add ecx,esi
|
|
_T1Lp1:
|
|
push ecx
|
|
mov edx,[nCelW]
|
|
xor ecx,ecx
|
|
_T1Lp2:
|
|
xor eax,eax // Load control byte
|
|
mov al,[esi]
|
|
inc esi
|
|
test al,al
|
|
js _T1J
|
|
|
|
mov ebx,[nL]
|
|
sub edx,eax
|
|
cmp edi,[glClipY]
|
|
jb _T1C1
|
|
add esi,eax
|
|
add edi,eax
|
|
jmp _T1x
|
|
_T1C1:
|
|
mov cl,[esi]
|
|
inc esi
|
|
mov cl,[ebx+ecx]
|
|
mov [edi],cl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz _T1C1
|
|
_T1x:
|
|
test edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
_T1J:
|
|
neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt:
|
|
pop ecx
|
|
sub edi,dword ptr [nBufferW]
|
|
cmp ecx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Draws a NORMAL cel in a cel file RAM buffer. NOTE: non-dungeon 5 offset cel
|
|
**
|
|
** pBuff = Buffer to draw in
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** nBuffW = Width of the buffer
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawBuffCel(BYTE *pBuff, long xp, long yp, long nBuffW, BYTE *pCelBuff, long nCel, long nCelW)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen;
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(pBuff != NULL);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL || pBuff == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
__asm {
|
|
mov ebx,dword ptr [pCelBuff]
|
|
mov eax,dword ptr [nCel]
|
|
shl eax,2
|
|
add ebx,eax
|
|
mov eax,dword ptr [ebx+4]
|
|
sub eax,dword ptr [ebx]
|
|
mov dword ptr [RLELen],eax
|
|
mov eax,dword ptr [pCelBuff]
|
|
add eax,dword ptr [ebx]
|
|
mov dword ptr [pFrom],eax
|
|
}
|
|
pTo = pBuff + (nBuffW * yp) + xp;
|
|
__asm {
|
|
mov esi,dword ptr [pFrom] // Source
|
|
mov edi,dword ptr [pTo] // Dest
|
|
|
|
mov eax,dword ptr [nBuffW] // Increase width
|
|
add eax,dword ptr [nCelW]
|
|
mov dword ptr [nBuffW],eax
|
|
|
|
mov ebx,dword ptr [RLELen]
|
|
add ebx,esi
|
|
|
|
_T1Lp1: mov edx,dword ptr [nCelW]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
sub edx,eax
|
|
mov ecx,eax
|
|
shr ecx,1
|
|
jnc _T1w
|
|
movsb
|
|
jecxz _T1x
|
|
_T1w: shr ecx,1
|
|
jnc _T1Lp3
|
|
movsw
|
|
jecxz _T1x
|
|
_T1Lp3: rep movsd
|
|
_T1x: or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBuffW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Makes a mask outline of a 5 offset slab cel in a cel file RAM buffer
|
|
**
|
|
** ocolor = Color to outline object with
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void OutlineSlabCel(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
long nBufferW;
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(gpBuffer);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL || gpBuffer == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
__asm {
|
|
mov ebx,dword ptr [pCelBuff]
|
|
mov eax,dword ptr [nCel]
|
|
shl eax,2
|
|
add ebx,eax
|
|
mov eax,dword ptr [ebx+4]
|
|
sub eax,dword ptr [ebx]
|
|
mov dword ptr [RLELen],eax
|
|
mov edx,dword ptr [pCelBuff]
|
|
add edx,dword ptr [ebx]
|
|
mov dword ptr [pFrom],edx
|
|
add edx,dword ptr [ostart]
|
|
xor eax,eax
|
|
mov ax,word ptr [edx]
|
|
mov dword ptr [offval],eax
|
|
mov edx,dword ptr [pFrom]
|
|
add edx,dword ptr [oend]
|
|
mov ax,word ptr [edx]
|
|
mov dword ptr [offval2],eax
|
|
}
|
|
if (offval != 0) {
|
|
if (oend == 8) offval2 = 0;
|
|
if (offval2 != 0) RLELen = offval2 - offval;
|
|
else RLELen -= offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
__asm {
|
|
mov esi,dword ptr [pFrom] // Source
|
|
mov edi,dword ptr [pTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nCelW]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [RLELen]
|
|
add ebx,esi
|
|
|
|
_T1Lp1: mov edx,dword ptr [nCelW]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
sub edx,eax
|
|
mov ecx,eax
|
|
mov ah,byte ptr [ocolor]
|
|
_T1Lp3: lodsb
|
|
or al,al
|
|
jz _T1Skip
|
|
mov byte ptr [edi-768],ah
|
|
mov byte ptr [edi-1],ah
|
|
mov byte ptr [edi+1],ah
|
|
mov byte ptr [edi+768],ah
|
|
_T1Skip: inc edi
|
|
loop _T1Lp3
|
|
or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Makes a mask outline of a 5 offset slab cel in a cel file RAM buffer. With clipping
|
|
**
|
|
** ocolor = Color to outline object with
|
|
** xp = Left X pixel position in offscreen buffer to draw to
|
|
** yp = Bottom Y pixel position in offscreen buffer to draw to
|
|
** *pCelBuff = pointer to cel file RAM buffer
|
|
** nCel = Cel number to draw in cel file (start with 1!!!!)
|
|
** nCelW = width of cel to draw
|
|
** nLVal = light value
|
|
**-----------------------------------------------------------------------*/
|
|
void COutlineSlabCel(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE *pTo;
|
|
BYTE *pFrom;
|
|
long RLELen, offval, offval2;
|
|
long nBufferW;
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(gpBuffer);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (pCelBuff == NULL || gpBuffer == NULL)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
__asm {
|
|
mov ebx,dword ptr [pCelBuff]
|
|
mov eax,dword ptr [nCel]
|
|
shl eax,2
|
|
add ebx,eax
|
|
mov eax,dword ptr [ebx+4]
|
|
sub eax,dword ptr [ebx]
|
|
mov dword ptr [RLELen],eax
|
|
mov edx,dword ptr [pCelBuff]
|
|
add edx,dword ptr [ebx]
|
|
mov dword ptr [pFrom],edx
|
|
add edx,dword ptr [ostart]
|
|
xor eax,eax
|
|
mov ax,word ptr [edx]
|
|
mov dword ptr [offval],eax
|
|
mov edx,dword ptr [pFrom]
|
|
add edx,dword ptr [oend]
|
|
mov ax,word ptr [edx]
|
|
mov dword ptr [offval2],eax
|
|
}
|
|
if (offval != 0) {
|
|
if (oend == 8) offval2 = 0;
|
|
if (offval2 != 0) RLELen = offval2 - offval;
|
|
else RLELen -= offval;
|
|
pFrom += offval;
|
|
pTo = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
__asm {
|
|
mov esi,dword ptr [pFrom] // Source
|
|
mov edi,dword ptr [pTo] // Dest
|
|
|
|
mov eax,768 // Increase width
|
|
add eax,dword ptr [nCelW]
|
|
mov dword ptr [nBufferW],eax
|
|
|
|
mov ebx,dword ptr [RLELen]
|
|
add ebx,esi
|
|
|
|
_T1Lp1: mov edx,dword ptr [nCelW]
|
|
|
|
_T1Lp2: xor eax,eax // Load control byte
|
|
lodsb
|
|
or al,al
|
|
js _T1J
|
|
|
|
sub edx,eax
|
|
mov ecx,dword ptr [glClipY]
|
|
cmp edi,ecx
|
|
jb _T1C1
|
|
add esi,eax
|
|
add edi,eax
|
|
jmp _T1x
|
|
_T1C1: sub ecx,768
|
|
cmp edi,ecx
|
|
jae _T1C2
|
|
mov ecx,eax
|
|
mov ah,byte ptr [ocolor]
|
|
_T1Lp3: lodsb
|
|
or al,al
|
|
jz _T1Skip
|
|
mov byte ptr [edi-768],ah
|
|
mov byte ptr [edi-1],ah
|
|
mov byte ptr [edi+1],ah
|
|
mov byte ptr [edi+768],ah
|
|
_T1Skip: inc edi
|
|
loop _T1Lp3
|
|
jmp _T1x
|
|
|
|
_T1C2: mov ecx,eax
|
|
mov ah,byte ptr [ocolor]
|
|
_T1Lp4: lodsb
|
|
or al,al
|
|
jz _T1Skip2
|
|
mov byte ptr [edi-768],ah
|
|
mov byte ptr [edi-1],ah
|
|
mov byte ptr [edi+1],ah
|
|
_T1Skip2: inc edi
|
|
loop _T1Lp4
|
|
|
|
_T1x: or edx,edx
|
|
jz _T1Nxt
|
|
jmp _T1Lp2
|
|
|
|
_T1J: neg al // Do jump
|
|
add edi,eax
|
|
sub edx,eax
|
|
jnz _T1Lp2
|
|
_T1Nxt: sub edi,dword ptr [nBufferW]
|
|
cmp ebx,esi
|
|
jnz _T1Lp1
|
|
} // end of asm block
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------*
|
|
**-----------------------------------------------------------------------*/
|
|
#if !RLE_DRAW
|
|
void TranslateCels(byte *p, byte *ttbl, int nf)
|
|
|
|
{
|
|
int j;
|
|
app_assert(p != NULL);
|
|
app_assert(ttbl != NULL);
|
|
|
|
for (j = 1; j <= nf; j++) {
|
|
__asm {
|
|
mov ebx,dword ptr [p]
|
|
mov eax,dword ptr [j]
|
|
shl eax,2
|
|
add ebx,eax
|
|
mov esi,dword ptr [p]
|
|
add esi,dword ptr [ebx]
|
|
add esi,10 // Source
|
|
|
|
mov edx,dword ptr [ebx+4] // Size
|
|
sub edx,dword ptr [ebx]
|
|
sub edx,10
|
|
|
|
mov edi,esi // Dest
|
|
|
|
mov ebx,dword ptr [ttbl] // Color conversion table
|
|
|
|
_TLp1: xor eax,eax // Load control byte
|
|
lodsb
|
|
stosb
|
|
dec edx
|
|
jz _TNxt
|
|
or al,al
|
|
js _TLp1
|
|
|
|
sub edx,eax
|
|
mov ecx,eax
|
|
_TLp2: lodsb
|
|
xlatb
|
|
stosb
|
|
loop _TLp2
|
|
or edx,edx
|
|
jnz _TLp1
|
|
|
|
_TNxt: nop
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** Plot a point
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawPoint(int x, int y, byte c)
|
|
{
|
|
BYTE *pTo;
|
|
|
|
app_assert(gpBuffer);
|
|
if ((y < 0) || (y >= 640)) return;
|
|
if ((x < 64) || (x >= 704)) return;
|
|
pTo = gpBuffer + nBuffWTbl[y] + x;
|
|
__asm {
|
|
mov edi, dword ptr [pTo];
|
|
cmp edi, dword ptr [glClipY]
|
|
jae _NoD
|
|
mov al, byte ptr [c]
|
|
mov byte ptr [edi], al
|
|
_NoD:
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** For line drawing
|
|
**-----------------------------------------------------------------------*/
|
|
#define dlswap(a,b) { a^=b; b^=a; a^=b; }
|
|
#define absolute(i,j,k) ( (i-j)*(k = ( (i-j)<0 ? -1 : 1)))
|
|
|
|
int dlreverse;
|
|
byte dlcolor;
|
|
BOOL dlclipflag;
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** plot for line drawing (temp probably, will write in asm)
|
|
**-----------------------------------------------------------------------*/
|
|
void plot(int x, int y)
|
|
{
|
|
BYTE *pTo;
|
|
|
|
app_assert(gpBuffer);
|
|
if (dlreverse) {
|
|
if (dlclipflag) {
|
|
if ((x < 0) || (x >= 640)) return;
|
|
if ((y < 64) || (y >= 704)) return;
|
|
}
|
|
pTo = gpBuffer + nBuffWTbl[x] + y;
|
|
} else {
|
|
if (dlclipflag) {
|
|
if ((y < 0) || (y >= 640)) return;
|
|
if ((x < 64) || (x >= 704)) return;
|
|
}
|
|
pTo = gpBuffer + nBuffWTbl[y] + x;
|
|
}
|
|
__asm {
|
|
mov edi, dword ptr [pTo];
|
|
cmp edi,dword ptr [glClipY]
|
|
jae _NoD
|
|
mov al,byte ptr [dlcolor]
|
|
mov byte ptr [edi],al
|
|
_NoD:
|
|
}
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
** line drawing ctrl (temp probably, will write in asm)
|
|
**-----------------------------------------------------------------------*/
|
|
void DrawLine(int a1, int b1, int a2, int b2, byte clr)
|
|
{
|
|
int dx, dy, incr1, incr2, D, x, y, _xend, c, pixels_left;
|
|
int x1, y1;
|
|
int sign_x, sign_y, step, i;
|
|
|
|
dlcolor = clr;
|
|
|
|
// Test clipping bounds to see if we even need to test on the pixel level
|
|
dlclipflag = FALSE;
|
|
if ((a1 < 64) || (a1 >= 704)) dlclipflag = TRUE;
|
|
if ((a2 < 64) || (a2 >= 704)) dlclipflag = TRUE;
|
|
if ((b1 < 160) || (b1 >= 512)) dlclipflag = TRUE;
|
|
if ((b2 < 160) || (b2 >= 512)) dlclipflag = TRUE;
|
|
|
|
dx = absolute(a2, a1, sign_x);
|
|
dy = absolute(b2, b1, sign_y);
|
|
|
|
if (sign_x == sign_y)
|
|
step = 1;
|
|
else
|
|
step = -1;
|
|
|
|
if (dy > dx) {
|
|
dlswap(a1, b1);
|
|
dlswap(a2, b2);
|
|
dlswap(dx, dy);
|
|
dlreverse = 1;
|
|
} else
|
|
dlreverse = 0;
|
|
|
|
if (a1 > a2) {
|
|
x = a2;
|
|
y = b2;
|
|
x1 = a1;
|
|
y1 = b1;
|
|
} else {
|
|
x = a1;
|
|
y = b1;
|
|
x1 = a2;
|
|
y1 = b2;
|
|
}
|
|
|
|
_xend = (dx - 1) / 4;
|
|
pixels_left = (dx - 1) % 4;
|
|
|
|
plot(x, y);
|
|
plot(x1, y1);
|
|
incr2 = 4 * dy - 2 * dx;
|
|
if (incr2 < 0) {
|
|
c = 2 * dy;
|
|
incr1 = 2 * c;
|
|
D = incr1 - dx;
|
|
|
|
for (i = 0; i < _xend; i++) {
|
|
++x;
|
|
--x1;
|
|
if (D < 0) {
|
|
plot(x, y);
|
|
plot(++x, y);
|
|
plot(x1, y1);
|
|
plot(--x1, y1);
|
|
D += incr1;
|
|
} else {
|
|
if (D < c) {
|
|
plot(x, y);
|
|
plot(++x, y += step);
|
|
plot(x1, y1);
|
|
plot(--x1, y1 -= step);
|
|
} else {
|
|
plot(x, y += step);
|
|
plot(++x, y);
|
|
plot(x1, y1 -= step);
|
|
plot(--x1, y1);
|
|
}
|
|
D += incr2;
|
|
}
|
|
}
|
|
|
|
if (pixels_left) {
|
|
if (D < 0) {
|
|
plot(++x, y);
|
|
if (pixels_left > 1)
|
|
plot(++x, y);
|
|
if (pixels_left > 2)
|
|
plot(--x1, y1);
|
|
} else {
|
|
if (D < c) {
|
|
plot(++x, y);
|
|
if (pixels_left > 1)
|
|
plot(++x, y += step);
|
|
if (pixels_left > 2)
|
|
plot(--x1, y1);
|
|
} else {
|
|
plot(++x, y += step);
|
|
if (pixels_left > 1)
|
|
plot(++x, y);
|
|
if (pixels_left > 2)
|
|
plot(--x1, y1 -= step);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
c = 2 * (dy - dx);
|
|
incr1 = 2 * c;
|
|
D = incr1 + dx;
|
|
for (i = 0; i < _xend; i++) {
|
|
++x;
|
|
--x1;
|
|
if (D > 0) {
|
|
plot(x, y += step);
|
|
plot(++x, y += step);
|
|
plot(x1, y1 -= step);
|
|
plot(--x1, y1 -= step);
|
|
D += incr1;
|
|
} else {
|
|
if (D < c) {
|
|
plot(x, y);
|
|
plot(++x, y += step);
|
|
plot(x1, y1);
|
|
plot(--x1, y1 -= step);
|
|
} else {
|
|
plot(x, y += step);
|
|
plot(++x, y);
|
|
plot(x1, y1 -= step);
|
|
plot(--x1, y1);
|
|
}
|
|
D += incr2;
|
|
}
|
|
}
|
|
|
|
if (pixels_left) {
|
|
if (D > 0) {
|
|
plot(++x, y += step);
|
|
if (pixels_left > 1)
|
|
plot(++x, y += step);
|
|
if (pixels_left > 2)
|
|
plot(--x1, y1 -= step);
|
|
} else {
|
|
if (D < c) {
|
|
plot(++x, y);
|
|
if (pixels_left > 1)
|
|
plot(++x, y += step);
|
|
if (pixels_left > 2)
|
|
plot(--x1, y1);
|
|
} else {
|
|
plot(++x, y += step);
|
|
if (pixels_left > 1)
|
|
plot(++x, y);
|
|
if (pixels_left > 2) {
|
|
if (D > c)
|
|
plot(--x1, y1 -= step);
|
|
else
|
|
plot(--x1, y1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
/*-----------------------------------------------------------------------**
|
|
**-----------------------------------------------------------------------*/
|
|
int GetDirection(int x1, int y1, int x2, int y2)
|
|
{
|
|
int mx, my, md;
|
|
|
|
mx = x2-x1;
|
|
my = y2-y1;
|
|
if (mx >= 0) {
|
|
if (my >= 0) {
|
|
md = 0;
|
|
if ((mx << 1) < my) md = 1;
|
|
if ((my << 1) < mx) md = 7;
|
|
} else {
|
|
md = 6;
|
|
my = -my;
|
|
if ((mx << 1) < my) md = 5;
|
|
if ((my << 1) < mx) md = 7;
|
|
}
|
|
} else {
|
|
if (my >= 0) {
|
|
md = 2;
|
|
mx = -mx;
|
|
if ((mx << 1) < my) md = 1;
|
|
if ((my << 1) < mx) md = 3;
|
|
} else {
|
|
md = 4;
|
|
mx = -mx;
|
|
my = -my;
|
|
if ((mx << 1) < my) md = 5;
|
|
if ((my << 1) < mx) md = 3;
|
|
}
|
|
}
|
|
return (md);
|
|
}
|
|
|
|
int SeedCount;
|
|
long orgseed;
|
|
|
|
//***************************************************************************
|
|
//***************************************************************************
|
|
void SetRndSeed(long s) {
|
|
sglGameSeed = s;
|
|
orgseed = s; //debug
|
|
SeedCount = 0;
|
|
}
|
|
|
|
//***************************************************************************
|
|
//***************************************************************************
|
|
long GetRndSeed() {
|
|
SeedCount++;
|
|
static const DWORD INCREMENT = 1;
|
|
static const DWORD MULTIPLIER = 0x015a4e35L;
|
|
sglGameSeed = MULTIPLIER * sglGameSeed + INCREMENT;
|
|
return abs(sglGameSeed);
|
|
}
|
|
|
|
|
|
//***************************************************************************
|
|
//***************************************************************************
|
|
long random(byte idx,long v) {
|
|
if (v <= 0) return 0;
|
|
|
|
// high order bits are more "random" than low order bits
|
|
if (v < 0x0ffff) return (GetRndSeed() >> 16) % v;
|
|
|
|
return GetRndSeed() % v;
|
|
}
|
|
|
|
|
|
//******************************************************************
|
|
// memory manager vars
|
|
//******************************************************************
|
|
#define TRACK_MEM_BLOCKS 1 // 0 in final
|
|
#if DEBUG_MEM
|
|
#define DUMP_MEM_BLOCKS 1 // 0 in final
|
|
#else
|
|
#define DUMP_MEM_BLOCKS 0 // 0 in final
|
|
#endif
|
|
#ifdef NDEBUG
|
|
#undef TRACK_MEM_BLOCKS
|
|
#undef DUMP_MEM_BLOCKS
|
|
#define TRACK_MEM_BLOCKS 0
|
|
#define DUMP_MEM_BLOCKS 0
|
|
#endif
|
|
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
typedef struct TMemType {
|
|
struct TMemType * pNext;
|
|
DWORD dwSig;
|
|
|
|
// current amount of memory allocated with this signature
|
|
DWORD dwCurrAmount;
|
|
|
|
// maximum amount ever allocated for this signature
|
|
DWORD dwMostEver;
|
|
|
|
// amount of memory allocated to this signature when the
|
|
// program had its maximum memory allocated
|
|
DWORD dwAmountAtMax;
|
|
} TMemType;
|
|
|
|
typedef union TPrintSig {
|
|
DWORD dwSig;
|
|
char szSig[sizeof(DWORD) + 1];
|
|
} TPrintSig;
|
|
|
|
static DWORD sgdwCurrAllocated = 0;
|
|
static DWORD sgdwHighestAllocated = 0;
|
|
static TMemType * sgpMemTypeHead = NULL;
|
|
|
|
typedef struct TMemBlockHdr {
|
|
DWORD dwBytes;
|
|
DWORD dwSig;
|
|
DWORD dwCheck1;
|
|
DWORD dwCheck2;
|
|
} TMemBlockHdr;
|
|
typedef struct TMemBlockFtr {
|
|
DWORD dwCheck3;
|
|
DWORD dwCheck4;
|
|
} TMemBlockFtr;
|
|
|
|
#define MEM_CHECK1 0x497208ab
|
|
#define MEM_CHECK2 0x127834dc
|
|
#define MEM_CHECK3 0x023481a9
|
|
#define MEM_CHECK4 0xfcb87147
|
|
|
|
#endif
|
|
|
|
// serialize access to memory manager -- according to Mike O'Brien,
|
|
// malloc does not serialize access in all cases in NT 4.0 even
|
|
// when using LIBCMT.LIB. Therefore, don't trust *any* memory munger
|
|
static CCritSect sgMemCrit;
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
static const char * sig_to_string(DWORD dwSig,TPrintSig * pSig) {
|
|
__asm mov eax, dwSig
|
|
__asm bswap eax
|
|
__asm mov dwSig, eax
|
|
pSig->dwSig = dwSig;
|
|
pSig->szSig[sizeof(DWORD)] = 0;
|
|
return pSig->szSig;
|
|
|
|
}
|
|
#endif
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
void mem_cleanup(BOOL bNormalExit) {
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
// serialize access to memory manager -- according to Mike O'Brien,
|
|
// malloc does not serialize access in all cases in NT 4.0 even
|
|
// when using LIBCMT.LIB. Therefore, don't trust *any* memory munger
|
|
sgMemCrit.Enter();
|
|
|
|
FILE * f = NULL;
|
|
|
|
#if DUMP_MEM_BLOCKS
|
|
if (bNormalExit) f = fopen("c:\\memdump.txt","wb");
|
|
#endif
|
|
|
|
if (f) {
|
|
fprintf(
|
|
f,
|
|
"sig most ever amount at max at end of game\r\n"
|
|
"------------------------------------------------------\r\n"
|
|
);
|
|
}
|
|
|
|
TMemType * pNext = NULL;
|
|
for (TMemType * pType = sgpMemTypeHead; pType; pType = pNext) {
|
|
if (f) {
|
|
TPrintSig sig;
|
|
fprintf(
|
|
f,
|
|
"%4s 0x%08x 0x%08x %8dk %8d\r\n",
|
|
sig_to_string(pType->dwSig,&sig),
|
|
pType->dwMostEver,
|
|
pType->dwAmountAtMax,
|
|
pType->dwAmountAtMax / 1024,
|
|
pType->dwCurrAmount
|
|
);
|
|
}
|
|
|
|
pNext = pType->pNext;
|
|
SMemFree(pType,__FILE__,__LINE__);
|
|
}
|
|
|
|
if (f) {
|
|
fprintf(
|
|
f,
|
|
"------------------------------------------------\r\n"
|
|
"max allocated 0x%08x %8dk\r\n",
|
|
sgdwHighestAllocated,
|
|
sgdwHighestAllocated / 1024
|
|
);
|
|
fclose(f);
|
|
}
|
|
|
|
sgMemCrit.Leave();
|
|
#endif
|
|
}
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
static TMemType * find_mem_type_by_sig(DWORD dwSig) {
|
|
// find existing block with signature
|
|
for (TMemType * pType = sgpMemTypeHead; pType; pType = pType->pNext)
|
|
if (pType->dwSig == dwSig) return pType;
|
|
|
|
// create a new signature block
|
|
pType = (TMemType *) SMemAlloc(sizeof(TMemType),__FILE__,__LINE__);
|
|
ZeroMemory(pType,sizeof TMemType);
|
|
pType->dwSig = dwSig;
|
|
|
|
// link to list
|
|
pType->pNext = sgpMemTypeHead;
|
|
sgpMemTypeHead = pType;
|
|
|
|
// return new signature block
|
|
return pType;
|
|
}
|
|
#endif
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
static void mem_addto_type(TMemType * pType,DWORD dwBytes) {
|
|
// fixup memory for this type
|
|
pType->dwCurrAmount += dwBytes;
|
|
if (pType->dwMostEver < pType->dwCurrAmount)
|
|
pType->dwMostEver = pType->dwCurrAmount;
|
|
|
|
// fixup memory for all types
|
|
sgdwCurrAllocated += dwBytes;
|
|
if (sgdwHighestAllocated < sgdwCurrAllocated) {
|
|
sgdwHighestAllocated = sgdwCurrAllocated;
|
|
for (TMemType * pHigh = sgpMemTypeHead; pHigh; pHigh = pHigh->pNext)
|
|
pHigh->dwAmountAtMax = pHigh->dwCurrAmount;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
static const char * mem_freefrom_type(TMemType * pType,DWORD dwBytes) {
|
|
// fixup memory for this type
|
|
DWORD dwTemp = pType->dwCurrAmount;
|
|
pType->dwCurrAmount -= dwBytes;
|
|
if (pType->dwCurrAmount > dwTemp)
|
|
return "memory block signature underflow: %s";
|
|
|
|
// fixup global memory indicator
|
|
dwTemp = sgdwCurrAllocated;
|
|
sgdwCurrAllocated -= dwBytes;
|
|
if (sgdwCurrAllocated > dwTemp)
|
|
return "memory free underflow";
|
|
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM
|
|
void mem_use_sig(DWORD dwSig,DWORD dwBytes) {
|
|
#if TRACK_MEM_BLOCKS
|
|
TMemType * pType = find_mem_type_by_sig(dwSig);
|
|
if (! pType) ErrorDlg(IDD_MEM_ERR,GetLastError(),__FILE__,__LINE__);
|
|
|
|
mem_addto_type(pType,dwBytes);
|
|
#endif
|
|
}
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
void mem_unuse_sig(DWORD dwSig,DWORD dwBytes) {
|
|
#if TRACK_MEM_BLOCKS
|
|
const char * pszErr_s;
|
|
TMemType * pType = find_mem_type_by_sig(dwSig);
|
|
if (pType)
|
|
pszErr_s = mem_freefrom_type(pType,dwBytes);
|
|
else
|
|
pszErr_s = "Bad signature unused: %s";
|
|
|
|
TPrintSig sig;
|
|
if (pszErr_s) app_fatal(pszErr_s,sig_to_string(dwSig,&sig));
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM
|
|
BYTE * mem_malloc_dbg(DWORD dwBytes,DWORD dwSig,DWORD dwLine,const TCHAR * pszFile)
|
|
#else
|
|
BYTE * DiabloAllocPtr(DWORD dwBytes)
|
|
#endif
|
|
{
|
|
// serialize access to memory manager -- according to Mike O'Brien,
|
|
// malloc does not serialize access in all cases in NT 4.0 even
|
|
// when using LIBCMT.LIB. Therefore, don't trust *any* memory munger
|
|
sgMemCrit.Enter();
|
|
|
|
// allocate memory block
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
DWORD dwAlloc = dwBytes + sizeof(TMemBlockHdr) + sizeof(TMemBlockFtr);
|
|
|
|
BYTE * rv = (BYTE *) SMemAlloc(dwAlloc,pszFile,dwLine);
|
|
#elif DEBUG_MEM
|
|
BYTE * rv = (BYTE *) SMemAlloc(dwBytes,pszFile,dwLine);
|
|
#else
|
|
BYTE * rv = (BYTE *) SMemAlloc(dwBytes,__FILE__,__LINE__);
|
|
#endif
|
|
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
if (rv) {
|
|
TMemType * pType = find_mem_type_by_sig(dwSig);
|
|
if (pType) {
|
|
mem_addto_type(pType,dwBytes);
|
|
|
|
TMemBlockHdr * pHdr = (TMemBlockHdr *) rv;
|
|
rv += sizeof(TMemBlockHdr);
|
|
TMemBlockFtr * pFtr = (TMemBlockFtr *) (rv + dwBytes);
|
|
|
|
pHdr->dwSig = dwSig;
|
|
pHdr->dwBytes = dwBytes;
|
|
pHdr->dwCheck1 = MEM_CHECK1;
|
|
pHdr->dwCheck2 = MEM_CHECK2;
|
|
|
|
pFtr->dwCheck3 = MEM_CHECK3;
|
|
pFtr->dwCheck4 = MEM_CHECK4;
|
|
}
|
|
else {
|
|
SMemFree(rv,__FILE__,__LINE__);
|
|
rv = NULL;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
sgMemCrit.Leave();
|
|
|
|
#if DEBUG_MEM
|
|
if (! rv) ErrorDlg(IDD_MEM_ERR,GetLastError(),pszFile,dwLine);
|
|
#else
|
|
if (! rv) ErrorDlg(IDD_MEM_ERR,GetLastError(),__FILE__,__LINE__);
|
|
#endif
|
|
|
|
return rv;
|
|
}
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM
|
|
void mem_free_dbg(void * p,DWORD dwLine,const TCHAR * pszFile)
|
|
#else
|
|
void mem_free_dbg(void * p)
|
|
#endif
|
|
{
|
|
if (! p) return;
|
|
|
|
// serialize access to memory manager -- according to Mike O'Brien,
|
|
// malloc does not serialize access in all cases in NT 4.0 even
|
|
// when using LIBCMT.LIB. Therefore, don't trust *any* memory munger
|
|
sgMemCrit.Enter();
|
|
|
|
// free memory block
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
const char * pszErr_s = NULL;
|
|
TMemBlockHdr * pHdr = (TMemBlockHdr *) ((BYTE *) p - sizeof(TMemBlockHdr));
|
|
DWORD dwSig = pHdr->dwSig; // assume signature is valid
|
|
if (pHdr->dwCheck1 != MEM_CHECK1 || pHdr->dwCheck2 != MEM_CHECK2)
|
|
pszErr_s = "Memory block header corruption: %s";
|
|
else {
|
|
// Now change it so if there is duplicate free we'll catch it.
|
|
pHdr->dwCheck1 = 0xDEADC0DE;
|
|
pHdr->dwCheck2 = 0xDEADC0DE;
|
|
}
|
|
|
|
if (! pszErr_s) {
|
|
TMemBlockFtr * pFtr = (TMemBlockFtr *) ((BYTE *) p + pHdr->dwBytes);
|
|
if (pFtr->dwCheck3 != MEM_CHECK3 || pFtr->dwCheck4 != MEM_CHECK4)
|
|
pszErr_s = "Memory block footer corruption: %s";
|
|
else {
|
|
// Now change it so if there is duplicate free we'll catch it.
|
|
pFtr->dwCheck3 = 0xDEADC0DE;
|
|
pFtr->dwCheck4 = 0xDEADC0DE;
|
|
}
|
|
}
|
|
if (! pszErr_s) {
|
|
TMemType * pType = find_mem_type_by_sig(dwSig);
|
|
if (pType)
|
|
pszErr_s = mem_freefrom_type(pType,pHdr->dwBytes);
|
|
else
|
|
pszErr_s = "Attempt to free memory with unknown signature %s";
|
|
}
|
|
|
|
p = (void *) pHdr;
|
|
SMemFree(p,pszFile,dwLine);
|
|
#elif DEBUG_MEM
|
|
SMemFree(p,pszFile,dwLine);
|
|
#else
|
|
SMemFree(p,__FILE__,__LINE__);
|
|
#endif
|
|
|
|
sgMemCrit.Leave();
|
|
|
|
// display any error which occurred -- outside critical section
|
|
#if DEBUG_MEM && TRACK_MEM_BLOCKS
|
|
if (pszErr_s) {
|
|
TPrintSig sig;
|
|
app_fatal(pszErr_s,sig_to_string(dwSig,&sig));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
#if DEBUG_MEM
|
|
BYTE * load_file_dbg(const char * pszName,DWORD * pdwFileLen,DWORD dwSig,DWORD dwLine,const TCHAR * pszFile)
|
|
#else
|
|
BYTE * LoadFileInMem(const char * pszName,DWORD * pdwFileLen)
|
|
#endif
|
|
{
|
|
HSFILE hFile;
|
|
|
|
#if DEBUG_MEM
|
|
if (! pszName) app_fatal("LoadFileInMem: %s:%d",pszFile,dwLine);
|
|
#else
|
|
app_assert(pszName);
|
|
#endif
|
|
|
|
patSFileOpenFile(pszName,&hFile);
|
|
DWORD dwFileLen = patSFileGetFileSize(hFile,NULL);
|
|
if (pdwFileLen) *pdwFileLen = dwFileLen;
|
|
if (! dwFileLen) app_fatal("Zero length SFILE:\n%s",pszName);
|
|
|
|
#if DEBUG_MEM
|
|
BYTE * pbMem = mem_malloc_dbg(dwFileLen,dwSig,dwLine,pszFile);
|
|
#else
|
|
BYTE * pbMem = DiabloAllocPtr(dwFileLen);
|
|
#endif
|
|
|
|
patSFileReadFile(hFile,pbMem,dwFileLen);
|
|
patSFileCloseFile(hFile);
|
|
return pbMem;
|
|
}
|
|
|
|
|
|
//******************************************************************
|
|
//******************************************************************
|
|
DWORD LoadFileWithMem(const char * pszName,BYTE * pbMem) {
|
|
HSFILE hFile;
|
|
|
|
app_assert(pszName);
|
|
if (! pbMem) app_fatal("LoadFileWithMem(NULL):\n%s",pszName);
|
|
|
|
patSFileOpenFile(pszName,&hFile);
|
|
DWORD dwFileLen = patSFileGetFileSize(hFile,NULL);
|
|
if (! dwFileLen) app_fatal("Zero length SFILE:\n%s",pszName);
|
|
patSFileReadFile(hFile,pbMem,dwFileLen);
|
|
patSFileCloseFile(hFile);
|
|
return dwFileLen;
|
|
}
|
|
|
|
|
|
//*************************************************************
|
|
// RLE Unitdraw Code
|
|
//*************************************************************
|
|
#if RLE_DRAW
|
|
#define MAX_RLE_COPY 65
|
|
static int sgnWidth; //used in both RLEDrawLitUnit f'cns
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void TranslateCels(BYTE *p, BYTE *ttbl, int nFrames)
|
|
{
|
|
app_assert(p != NULL);
|
|
app_assert(ttbl != NULL);
|
|
|
|
int nDataSize;
|
|
BYTE * pImage;
|
|
char bBlock;
|
|
for (int j = 1; j <= nFrames; j++) {
|
|
pImage = p + ((DWORD*)p)[j] + sizeof(WORD)*5;
|
|
nDataSize = ((DWORD*)p)[j+1] - ((DWORD*)p)[j] - sizeof(WORD)*5;
|
|
while (nDataSize) {
|
|
bBlock = *pImage++;
|
|
nDataSize--;
|
|
app_assert(nDataSize >= 0);
|
|
//check for skip
|
|
if (bBlock >= 0)
|
|
continue;
|
|
bBlock = -bBlock;
|
|
//check for run
|
|
if (bBlock > MAX_RLE_COPY) {
|
|
bBlock -= MAX_RLE_COPY;
|
|
nDataSize--;
|
|
app_assert(nDataSize >= 0);
|
|
*pImage = ttbl[*pImage++];
|
|
continue;
|
|
}
|
|
//do copy
|
|
nDataSize -= bBlock;
|
|
app_assert(nDataSize >= 0);
|
|
while (bBlock--)
|
|
*pImage = ttbl[*pImage++];
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
static void RLEDrawUnit(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth) {
|
|
_asm {
|
|
//**** Assumes _fastcall convention!! ****
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
//eax - copy/run/skip block size
|
|
//ebx - pixels left to draw this line
|
|
//ecx - bytes of RLE data left
|
|
//edx - scratch
|
|
//esi - source RLE data
|
|
//edi - destination buffer
|
|
|
|
mov esi, edx
|
|
mov edi, ecx
|
|
|
|
xor eax, eax
|
|
mov ebx, [nWidth]
|
|
mov ecx, [nDataSize]
|
|
|
|
Loop1:
|
|
mov al,[esi]
|
|
inc esi
|
|
dec ecx
|
|
|
|
//negative packets are copy/runs, nonnegative are skips
|
|
test al,al
|
|
jns SkipLoop
|
|
|
|
neg al
|
|
//packets larger than MAX_RLE_COPY are runs, rest are copies
|
|
cmp al,MAX_RLE_COPY
|
|
jle Copy
|
|
|
|
//get size of run
|
|
sub al,MAX_RLE_COPY
|
|
dec ecx
|
|
|
|
//write out run packet
|
|
mov dl,[esi]
|
|
inc esi
|
|
sub ebx,eax
|
|
RunMemset:
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz RunMemset
|
|
jmp EOLTest
|
|
|
|
Copy:
|
|
//write out copy packet
|
|
sub ecx,eax
|
|
sub ebx,eax
|
|
CopyMemcpy:
|
|
mov dl,[esi]
|
|
inc esi
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz CopyMemcpy
|
|
|
|
EOLTest:
|
|
//if at end of line, move dst and reset linecounter
|
|
test ebx,ebx
|
|
jnz NextBlock
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
jmp NextBlock
|
|
|
|
SkipLoop:
|
|
//does skip extend past end of this line?
|
|
cmp eax,ebx
|
|
jle SingleLineSkip
|
|
mov edx,ebx
|
|
add edi,ebx
|
|
sub eax,ebx
|
|
jmp SkipMem
|
|
SingleLineSkip:
|
|
mov edx,eax
|
|
add edi,eax
|
|
xor eax,eax
|
|
SkipMem:
|
|
//if at end of line, move dst and reset linecounter
|
|
sub ebx,edx
|
|
jnz SkipNotEOL
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
SkipNotEOL:
|
|
//have we finished off this block? (skips may span multiple lines)
|
|
test eax,eax
|
|
jnz SkipLoop
|
|
|
|
NextBlock:
|
|
test ecx,ecx
|
|
jnz Loop1
|
|
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
static void RLEDrawOutline(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE bOutLineColor) {
|
|
_asm {
|
|
//**** Assumes _fastcall convention!! ****
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
//eax - copy/run/skip block size
|
|
//ebx - pixels left to draw this line
|
|
//ecx - bytes of RLE data left
|
|
//dl - outline color
|
|
//dh - scratch
|
|
//esi - source RLE data
|
|
//edi - destination buffer
|
|
|
|
mov esi,edx
|
|
mov edi,ecx
|
|
|
|
xor eax,eax
|
|
mov ebx,[nWidth]
|
|
xor edx,edx
|
|
mov ecx,[nDataSize]
|
|
mov dl, [bOutLineColor]
|
|
|
|
Loop1:
|
|
mov al,[esi]
|
|
inc esi
|
|
dec ecx
|
|
|
|
//negative packets are copy/runs, nonnegative are skips
|
|
test al,al
|
|
jns SkipLoop
|
|
|
|
neg al
|
|
//packets larger than MAX_RLE_COPY are runs, rest are copies
|
|
cmp al,MAX_RLE_COPY
|
|
jle Copy
|
|
|
|
//get size of run
|
|
sub al,MAX_RLE_COPY
|
|
dec ecx
|
|
|
|
//no outline for color zero (shadows)
|
|
mov dh,[esi]
|
|
inc esi
|
|
test dh,dh
|
|
jz SkipLoop
|
|
|
|
//write outline for run packet
|
|
mov [edi-1],dl //outline pixel left
|
|
sub ebx,eax
|
|
mov [edi+eax],dl //and right of run
|
|
RunMemset:
|
|
mov [edi-BUFFERX],dl //outline above
|
|
mov [edi+BUFFERX],dl //and below run
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz RunMemset
|
|
jmp EOLCheck
|
|
|
|
Copy:
|
|
sub ecx,eax
|
|
sub ebx,eax
|
|
CopyMemcpy:
|
|
mov dh,[esi]
|
|
inc esi
|
|
//don't draw outline for shadow pixels
|
|
test dh,dh
|
|
jz SkipPixel
|
|
|
|
mov [edi-1],dl //outline pixel left
|
|
mov [edi+1],dl //and right of copy
|
|
mov [edi-BUFFERX],dl //outline above
|
|
mov [edi+BUFFERX],dl //and below copy
|
|
SkipPixel:
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz CopyMemcpy
|
|
|
|
EOLCheck:
|
|
//if at end of line, move dst and reset linecounter
|
|
test ebx,ebx
|
|
jnz NextBlock
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
jmp NextBlock
|
|
|
|
SkipLoop:
|
|
cmp eax,ebx
|
|
jle SingleLineSkip
|
|
mov edx,ebx
|
|
add edi,ebx
|
|
sub eax,ebx
|
|
jmp SkipMem
|
|
SingleLineSkip:
|
|
mov edx,eax
|
|
add edi,eax
|
|
xor eax,eax
|
|
SkipMem:
|
|
//if at end of line, move dst and reset linecounter
|
|
sub ebx,edx
|
|
jnz SkipNotEOL
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
SkipNotEOL:
|
|
//have we finished off this block?
|
|
test eax,eax
|
|
jnz SkipLoop
|
|
mov dl, [bOutLineColor]
|
|
|
|
NextBlock:
|
|
test ecx,ecx
|
|
jnz Loop1
|
|
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
static void RLEDrawLitUnit(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE * pLightTable) {
|
|
_asm {
|
|
//**** Assumes _fastcall convention!! ****
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
//eax - copy/run/skip block size
|
|
//ebx - pixels left to draw this line
|
|
//ecx - bytes of RLE data left
|
|
//edx - scratch
|
|
//ebp - light table pointer
|
|
//esi - source RLE data
|
|
//edi - destination buffer
|
|
|
|
mov esi, edx
|
|
mov edi, ecx
|
|
|
|
mov ebx, [nWidth]
|
|
mov ecx, [nDataSize]
|
|
mov edx, [pLightTable]
|
|
push ebp
|
|
mov [sgnWidth],ebx //cheesy way to avoid using ebp
|
|
mov ebp,edx
|
|
xor eax,eax
|
|
xor edx,edx
|
|
|
|
Loop1:
|
|
mov al,[esi]
|
|
inc esi
|
|
dec ecx
|
|
|
|
//negative packets are copy/runs, nonnegative are skips
|
|
test al,al
|
|
jns SkipLoop
|
|
|
|
neg al
|
|
//packets larger than MAX_RLE_COPY are runs, rest are copies
|
|
cmp al,MAX_RLE_COPY
|
|
jle Copy
|
|
|
|
//get size of run
|
|
sub al,MAX_RLE_COPY
|
|
dec ecx
|
|
|
|
//write run packet
|
|
sub ebx,eax
|
|
mov dl,[esi]
|
|
inc esi
|
|
mov dl,[ebp+edx]
|
|
RunMemset:
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz RunMemset
|
|
jmp EOLCheck
|
|
|
|
Copy:
|
|
//write copy packet
|
|
sub ecx,eax
|
|
sub ebx,eax
|
|
CopyMemcpy:
|
|
mov dl,[esi]
|
|
inc esi
|
|
mov dl,[ebp+edx]
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz CopyMemcpy
|
|
|
|
EOLCheck:
|
|
//if at end of line, move dst and reset linecounter
|
|
test ebx,ebx
|
|
jnz NextBlock
|
|
mov ebx,[sgnWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
jmp NextBlock
|
|
|
|
SkipLoop:
|
|
cmp eax,ebx
|
|
jle SingleLineSkip
|
|
mov edx,ebx
|
|
add edi,ebx
|
|
sub eax,ebx
|
|
jmp SkipMem
|
|
SingleLineSkip:
|
|
mov edx,eax
|
|
add edi,eax
|
|
xor eax,eax
|
|
SkipMem:
|
|
//if at end of line, move dst and reset linecounter
|
|
sub ebx,edx
|
|
jnz SkipNotEOL
|
|
mov ebx,[sgnWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
SkipNotEOL:
|
|
//have we finished off this block?
|
|
test eax,eax
|
|
jnz SkipLoop
|
|
|
|
NextBlock:
|
|
test ecx,ecx
|
|
jnz Loop1
|
|
|
|
pop ebp
|
|
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
static void RLEDrawUnitClipped(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth) {
|
|
_asm {
|
|
//**** Assumes _fastcall convention!! ****
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
//eax - copy/run/skip block size
|
|
//ebx - pixels left to draw this line
|
|
//ecx - bytes of RLE data left
|
|
//edx - scratch
|
|
//esi - source RLE data
|
|
//edi - destination buffer
|
|
|
|
mov esi, edx
|
|
mov edi, ecx
|
|
|
|
xor eax, eax
|
|
mov ebx, [nWidth]
|
|
mov ecx, [nDataSize]
|
|
|
|
Loop1:
|
|
mov al,[esi]
|
|
inc esi
|
|
dec ecx
|
|
|
|
//negative packets are copy/runs, nonnegative are skips
|
|
test al,al
|
|
jns SkipLoop
|
|
|
|
neg al
|
|
//packets larger than MAX_RLE_COPY are runs, rest are copies
|
|
cmp al,MAX_RLE_COPY
|
|
jle Copy
|
|
|
|
//get size of run
|
|
sub al,MAX_RLE_COPY
|
|
dec ecx
|
|
|
|
//prepare to write out run packet
|
|
mov dl,[esi]
|
|
inc esi
|
|
|
|
//off end of buffer?
|
|
cmp edi,[glClipY]
|
|
jge SkipLoop
|
|
|
|
sub ebx,eax
|
|
RunMemset:
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz RunMemset
|
|
jmp EOLTest
|
|
|
|
Copy:
|
|
//prepare to write out copy packet
|
|
sub ecx,eax
|
|
|
|
//off end of buffer?
|
|
cmp edi,[glClipY]
|
|
jl PreCopyMemcpy
|
|
add esi,eax
|
|
jmp SkipLoop
|
|
|
|
PreCopyMemcpy:
|
|
sub ebx,eax
|
|
CopyMemcpy:
|
|
mov dl,[esi]
|
|
inc esi
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz CopyMemcpy
|
|
|
|
EOLTest:
|
|
//if at end of line, move dst and reset linecounter
|
|
test ebx,ebx
|
|
jnz NextBlock
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
jmp NextBlock
|
|
|
|
SkipLoop:
|
|
//does skip extend past end of this line?
|
|
cmp eax,ebx
|
|
jle SingleLineSkip
|
|
mov edx,ebx
|
|
add edi,ebx
|
|
sub eax,ebx
|
|
jmp SkipMem
|
|
SingleLineSkip:
|
|
mov edx,eax
|
|
add edi,eax
|
|
xor eax,eax
|
|
SkipMem:
|
|
//if at end of line, move dst and reset linecounter
|
|
sub ebx,edx
|
|
jnz SkipNotEOL
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
SkipNotEOL:
|
|
//have we finished off this block? (skips may span multiple lines)
|
|
test eax,eax
|
|
jnz SkipLoop
|
|
|
|
NextBlock:
|
|
test ecx,ecx
|
|
jnz Loop1
|
|
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
static void RLEDrawOutlineClipped(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE bOutLineColor) {
|
|
_asm {
|
|
//**** Assumes _fastcall convention!! ****
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
//eax - copy/run/skip block size
|
|
//ebx - pixels left to draw this line
|
|
//ecx - bytes of RLE data left
|
|
//dl - outline color
|
|
//dh - scratch
|
|
//esi - source RLE data
|
|
//edi - destination buffer
|
|
|
|
mov esi,edx
|
|
mov edi,ecx
|
|
|
|
xor eax,eax
|
|
mov ebx,[nWidth]
|
|
xor edx,edx
|
|
mov ecx,[nDataSize]
|
|
mov dl, [bOutLineColor]
|
|
|
|
Loop1:
|
|
mov al,[esi]
|
|
inc esi
|
|
dec ecx
|
|
|
|
//negative packets are copy/runs, nonnegative are skips
|
|
test al,al
|
|
jns SkipLoop
|
|
|
|
neg al
|
|
//packets larger than MAX_RLE_COPY are runs, rest are copies
|
|
cmp al,MAX_RLE_COPY
|
|
jle Copy
|
|
|
|
//get size of run
|
|
sub al,MAX_RLE_COPY
|
|
dec ecx
|
|
|
|
//no outline for color zero (shadows)
|
|
mov dh,[esi]
|
|
inc esi
|
|
test dh,dh
|
|
jz SkipLoop
|
|
|
|
//off end of buffer?
|
|
cmp edi,[glClipY]
|
|
jge SkipLoop
|
|
|
|
//write outline for run packet
|
|
mov [edi-1],dl //outline pixel left
|
|
sub ebx,eax
|
|
mov [edi+eax],dl //and right of run
|
|
RunMemset:
|
|
mov [edi-BUFFERX],dl //outline above
|
|
mov [edi+BUFFERX],dl //and below run
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz RunMemset
|
|
jmp EOLCheck
|
|
|
|
Copy:
|
|
sub ecx,eax
|
|
|
|
//off end of buffer?
|
|
cmp edi,[glClipY]
|
|
jl PreCopyMemcpy
|
|
add esi,eax
|
|
jmp SkipLoop
|
|
|
|
PreCopyMemcpy:
|
|
sub ebx,eax
|
|
CopyMemcpy:
|
|
mov dh,[esi]
|
|
inc esi
|
|
//don't draw outline for shadow pixels
|
|
test dh,dh
|
|
jz SkipPixel
|
|
|
|
mov [edi-1],dl //outline pixel left
|
|
mov [edi+1],dl //and right of copy
|
|
mov [edi-BUFFERX],dl //outline above
|
|
mov [edi+BUFFERX],dl //and below copy
|
|
SkipPixel:
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz CopyMemcpy
|
|
|
|
EOLCheck:
|
|
//if at end of line, move dst and reset linecounter
|
|
test ebx,ebx
|
|
jnz NextBlock
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
jmp NextBlock
|
|
|
|
SkipLoop:
|
|
cmp eax,ebx
|
|
jle SingleLineSkip
|
|
mov edx,ebx
|
|
add edi,ebx
|
|
sub eax,ebx
|
|
jmp SkipMem
|
|
SingleLineSkip:
|
|
mov edx,eax
|
|
add edi,eax
|
|
xor eax,eax
|
|
SkipMem:
|
|
//if at end of line, move dst and reset linecounter
|
|
sub ebx,edx
|
|
jnz SkipNotEOL
|
|
mov ebx,[nWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
SkipNotEOL:
|
|
//have we finished off this block?
|
|
test eax,eax
|
|
jnz SkipLoop
|
|
mov dl, [bOutLineColor]
|
|
|
|
NextBlock:
|
|
test ecx,ecx
|
|
jnz Loop1
|
|
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
static void RLEDrawLitUnitClipped(BYTE * pDst, BYTE * pRLEData, int nDataSize, int nWidth, BYTE * pLightTable) {
|
|
_asm {
|
|
//**** Assumes _fastcall convention!! ****
|
|
push ebx
|
|
push esi
|
|
push edi
|
|
|
|
//eax - copy/run/skip block size
|
|
//ebx - pixels left to draw this line
|
|
//ecx - bytes of RLE data left
|
|
//edx - scratch
|
|
//ebp - light table pointer
|
|
//esi - source RLE data
|
|
//edi - destination buffer
|
|
|
|
mov esi, edx
|
|
mov edi, ecx
|
|
|
|
mov ebx, [nWidth]
|
|
mov ecx, [nDataSize]
|
|
mov edx, [pLightTable]
|
|
push ebp
|
|
mov [sgnWidth],ebx //cheesy way to avoid using ebp
|
|
mov ebp,edx
|
|
xor eax,eax
|
|
xor edx,edx
|
|
|
|
Loop1:
|
|
mov al,[esi]
|
|
inc esi
|
|
dec ecx
|
|
|
|
//negative packets are copy/runs, nonnegative are skips
|
|
test al,al
|
|
jns SkipLoop
|
|
|
|
neg al
|
|
//packets larger than MAX_RLE_COPY are runs, rest are copies
|
|
cmp al,MAX_RLE_COPY
|
|
jle Copy
|
|
|
|
//get size of run
|
|
sub al,MAX_RLE_COPY
|
|
dec ecx
|
|
|
|
//prepare to write run packet
|
|
mov dl,[esi]
|
|
inc esi
|
|
mov dl,[ebp+edx]
|
|
|
|
//off end of buffer?
|
|
cmp edi,[glClipY]
|
|
jge SkipLoop
|
|
|
|
sub ebx,eax
|
|
RunMemset:
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz RunMemset
|
|
jmp EOLCheck
|
|
|
|
Copy:
|
|
//write copy packet
|
|
sub ecx,eax
|
|
|
|
//off end of buffer?
|
|
cmp edi,[glClipY]
|
|
jl PreCopyMemcpy
|
|
add esi,eax
|
|
jmp SkipLoop
|
|
|
|
PreCopyMemcpy:
|
|
sub ebx,eax
|
|
CopyMemcpy:
|
|
mov dl,[esi]
|
|
inc esi
|
|
mov dl,[ebp+edx]
|
|
mov [edi],dl
|
|
dec eax
|
|
lea edi,[edi+1]
|
|
jnz CopyMemcpy
|
|
|
|
EOLCheck:
|
|
//if at end of line, move dst and reset linecounter
|
|
test ebx,ebx
|
|
jnz NextBlock
|
|
mov ebx,[sgnWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
jmp NextBlock
|
|
|
|
SkipLoop:
|
|
cmp eax,ebx
|
|
jle SingleLineSkip
|
|
mov edx,ebx
|
|
add edi,ebx
|
|
sub eax,ebx
|
|
jmp SkipMem
|
|
SingleLineSkip:
|
|
mov edx,eax
|
|
add edi,eax
|
|
xor eax,eax
|
|
SkipMem:
|
|
//if at end of line, move dst and reset linecounter
|
|
sub ebx,edx
|
|
jnz SkipNotEOL
|
|
mov ebx,[sgnWidth]
|
|
sub edi,BUFFERX
|
|
sub edi,ebx
|
|
SkipNotEOL:
|
|
//have we finished off this block?
|
|
test eax,eax
|
|
jnz SkipLoop
|
|
|
|
NextBlock:
|
|
test ecx,ecx
|
|
jnz Loop1
|
|
|
|
pop ebp
|
|
|
|
pop edi
|
|
pop esi
|
|
pop ebx
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
static BYTE LevelUnitPixel(const BYTE *row, int x, int width, BYTE *pLightTable)
|
|
{
|
|
BYTE pixel, src;
|
|
int left, right, curr, nearAvg, darkest;
|
|
|
|
src = row[x];
|
|
if (src == 0)
|
|
return 0;
|
|
|
|
pixel = gbLevelUnitContrastTable[src];
|
|
if (pLightTable != NULL)
|
|
pixel = pLightTable[pixel];
|
|
|
|
if (x <= 0 || x + 1 >= width)
|
|
return pixel;
|
|
|
|
left = gbLevelUnitLumaTable[row[x - 1]];
|
|
right = gbLevelUnitLumaTable[row[x + 1]];
|
|
curr = gbLevelUnitLumaTable[src];
|
|
nearAvg = (left + right) >> 1;
|
|
darkest = (left < right) ? left : right;
|
|
|
|
if (nearAvg - curr > 10)
|
|
return gbLevelUnitAoTable[pixel];
|
|
if (curr - darkest > 16 && curr < 230)
|
|
return gbLevelUnitAoTable[pixel];
|
|
if (curr - nearAvg > 18)
|
|
return gbLevelUnitSharpenLightTable[pixel];
|
|
|
|
return pixel;
|
|
}
|
|
|
|
static BOOL UseLevelUnitEnhance();
|
|
|
|
static void RLEDrawEnhancedUnit(BYTE *pDst, BYTE *pRLEData, int nDataSize, int nWidth, BYTE *pLightTable, BOOL clipped)
|
|
{
|
|
BYTE row[BUFFERX];
|
|
BYTE mask[BUFFERX];
|
|
BYTE *pSrc, *pRowDst;
|
|
int remaining, rowLeft, x, i;
|
|
signed char packet;
|
|
BYTE pixel;
|
|
int count;
|
|
|
|
if (nWidth <= 0 || nWidth > BUFFERX) {
|
|
if (pLightTable != NULL) {
|
|
if (clipped)
|
|
RLEDrawLitUnitClipped(pDst, pRLEData, nDataSize, nWidth, pLightTable);
|
|
else
|
|
RLEDrawLitUnit(pDst, pRLEData, nDataSize, nWidth, pLightTable);
|
|
}
|
|
else {
|
|
if (clipped)
|
|
RLEDrawUnitClipped(pDst, pRLEData, nDataSize, nWidth);
|
|
else
|
|
RLEDrawUnit(pDst, pRLEData, nDataSize, nWidth);
|
|
}
|
|
return;
|
|
}
|
|
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
pSrc = pRLEData;
|
|
pRowDst = pDst;
|
|
remaining = nDataSize;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
|
|
while (remaining > 0) {
|
|
packet = (signed char)*pSrc++;
|
|
remaining--;
|
|
|
|
if (packet >= 0) {
|
|
count = packet;
|
|
while (count > 0) {
|
|
i = (count < rowLeft) ? count : rowLeft;
|
|
x += i;
|
|
rowLeft -= i;
|
|
count -= i;
|
|
|
|
if (rowLeft == 0) {
|
|
if (!clipped || pRowDst < (BYTE *)glClipY) {
|
|
for (i = 0; i < nWidth; i++) {
|
|
if (mask[i])
|
|
pRowDst[i] = LevelUnitPixel(row, i, nWidth, pLightTable);
|
|
}
|
|
}
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
pRowDst -= BUFFERX;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
count = -packet;
|
|
if (count > MAX_RLE_COPY) {
|
|
count -= MAX_RLE_COPY;
|
|
if (remaining <= 0)
|
|
break;
|
|
pixel = *pSrc++;
|
|
remaining--;
|
|
while (count-- > 0) {
|
|
row[x] = pixel;
|
|
mask[x] = TRUE;
|
|
x++;
|
|
rowLeft--;
|
|
|
|
if (rowLeft == 0) {
|
|
if (!clipped || pRowDst < (BYTE*)glClipY) {
|
|
for (i = 0; i < nWidth; i++) {
|
|
if (mask[i])
|
|
pRowDst[i] = LevelUnitPixel(row, i, nWidth, pLightTable);
|
|
}
|
|
}
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
pRowDst -= BUFFERX;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
while (count-- > 0 && remaining > 0) {
|
|
pixel = *pSrc++;
|
|
remaining--;
|
|
row[x] = pixel;
|
|
mask[x] = TRUE;
|
|
x++;
|
|
rowLeft--;
|
|
|
|
if (rowLeft == 0) {
|
|
if (!clipped || pRowDst < (BYTE*)glClipY) {
|
|
for (i = 0; i < nWidth; i++) {
|
|
if (mask[i])
|
|
pRowDst[i] = LevelUnitPixel(row, i, nWidth, pLightTable);
|
|
}
|
|
}
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
pRowDst -= BUFFERX;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static void RLEDrawUnitLerpOverlay(BYTE *pDst, BYTE *pRLEData, int nDataSize, int nWidth, BYTE *pLightTable, BOOL clipped, int density)
|
|
{
|
|
BYTE row[BUFFERX];
|
|
BYTE mask[BUFFERX];
|
|
BYTE *pSrc, *pRowDst;
|
|
int remaining, rowLeft, x, i, y;
|
|
signed char packet;
|
|
BYTE pixel;
|
|
int count;
|
|
BOOL enhanced;
|
|
|
|
if (density <= 0)
|
|
return;
|
|
if (density > 3)
|
|
density = 3;
|
|
if (nWidth <= 0 || nWidth > BUFFERX)
|
|
return;
|
|
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
enhanced = UseLevelUnitEnhance();
|
|
pSrc = pRLEData;
|
|
pRowDst = pDst;
|
|
remaining = nDataSize;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
y = 0;
|
|
|
|
while (remaining > 0) {
|
|
packet = (signed char)*pSrc++;
|
|
remaining--;
|
|
|
|
if (packet >= 0) {
|
|
count = packet;
|
|
while (count > 0) {
|
|
i = (count < rowLeft) ? count : rowLeft;
|
|
x += i;
|
|
rowLeft -= i;
|
|
count -= i;
|
|
|
|
if (rowLeft == 0) {
|
|
if (!clipped || pRowDst < (BYTE*)glClipY) {
|
|
for (i = 0; i < nWidth; i++) {
|
|
if (mask[i] && (((i + y) & 3) < density))
|
|
pRowDst[i] = enhanced ? LevelUnitPixel(row, i, nWidth, pLightTable) : (pLightTable ? pLightTable[row[i]] : row[i]);
|
|
}
|
|
}
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
pRowDst -= BUFFERX;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
y++;
|
|
}
|
|
}
|
|
continue;
|
|
}
|
|
|
|
count = -packet;
|
|
if (count > MAX_RLE_COPY) {
|
|
count -= MAX_RLE_COPY;
|
|
if (remaining <= 0)
|
|
break;
|
|
pixel = *pSrc++;
|
|
remaining--;
|
|
while (count-- > 0) {
|
|
row[x] = pixel;
|
|
mask[x] = TRUE;
|
|
x++;
|
|
rowLeft--;
|
|
|
|
if (rowLeft == 0) {
|
|
if (!clipped || pRowDst < (BYTE*)glClipY) {
|
|
for (i = 0; i < nWidth; i++) {
|
|
if (mask[i] && (((i + y) & 3) < density))
|
|
pRowDst[i] = enhanced ? LevelUnitPixel(row, i, nWidth, pLightTable) : (pLightTable ? pLightTable[row[i]] : row[i]);
|
|
}
|
|
}
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
pRowDst -= BUFFERX;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
y++;
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
while (count-- > 0 && remaining > 0) {
|
|
pixel = *pSrc++;
|
|
remaining--;
|
|
row[x] = pixel;
|
|
mask[x] = TRUE;
|
|
x++;
|
|
rowLeft--;
|
|
|
|
if (rowLeft == 0) {
|
|
if (!clipped || pRowDst < (BYTE*)glClipY) {
|
|
for (i = 0; i < nWidth; i++) {
|
|
if (mask[i] && (((i + y) & 3) < density))
|
|
pRowDst[i] = enhanced ? LevelUnitPixel(row, i, nWidth, pLightTable) : (pLightTable ? pLightTable[row[i]] : row[i]);
|
|
}
|
|
}
|
|
memset(row, 0, nWidth);
|
|
memset(mask, 0, nWidth);
|
|
pRowDst -= BUFFERX;
|
|
rowLeft = nWidth;
|
|
x = 0;
|
|
y++;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
static BOOL UseLevelUnitEnhance()
|
|
{
|
|
return gbLevelTileEnhanceActive && leveltype != 0;
|
|
}
|
|
|
|
static void DrawEnhancedUnitCommon(
|
|
long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, BYTE *pLightTable, BOOL clipped)
|
|
{
|
|
BYTE *pDst, *pSrc;
|
|
DWORD *pFrameTable;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int)pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel + 1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart * 16] + xp;
|
|
|
|
if (UseLevelUnitEnhance()) {
|
|
RLEDrawEnhancedUnit(pDst, pSrc, RLELen, nCelW, pLightTable, clipped);
|
|
return;
|
|
}
|
|
|
|
if (pLightTable != NULL) {
|
|
if (clipped)
|
|
RLEDrawLitUnitClipped(pDst, pSrc, RLELen, nCelW, pLightTable);
|
|
else
|
|
RLEDrawLitUnit(pDst, pSrc, RLELen, nCelW, pLightTable);
|
|
}
|
|
else {
|
|
if (clipped)
|
|
RLEDrawUnitClipped(pDst, pSrc, RLELen, nCelW);
|
|
else
|
|
RLEDrawUnit(pDst, pSrc, RLELen, nCelW);
|
|
}
|
|
}
|
|
|
|
static void DrawUnitLerpOverlayCommon(
|
|
long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, BYTE *pLightTable, BOOL clipped, int density)
|
|
{
|
|
BYTE *pDst, *pSrc;
|
|
DWORD *pFrameTable;
|
|
long RLELen, offval, offval2;
|
|
|
|
if (density <= 0)
|
|
return;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int)pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel + 1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart * 16] + xp;
|
|
RLEDrawUnitLerpOverlay(pDst, pSrc, RLELen, nCelW, pLightTable, clipped, density);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawUnit (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend)
|
|
{
|
|
BYTE *pDst, *pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, nFrameStart, nFrameEnd;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
nFrameStart = *(WORD*)(pSrc + ostart);
|
|
if (!nFrameStart)
|
|
return;
|
|
nFrameEnd = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (nFrameEnd ? nFrameEnd : pFrameTable[nCel+1] - pFrameTable[nCel]) - nFrameStart;
|
|
pSrc += nFrameStart;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp;
|
|
RLEDrawUnit(pDst, pSrc, RLELen, nCelW);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawUnitOutline(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE * pDst, * pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp;
|
|
RLEDrawOutline(pDst,pSrc,RLELen,nCelW,ocolor);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawInfraUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff)
|
|
{
|
|
BYTE * pDst, * pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, offval, offval2, ltaboff;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp;
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
RLEDrawLitUnit(pDst,pSrc,RLELen,nCelW,pLightTbl+ltaboff);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawLitUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE * pDst, * pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp;
|
|
if (nLVal)
|
|
RLEDrawLitUnit(pDst,pSrc,RLELen,nCelW,pLightTbl + (nLVal << 8));
|
|
else
|
|
RLEDrawUnit(pDst,pSrc,RLELen,nCelW);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawUnitClipped (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend)
|
|
{
|
|
BYTE * pDst, * pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp;
|
|
RLEDrawUnitClipped(pDst, pSrc, RLELen, nCelW);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawUnitOutlineClipped(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE * pDst, * pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp;
|
|
glClipY -= BUFFERX;
|
|
RLEDrawOutlineClipped(pDst,pSrc,RLELen,nCelW,ocolor);
|
|
glClipY += BUFFERX;
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawInfraUnitClipped(
|
|
long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff)
|
|
{
|
|
BYTE * pDst, * pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, offval, offval2, ltaboff;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - ostart*16] + xp;
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
RLEDrawLitUnitClipped(pDst,pSrc,RLELen,nCelW,pLightTbl + ltaboff);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawLitUnitClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
BYTE * pDst, * pSrc;
|
|
DWORD * pFrameTable;
|
|
long RLELen, offval, offval2;
|
|
|
|
app_assert(gpBuffer != NULL);
|
|
app_assert(pCelBuff != NULL);
|
|
app_assert(nCel > 0);
|
|
// jcm.patch1.start.1/14/97
|
|
#ifdef GRACEFUL_EXIT
|
|
if (gpBuffer == NULL || pCelBuff == NULL || nCel <= 0)
|
|
return;
|
|
#endif
|
|
// jcm.patch1.end.1/14/97
|
|
|
|
pFrameTable = (DWORD*)pCelBuff;
|
|
app_assert(nCel <= (int) pFrameTable[0]);
|
|
pSrc = pCelBuff + pFrameTable[nCel];
|
|
offval = *(WORD*)(pSrc + ostart);
|
|
if (!offval)
|
|
return;
|
|
offval2 = (oend == 8) ? 0 : *(WORD*)(pSrc + oend);
|
|
RLELen = (offval2 ? offval2 : pFrameTable[nCel+1] - pFrameTable[nCel]) - offval;
|
|
pSrc += offval;
|
|
pDst = gpBuffer + nBuffWTbl[yp - (ostart << 4)] + xp;
|
|
if (nLVal)
|
|
RLEDrawLitUnitClipped(pDst,pSrc,RLELen,nCelW,pLightTbl + (nLVal << 8));
|
|
else
|
|
RLEDrawUnitClipped(pDst,pSrc,RLELen,nCelW);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawEnhancedUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
DrawEnhancedUnitCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, NULL, FALSE);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawUnitLerpOverlay(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, int density)
|
|
{
|
|
DrawUnitLerpOverlayCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, NULL, FALSE, density);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawEnhancedUnitClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
DrawEnhancedUnitCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, NULL, TRUE);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawUnitLerpOverlayClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, int density)
|
|
{
|
|
DrawUnitLerpOverlayCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, NULL, TRUE, density);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawEnhancedLitUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
DrawEnhancedUnitCommon(
|
|
xp,
|
|
yp,
|
|
pCelBuff,
|
|
nCel,
|
|
nCelW,
|
|
ostart,
|
|
oend,
|
|
nLVal ? pLightTbl + (nLVal << 8) : NULL,
|
|
FALSE);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawLitUnitLerpOverlay(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, int density)
|
|
{
|
|
DrawUnitLerpOverlayCommon(
|
|
xp,
|
|
yp,
|
|
pCelBuff,
|
|
nCel,
|
|
nCelW,
|
|
ostart,
|
|
oend,
|
|
nLVal ? pLightTbl + (nLVal << 8) : NULL,
|
|
FALSE,
|
|
density);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawEnhancedLitUnitClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend)
|
|
{
|
|
DrawEnhancedUnitCommon(
|
|
xp,
|
|
yp,
|
|
pCelBuff,
|
|
nCel,
|
|
nCelW,
|
|
ostart,
|
|
oend,
|
|
nLVal ? pLightTbl + (nLVal << 8) : NULL,
|
|
TRUE);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawLitUnitLerpOverlayClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, int density)
|
|
{
|
|
DrawUnitLerpOverlayCommon(
|
|
xp,
|
|
yp,
|
|
pCelBuff,
|
|
nCel,
|
|
nCelW,
|
|
ostart,
|
|
oend,
|
|
nLVal ? pLightTbl + (nLVal << 8) : NULL,
|
|
TRUE,
|
|
density);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawEnhancedInfraUnit(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff)
|
|
{
|
|
long ltaboff;
|
|
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
DrawEnhancedUnitCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, pLightTbl + ltaboff, FALSE);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawInfraUnitLerpOverlay(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff, int density)
|
|
{
|
|
long ltaboff;
|
|
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
DrawUnitLerpOverlayCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, pLightTbl + ltaboff, FALSE, density);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawEnhancedInfraUnitClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff)
|
|
{
|
|
long ltaboff;
|
|
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
DrawEnhancedUnitCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, pLightTbl + ltaboff, TRUE);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
#if RLE_DRAW
|
|
void DrawInfraUnitLerpOverlayClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, char loff, int density)
|
|
{
|
|
long ltaboff;
|
|
|
|
ltaboff = light4flag ? 1024 : 4096;
|
|
if (loff == LIGHT_STONE)
|
|
ltaboff += 256;
|
|
if (loff >= LIGHT_U)
|
|
ltaboff += ((loff - LIGHT_U) << 8) + 768;
|
|
DrawUnitLerpOverlayCommon(xp, yp, pCelBuff, nCel, nCelW, ostart, oend, pLightTbl + ltaboff, TRUE, density);
|
|
}
|
|
#endif
|
|
|
|
|
|
//*************************************************************************
|
|
//*************************************************************************
|
|
void play_movie(const char * pszMovie,BOOL bAllowCancel);
|
|
void PlayInGameMovie(const char * pszMovie) {
|
|
PaletteFadeOut(FADE_FAST);
|
|
play_movie(pszMovie,FALSE);
|
|
ClrDraw();
|
|
force_redraw = FULLDRAW;
|
|
FullBlit(TRUE);
|
|
PaletteFadeIn(FADE_FAST);
|
|
force_redraw = FULLDRAW;
|
|
}
|