Files
Hellfire/TOWN.CPP
T
2026-05-30 02:50:21 -07:00

2028 lines
49 KiB
C++

/*-----------------------------------------------------------------------**
** Diablo
**
** Town file
**
** (C)1995 Condor, Inc. All rights reserved.
**
**-----------------------------------------------------------------------**
** $Header: /Diablo/TOWN.CPP 2 1/23/97 12:21p Jmorin $
**-----------------------------------------------------------------------**
**
** File Routines
**-----------------------------------------------------------------------*/
#include "diablo.h"
#pragma hdrstop
#include "sound.h"
#include "engine.h"
#include "scrollrt.h"
#include "scrlasm.h"
#include "gendung.h"
#include "items.h"
#include "cursor.h"
#include "trigs.h"
#include "control.h"
#include "gamemenu.h"
#include "player.h"
#include "monster.h"
#include "town.h"
#include "towners.h"
#include "inv.h"
#include "quests.h"
#include "minitext.h"
#include "stores.h"
#include "effects.h"
#include "automap.h"
#include "help.h"
#include "error.h"
#include "doom.h"
#include "multi.h"
#define T_POUTC 165
#define TOWN_PLAYER_LIGHT 1
// #define TESTINGCRYPT // JKE set this to keep the crypt open
#if RLE_DRAW
void DrawUnit (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend);
void DrawLitUnit (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend);
void DrawLitUnitLerpOverlay(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, int density);
void DrawUnitClipped (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend);
void DrawLitUnitClipped (long xp,long yp,BYTE *pCelBuff,long nCel,long nCelW,long ostart,long oend);
void DrawLitUnitLerpOverlayClipped(long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, int density);
void DrawUnitOutline(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend);
void DrawUnitOutlineClipped(byte ocolor, long xp, long yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend);
#endif
extern "C" {
extern int gnTownTileX;
extern int gnTownTileY;
extern int gnTownFlickerFrame;
}
extern int gnRenderFrameInterp;
extern int PlrWalkLenTbl[NUM_CLASSES];
static void T_DrawHTLXsub (BYTE *pTo, int sx, int sy, int xp, int yp, BOOL chflag);
static void T_DrawHTLXsub2 (BYTE *pTo, int sx, int sy, int sv, int sv2, int xp, int yp, BOOL chflag);
static void T_DrawHTLXsub3 (BYTE *pTo, int sx, int sy, int ev, int ev2, int xp, int yp, BOOL chflag);
static void T_DrawPlayerTownUnit(PlayerStruct *pPlayer, int xp, int yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, BOOL clipped);
void ApplyWorldGoldShimmer(ItemStruct *pItem, int itemIndex, int x, int y, int ostart, int oend);
void plrmsg_draw();
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void T_SetTownTile(int sx, int sy)
{
gnTownTileX = sx;
gnTownTileY = sy;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int T_VisualHalfStep(long velocity)
{
int interp;
__int64 step;
interp = gnRenderFrameInterp;
if (interp <= 0 || velocity == 0)
return 0;
if (interp > 256)
interp = 256;
step = velocity;
if (step < 0)
return -(int)(((-step) * interp) >> 16);
return (int)((step * interp) >> 16);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BOOL T_PlayerUsesVisualLerp(PlayerStruct *pPlayer)
{
return pPlayer->_pmode == PM_WALK
|| pPlayer->_pmode == PM_WALK2
|| pPlayer->_pmode == PM_WALK3;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static BOOL T_PlayerHasVisualStep(PlayerStruct *pPlayer)
{
int walkLen;
walkLen = 8;
if (currlevel != 0)
walkLen = PlrWalkLenTbl[pPlayer->_pClass];
return pPlayer->_pVar8 < walkLen;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int T_GetPlayerDrawX(PlayerStruct *pPlayer, int xp)
{
xp += pPlayer->_pxoff;
if (T_PlayerUsesVisualLerp(pPlayer) && T_PlayerHasVisualStep(pPlayer))
xp += T_VisualHalfStep(pPlayer->_pxvel);
return xp;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int T_GetPlayerDrawY(PlayerStruct *pPlayer, int yp)
{
yp += pPlayer->_pyoff;
if (T_PlayerUsesVisualLerp(pPlayer) && T_PlayerHasVisualStep(pPlayer))
yp += T_VisualHalfStep(pPlayer->_pyvel);
return yp;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int T_GetScrollDrawX()
{
int sxoff;
PlayerStruct *pPlayer;
sxoff = ScrollInfo._sxoff;
if (ScrollInfo._sdir == SCRL_NONE)
return sxoff;
pPlayer = &plr[myplr];
if (T_PlayerUsesVisualLerp(pPlayer) && T_PlayerHasVisualStep(pPlayer))
sxoff -= T_VisualHalfStep(pPlayer->_pxvel);
return sxoff;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int T_GetScrollDrawY()
{
int syoff;
PlayerStruct *pPlayer;
syoff = ScrollInfo._syoff;
if (ScrollInfo._sdir == SCRL_NONE)
return syoff;
pPlayer = &plr[myplr];
if (T_PlayerUsesVisualLerp(pPlayer) && T_PlayerHasVisualStep(pPlayer))
syoff -= T_VisualHalfStep(pPlayer->_pyvel);
return syoff;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int T_GetVisualLerpDensity(int animCnt, int animDelay)
{
int interp;
int progress;
int density;
if (animDelay <= 1)
return 0;
interp = gnRenderFrameInterp;
if (interp < 0)
interp = 0;
if (interp > 256)
interp = 256;
progress = animCnt * 256 + interp;
density = (progress * 4) / (animDelay * 256);
if (density < 1)
return 0;
if (density > 3)
density = 3;
return density;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static int T_GetPlayerLerpFrame(PlayerStruct *pPlayer, int *density)
{
int frame;
*density = T_GetVisualLerpDensity(pPlayer->_pAnimCnt, pPlayer->_pAnimDelay);
if (*density == 0)
return 0;
frame = pPlayer->_pAnimFrame + 1;
if (frame > pPlayer->_pAnimLen)
return 0;
return frame;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void T_DrawPlayerTownUnit(PlayerStruct *pPlayer, int xp, int yp, BYTE *pCelBuff, long nCel, long nCelW, long ostart, long oend, BOOL clipped)
{
long oldnLVal;
int density, nextFrame;
oldnLVal = nLVal;
nLVal = TOWN_PLAYER_LIGHT;
#if RLE_DRAW
if (clipped)
DrawLitUnitClipped(xp, yp, pCelBuff, nCel, nCelW, ostart, oend);
else
DrawLitUnit(xp, yp, pCelBuff, nCel, nCelW, ostart, oend);
nextFrame = T_GetPlayerLerpFrame(pPlayer, &density);
if (nextFrame) {
if (clipped)
DrawLitUnitLerpOverlayClipped(xp, yp, pCelBuff, nextFrame, nCelW, ostart, oend, density);
else
DrawLitUnitLerpOverlay(xp, yp, pCelBuff, nextFrame, nCelW, ostart, oend, density);
}
#else
if (clipped)
CDrawSlabCelL(xp, yp, pCelBuff, nCel, nCelW, ostart, oend);
else
DrawSlabCelL(xp, yp, pCelBuff, nCel, nCelW, ostart, oend);
#endif
nLVal = oldnLVal;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void TDrawBlankMini(BYTE *pDecodeTo)
{
app_assert(gpBuffer);
__asm {
mov edi,dword ptr [pDecodeTo] // Dest
mov edx,30
mov ebx,1
xor eax,eax
//mov eax,0d3d3d3d3h
_BLp1: cmp edi,dword ptr [glClipY]
jb _Done
add edi,edx
mov ecx,ebx
rep stosd
add edi,edx
sub edi,NBUFFW64
or edx,edx
jz _Bb
sub edx,2
inc ebx
jmp _BLp1
_Bb: mov edx,2
mov ebx,15
_BLp2: cmp edi,dword ptr [glClipY]
jb _Done
add edi,edx
mov ecx,ebx
rep stosd
add edi,edx
sub edi,NBUFFW64
dec ebx
add edx,2
cmp edx,32
jnz _BLp2
_Done: nop
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void TCDrawBlankMini(BYTE *pDecodeTo)
{
app_assert(gpBuffer);
__asm {
mov edi,dword ptr [pDecodeTo] // Dest
mov edx,30
mov ebx,1
xor eax,eax
//mov eax,0d3d3d3d3h
_BLp1: cmp edi,dword ptr [glClipY]
jb _C1
add edi,64
jmp _C2
_C1: add edi,edx
mov ecx,ebx
rep stosd
add edi,edx
_C2: sub edi,NBUFFW64
or edx,edx
jz _Bb
sub edx,2
inc ebx
jmp _BLp1
_Bb: mov edx,2
mov ebx,15
_BLp2: cmp edi,dword ptr [glClipY]
jb _C3
add edi,64
jmp _C4
_C3: add edi,edx
mov ecx,ebx
rep stosd
add edi,edx
_C4: sub edi,NBUFFW64
dec ebx
add edx,2
cmp edx,32
jnz _BLp2
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_CDrawSpecial(BYTE *pTo, long nCel)
{
/*
long RLELen;
long nBufferW;
app_assert(gpBuffer);
__asm {
mov ebx,dword ptr [pSpecialCels]
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 esi,dword ptr [pSpecialCels]
add esi,dword ptr [ebx]
mov edi,dword ptr [pTo] // Dest
mov eax,832 // Increase width
mov dword ptr [nBufferW],eax
mov ebx,dword ptr [RLELen]
add ebx,esi
_T1Lp1: mov edx,64
_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
}
*/
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawSpecial(BYTE *pTo, int nCel)
{
/*
long RLELen;
long nBufferW;
app_assert(gpBuffer);
__asm {
mov ebx,dword ptr [pSpecialCels]
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 esi,dword ptr [pSpecialCels]
add esi,dword ptr [ebx]
mov edi,dword ptr [pTo] // Dest
mov eax,832 // Increase width
mov dword ptr [nBufferW],eax
mov ebx,dword ptr [RLELen]
add ebx,esi
_T1Lp1: mov edx,64
_T1Lp2: xor eax,eax // Load control byte
lodsb
or al,al
js _T1J
sub edx,eax
cmp edi,dword ptr [glClipY]
jb _Done
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
_Done: nop
}
*/
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawEFlag1(BYTE *pTo2, int sx, int sy, int xp, int yp)
{
BYTE *pTo;
int t;
WORD *mt;
pTo = pTo2;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 12; t += 2)
{
if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo);
if (gdwPNum = mt[t+1]) DrawMTileClipBottom (pTo+32);
pTo -= NBUFFWSL5;
}
T_DrawHTLXsub (pTo2, sx, sy, xp, yp, FALSE);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void T_DrawHTLXsub (BYTE *pTo, int sx, int sy, int xp, int yp, BOOL chflag)
{
int pxp,pyp;
char bv;
int mi;
app_assert(gpBuffer);
pTo = gpBuffer + nBuffWTbl[yp] + xp;
if (dItem[sx][sy] != 0) {
bv = dItem[sx][sy] - 1;
pxp = xp - item[bv]._iAnimWidth2;
if (bv == cursitem) COutlineSlabCel(181, pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, 8);
CDrawSlabCel(pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, 8);
ApplyWorldGoldShimmer(&item[bv], bv, pxp, yp, 0, 8);
}
if ((dFlags[sx][sy] & BFLAG_MONSTLR) != 0) {
mi = -(dMonster[sx][sy-1] + 1);
pxp = xp - towner[mi]._tAnimWidth2;
pyp = yp;
if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8);
CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8);
}
if (dMonster[sx][sy] > 0) {
mi = dMonster[sx][sy] - 1;
pxp = xp - towner[mi]._tAnimWidth2;
pyp = yp;
if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8);
CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, 8);
}
if ((dFlags[sx][sy] & BFLAG_PLRLR) != 0) {
bv = -(dPlayer[sx][sy-1] + 1);
pxp = T_GetPlayerDrawX(&plr[bv], xp) - plr[bv]._pAnimWidth2;
pyp = T_GetPlayerDrawY(&plr[bv], yp);
#if RLE_DRAW
if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8);
#else
if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8);
#endif
T_DrawPlayerTownUnit(&plr[bv], pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8, TRUE);
if (chflag)
{
// if (plr[bv]._peflag == 2) T_DrawEFlag1(pTo-NBUFFWSL4+96, sx-2, sy+1, xp-96, yp-16);
if (plr[bv]._peflag != 0) T_DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp);
}
}
if (dFlags[sx][sy] & BFLAG_DEADPLR)
DrawDeadPlr(sx, sy, xp, yp, 0, 8, TRUE);
if (dPlayer[sx][sy] > 0) {
bv = dPlayer[sx][sy] - 1;
pxp = T_GetPlayerDrawX(&plr[bv], xp) - plr[bv]._pAnimWidth2;
pyp = T_GetPlayerDrawY(&plr[bv], yp);
#if RLE_DRAW
if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8);
#else
if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8);
#endif
T_DrawPlayerTownUnit(&plr[bv], pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, 8, TRUE);
if (chflag)
{
// if (plr[bv]._peflag == 2) T_DrawEFlag1(pTo-NBUFFWSL4+96, sx-2, sy+1, xp-96, yp-16);
if (plr[bv]._peflag != 0) T_DrawEFlag1(pTo-64, sx-1, sy+1, xp-64, yp);
}
}
if ((dFlags[sx][sy] & BFLAG_MISSILE) != 0) CDrawMissile(sx, sy, xp, yp, 0, 8, FALSE);
if (dSpecial[sx][sy]) T_CDrawSpecial(pTo, dSpecial[sx][sy]);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawHTileLineX (int sx, int sy, int xp, int yp, int nd, int halfflag)
{
int i;
BYTE *pTo;
int t;
WORD *mt;
app_assert(gpBuffer);
if (halfflag != 0) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
if (gdwPNum = dPiece[sx][sy]) {
pTo = gpBuffer + nBuffWTbl[yp] + xp + 32;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 1; t < 17; t += 2)
{
if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo);
pTo -= NBUFFWSL5;
}
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub (pTo, sx, sy, xp, yp, FALSE);
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
sx++;
sy--;
xp += 64;
}
nd -= halfflag;
for (i = 0; i < nd; i++) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
gdwPNum = dPiece[sx][sy];
if (gdwPNum != 0) {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 16; t+= 2)
{
if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo);
if (gdwPNum = mt[t+1]) DrawMTileClipBottom (pTo+32);
pTo -= NBUFFWSL5;
}
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub (pTo, sx, sy, xp, yp, TRUE);
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
sx++;
sy--;
xp += 64;
}
if (halfflag != 0) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
gdwPNum = dPiece[sx][sy];
if (gdwPNum != 0) {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 16; t+= 2)
{
if (gdwPNum = mt[t]) DrawMTileClipBottom (pTo);
pTo -= NBUFFWSL5;
}
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub (pTo, sx, sy, xp, yp, FALSE);
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawEFlag2(BYTE *pTo2, int sx, int sy, int sv, int sv2, int xp, int yp)
{
BYTE *pTo;
int t;
WORD *mt;
if (sv == 0) pTo = pTo2;
else
pTo = pTo2 + (NBUFFWSL5 * sv);
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 6; t++)
{
if (sv <= t) {
if (gdwPNum = mt[2*t+2]) DrawMTileClipBottom (pTo);
if (gdwPNum = mt[2*t+3]) DrawMTileClipBottom (pTo+32);
}
pTo -= NBUFFWSL5;
}
if (sv2 < 8) {
T_DrawHTLXsub2 (pTo2, sx, sy, sv, sv2, xp, yp, FALSE);
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void T_DrawHTLXsub2 (BYTE *pTo, int sx, int sy, int sv, int sv2, int xp, int yp, BOOL chflag)
{
int pxp,pyp;
char bv;
int mi;
if (dItem[sx][sy] != 0) {
bv = dItem[sx][sy] - 1;
pxp = xp - item[bv]._iAnimWidth2;
if (bv == cursitem) COutlineSlabCel(181, pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, sv2, 8);
CDrawSlabCel(pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, sv2, 8);
ApplyWorldGoldShimmer(&item[bv], bv, pxp, yp, sv2, 8);
}
if ((dFlags[sx][sy] & BFLAG_MONSTLR) != 0) {
mi = -(dMonster[sx][sy-1] + 1);
pxp = xp - towner[mi]._tAnimWidth2;
pyp = yp;
if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8);
CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8);
}
if (dMonster[sx][sy] > 0) {
mi = dMonster[sx][sy] - 1;
pxp = xp - towner[mi]._tAnimWidth2;
pyp = yp;
if (mi == cursmonst) COutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8);
CDrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, sv2, 8);
}
if ((dFlags[sx][sy] & BFLAG_PLRLR) != 0) {
bv = -(dPlayer[sx][sy-1] + 1);
pxp = T_GetPlayerDrawX(&plr[bv], xp) - plr[bv]._pAnimWidth2;
pyp = T_GetPlayerDrawY(&plr[bv], yp);
#if RLE_DRAW
if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8);
#else
if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8);
#endif
T_DrawPlayerTownUnit(&plr[bv], pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8, TRUE);
if (chflag)
{
// if (plr[bv]._peflag == 2) T_DrawEFlag2(pTo-NBUFFWSL4+96, sx-2, sy+1, sv, sv2, xp-96, yp-16);
if (plr[bv]._peflag != 0) T_DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp);
}
}
if (dFlags[sx][sy] & BFLAG_DEADPLR)
DrawDeadPlr(sx, sy, xp, yp, sv2, 8, TRUE);
if (dPlayer[sx][sy] > 0) {
bv = dPlayer[sx][sy] - 1;
pxp = T_GetPlayerDrawX(&plr[bv], xp) - plr[bv]._pAnimWidth2;
pyp = T_GetPlayerDrawY(&plr[bv], yp);
#if RLE_DRAW
if (bv == cursplr) DrawUnitOutlineClipped(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8);
#else
if (bv == cursplr) COutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8);
#endif
T_DrawPlayerTownUnit(&plr[bv], pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, sv2, 8, TRUE);
if (chflag)
{
// if (plr[bv]._peflag == 2) T_DrawEFlag2(pTo-NBUFFWSL4+96, sx-2, sy+1, sv, sv2, xp-96, yp-16);
if (plr[bv]._peflag != 0) T_DrawEFlag2(pTo-64, sx-1, sy+1, sv, sv2, xp-64, yp);
}
}
if ((dFlags[sx][sy] & BFLAG_MISSILE) != 0) CDrawMissile(sx, sy, xp, yp, sv2, 8, FALSE);
if (dSpecial[sx][sy]) T_CDrawSpecial(pTo+nBuffWTbl[sv2<<4], dSpecial[sx][sy]);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawHTLX2 (int sx, int sy, int xp, int yp, int nd, int sv, int halfflag)
{
int i;
BYTE *pTo;
int sv2;
int t;
WORD *mt;
app_assert(gpBuffer);
sv2 = (sv + 1) << 1;
if (halfflag != 0) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
if (gdwPNum = dPiece[sx][sy]) {
pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5 + 32;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 7; t++)
{
if ((sv <= t) && (gdwPNum = mt[2*t+3])) DrawMTileClipBottom (pTo);
pTo -= NBUFFWSL5;
}
if (sv2 < 8) {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, FALSE);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
sx++;
sy--;
xp += 64;
}
nd -= halfflag;
for (i = 0; i < nd; i++) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
gdwPNum = dPiece[sx][sy];
if (gdwPNum != 0) {
pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 7; t++)
{
if (sv <= t) {
if (gdwPNum = mt[2*t+2]) DrawMTileClipBottom (pTo);
if (gdwPNum = mt[2*t+3]) DrawMTileClipBottom (pTo+32);
}
pTo -= NBUFFWSL5;
}
if (sv2 < 8) {
pTo = gpBuffer + nBuffWTbl[yp] + xp - (sv2 * NBUFFWSL4);
T_DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, TRUE);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
sx++;
sy--;
xp += 64;
}
if (halfflag != 0) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
gdwPNum = dPiece[sx][sy];
if (gdwPNum != 0) {
pTo = gpBuffer + nBuffWTbl[yp] + xp - NBUFFWSL5;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 7; t++)
{
if ((sv <= t) && (gdwPNum = mt[2*t+2])) DrawMTileClipBottom (pTo);
pTo -= NBUFFWSL5;
}
if (sv2 < 8) {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub2 (pTo, sx, sy, sv, sv2, xp, yp, FALSE);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TCDrawBlankMini(pTo);
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawEFlag3(BYTE *pTo2, int sx, int sy, int ev, int ev2, int xp, int yp)
{
BYTE *pTo;
int t;
WORD *mt;
pTo = pTo2;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 7; t++)
{
if (ev >= t) {
if (gdwPNum = mt[2*t]) DrawMTileClipTop (pTo);
if (gdwPNum = mt[2*t+1]) DrawMTileClipTop (pTo+32);
}
pTo -= NBUFFWSL5;
}
T_DrawHTLXsub3 (pTo2, sx, sy, ev, ev2, xp, yp, FALSE);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
static void T_DrawHTLXsub3 (BYTE *pTo, int sx, int sy, int ev, int ev2, int xp, int yp, BOOL chflag)
{
int pxp,pyp;
char bv;
int mi;
if (dItem[sx][sy] != 0) {
bv = dItem[sx][sy] - 1;
pxp = xp - item[bv]._iAnimWidth2;
if (bv == cursitem) OutlineSlabCel(181, pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, ev2);
app_assert(item[bv]._iAnimData);
DrawSlabCel(pxp, yp, item[bv]._iAnimData, item[bv]._iAnimFrame, item[bv]._iAnimWidth, 0, ev2);
ApplyWorldGoldShimmer(&item[bv], bv, pxp, yp, 0, ev2);
}
if ((dFlags[sx][sy] & BFLAG_MONSTLR) != 0) {
mi = -(dMonster[sx][sy-1] + 1);
pxp = xp - towner[mi]._tAnimWidth2;
pyp = yp;
if (mi == cursmonst) OutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2);
app_assert(towner[mi]._tAnimData);
DrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2);
}
if (dMonster[sx][sy] > 0) {
mi = dMonster[sx][sy] - 1;
pxp = xp - towner[mi]._tAnimWidth2;
pyp = yp;
if (mi == cursmonst) OutlineSlabCel(166, pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2);
app_assert(towner[mi]._tAnimData);
DrawSlabCel(pxp, pyp, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth, 0, ev2);
}
if ((dFlags[sx][sy] & BFLAG_PLRLR) != 0) {
bv = -(dPlayer[sx][sy-1] + 1);
pxp = T_GetPlayerDrawX(&plr[bv], xp) - plr[bv]._pAnimWidth2;
pyp = T_GetPlayerDrawY(&plr[bv], yp);
#if RLE_DRAW
if (bv == cursplr) DrawUnitOutline(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2);
app_assert(plr[bv]._pAnimData);
#else
if (bv == cursplr) OutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2);
app_assert(plr[bv]._pAnimData);
#endif
T_DrawPlayerTownUnit(&plr[bv], pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2, FALSE);
if (chflag)
{
// if (plr[bv]._peflag == 2) T_DrawEFlag3(pTo-NBUFFWSL4-96, sx-2, sy+1, ev, ev2, xp-96, yp-16);
if (plr[bv]._peflag != 0) T_DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp);
}
}
if (dFlags[sx][sy] & BFLAG_DEADPLR)
DrawDeadPlr(sx, sy, xp, yp, 0, ev2, FALSE);
if (dPlayer[sx][sy] > 0) {
bv = dPlayer[sx][sy] - 1;
pxp = T_GetPlayerDrawX(&plr[bv], xp) - plr[bv]._pAnimWidth2;
pyp = T_GetPlayerDrawY(&plr[bv], yp);
#if RLE_DRAW
if (bv == cursplr) DrawUnitOutline(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2);
app_assert(plr[bv]._pAnimData);
#else
if (bv == cursplr) OutlineSlabCel(T_POUTC, pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2);
app_assert(plr[bv]._pAnimData);
#endif
T_DrawPlayerTownUnit(&plr[bv], pxp, pyp, plr[bv]._pAnimData, plr[bv]._pAnimFrame, plr[bv]._pAnimWidth, 0, ev2, FALSE);
if (chflag)
{
// if (plr[bv]._peflag == 2) T_DrawEFlag3(pTo-NBUFFWSL4-96, sx-2, sy+1, ev, ev2, xp-96, yp-16);
if (plr[bv]._peflag != 0) T_DrawEFlag3(pTo-64, sx-1, sy+1, ev, ev2, xp-64, yp);
}
}
if ((dFlags[sx][sy] & BFLAG_MISSILE) != 0) DrawMissile(sx, sy, xp, yp, 0, ev2, FALSE);
if (dSpecial[sx][sy]) T_DrawSpecial(pTo, dSpecial[sx][sy]);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawHTLX3 (int sx, int sy, int xp, int yp, int nd, int ev, int halfflag)
{
int i;
BYTE *pTo;
int ev2;
int t;
WORD *mt;
app_assert(gpBuffer);
ev2 = (ev + 1) << 1;
if (ev2 > 8) ev2 = 8;
if (halfflag != 0) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
if (gdwPNum = dPiece[sx][sy]) {
pTo = gpBuffer + nBuffWTbl[yp] + xp + 32;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 7; t++)
{
if ((ev >= t) && (gdwPNum = mt[2*t+1])) DrawMTileClipTop (pTo);
pTo -= NBUFFWSL5;
}
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, FALSE);
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TDrawBlankMini(pTo);
}
sx++;
sy--;
xp += 64;
}
nd -= halfflag;
for (i = 0; i < nd; i++) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
gdwPNum = dPiece[sx][sy];
if (gdwPNum != 0) {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 7; t++)
{
if (ev >= t) {
if (gdwPNum = mt[2*t]) DrawMTileClipTop (pTo);
if (gdwPNum = mt[2*t+1]) DrawMTileClipTop (pTo+32);
}
pTo -= NBUFFWSL5;
}
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, TRUE);
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TDrawBlankMini(pTo);
}
sx++;
sy--;
xp += 64;
}
if (halfflag != 0) {
if ((sy >= 0) && (sy < DMAXY) && (sx >= 0) && (sx < DMAXX)) {
gdwPNum = dPiece[sx][sy];
if (gdwPNum != 0) {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
mt = &dMT2[CalcRot(sx,sy)].mt[0];
T_SetTownTile(sx, sy);
for(t = 0; t < 7; t++)
{
if ((ev >= t) && (gdwPNum = mt[2*t])) DrawMTileClipTop (pTo);
pTo -= NBUFFWSL5;
}
pTo = gpBuffer + nBuffWTbl[yp] + xp;
T_DrawHTLXsub3 (pTo, sx, sy, ev, ev2, xp, yp, FALSE);
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TDrawBlankMini(pTo);
}
} else {
pTo = gpBuffer + nBuffWTbl[yp] + xp;
TDrawBlankMini(pTo);
}
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_SVGADrawView (int StartX, int StartY)
{
int xpos, ypos;
int i;
int width,height;
ViewDX = 640;
ViewDY = 352;
ViewBX = 10;
ViewBY = 11;
xpos = 64 + T_GetScrollDrawX();
ypos = 175 + T_GetScrollDrawY();
StartX -= 10;
StartY -= 1;
width = 10;
height = 5;
if (chrflag || questlog) {
StartX += 2;
StartY -= 2;
xpos += 288;
width = 6;
}
if (invflag || sbookflag) {
StartX += 2;
StartY -= 2;
xpos -= 32;
width = 6;
}
switch (ScrollInfo._sdir) {
case SCRL_NONE :
break;
case SCRL_U :
ypos -= 32;
StartX--;
StartY--;
height++;
break;
case SCRL_UR :
ypos -= 32;
StartX--;
StartY--;
width++;
height++;
break;
case SCRL_R :
width++;
break;
case SCRL_DR :
width++;
height++;
break;
case SCRL_D :
height++;
break;
case SCRL_DL :
xpos -= 64;
StartX--;
StartY++;
width++;
height++;
break;
case SCRL_L :
xpos -= 64;
StartX--;
StartY++;
width++;
break;
case SCRL_UL :
xpos -= 64;
ypos -= 32;
StartX -= 2;
width++;
height++;
break;
}
app_assert(gpBuffer);
glClipY = (long)gpBuffer + nBuffWTbl[160];
for (i = 0; i < 7; i++) {
T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 0);
StartY++;
xpos -= 32;
ypos += 16;
T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 1);
StartX++;
xpos += 32;
ypos += 16;
}
app_assert(gpBuffer);
glClipY = (long)gpBuffer + nBuffWTbl[512];
for (i = 0; i < height; i++) {
T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 0);
StartY++;
xpos -= 32;
ypos += 16;
T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 1);
StartX++;
xpos += 32;
ypos += 16;
}
for (i = 0; i < 7; i++) {
T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 0);
StartY++;
xpos -= 32;
ypos += 16;
T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 1);
StartX++;
xpos += 32;
ypos += 16;
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_VGADrawView (int StartX, int StartY)
{
int xpos, ypos;
int i;
int width,height;
long csrc, cdest, cw;
ViewDX = 384;
ViewDY = 192;
ViewBX = 6;
ViewBY = 6;
xpos = 64 + T_GetScrollDrawX();
ypos = 143 + T_GetScrollDrawY();
StartX -= 6;
StartY -= 1;
width = 6;
height = 0;
switch (ScrollInfo._sdir) {
case SCRL_NONE :
break;
case SCRL_U :
ypos -= 32;
StartX--;
StartY--;
height++;
break;
case SCRL_UR :
ypos -= 32;
StartX--;
StartY--;
width++;
height++;
break;
case SCRL_R :
width++;
break;
case SCRL_DR :
width++;
height++;
break;
case SCRL_D :
height++;
break;
case SCRL_DL :
xpos -= 64;
StartX--;
StartY++;
width++;
height++;
break;
case SCRL_L :
xpos -= 64;
StartX--;
StartY++;
width++;
break;
case SCRL_UL :
xpos -= 64;
ypos -= 32;
StartX -= 2;
width++;
height++;
break;
}
app_assert(gpBuffer);
glClipY = (long)gpBuffer + nBuffWTbl[143];
for (i = 0; i < 7; i++) {
T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 0);
StartY++;
xpos -= 32;
ypos += 16;
T_DrawHTLX3(StartX, StartY, xpos, ypos, width, i, 1);
StartX++;
xpos += 32;
ypos += 16;
}
app_assert(gpBuffer);
glClipY = (long)gpBuffer + nBuffWTbl[320];
for (i = 0; i < height; i++) {
T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 0);
StartY++;
xpos -= 32;
ypos += 16;
T_DrawHTileLineX(StartX, StartY, xpos, ypos, width, 1);
StartX++;
xpos += 32;
ypos += 16;
}
for (i = 0; i < 7; i++) {
T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 0);
StartY++;
xpos -= 32;
ypos += 16;
T_DrawHTLX2(StartX, StartY, xpos, ypos, width, i, 1);
StartX++;
xpos += 32;
ypos += 16;
}
if (chrflag || questlog) {
csrc = 245168;
cdest = 392064;
cw = 160;
} else {
if (invflag || sbookflag) {
csrc = 245168;
cdest = 391744;
cw = 160;
} else {
csrc = 245088;
cdest = 391744;
cw = 320;
}
}
// Double res copy
app_assert(gpBuffer);
__asm {
mov esi,[gpBuffer]
mov edx,[cdest]
mov edi,esi
mov ecx,[csrc]
add edi,edx
add esi,ecx
mov ebx,edi
add ebx,768
mov edx,176
_YLp:
mov ecx,[cw]
_XLp:
mov al,[esi]
inc esi
mov ah,al
mov [edi],ax
mov [ebx],ax
add edi,2
add ebx,2
dec ecx
jnz _XLp
mov eax,768
add eax,[cw]
sub esi,eax
add eax,eax
sub ebx,eax
sub edi,eax
dec edx
jnz _YLp
}
/* // Double res copy (Old)
app_assert(gpBuffer);
__asm {
mov esi,dword ptr [gpBuffer]
mov edi,esi
add esi,dword ptr [csrc]
add edi,dword ptr [cdest]
mov ebx,edi
add ebx,768
mov edx,176
_YLp: mov ecx,dword ptr [cw]
_XLp: lodsb
mov ah,al
stosw
mov word ptr [ebx],ax
add ebx,2
loop _XLp
mov eax,768
add eax,dword ptr [cw]
sub esi,eax
add eax,eax
sub ebx,eax
sub edi,eax
dec edx
jnz _YLp
}*/
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_DrawView (int StartX, int StartY)
{
/* __asm {
mov edi,dword ptr [gpBuffer]
add edi,122944
mov edx,352
mov eax,092929292h // yellow
//xor eax,eax // black
_YLp: mov ecx,160
rep stosd
add edi,128
dec edx
jnz _YLp
}*/
// Non-town draw routines use nLVal and nTrans as global params,
// but in town all tiles are fully lit, and there are no transparent
// walls, so we set them here once for the whole screen
nLVal = 0;
nTrans = 0;
gnTownFlickerFrame = GetTickCount() / 120;
if (svgamode) T_SVGADrawView (StartX, StartY);
else T_VGADrawView (StartX, StartY);
if (automapflag) DrawAutomap();
if ((stextflag) && (!qtextflag)) DrawSText();
if (invflag) DrawInv();
else if (sbookflag) DrawSpellBook();
DrawDurIcon();
if (chrflag) DrawChr();
else if (questlog) DrawQuestLog();
else if ((plr[myplr]._pStatPts != 0) && (!spselflag)) DrawLevelUpIcon();
if (uitemflag) DrawUniqueInfo();
if (qtextflag) DrawQText();
if (spselflag) DrawSpellList();
if (dropGoldFlag) DrawGoldBox(dropGoldValue);
if (helpflag) DrawHelp();
if (msgflag) DrawDiabloMsg();
if (PauseMode && !deathflag) DrawPause();
plrmsg_draw();
gmenu_draw();
DrawMapOfDoom();
DrawInfoBox();
DrawHealthTop();
DrawManaTop();
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_SetDungeonMicros()
{
int wv;
int i,j;
int t;
WORD *mtsource;
WORD *mt;
// Init the light values for each piece
for (j = 0; j < DMAXY; j++) {
for (i = 0; i < DMAXX; i++) {
wv = dPiece[i][j];
mt = &dMT2[CalcRot(i,j)].mt[0];
if (wv != 0) {
wv--;
mtsource = (WORD *)(pMiniTiles + 32*wv);
for(t = 0; t < 16; t++)
// MiniTiles array uses opposite y direction
// hence wierd index on next line
mt[t] = mtsource[14-(t&0xe)+(t&1)];
} else {
for(t = 0; t < 16; t++)
mt[t] = 0;
}
}
}
#if 0
int xmp,ymp,nPNum;
int s;
WORD tempmt[16];
// Zero micro tile values for each piece
for (j = 0; j < DMAXY; j++) {
for (i = 0; i < DMAXX; i++) {
mt = &dMT2[CalcRot(i,j)].mt[0];
for(t = 0; t < 16; t++)
tempmt[t] = 0;
nPNum = mt[0];
if (((nPNum & 0x7000) == 0x4000) && (nPNum)) tempmt[0] = 1;
nPNum = mt[1];
if (((nPNum & 0x7000) == 0x5000) && (nPNum != 0)) tempmt[1] = 1;
for(t = 2; t < 16; t++)
{
nPNum = mt[t];
if (((nPNum & 0x7000) == 0) && nPNum)
{
tempmt[t] = 1;
xmp = i;
ymp = j;
for(s = t-2; s >= 0 && xmp > 0 && ymp > 0; s -= 2)
{
xmp--;
ymp--;
dMT2[CalcRot(xmp,ymp)].mt[s] = 0;
}
}
}
for(t = 0; t < 13; t += 2)
{
if(tempmt[t] && tempmt[t+2])
{
xmp = i-1;
ymp = j;
for(s = t+1; s >= 0 && xmp >= 0 && ymp >= 0; s -= 2)
{
dMT2[CalcRot(xmp,ymp)].mt[s] = 0;
xmp--;
ymp--;
}
}
}
for(t = 1; t < 14; t += 2)
{
if(tempmt[t] && tempmt[t+2])
{
xmp = i;
ymp = j-1;
for(s = t+1; s >= 0 && xmp >= 0 && ymp >= 0; s -= 2)
{
dMT2[CalcRot(xmp,ymp)].mt[s] = 0;
xmp--;
ymp--;
}
}
}
}
}
#endif
if (svgamode) {
ViewDX = 640;
ViewDY = 352;
ViewBX = 10;
ViewBY = 11;
} else {
ViewDX = 384;
ViewDY = 224;
ViewBX = 6;
ViewBY = 7;
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_FillSector (BYTE *P3Tiles, BYTE *pSector, int xi, int yi, int w, int h)
{
int i,j,xx,yy;
long v1,v2,v3,v4,ii;
// Convert dungeon mega tiles to mini tiles
ii = 4;
yy = yi;
for (j = 0; j < h; j++) {
xx = xi;
for (i = 0; i < w; i++) {
__asm {
mov esi,dword ptr [pSector]
mov eax,dword ptr [ii]
add esi,eax
xor eax,eax
lodsw
or eax,eax
jz _Zero
dec eax
mov esi,dword ptr [P3Tiles]
shl eax,3
add esi,eax
xor eax,eax
lodsw
inc eax
mov dword ptr [v1],eax
lodsw
inc eax
mov dword ptr [v2],eax
lodsw
inc eax
mov dword ptr [v3],eax
lodsw
inc eax
mov dword ptr [v4],eax
jmp _Done
_Zero: mov dword ptr [v1],eax
mov dword ptr [v2],eax
mov dword ptr [v3],eax
mov dword ptr [v4],eax
_Done: nop
}
dPiece[xx][yy] = (int) v1;
dPiece[xx+1][yy] = (int) v2;
dPiece[xx][yy+1] = (int) v3;
dPiece[xx+1][yy+1] = (int) v4;
xx += 2;
ii += 2;
}
yy += 2;
}
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void T_FillTile(BYTE *P3Tiles, int xx, int yy, int t)
{
long v1,v2,v3,v4;
// Convert dungeon mega tiles to mini tiles
__asm {
mov eax,dword ptr [t]
dec eax
mov esi,dword ptr [P3Tiles]
shl eax,3
add esi,eax
xor eax,eax
lodsw
inc eax
mov dword ptr [v1],eax
lodsw
inc eax
mov dword ptr [v2],eax
lodsw
inc eax
mov dword ptr [v3],eax
lodsw
inc eax
mov dword ptr [v4],eax
jmp _Done
mov dword ptr [v1],eax
mov dword ptr [v2],eax
mov dword ptr [v3],eax
mov dword ptr [v4],eax
_Done: nop
}
dPiece[xx][yy] = (int) v1;
dPiece[xx+1][yy] = (int) v2;
dPiece[xx][yy+1] = (int) v3;
dPiece[xx+1][yy+1] = (int) v4;
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
void OpenNest()
{
dPiece[78][60] = 1162; // shadow at fork
dPiece[79][60] = 1163;
dPiece[78][61] = 1164;
dPiece[79][61] = 1294;
dPiece[78][62] = 1262; // bridge
dPiece[78][63] = 1264;
dPiece[79][62] = 1296;
dPiece[79][63] = 1297;
dPiece[79][64] = 1298; // second shadow
dPiece[78][64] = 282;
dPiece[78][65] = 284;
dPiece[79][65] = 285;
dPiece[80][60] = 1299; // start tile of thing
dPiece[80][61] = 1301;
dPiece[81][61] = 1302;
dPiece[82][60] = 1303; // second tile of thing
dPiece[83][60] = 1304;
dPiece[82][61] = 1305;
dPiece[83][61] = 1306;
dPiece[80][62] = 1307; // third tile of thing
dPiece[81][62] = 1308;
dPiece[80][63] = 1309;
dPiece[81][63] = 1310;
dPiece[80][64] = 1311; // forth tile of thing
dPiece[81][64] = 1312;
dPiece[80][65] = 1313;
dPiece[81][65] = 1314;
dPiece[82][64] = 1319; // fifth tile of thing
dPiece[83][64] = 1320;
dPiece[82][65] = 1321;
dPiece[83][65] = 1322;
dPiece[82][62] = 1315; // sixth tile of thing
dPiece[83][62] = 1316;
dPiece[82][63] = 1317;
dPiece[83][63] = 1318;
dPiece[84][61] = 280; // remove tree
dPiece[84][62] = 280;
dPiece[84][63] = 280;
// dPiece[85][59] = 11;
dPiece[85][60] = 280;
dPiece[85][61] = 280;
dPiece[85][62] = 8;
dPiece[85][63] = 8;
dPiece[85][64] = 8;
dPiece[86][60] = 217;
dPiece[86][61] = 24;
dPiece[85][62] = 19;
// dPiece[86][62] = 11;
// dPiece[86][63] = 11;
// dPiece[86][64] = 11;
dPiece[84][64] = 280;
// dPiece[86][65] = 11;
T_SetDungeonMicros();
}
void CloseNest()
{
dPiece[78][60] = 1162; // shadow at fork
dPiece[79][60] = 1259;
dPiece[78][61] = 1260;
dPiece[79][61] = 1261;
dPiece[78][62] = 1262; // bridge
dPiece[79][62] = 1263;
dPiece[78][63] = 1264;
dPiece[79][63] = 1265;
dPiece[78][64] = 1266; // second shadow
dPiece[79][64] = 1267;
dPiece[78][65] = 1268;
dPiece[80][60] = 1269; // start tile of thing
dPiece[81][60] = 1270;
dPiece[80][61] = 1271;
dPiece[81][61] = 1272;
dPiece[82][60] = 1273; // second tile of thing
dPiece[83][60] = 1274;
dPiece[82][61] = 1275;
dPiece[83][61] = 1276;
dPiece[80][62] = 1277; // third tile of thing
dPiece[81][62] = 1278;
dPiece[80][63] = 1279;
dPiece[81][63] = 1280;
dPiece[80][64] = 1281; // forth tile of thing
dPiece[81][64] = 1282;
dPiece[80][65] = 1283;
dPiece[81][65] = 1284;
dPiece[82][64] = 1289; // fifth tile of thing
dPiece[83][64] = 1290;
dPiece[82][65] = 1291;
dPiece[83][65] = 1292;
dPiece[82][62] = 1285; // sixth tile of thing
dPiece[83][62] = 1286;
dPiece[82][63] = 1287;
dPiece[83][63] = 1288;
dPiece[84][61] = 280; // remove tree
dPiece[84][62] = 280;
dPiece[84][63] = 280;
// dPiece[85][59] = 11;
dPiece[85][60] = 280;
dPiece[85][61] = 280;
dPiece[85][62] = 8;
dPiece[85][63] = 8;
dPiece[85][64] = 8;
dPiece[86][60] = 217;
dPiece[86][61] = 24;
dPiece[85][62] = 19;
// dPiece[86][62] = 11;
// dPiece[86][63] = 11;
// dPiece[86][64] = 11;
dPiece[84][64] = 280;
// dPiece[86][65] = 11;
T_SetDungeonMicros();
}
void CloseCrypt()
{
dPiece[36][21] = 1323;
dPiece[37][21] = 1324;
dPiece[36][22] = 1325;
dPiece[37][22] = 1326;
dPiece[36][23] = 1327;
dPiece[37][23] = 1328;
dPiece[36][24] = 1329;
dPiece[37][24] = 1330;
dPiece[35][21] = 1339;
dPiece[34][21] = 1340;
// dPiece[34][22] = 1341;
// dPiece[35][22] = 1342;
T_SetDungeonMicros();
}
void OpenCrypt()
{
dPiece[36][21] = 1331;
dPiece[37][21] = 1332;
dPiece[36][22] = 1333;
dPiece[37][22] = 1334;
dPiece[36][23] = 1335;
dPiece[37][23] = 1336;
dPiece[36][24] = 1337;
dPiece[37][24] = 1338;
dPiece[35][21] = 1339;
dPiece[34][21] = 1340;
// dPiece[34][22] = 1341;
// dPiece[35][22] = 1342;
T_SetDungeonMicros();
}
void T_Pass3()
{
BYTE *P3Tiles;
BYTE *pSector;
int xx,yy;
// Init Dungeon to blank
for (yy = 0; yy < DMAXY; yy+=2) {
for (xx = 0; xx < DMAXX; xx+=2) {
dPiece[xx][yy] = 0;
dPiece[xx+1][yy] = 0;
dPiece[xx][yy+1] = 0;
dPiece[xx+1][yy+1] = 0;
}
}
// Load convertion tiles
P3Tiles = LoadFileInMemSig("Levels\\TownData\\Town.TIL",NULL,'TOWN');
// Load map sector
pSector = LoadFileInMemSig("Levels\\TownData\\Sector1s.DUN",NULL,'TOWN');
T_FillSector(P3Tiles, pSector, 46, 46, 25, 25);
DiabloFreePtr(pSector);
pSector = LoadFileInMemSig("Levels\\TownData\\Sector2s.DUN",NULL,'TOWN');
T_FillSector(P3Tiles, pSector, 46, 0, 25, 23);
DiabloFreePtr(pSector);
pSector = LoadFileInMemSig("Levels\\TownData\\Sector3s.DUN",NULL,'TOWN');
T_FillSector(P3Tiles, pSector, 0, 46, 23, 25);
DiabloFreePtr(pSector);
pSector = LoadFileInMemSig("Levels\\TownData\\Sector4s.DUN",NULL,'TOWN');
T_FillSector(P3Tiles, pSector, 0, 0, 23, 23);
DiabloFreePtr(pSector);
#ifdef TESTINGCRYPT
quests[Q_CRYPTMAP]._qactive = QUEST_DONE;
#endif
#if IS_VERSION(SHAREWARE)
// Close Maus shortcut
T_FillTile(P3Tiles, 48, 20, 320);
// Close cave shortcut
T_FillTile(P3Tiles, 16, 68, 332);
T_FillTile(P3Tiles, 16, 70, 331);
// Close crev shortcut
for (xx = 36; xx < 46; xx++) T_FillTile(P3Tiles, xx, 78, random(0,4)+1);
#else
if (gbMaxPlayers == 1) {
if ((quests[Q_FARMER]._qactive == QUEST_DONE) || (quests[Q_FARMER]._qactive == QUEST_REALLYDONE)
|| (quests[Q_COWSUIT]._qactive == QUEST_DONE) || (quests[Q_COWSUIT]._qactive == QUEST_REALLYDONE))
{
OpenNest();
}
else
{
CloseNest();
}
if ((quests[Q_CRYPTMAP]._qactive != QUEST_DONE) && (!plr[myplr]._pLvlVisited[CRYPTSTART]))
CloseCrypt();
else
OpenCrypt();
// Close Maus shortcut
if (!((plr[myplr].pTownWarps & 0x01) || plr[myplr]._pLevel >= 10))
T_FillTile(P3Tiles, 48, 20, 320);
// Close cave shortcut
if (!((plr[myplr].pTownWarps & 0x02) || plr[myplr]._pLevel >= 15))
{
T_FillTile(P3Tiles, 16, 68, 332);
T_FillTile(P3Tiles, 16, 70, 331);
}
// Close crev shortcut or open or close or whatever is asked today
if (!((plr[myplr].pTownWarps & 0x04) || plr[myplr]._pLevel >= 20))
// if (!(plr[myplr].pTownWarps & 0x04))
{
for (xx = 36; xx < 46; xx++)
T_FillTile(P3Tiles, xx, 78, random(0,4)+1);
}
}
else
{
if ((quests[Q_FARMER]._qactive == QUEST_DONE) || (quests[Q_FARMER]._qactive == QUEST_REALLYDONE)
|| (quests[Q_COWSUIT]._qactive == QUEST_DONE) || (quests[Q_COWSUIT]._qactive == QUEST_REALLYDONE))
{
OpenNest();
}
else
{
CloseNest();
}
if ((quests[Q_CRYPTMAP]._qactive != QUEST_DONE) && (!plr[myplr]._pLvlVisited[CRYPTSTART]))
CloseCrypt();
else
OpenCrypt();
}
#endif
if ((quests[Q_PWATER]._qactive == QUEST_DONE) || (quests[Q_PWATER]._qactive == QUEST_NOTAVAIL))
T_FillTile(P3Tiles, 60, 70, 71);
else
T_FillTile(P3Tiles, 60, 70, 342);
DiabloFreePtr(P3Tiles);
}
/*-----------------------------------------------------------------------**
**-----------------------------------------------------------------------*/
extern int TWarpFrom;
void CreateTown(int entry)
{
int i,j;
dminx = 10;
dminy = 10;
dmaxx = 84;
dmaxy = 84;
if (entry == LVL_DOWN) {
ViewX = 75; // Your house
ViewY = 68;
} else {
if (entry == LVL_UP) {
ViewX = 25; // Near church
ViewY = 31;
} else {
if (entry == LVL_TWARPUP) {
if (TWarpFrom == 5) {
ViewX = 49; // Maus warp
ViewY = 22;
}
if (TWarpFrom == 9) {
ViewX = 18; // Cave warp
ViewY = 69;
}
if (TWarpFrom == 13) {
ViewX = 41; // Hell warp
ViewY = 81;
}// JKE add level up here.
if (TWarpFrom == CRYPTSTART) {
ViewX = 36;
ViewY = 25;
}
if (TWarpFrom == HIVESTART) {
ViewX = 79;
ViewY = 62;
}
}
}
}
T_Pass3();
// Init the light values for each piece
ZeroMemory(dLight,sizeof(dLight));
ZeroMemory(dFlags,sizeof(dFlags));
ZeroMemory(dPlayer,sizeof(dPlayer));
ZeroMemory(dMonster,sizeof(dMonster));
ZeroMemory(dObject,sizeof(dObject));
ZeroMemory(dItem,sizeof(dItem));
ZeroMemory(dSpecial,sizeof(dSpecial));
for (j = 0; j < DMAXY; j++) {
for (i = 0; i < DMAXX; i++) {
int nPiece = dPiece[i][j];
if (nPiece == 360) dSpecial[i][j] = 1;
else if (nPiece == 358) dSpecial[i][j] = 2;
else if (nPiece == 129) dSpecial[i][j] = 6;
else if (nPiece == 130) dSpecial[i][j] = 7;
else if (nPiece == 128) dSpecial[i][j] = 8;
else if (nPiece == 117) dSpecial[i][j] = 9;
else if (nPiece == 157) dSpecial[i][j] = 10;
else if (nPiece == 158) dSpecial[i][j] = 11;
else if (nPiece == 156) dSpecial[i][j] = 12;
else if (nPiece == 162) dSpecial[i][j] = 13;
else if (nPiece == 160) dSpecial[i][j] = 14;
else if (nPiece == 214) dSpecial[i][j] = 15;
else if (nPiece == 212) dSpecial[i][j] = 16;
else if (nPiece == 217) dSpecial[i][j] = 17;
else if (nPiece == 216) dSpecial[i][j] = 18;
}
}
T_SetDungeonMicros();
}