Devilution
Diablo devolved - magic behind the 1996 computer game
scrollrt.cpp
Go to the documentation of this file.
1 #include "all.h"
2 
4 
10 DWORD sgdwCursX;
11 DWORD sgdwCursY;
15 BYTE *gpBufStart;
19 BYTE *gpBufEnd;
21 
42 int cel_foliage_active = false;
48 void (*DrawPlrProc)(int, int, int, int, int, BYTE *, int, int, int, int);
49 BYTE sgSaveBack[8192];
51 
53 
54 /* data */
55 
56 /* used in 1.00 debug */
57 char *szMonModeAssert[18] = {
58  "standing",
59  "walking (1)",
60  "walking (2)",
61  "walking (3)",
62  "attacking",
63  "getting hit",
64  "dying",
65  "attacking (special)",
66  "fading in",
67  "fading out",
68  "attacking (ranged)",
69  "standing (special)",
70  "attacking (special ranged)",
71  "delaying",
72  "charging",
73  "stoned",
74  "healing",
75  "talking"
76 };
77 
78 char *szPlrModeAssert[12] = {
79  "standing",
80  "walking (1)",
81  "walking (2)",
82  "walking (3)",
83  "attacking (melee)",
84  "attacking (ranged)",
85  "blocking",
86  "getting hit",
87  "dying",
88  "casting a spell",
89  "changing levels",
90  "quitting"
91 };
92 
96 void ClearCursor() // CODE_FIX: this was supposed to be in cursor.cpp
97 {
98  sgdwCursWdt = 0;
99  sgdwCursWdtOld = 0;
100 }
101 
106 {
107  int i;
108  BYTE *src, *dst;
109 
110  if (sgdwCursWdt == 0) {
111  return;
112  }
113 
114  assert(gpBuffer);
115  src = sgSaveBack;
117  i = sgdwCursHgt;
118 
119  if (sgdwCursHgt != 0) {
120  while (i--) {
121  memcpy(dst, src, sgdwCursWdt);
122  src += sgdwCursWdt;
123  dst += BUFFER_WIDTH;
124  }
125  }
126 
131  sgdwCursWdt = 0;
132 }
133 
138 {
139  int i, mx, my, col;
140  BYTE *src, *dst;
141 
142  assert(! sgdwCursWdt);
143 
144  if (pcurs <= CURSOR_NONE || cursW == 0 || cursH == 0) {
145  return;
146  }
147 
148  if (sgbControllerActive && pcurs != CURSOR_TELEPORT && !invflag && (!chrflag || plr[myplr]._pStatPts <= 0)) {
149  return;
150  }
151 
152  mx = MouseX - 1;
153  if (mx < 0 - cursW - 1) {
154  return;
155  } else if (mx > SCREEN_WIDTH - 1) {
156  return;
157  }
158  my = MouseY - 1;
159  if (my < 0 - cursH - 1) {
160  return;
161  } else if (my > SCREEN_HEIGHT - 1) {
162  return;
163  }
164 
165  sgdwCursX = mx;
166  sgdwCursWdt = sgdwCursX + cursW + 1;
167  if (sgdwCursWdt > SCREEN_WIDTH - 1) {
169  }
170  sgdwCursX &= ~3;
171  sgdwCursWdt |= 3;
173  sgdwCursWdt++;
174 
175  sgdwCursY = my;
176  sgdwCursHgt = sgdwCursY + cursH + 1;
177  if (sgdwCursHgt > SCREEN_HEIGHT - 1) {
179  }
181  sgdwCursHgt++;
182 
184  assert(gpBuffer);
185  dst = sgSaveBack;
187 
188  for (i = sgdwCursHgt; i != 0; i--, dst += sgdwCursWdt, src += BUFFER_WIDTH) {
189  memcpy(dst, src, sgdwCursWdt);
190  }
191 
192  mx++;
193  my++;
195 
196  if (pcurs >= CURSOR_FIRSTITEM) {
197  col = PAL16_YELLOW + 5;
198  if (plr[myplr].HoldItem._iMagical != 0) {
199  col = PAL16_BLUE + 5;
200  }
201  if (!plr[myplr].HoldItem._iStatFlag) {
202  col = PAL16_RED + 5;
203  }
204  CelBlitOutline(col, mx + SCREEN_X, my + cursH + SCREEN_Y - 1, pCursCels, pcurs, cursW);
205  if (col != PAL16_RED + 5) {
207  } else {
209  }
210  } else {
212  }
213 }
214 
222 void DrawMissilePrivate(MissileStruct *m, int sx, int sy, BOOL pre)
223 {
224  int mx, my, nCel, frames;
225  BYTE *pCelBuff;
226 
227  if (m->_miPreFlag != pre || !m->_miDrawFlag)
228  return;
229 
230  pCelBuff = m->_miAnimData;
231  if (!pCelBuff) {
232  // app_fatal("Draw Missile 2 type %d: NULL Cel Buffer", m->_mitype);
233  return;
234  }
235  nCel = m->_miAnimFrame;
236  frames = SDL_SwapLE32(*(DWORD *)pCelBuff);
237  if (nCel < 1 || frames > 50 || nCel > frames) {
238  // app_fatal("Draw Missile 2: frame %d of %d, missile type==%d", nCel, frames, m->_mitype);
239  return;
240  }
241  mx = sx + m->_mixoff - m->_miAnimWidth2;
242  my = sy + m->_miyoff;
243  if (m->_miUniqTrans)
245  else if (m->_miLightFlag)
247  else
248  Cl2Draw(mx, my, m->_miAnimData, m->_miAnimFrame, m->_miAnimWidth);
249 }
250 
259 void DrawMissile(int x, int y, int sx, int sy, BOOL pre)
260 {
261  int i;
262  MissileStruct *m;
263 
264  if (!(dFlags[x][y] & BFLAG_MISSILE))
265  return;
266 
267  if (dMissile[x][y] != -1) {
268  m = &missile[dMissile[x][y] - 1];
269  DrawMissilePrivate(m, sx, sy, pre);
270  return;
271  }
272 
273  for (i = 0; i < nummissiles; i++) {
275  m = &missile[missileactive[i]];
276  if (m->_mix != x || m->_miy != y)
277  continue;
278  DrawMissilePrivate(m, sx, sy, pre);
279  }
280 }
281 
290 static void DrawMonster(int x, int y, int mx, int my, int m)
291 {
292  int nCel, frames;
293  char trans;
294  BYTE *pCelBuff;
295 
296  if ((DWORD)m >= MAXMONSTERS) {
297  // app_fatal("Draw Monster: tried to draw illegal monster %d", m);
298  return;
299  }
300 
301  pCelBuff = monster[m]._mAnimData;
302  if (!pCelBuff) {
303  // app_fatal("Draw Monster \"%s\": NULL Cel Buffer", monster[m].mName);
304  return;
305  }
306 
307  nCel = monster[m]._mAnimFrame;
308  frames = SDL_SwapLE32(*(DWORD *)pCelBuff);
309  if (nCel < 1 || frames > 50 || nCel > frames) {
310  /*
311  const char *szMode = "unknown action";
312  if(monster[m]._mmode <= 17)
313  szMode = szMonModeAssert[monster[m]._mmode];
314  app_fatal(
315  "Draw Monster \"%s\" %s: facing %d, frame %d of %d",
316  monster[m].mName,
317  szMode,
318  monster[m]._mdir,
319  nCel,
320  frames);
321  */
322  return;
323  }
324 
325  if (!(dFlags[x][y] & BFLAG_LIT)) {
326  Cl2DrawLightTbl(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->width, 1);
327  } else {
328  trans = 0;
329  if (monster[m]._uniqtype)
330  trans = monster[m]._uniqtrans + 4;
331  if (monster[m]._mmode == MM_STONE)
332  trans = 2;
333  if (plr[myplr]._pInfraFlag && light_table_index > 8)
334  trans = 1;
335  if (trans)
336  Cl2DrawLightTbl(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->width, trans);
337  else
338  Cl2DrawLight(mx, my, monster[m]._mAnimData, monster[m]._mAnimFrame, monster[m].MType->width);
339  }
340 }
341 
353 static void DrawPlayer(int pnum, int x, int y, int px, int py, BYTE *pCelBuff, int nCel, int nWidth)
354 {
355  int l, frames;
356 
357  if (dFlags[x][y] & BFLAG_LIT || plr[myplr]._pInfraFlag || !setlevel && !currlevel) {
358  if (!pCelBuff) {
359  // app_fatal("Drawing player %d \"%s\": NULL Cel Buffer", pnum, plr[pnum]._pName);
360  return;
361  }
362  frames = SDL_SwapLE32(*(DWORD *)pCelBuff);
363  if (nCel < 1 || frames > 50 || nCel > frames) {
364  /*
365  const char *szMode = "unknown action";
366  if(plr[pnum]._pmode <= PM_QUIT)
367  szMode = szPlrModeAssert[plr[pnum]._pmode];
368  app_fatal(
369  "Drawing player %d \"%s\" %s: facing %d, frame %d of %d",
370  pnum,
371  plr[pnum]._pName,
372  szMode,
373  plr[pnum]._pdir,
374  nCel,
375  frames);
376  */
377  return;
378  }
379  if (pnum == pcursplr)
380  Cl2DrawOutline(165, px, py, pCelBuff, nCel, nWidth);
381  if (pnum == myplr) {
382  Cl2Draw(px, py, pCelBuff, nCel, nWidth);
383  if (plr[pnum].pManaShield)
384  Cl2Draw(
385  px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0],
386  py,
387  misfiledata[MFILE_MANASHLD].mAnimData[0],
388  1,
389  misfiledata[MFILE_MANASHLD].mAnimWidth[0]);
390  } else if (!(dFlags[x][y] & BFLAG_LIT) || plr[myplr]._pInfraFlag && light_table_index > 8) {
391  Cl2DrawLightTbl(px, py, pCelBuff, nCel, nWidth, 1);
392  if (plr[pnum].pManaShield)
394  px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0],
395  py,
396  misfiledata[MFILE_MANASHLD].mAnimData[0],
397  1,
398  misfiledata[MFILE_MANASHLD].mAnimWidth[0],
399  1);
400  } else {
401  l = light_table_index;
402  if (light_table_index < 5)
403  light_table_index = 0;
404  else
405  light_table_index -= 5;
406  Cl2DrawLight(px, py, pCelBuff, nCel, nWidth);
407  if (plr[pnum].pManaShield)
408  Cl2DrawLight(
409  px + plr[pnum]._pAnimWidth2 - misfiledata[MFILE_MANASHLD].mAnimWidth2[0],
410  py,
411  misfiledata[MFILE_MANASHLD].mAnimData[0],
412  1,
413  misfiledata[MFILE_MANASHLD].mAnimWidth[0]);
414  light_table_index = l;
415  }
416  }
417 }
418 
426 void DrawDeadPlayer(int x, int y, int sx, int sy)
427 {
428  int i, px, py, nCel, frames;
429  PlayerStruct *p;
430  BYTE *pCelBuff;
431 
432  dFlags[x][y] &= ~BFLAG_DEAD_PLAYER;
433 
434  for (i = 0; i < MAX_PLRS; i++) {
435  p = &plr[i];
436  if (p->plractive && !p->_pHitPoints && p->plrlevel == (BYTE)currlevel && p->WorldX == x && p->WorldY == y) {
437  pCelBuff = p->_pAnimData;
438  if (!pCelBuff) {
439  // app_fatal("Drawing dead player %d \"%s\": NULL Cel Buffer", i, p->_pName);
440  break;
441  }
442  nCel = p->_pAnimFrame;
443  frames = SDL_SwapLE32(*(DWORD *)pCelBuff);
444  if (nCel < 1 || frames > 50 || nCel > frames) {
445  // app_fatal("Drawing dead player %d \"%s\": facing %d, frame %d of %d", i, p->_pName, p->_pdir, nCel, frame);
446  break;
447  }
448  dFlags[x][y] |= BFLAG_DEAD_PLAYER;
449  px = sx + p->_pxoff - p->_pAnimWidth2;
450  py = sy + p->_pyoff;
451  DrawPlayer(i, x, y, px, py, p->_pAnimData, p->_pAnimFrame, p->_pAnimWidth);
452  }
453  }
454 }
455 
464 static void DrawObject(int x, int y, int ox, int oy, BOOL pre)
465 {
466  int sx, sy, xx, yy, nCel, frames;
467  char bv;
468  BYTE *pCelBuff;
469 
470  if (dObject[x][y] == 0 || light_table_index >= lightmax)
471  return;
472 
473  if (dObject[x][y] > 0) {
474  bv = dObject[x][y] - 1;
475  if (object[bv]._oPreFlag != pre)
476  return;
477  sx = ox - object[bv]._oAnimWidth2;
478  sy = oy;
479  } else {
480  bv = -(dObject[x][y] + 1);
481  if (object[bv]._oPreFlag != pre)
482  return;
483  xx = object[bv]._ox - x;
484  yy = object[bv]._oy - y;
485  sx = (xx << 5) + ox - object[bv]._oAnimWidth2 - (yy << 5);
486  sy = oy + (yy << 4) + (xx << 4);
487  }
488 
489  assert((unsigned char)bv < MAXOBJECTS);
490 
491  pCelBuff = object[bv]._oAnimData;
492  if (!pCelBuff) {
493  // app_fatal("Draw Object type %d: NULL Cel Buffer", object[bv]._otype);
494  return;
495  }
496 
497  nCel = object[bv]._oAnimFrame;
498  frames = SDL_SwapLE32(*(DWORD *)pCelBuff);
499  if (nCel < 1 || frames > 50 || nCel > (int)frames) {
500  // app_fatal("Draw Object: frame %d of %d, object type==%d", nCel, frames, object[bv]._otype);
501  return;
502  }
503 
504  if (bv == pcursobj)
505  CelBlitOutline(194, sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth);
506  if (object[bv]._oLight) {
507  CelClippedDrawLight(sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth);
508  } else {
509  CelClippedDraw(sx, sy, object[bv]._oAnimData, object[bv]._oAnimFrame, object[bv]._oAnimWidth);
510  }
511 }
512 
513 static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy);
514 
522 static void drawCell(int x, int y, int sx, int sy)
523 {
524  BYTE *dst;
525  MICROS *pMap;
526 
527  dst = &gpBuffer[sx + sy * BUFFER_WIDTH];
528  pMap = &dpiece_defs_map_2[x][y];
529  level_piece_id = dPiece[x][y];
532  for (int i = 0; i<MicroTileLen>> 1; i++) {
533  level_cel_block = pMap->mt[2 * i];
534  if (level_cel_block != 0) {
535  arch_draw_type = i == 0 ? 1 : 0;
536  RenderTile(dst);
537  }
538  level_cel_block = pMap->mt[2 * i + 1];
539  if (level_cel_block != 0) {
540  arch_draw_type = i == 0 ? 2 : 0;
541  RenderTile(dst + 32);
542  }
543  dst -= BUFFER_WIDTH * 32;
544  }
545  cel_foliage_active = false;
546 }
547 
555 static void drawFloor(int x, int y, int sx, int sy)
556 {
558  light_table_index = dLight[x][y];
559 
560  BYTE *dst = &gpBuffer[sx + sy * BUFFER_WIDTH];
561  arch_draw_type = 1; // Left
563  if (level_cel_block != 0) {
564  RenderTile(dst);
565  }
566  arch_draw_type = 2; // Right
568  if (level_cel_block != 0) {
569  RenderTile(dst + 32);
570  }
571 }
572 
581 static void DrawItem(int x, int y, int sx, int sy, BOOL pre)
582 {
583  char bItem = dItem[x][y];
584  ItemStruct *pItem;
585 
586  if (bItem == 0)
587  return;
588 
589  pItem = &item[bItem - 1];
590  if (pItem->_iPostDraw == pre)
591  return;
592 
593  assert((unsigned char)bItem <= MAXITEMS);
594  int px = sx - pItem->_iAnimWidth2;
595  if (bItem - 1 == pcursitem) {
596  CelBlitOutline(181, px, sy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth);
597  }
598  CelClippedDrawLight(px, sy, pItem->_iAnimData, pItem->_iAnimFrame, pItem->_iAnimWidth);
599 }
600 
609 static void DrawMonsterHelper(int x, int y, int oy, int sx, int sy)
610 {
611  int mi, px, py;
612  MonsterStruct *pMonster;
613 
614  if (!(dFlags[x][y] & BFLAG_LIT) && !plr[myplr]._pInfraFlag)
615  return;
616 
617  mi = dMonster[x][y + oy];
618  mi = mi > 0 ? mi - 1 : -(mi + 1);
619 
620  if (leveltype == DTYPE_TOWN) {
621  px = sx - towner[mi]._tAnimWidth2;
622  if (mi == pcursmonst) {
623  CelBlitOutline(166, px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth);
624  }
625  assert(towner[mi]._tAnimData);
626  CelClippedDraw(px, sy, towner[mi]._tAnimData, towner[mi]._tAnimFrame, towner[mi]._tAnimWidth);
627  return;
628  }
629 
630  if ((DWORD)mi >= MAXMONSTERS) {
631  // app_fatal("Draw Monster: tried to draw illegal monster %d", mi);
632  }
633 
634  pMonster = &monster[mi];
635  if (pMonster->_mFlags & MFLAG_HIDDEN) {
636  return;
637  }
638 
639  if (pMonster->MType != NULL) {
640  // app_fatal("Draw Monster \"%s\": uninitialized monster", pMonster->mName);
641  }
642 
643  px = sx + pMonster->_mxoff - pMonster->MType->width2;
644  py = sy + pMonster->_myoff;
645  if (mi == pcursmonst) {
646  Cl2DrawOutline(233, px, py, pMonster->_mAnimData, pMonster->_mAnimFrame, pMonster->MType->width);
647  }
648  DrawMonster(x, y, px, py, mi);
649 }
650 
659 static void DrawPlayerHelper(int x, int y, int oy, int sx, int sy)
660 {
661  int p = dPlayer[x][y + oy];
662  p = p > 0 ? p - 1 : -(p + 1);
663  PlayerStruct *pPlayer = &plr[p];
664  int px = sx + pPlayer->_pxoff - pPlayer->_pAnimWidth2;
665  int py = sy + pPlayer->_pyoff;
666 
667  DrawPlayer(p, x, y + oy, px, py, pPlayer->_pAnimData, pPlayer->_pAnimFrame, pPlayer->_pAnimWidth);
668 }
669 
677 static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy)
678 {
679  int mi, px, py, nCel, nMon, negMon, frames;
680  char bFlag, bDead, bObj, bItem, bPlr, bArch, bMap, negPlr, dd;
681  DeadStruct *pDeadGuy;
682  BYTE *pCelBuff;
683 
684  assert((DWORD)sx < MAXDUNX);
685  assert((DWORD)sy < MAXDUNY);
686 
687  if (dRendered[sx][sy])
688  return;
689  dRendered[sx][sy] = true;
690 
691  light_table_index = dLight[sx][sy];
692 
693  drawCell(sx, sy, dx, dy);
694 
695  bFlag = dFlags[sx][sy];
696  bDead = dDead[sx][sy];
697  bMap = dTransVal[sx][sy];
698 
699  negMon = dMonster[sx][sy - 1];
700 
701  if (visiondebug && bFlag & BFLAG_LIT) {
702  CelClippedDraw(dx, dy, pSquareCel, 1, 64);
703  }
704 
705  if (MissilePreFlag) {
706  DrawMissile(sx, sy, dx, dy, TRUE);
707  }
708 
709  if (light_table_index < lightmax && bDead != 0) {
710  pDeadGuy = &dead[(bDead & 0x1F) - 1];
711  dd = (bDead >> 5) & 7;
712  px = dx - pDeadGuy->_deadWidth2;
713  pCelBuff = pDeadGuy->_deadData[dd];
714  assert(pDeadGuy->_deadData[dd] != NULL);
715  if (pCelBuff != NULL) {
716  if (pDeadGuy->_deadtrans != 0) {
717  Cl2DrawLightTbl(px, dy, pCelBuff, pDeadGuy->_deadFrame, pDeadGuy->_deadWidth, pDeadGuy->_deadtrans);
718  } else {
719  Cl2DrawLight(px, dy, pCelBuff, pDeadGuy->_deadFrame, pDeadGuy->_deadWidth);
720  }
721  }
722  }
723  DrawObject(sx, sy, dx, dy, 1);
724  DrawItem(sx, sy, dx, dy, 1);
725  if (bFlag & BFLAG_PLAYERLR) {
726  assert((DWORD)(sy-1) < MAXDUNY);
727  DrawPlayerHelper(sx, sy, -1, dx, dy);
728  }
729  if (bFlag & BFLAG_MONSTLR && negMon < 0) {
730  DrawMonsterHelper(sx, sy, -1, dx, dy);
731  }
732  if (bFlag & BFLAG_DEAD_PLAYER) {
733  DrawDeadPlayer(sx, sy, dx, dy);
734  }
735  if (dPlayer[sx][sy] > 0) {
736  DrawPlayerHelper(sx, sy, 0, dx, dy);
737  }
738  if (dMonster[sx][sy] > 0) {
739  DrawMonsterHelper(sx, sy, 0, dx, dy);
740  }
741  DrawMissile(sx, sy, dx, dy, FALSE);
742  DrawObject(sx, sy, dx, dy, 0);
743  DrawItem(sx, sy, dx, dy, 0);
744 
745  if (leveltype != DTYPE_TOWN) {
746  bArch = dSpecial[sx][sy];
747  if (bArch != 0) {
750  }
751  } else {
752  // Tree leafs should always cover player when entering or leaving the tile,
753  // So delay the rendering untill after the next row is being drawn.
754  // This could probably have been better solved by sprites in screen space.
755  if (sx > 0 && sy > 0 && dy > 32 + SCREEN_Y) {
756  bArch = dSpecial[sx - 1][sy - 1];
757  if (bArch != 0) {
758  CelBlitFrame(&gpBuffer[dx + BUFFER_WIDTH * (dy - 32)], pSpecialCels, bArch, 64);
759  }
760  }
761  }
762 }
763 
773 static void scrollrt_drawFloor(int x, int y, int sx, int sy, int blocks, int chunks)
774 {
775  assert(gpBuffer);
776 
777  for (int i = 0; i < (blocks << 1); i++) {
778  for (int j = 0; j < chunks ; j++) {
779  if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY) {
780  level_piece_id = dPiece[x][y];
781  if (level_piece_id != 0) {
783  drawFloor(x, y, sx, sy);
784  } else {
785  world_draw_black_tile(sx, sy);
786  }
787  } else {
788  world_draw_black_tile(sx, sy);
789  }
790  x++;
791  y--;
792  sx += 64;
793  }
794  // Return to start of row
795  x -= chunks;
796  y += chunks;
797  sx -= chunks * 64;
798  sy += 16;
799 
800  // Jump to next row
801  if (i & 1) {
802  x++;
803  chunks--;
804  sx += 32;
805  } else {
806  y++;
807  chunks++;
808  sx -= 32;
809  }
810  }
811 }
812 
813 #define IsWall(x, y) (dPiece[x][y] == 0 || nSolidTable[dPiece[x][y]] || dSpecial[x][y] != 0)
814 #define IsWalktabke(x, y) (dPiece[x][y] != 0 && !nSolidTable[dPiece[x][y]])
815 
825 static void scrollrt_draw(int x, int y, int sx, int sy, int blocks, int chunks)
826 {
827  assert(gpBuffer);
828 
829  for (int i = 0; i < (blocks << 1); i++) {
830  for (int j = 0; j < chunks ; j++) {
831  if (x >= 0 && x < MAXDUNX && y >= 0 && y < MAXDUNY) {
832  if (x + 1 < MAXDUNX && y - 1 >= 0 && sx + 64 <= SCREEN_X + SCREEN_WIDTH) {
833  // Render objects behind walls first to prevent sprites, that are moving
834  // between tiles, from poking through the walls as they exceed the tile bound.
835  // A propper fix for this would probably be to layout the sceen and render by
836  // sprite screen position rather then tile position.
837  if (IsWall(x, y) && (IsWall(x + 1, y) || (x > 0 && IsWall(x - 1, y)))) { // Part of a wall aligned on the x-axis
838  if (IsWalktabke(x + 1, y - 1) && IsWalktabke(x, y - 1) ) { // Has wakable area behind it
839  scrollrt_draw_dungeon(x + 1, y - 1, sx + 64, sy);
840  }
841  }
842  }
843  if (dPiece[x][y] != 0) {
844  scrollrt_draw_dungeon(x, y, sx, sy);
845  }
846  }
847  x++;
848  y--;
849  sx += 64;
850  }
851  // Return to start of row
852  x -= chunks;
853  y += chunks;
854  sx -= chunks * 64;
855  sy += 16;
856 
857  // Jump to next row
858  if (i & 1) {
859  x++;
860  chunks--;
861  sx += 32;
862  } else {
863  y++;
864  chunks++;
865  sx -= 32;
866  }
867  }
868 }
869 
875 static void DrawGame(int x, int y)
876 {
877  int i, sx, sy, chunks, blocks;
878  int wdt, nSrcOff, nDstOff;
879 
880  sx = (SCREEN_WIDTH % 64) / 2;
881  sy = (VIEWPORT_HEIGHT % 32) / 2;
882 
883  if (zoomflag) {
884  chunks = ceil(SCREEN_WIDTH / 64);
885  blocks = ceil(VIEWPORT_HEIGHT / 32);
886 
889  } else {
890  sy -= 32;
891 
892  chunks = ceil(SCREEN_WIDTH / 2 / 64) + 1; // TODO why +1?
893  blocks = ceil(VIEWPORT_HEIGHT / 2 / 32);
894 
896  gpBufEnd = &gpBuffer[(160 + SCREEN_Y) * BUFFER_WIDTH];
897  }
898 
899  sx += ScrollInfo._sxoff + SCREEN_X;
900  sy += ScrollInfo._syoff + SCREEN_Y + 15;
901 
902  // Center screen
903  x -= chunks;
904  y--;
905 
906  // Keep evaulating untill MicroTiles can't affect screen
907  blocks += ceil(MicroTileLen / 2);
908 
909  if (PANELS_COVER) {
910  if (zoomflag) {
911  if (chrflag || questlog) {
912  x += 2;
913  y -= 2;
914  sx += 288;
915  chunks -= 4;
916  }
917  if (invflag || sbookflag) {
918  x += 2;
919  y -= 2;
920  sx -= 32;
921  chunks -= 4;
922  }
923  }
924  }
925 
926  switch (ScrollInfo._sdir) {
927  case SDIR_N:
928  sy -= 32;
929  x--;
930  y--;
931  blocks++;
932  break;
933  case SDIR_NE:
934  sy -= 32;
935  x--;
936  y--;
937  chunks++;
938  blocks++;
939  break;
940  case SDIR_E:
941  chunks++;
942  break;
943  case SDIR_SE:
944  chunks++;
945  blocks++;
946  break;
947  case SDIR_S:
948  blocks++;
949  break;
950  case SDIR_SW:
951  sx -= 64;
952  x--;
953  y++;
954  chunks++;
955  blocks++;
956  break;
957  case SDIR_W:
958  sx -= 64;
959  x--;
960  y++;
961  chunks++;
962  break;
963  case SDIR_NW:
964  sx -= 64;
965  sy -= 32;
966  x -= 2;
967  chunks++;
968  blocks++;
969  break;
970  }
971 
972  memset(dRendered, 0, sizeof(dRendered));
973  scrollrt_drawFloor(x, y, sx, sy, blocks, chunks);
974  scrollrt_draw(x, y, sx, sy, blocks, chunks);
975 
978 
979  if (zoomflag)
980  return;
981 
982  nSrcOff = SCREENXY(32, VIEWPORT_HEIGHT / 2 - 17);
983  nDstOff = SCREENXY(0, VIEWPORT_HEIGHT - 2);
984  wdt = SCREEN_WIDTH / 2;
985  if (PANELS_COVER) {
986  if (chrflag || questlog) {
987  nSrcOff = SCREENXY(112, VIEWPORT_HEIGHT / 2 - 17);
988  nDstOff = SCREENXY(SPANEL_WIDTH, VIEWPORT_HEIGHT - 2);
989  wdt = (SCREEN_WIDTH - SPANEL_WIDTH) / 2;
990  } else if (invflag || sbookflag) {
991  nSrcOff = SCREENXY(112, VIEWPORT_HEIGHT / 2 - 17);
992  nDstOff = SCREENXY(0, VIEWPORT_HEIGHT - 2);
993  wdt = (SCREEN_WIDTH - SPANEL_WIDTH) / 2;
994  }
995  }
996 
997  int hgt;
998  BYTE *src, *dst1, *dst2;
999 
1000  src = &gpBuffer[nSrcOff];
1001  dst1 = &gpBuffer[nDstOff];
1002  dst2 = &gpBuffer[nDstOff + BUFFER_WIDTH];
1003 
1004  for (hgt = VIEWPORT_HEIGHT / 2; hgt != 0; hgt--, src -= BUFFER_WIDTH + wdt, dst1 -= 2 * (BUFFER_WIDTH + wdt), dst2 -= 2 * (BUFFER_WIDTH + wdt)) {
1005  for (i = wdt; i != 0; i--) {
1006  *dst1++ = *src;
1007  *dst1++ = *src;
1008  *dst2++ = *src;
1009  *dst2++ = *src;
1010  src++;
1011  }
1012  }
1013 }
1014 
1015 // DevilutionX extension.
1016 extern void DrawControllerModifierHints();
1017 
1023 void DrawView(int StartX, int StartY)
1024 {
1025  DrawGame(StartX, StartY);
1026  if (automapflag) {
1027  DrawAutomap();
1028  }
1029  if (stextflag && !qtextflag)
1030  DrawSText();
1031  if (invflag) {
1032  DrawInv();
1033  } else if (sbookflag) {
1034  DrawSpellBook();
1035  }
1036 
1037  DrawDurIcon();
1038 
1039  if (chrflag) {
1040  DrawChr();
1041  } else if (questlog) {
1042  DrawQuestLog();
1043  }
1044  if (!chrflag && plr[myplr]._pStatPts != 0 && !spselflag
1046  DrawLevelUpIcon();
1047  }
1048  if (uitemflag) {
1049  DrawUniqueInfo();
1050  }
1051  if (qtextflag) {
1052  DrawQText();
1053  }
1054  if (spselflag) {
1055  DrawSpellList();
1056  }
1057  if (dropGoldFlag) {
1059  }
1060  if (helpflag) {
1061  DrawHelp();
1062  }
1063  if (msgflag) {
1064  DrawDiabloMsg();
1065  }
1066  if (deathflag) {
1067  RedBack();
1068  } else if (PauseMode != 0) {
1069  gmenu_draw_pause();
1070  }
1071 
1073  DrawPlrMsg();
1074  gmenu_draw();
1075  doom_draw();
1076  DrawInfoBox();
1077  DrawLifeFlask();
1078  DrawManaFlask();
1079 }
1080 
1085 {
1086  lock_buf(3);
1087 
1088  assert(gpBuffer);
1089 
1090  int i;
1091  BYTE *dst;
1092 
1093  dst = &gpBuffer[SCREENXY(0, 0)];
1094 
1095  for (i = 0; i < SCREEN_HEIGHT; i++, dst += BUFFER_WIDTH) {
1096  memset(dst, 0, SCREEN_WIDTH);
1097  }
1098 
1099  unlock_buf(3);
1100 }
1101 
1102 #ifdef _DEBUG
1103 
1106 void ScrollView()
1107 {
1108  BOOL scroll;
1109 
1110  if (pcurs >= CURSOR_FIRSTITEM)
1111  return;
1112 
1113  scroll = FALSE;
1114 
1115  if (MouseX < 20) {
1116  if (dmaxy - 1 <= ViewY || dminx >= ViewX) {
1117  if (dmaxy - 1 > ViewY) {
1118  ViewY++;
1119  scroll = TRUE;
1120  }
1121  if (dminx < ViewX) {
1122  ViewX--;
1123  scroll = TRUE;
1124  }
1125  } else {
1126  ViewY++;
1127  ViewX--;
1128  scroll = TRUE;
1129  }
1130  }
1131  if (MouseX > SCREEN_WIDTH - 20) {
1132  if (dmaxx - 1 <= ViewX || dminy >= ViewY) {
1133  if (dmaxx - 1 > ViewX) {
1134  ViewX++;
1135  scroll = TRUE;
1136  }
1137  if (dminy < ViewY) {
1138  ViewY--;
1139  scroll = TRUE;
1140  }
1141  } else {
1142  ViewY--;
1143  ViewX++;
1144  scroll = TRUE;
1145  }
1146  }
1147  if (MouseY < 20) {
1148  if (dminy >= ViewY || dminx >= ViewX) {
1149  if (dminy < ViewY) {
1150  ViewY--;
1151  scroll = TRUE;
1152  }
1153  if (dminx < ViewX) {
1154  ViewX--;
1155  scroll = TRUE;
1156  }
1157  } else {
1158  ViewX--;
1159  ViewY--;
1160  scroll = TRUE;
1161  }
1162  }
1163  if (MouseY > SCREEN_HEIGHT - 20) {
1164  if (dmaxy - 1 <= ViewY || dmaxx - 1 <= ViewX) {
1165  if (dmaxy - 1 > ViewY) {
1166  ViewY++;
1167  scroll = TRUE;
1168  }
1169  if (dmaxx - 1 > ViewX) {
1170  ViewX++;
1171  scroll = TRUE;
1172  }
1173  } else {
1174  ViewX++;
1175  ViewY++;
1176  scroll = TRUE;
1177  }
1178  }
1179 
1180  if (scroll)
1182 }
1183 #endif
1184 
1189 {
1190  frameflag = frameflag == 0;
1191  framestart = SDL_GetTicks();
1192 }
1193 
1197 static void DrawFPS()
1198 {
1199  DWORD tc, frames;
1200  char String[12];
1201  HDC hdc;
1202 
1203  if (frameflag && gbActive && pPanelText) {
1204  frameend++;
1205  tc = SDL_GetTicks();
1206  frames = tc - framestart;
1207  if (tc - framestart >= 1000) {
1208  framestart = tc;
1209  framerate = 1000 * frameend / frames;
1210  frameend = 0;
1211  }
1212  snprintf(String, 12, "%d FPS", framerate);
1213  PrintGameStr(8, 65, String, COL_RED);
1214  }
1215 }
1216 
1224 static void DoBlitScreen(DWORD dwX, DWORD dwY, DWORD dwWdt, DWORD dwHgt)
1225 {
1226  SDL_Rect SrcRect = {
1227  dwX + SCREEN_X,
1228  dwY + SCREEN_Y,
1229  dwWdt,
1230  dwHgt,
1231  };
1232  SDL_Rect DstRect = {
1233  dwX,
1234  dwY,
1235  dwWdt,
1236  dwHgt,
1237  };
1238 
1239  BltFast(&SrcRect, &DstRect);
1240 }
1241 
1251 static void DrawMain(int dwHgt, BOOL draw_desc, BOOL draw_hp, BOOL draw_mana, BOOL draw_sbar, BOOL draw_btn)
1252 {
1253  int ysize;
1254  DWORD dwTicks;
1255  BOOL retry;
1256 
1257  ysize = dwHgt;
1258 
1259  if (!gbActive) {
1260  return;
1261  }
1262 
1263  assert(ysize >= 0 && ysize <= SCREEN_HEIGHT);
1264 
1265  if (ysize > 0) {
1266  DoBlitScreen(0, 0, SCREEN_WIDTH, ysize);
1267  }
1268  if (ysize < SCREEN_HEIGHT) {
1269  if (draw_sbar) {
1270  DoBlitScreen(PANEL_LEFT + 204, PANEL_TOP + 5, 232, 28);
1271  }
1272  if (draw_desc) {
1273  DoBlitScreen(PANEL_LEFT + 176, PANEL_TOP + 46, 288, 60);
1274  }
1275  if (draw_mana) {
1276  DoBlitScreen(PANEL_LEFT + 460, PANEL_TOP, 88, 72);
1277  DoBlitScreen(PANEL_LEFT + 564, PANEL_TOP + 64, 56, 56);
1278  }
1279  if (draw_hp) {
1280  DoBlitScreen(PANEL_LEFT + 96, PANEL_TOP, 88, 72);
1281  }
1282  if (draw_btn) {
1283  DoBlitScreen(PANEL_LEFT + 8, PANEL_TOP + 5, 72, 119);
1284  DoBlitScreen(PANEL_LEFT + 556, PANEL_TOP + 5, 72, 48);
1285  if (gbMaxPlayers > 1) {
1286  DoBlitScreen(PANEL_LEFT + 84, PANEL_TOP + 91, 36, 32);
1287  DoBlitScreen(PANEL_LEFT + 524, PANEL_TOP + 91, 36, 32);
1288  }
1289  }
1290  if (sgdwCursWdtOld != 0) {
1292  }
1293  if (sgdwCursWdt != 0) {
1295  }
1296  }
1297 }
1298 
1303 void scrollrt_draw_game_screen(BOOL draw_cursor)
1304 {
1305  int hgt;
1306 
1307  if (force_redraw == 255) {
1308  force_redraw = 0;
1309  hgt = SCREEN_HEIGHT;
1310  } else {
1311  hgt = 0;
1312  }
1313 
1314  if (draw_cursor) {
1315  lock_buf(0);
1317  unlock_buf(0);
1318  }
1319 
1320  DrawMain(hgt, 0, 0, 0, 0, 0);
1321 
1322  if (draw_cursor) {
1323  lock_buf(0);
1325  unlock_buf(0);
1326  }
1327  RenderPresent();
1328 }
1329 
1334 {
1335  int hgt;
1336  BOOL ddsdesc, ctrlPan;
1337 
1338  if (!gbRunGame) {
1339  return;
1340  }
1341 
1343  drawhpflag = TRUE;
1344  drawmanaflag = TRUE;
1345  drawbtnflag = TRUE;
1346  drawsbarflag = TRUE;
1347  ddsdesc = FALSE;
1348  ctrlPan = TRUE;
1349  hgt = SCREEN_HEIGHT;
1350  } else {
1351  ddsdesc = TRUE;
1352  ctrlPan = FALSE;
1353  hgt = VIEWPORT_HEIGHT;
1354  }
1355 
1356  force_redraw = 0;
1357 
1358  lock_buf(0);
1359  DrawView(ViewX, ViewY);
1360  if (ctrlPan) {
1361  DrawCtrlPan();
1362  }
1363  if (drawhpflag) {
1364  UpdateLifeFlask();
1365  }
1366  if (drawmanaflag) {
1367  UpdateManaFlask();
1368  }
1369  if (drawbtnflag) {
1370  DrawCtrlBtns();
1371  }
1372  if (drawsbarflag) {
1373  DrawInvBelt();
1374  }
1375  if (talkflag) {
1376  DrawTalkPan();
1377  hgt = SCREEN_HEIGHT;
1378  }
1380 
1381  DrawFPS();
1382 
1383  unlock_buf(0);
1384 
1386 
1387  lock_buf(0);
1389  unlock_buf(0);
1390  RenderPresent();
1391 
1392  drawhpflag = FALSE;
1393  drawmanaflag = FALSE;
1394  drawbtnflag = FALSE;
1395  drawsbarflag = FALSE;
1396 }
1397 
DeadStruct::_deadData
unsigned char * _deadData[8]
Definition: structs.h:1199
gpBuffer
BYTE * gpBuffer
MissilePreFlag
BOOL MissilePreFlag
Definition: missiles.cpp:16
sgdwCursHgtOld
DWORD sgdwCursHgtOld
Definition: scrollrt.cpp:50
talkflag
BOOL talkflag
Definition: control.cpp:46
SDIR_NW
@ SDIR_NW
Definition: enums.h:2102
MouseY
int MouseY
Definition: diablo.cpp:17
DrawPlrMsg
void DrawPlrMsg()
Definition: plrmsg.cpp:84
ScrollStruct::_sdir
int _sdir
Definition: structs.h:1110
SCREENXY
#define SCREENXY(x, y)
Definition: defs.h:155
DrawCtrlPan
void DrawCtrlPan()
Definition: control.cpp:831
force_redraw
int force_redraw
Definition: diablo.cpp:30
Cl2DrawLightTbl
void Cl2DrawLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
Blit CL2 sprite, and apply a given lighting, to the back buffer at the given coordianates.
Definition: engine.cpp:1123
PlayerStruct::_pAnimFrame
int _pAnimFrame
Definition: structs.h:209
currlevel
BYTE currlevel
Definition: gendung.cpp:40
Cl2DrawOutline
void Cl2DrawOutline(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Blit a solid colder shape one pixel larger then the given sprite shape, to the back buffer at the giv...
Definition: engine.cpp:1009
DrawChr
void DrawChr()
Definition: control.cpp:1321
MissileStruct::_miAnimWidth
int _miAnimWidth
Definition: structs.h:427
MICROS::mt
WORD mt[16]
Definition: structs.h:1122
PlayerStruct::_pxoff
int _pxoff
Definition: structs.h:198
dminx
int dminx
Definition: gendung.cpp:77
SCREEN_Y
#define SCREEN_Y
Definition: defs.h:126
MAX_PLRS
#define MAX_PLRS
Definition: defs.h:16
DrawMissile
void DrawMissile(int x, int y, int sx, int sy, BOOL pre)
Render a missile sprites for a given tile.
Definition: scrollrt.cpp:259
MAXMISSILES
#define MAXMISSILES
Definition: defs.h:30
MFILE_MANASHLD
@ MFILE_MANASHLD
Definition: enums.h:1274
pSpecialCels
BYTE * pSpecialCels
Definition: gendung.cpp:55
DrawTalkPan
void DrawTalkPan()
Definition: control.cpp:2002
level_cel_block
DWORD level_cel_block
Specifies the current MIN block of the level CEL file, as used during rendering of the level tiles.
Definition: scrollrt.cpp:28
zoomflag
BOOL zoomflag
Definition: diablo.cpp:24
MissileStruct::_miDrawFlag
BOOL _miDrawFlag
Definition: structs.h:432
cel_transparency_active
int cel_transparency_active
Specifies whether transparency is active for the current CEL file being decoded.
Definition: scrollrt.cpp:38
sgdwCursY
DWORD sgdwCursY
Definition: scrollrt.cpp:11
DrawSpellList
void DrawSpellList()
Definition: control.cpp:317
RenderPresent
void RenderPresent()
PlayerStruct::WorldX
int WorldX
Definition: structs.h:188
IsWalktabke
#define IsWalktabke(x, y)
Definition: scrollrt.cpp:814
cursH
DEVILUTION_BEGIN_NAMESPACE int cursH
Definition: cursor.cpp:10
dmaxx
int dmaxx
Definition: gendung.cpp:68
frameflag
int frameflag
Definition: diablo.cpp:67
MAXDUNX
#define MAXDUNX
Definition: defs.h:25
pcursplr
char pcursplr
Definition: cursor.cpp:23
CelClippedBlitLightTrans
void CelClippedBlitLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
Same as CelBlitLightTransSafe.
Definition: engine.cpp:424
DrawMonsterHelper
static void DrawMonsterHelper(int x, int y, int oy, int sx, int sy)
Check if and how a mosnter should be rendered.
Definition: scrollrt.cpp:609
PlayerStruct::_pAnimWidth2
int _pAnimWidth2
Definition: structs.h:211
ItemStruct::_iAnimWidth2
int _iAnimWidth2
Definition: structs.h:110
item
ItemStruct item[MAXITEMS+1]
Definition: items.cpp:15
MAXITEMS
#define MAXITEMS
Definition: defs.h:27
MonsterStruct::_mAnimFrame
int _mAnimFrame
Definition: structs.h:567
gbActive
int gbActive
Definition: init.cpp:16
DrawFPS
static void DrawFPS()
Display the current average FPS over 1 sec.
Definition: scrollrt.cpp:1197
questlog
BOOL questlog
Definition: quests.cpp:6
TransList
BOOLEAN TransList[256]
Definition: gendung.cpp:41
MICROS
Definition: structs.h:1121
CelBlitFrame
void CelBlitFrame(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
Blit a given CEL frame to the given buffer.
Definition: engine.cpp:59
CMonster::width
int width
Definition: structs.h:526
ViewX
int ViewX
Definition: gendung.cpp:73
missile
MissileStruct missile[MAXMISSILES]
Definition: missiles.cpp:12
DrawDurIcon
void DrawDurIcon()
Definition: control.cpp:1663
dropGoldValue
int dropGoldValue
Definition: control.cpp:23
framestart
int framestart
Definition: diablo.cpp:70
VIEWPORT_HEIGHT
#define VIEWPORT_HEIGHT
Definition: defs.h:149
towner
TownerStruct towner[16]
Definition: towners.cpp:13
automapflag
BOOL automapflag
Specifies whether the automap is enabled.
Definition: automap.cpp:18
RenderTile
void RenderTile(BYTE *pBuff)
Blit current world CEL to the given buffer.
Definition: render.cpp:187
MissileStruct::_miPreFlag
BOOL _miPreFlag
Definition: structs.h:434
PAL16_YELLOW
#define PAL16_YELLOW
Definition: defs.h:100
MissileStruct::_mixoff
int _mixoff
Definition: structs.h:411
all.h
ViewY
int ViewY
Definition: gendung.cpp:74
DrawLevelUpIcon
void DrawLevelUpIcon()
Definition: control.cpp:1579
sgdwCursX
DWORD sgdwCursX
Definition: scrollrt.cpp:10
MissileStruct::_miy
int _miy
Definition: structs.h:410
sgSaveBack
BYTE sgSaveBack[8192]
Definition: scrollrt.cpp:49
dObject
char dObject[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:19
BltFast
void BltFast(SDL_Rect *src_rect, SDL_Rect *dst_rect)
ItemStruct::_iAnimData
unsigned char * _iAnimData
Definition: structs.h:106
DrawControllerModifierHints
void DrawControllerModifierHints()
doom_draw
void doom_draw()
Definition: doom.cpp:83
PauseMode
int PauseMode
Definition: diablo.cpp:41
scrollrt_draw_dungeon
static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy)
Render object sprites.
Definition: scrollrt.cpp:677
level_piece_id
int level_piece_id
Specifies the current dungeon piece ID of the level, as used during rendering of the level tiles.
Definition: scrollrt.cpp:46
ItemStruct
Definition: structs.h:99
gbMaxPlayers
BYTE gbMaxPlayers
Specifies the maximum number of players in a game, where 1 represents a single player game and 4 repr...
Definition: multi.cpp:34
DrawAndBlit
void DrawAndBlit()
Render the game.
Definition: scrollrt.cpp:1333
Cl2DrawLight
void Cl2DrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Blit CL2 sprite, and apply lighting, to the back buffer at the given coordinates.
Definition: engine.cpp:1237
SCREEN_WIDTH
#define SCREEN_WIDTH
Definition: defs.h:105
DeadStruct::_deadWidth2
int _deadWidth2
Definition: structs.h:1202
sgdwCursWdt
DWORD sgdwCursWdt
Definition: scrollrt.cpp:47
DrawView
void DrawView(int StartX, int StartY)
Start rendering of screen, town variation.
Definition: scrollrt.cpp:1023
DrawPlayer
static void DrawPlayer(int pnum, int x, int y, int px, int py, BYTE *pCelBuff, int nCel, int nWidth)
Render a player sprite.
Definition: scrollrt.cpp:353
MAXDUNY
#define MAXDUNY
Definition: defs.h:26
UpdateManaFlask
void UpdateManaFlask()
Controls the drawing of the area of the life flask within the control panel.
Definition: control.cpp:720
MissileStruct::_miyoff
int _miyoff
Definition: structs.h:412
CelClippedDrawLight
void CelClippedDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Same as CelDrawLight but with the option to skip parts of the top and bottom of the sprite.
Definition: engine.cpp:129
BFLAG_LIT
@ BFLAG_LIT
Definition: enums.h:1883
sbookflag
BOOL sbookflag
Definition: control.cpp:48
dLight
char dLight[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:27
ItemStruct::_iAnimFrame
int _iAnimFrame
Definition: structs.h:108
CURSOR_NONE
@ CURSOR_NONE
Definition: enums.h:2066
DeadStruct::_deadFrame
int _deadFrame
Definition: structs.h:1200
dPiece
int dPiece[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:26
CURSOR_FIRSTITEM
@ CURSOR_FIRSTITEM
Definition: enums.h:2078
gpBufStart
BYTE * gpBufStart
Upper bound of back buffer.
Definition: scrollrt.cpp:15
DrawAutomap
void DrawAutomap()
Definition: automap.cpp:174
nSolidTable
BOOLEAN nSolidTable[2049]
List of path blocking dPieces.
Definition: gendung.cpp:45
MissileStruct::_miUniqTrans
int _miUniqTrans
Definition: structs.h:435
assert
#define assert(exp)
Definition: defs.h:168
DrawMain
static void DrawMain(int dwHgt, BOOL draw_desc, BOOL draw_hp, BOOL draw_mana, BOOL draw_sbar, BOOL draw_btn)
Check render pipline and blit indivudal screen parts.
Definition: scrollrt.cpp:1251
szMonModeAssert
char * szMonModeAssert[18]
used in 1.00 debug
Definition: scrollrt.cpp:57
MonsterStruct::_mxoff
int _mxoff
Definition: structs.h:554
drawbtnflag
BOOL drawbtnflag
Definition: control.cpp:50
scrollrt_draw_cursor_item
static void scrollrt_draw_cursor_item()
Draw the cursor on the back buffer.
Definition: scrollrt.cpp:137
MissileStruct::_miLightFlag
BOOL _miLightFlag
Definition: structs.h:433
DrawQuestLog
void DrawQuestLog()
Definition: quests.cpp:733
UpdateLifeFlask
void UpdateLifeFlask()
Controls the drawing of the area of the life flask within the control panel.
Definition: control.cpp:669
DrawManaFlask
void DrawManaFlask()
Definition: control.cpp:684
uitemflag
BOOL uitemflag
Definition: items.cpp:11
gbRunGame
BOOL gbRunGame
Definition: diablo.cpp:21
sgdwCursXOld
DWORD sgdwCursXOld
Definition: scrollrt.cpp:29
DEVILUTION_END_NAMESPACE
#define DEVILUTION_END_NAMESPACE
Definition: types.h:10
light_table_index
DEVILUTION_BEGIN_NAMESPACE int light_table_index
Specifies the current light entry.
Definition: scrollrt.cpp:8
PlayerStruct::_pAnimData
unsigned char * _pAnimData
Definition: structs.h:205
monster
MonsterStruct monster[MAXMONSTERS]
Definition: monster.cpp:19
MonsterStruct::MType
CMonster * MType
Definition: structs.h:612
DrawCtrlBtns
void DrawCtrlBtns()
Draws the control panel buttons in their current state.
Definition: control.cpp:841
lock_buf
void lock_buf(BYTE idx)
DrawSText
void DrawSText()
Definition: stores.cpp:1509
SDIR_E
@ SDIR_E
Definition: enums.h:2097
SDIR_W
@ SDIR_W
Definition: enums.h:2101
PANEL_WIDTH
#define PANEL_WIDTH
Definition: defs.h:132
dMissile
char dMissile[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:76
SDIR_SE
@ SDIR_SE
Definition: enums.h:2098
PlayerStruct::plractive
BOOLEAN plractive
Definition: structs.h:181
cel_foliage_active
int cel_foliage_active
Specifies whether foliage (tile has extra content that overlaps previous tile) being rendered.
Definition: scrollrt.cpp:42
drawFloor
static void drawFloor(int x, int y, int sx, int sy)
Render a floor tiles.
Definition: scrollrt.cpp:555
drawsbarflag
BOOL drawsbarflag
Definition: inv.cpp:12
ItemStruct::_iAnimWidth
int _iAnimWidth
Definition: structs.h:109
dItem
char dItem[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:57
SDIR_N
@ SDIR_N
Definition: enums.h:2095
DrawMonster
static void DrawMonster(int x, int y, int mx, int my, int m)
Render a monster sprite.
Definition: scrollrt.cpp:290
COL_RED
@ COL_RED
Definition: enums.h:1995
dRendered
bool dRendered[MAXDUNX][MAXDUNY]
Definition: scrollrt.cpp:52
DrawInvBelt
void DrawInvBelt()
Definition: inv.cpp:404
DeadStruct::_deadtrans
char _deadtrans
Definition: structs.h:1203
scrollrt_draw
static void scrollrt_draw(int x, int y, int sx, int sy, int blocks, int chunks)
Render a row of tile.
Definition: scrollrt.cpp:825
BFLAG_DEAD_PLAYER
@ BFLAG_DEAD_PLAYER
Definition: enums.h:1879
unlock_buf
void unlock_buf(BYTE idx)
dmaxy
int dmaxy
Definition: gendung.cpp:69
missileactive
DEVILUTION_BEGIN_NAMESPACE int missileactive[MAXMISSILES]
Definition: missiles.cpp:10
pSquareCel
BYTE * pSquareCel
Definition: debug.cpp:19
MissileStruct::_mix
int _mix
Definition: structs.h:409
DrawInv
void DrawInv()
Definition: inv.cpp:160
sgdwCursWdtOld
DWORD sgdwCursWdtOld
Definition: scrollrt.cpp:9
MonsterStruct::_mFlags
int _mFlags
Definition: structs.h:583
DeadStruct::_deadWidth
int _deadWidth
Definition: structs.h:1201
gpBufEnd
BYTE * gpBufEnd
Lower bound of back buffer.
Definition: scrollrt.cpp:19
DrawPlayerHelper
static void DrawPlayerHelper(int x, int y, int oy, int sx, int sy)
Check if and how a player should be rendered.
Definition: scrollrt.cpp:659
CelClippedDraw
void CelClippedDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Same as CelDraw but with the option to skip parts of the top and bottom of the sprite.
Definition: engine.cpp:79
gmenu_draw_pause
void gmenu_draw_pause()
Definition: gmenu.cpp:50
SPANEL_WIDTH
#define SPANEL_WIDTH
Definition: defs.h:139
setlevel
BOOLEAN setlevel
Definition: gendung.cpp:65
pcursmonst
int pcursmonst
Definition: cursor.cpp:13
sgdwCursHgt
DWORD sgdwCursHgt
Definition: scrollrt.cpp:20
PANELS_COVER
#define PANELS_COVER
Definition: defs.h:141
pcursobj
char pcursobj
Definition: cursor.cpp:22
MissileStruct
Definition: structs.h:407
DrawLifeFlask
void DrawLifeFlask()
Draws the top dome of the life flask (that part that protrudes out of the control panel).
Definition: control.cpp:647
DeadStruct
Definition: structs.h:1198
dpiece_defs_map_2
MICROS dpiece_defs_map_2[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:79
CelClippedDrawSafe
void CelClippedDrawSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Same as CelClippedDraw but checks for drawing outside the buffer.
Definition: engine.cpp:246
MAXOBJECTS
#define MAXOBJECTS
Definition: defs.h:33
DTYPE_TOWN
@ DTYPE_TOWN
Definition: enums.h:1868
DrawItem
static void DrawItem(int x, int y, int sx, int sy, BOOL pre)
Draw item for a given tile.
Definition: scrollrt.cpp:581
spselflag
BOOL spselflag
Definition: control.cpp:62
DrawMissilePrivate
void DrawMissilePrivate(MissileStruct *m, int sx, int sy, BOOL pre)
Render a missile sprite.
Definition: scrollrt.cpp:222
arch_draw_type
char arch_draw_type
Specifies the type of arches to render.
Definition: scrollrt.cpp:34
invflag
DEVILUTION_BEGIN_NAMESPACE BOOL invflag
Definition: inv.cpp:10
PlayerStruct::_pAnimWidth
int _pAnimWidth
Definition: structs.h:210
MissileStruct::_miAnimData
unsigned char * _miAnimData
Definition: structs.h:424
pPanelText
BYTE * pPanelText
Definition: control.cpp:27
SPANEL_HEIGHT
#define SPANEL_HEIGHT
Definition: defs.h:140
dTransVal
char dTransVal[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:37
MissileStruct::_miAnimFrame
int _miAnimFrame
Definition: structs.h:431
CMonster::width2
int width2
Definition: structs.h:527
dead
DeadStruct dead[MAXDEAD]
Definition: dead.cpp:12
PAL16_RED
#define PAL16_RED
Definition: defs.h:102
EnableFrameCount
void EnableFrameCount()
Initialize the FPS meter.
Definition: scrollrt.cpp:1188
scrollrt_draw_game_screen
void scrollrt_draw_game_screen(BOOL draw_cursor)
Redraw screen.
Definition: scrollrt.cpp:1303
DrawPlrProc
void(* DrawPlrProc)(int, int, int, int, int, BYTE *, int, int, int, int)
Definition: scrollrt.cpp:48
msgflag
char msgflag
Definition: error.cpp:12
MM_STONE
@ MM_STONE
Definition: enums.h:2028
szPlrModeAssert
char * szPlrModeAssert[12]
Definition: scrollrt.cpp:78
MonsterStruct
Definition: structs.h:539
drawCell
static void drawCell(int x, int y, int sx, int sy)
Render a cell.
Definition: scrollrt.cpp:522
framerate
int framerate
Definition: diablo.cpp:69
ItemStruct::_iPostDraw
BOOL _iPostDraw
Definition: structs.h:113
chrflag
BOOL chrflag
Definition: control.cpp:49
dSpecial
char dSpecial[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:50
pcursitem
char pcursitem
Definition: cursor.cpp:21
PlayerStruct::_pyoff
int _pyoff
Definition: structs.h:199
myplr
int myplr
Definition: player.cpp:9
sgdwCursYOld
DWORD sgdwCursYOld
Definition: scrollrt.cpp:30
DrawSpellBook
void DrawSpellBook()
Definition: control.cpp:1774
DrawInfoBox
void DrawInfoBox()
Sets a string to be drawn in the info box and then draws it.
Definition: control.cpp:1190
MonsterStruct::_uniqtrans
unsigned char _uniqtrans
Definition: structs.h:592
helpflag
BOOL helpflag
Definition: help.cpp:12
PlayerStruct::_pHitPoints
int _pHitPoints
Definition: structs.h:258
MissileStruct::_miAnimWidth2
int _miAnimWidth2
Definition: structs.h:428
nTransTable
BOOLEAN nTransTable[2049]
List of transparent dPieces.
Definition: gendung.cpp:15
drawmanaflag
BOOL drawmanaflag
Definition: control.cpp:24
nummissiles
int nummissiles
Definition: missiles.cpp:13
IsWall
#define IsWall(x, y)
Definition: scrollrt.cpp:813
BUFFER_WIDTH
#define BUFFER_WIDTH
Definition: defs.h:128
PlayerStruct::plrlevel
int plrlevel
Definition: structs.h:187
ClearScreenBuffer
void ClearScreenBuffer()
Render the whole screen black.
Definition: scrollrt.cpp:1084
DrawHelp
void DrawHelp()
Definition: help.cpp:452
CelDrawLightRedSafe
void CelDrawLightRedSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
Same as CelDrawLightRed but checks for drawing outside the buffer.
Definition: engine.cpp:450
world_draw_black_tile
void world_draw_black_tile(int sx, int sy)
Render a black tile.
Definition: render.cpp:309
MonsterStruct::_myoff
int _myoff
Definition: structs.h:555
pcurs
int pcurs
Definition: cursor.cpp:27
dMonster
int dMonster[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:17
scrollrt_drawFloor
static void scrollrt_drawFloor(int x, int y, int sx, int sy, int blocks, int chunks)
Render a row of floor tiles.
Definition: scrollrt.cpp:773
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
sgbControllerActive
bool sgbControllerActive
DrawObject
static void DrawObject(int x, int y, int ox, int oy, BOOL pre)
Render an object sprite.
Definition: scrollrt.cpp:464
PANEL_TOP
#define PANEL_TOP
Definition: defs.h:134
pCursCels
BYTE * pCursCels
Definition: cursor.cpp:15
misfiledata
MisFileData misfiledata[]
Data related to each missile graphic ID.
Definition: misdat.cpp:86
BFLAG_MISSILE
@ BFLAG_MISSILE
Definition: enums.h:1877
dropGoldFlag
BOOL dropGoldFlag
Definition: control.cpp:15
SCREEN_X
#define SCREEN_X
Definition: defs.h:125
PANEL_LEFT
#define PANEL_LEFT
Definition: defs.h:135
DrawGoldSplit
void DrawGoldSplit(int amount)
Definition: control.cpp:1901
SDIR_SW
@ SDIR_SW
Definition: enums.h:2100
dPlayer
char dPlayer[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:49
TownerStruct::_tAnimWidth2
int _tAnimWidth2
Definition: structs.h:1064
dFlags
char dFlags[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:56
ScrollInfo
ScrollStruct ScrollInfo
Definition: gendung.cpp:46
Cl2Draw
void Cl2Draw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Blit CL2 sprite, to the back buffer at the given coordianates.
Definition: engine.cpp:904
ScrollStruct::_syoff
int _syoff
Definition: structs.h:1107
PAL16_BLUE
#define PAL16_BLUE
Definition: defs.h:99
MicroTileLen
int MicroTileLen
Definition: gendung.cpp:24
drawhpflag
BOOL drawhpflag
Definition: control.cpp:14
PANEL_HEIGHT
#define PANEL_HEIGHT
Definition: defs.h:133
scrollrt_draw_cursor_back_buffer
static void scrollrt_draw_cursor_back_buffer()
Remove the cursor from the back buffer.
Definition: scrollrt.cpp:105
PlayerStruct::WorldY
int WorldY
Definition: structs.h:189
SDIR_S
@ SDIR_S
Definition: enums.h:2099
dminy
int dminy
Definition: gendung.cpp:78
frameend
int frameend
Definition: diablo.cpp:68
DrawDiabloMsg
void DrawDiabloMsg()
Definition: error.cpp:93
MFLAG_HIDDEN
@ MFLAG_HIDDEN
Definition: enums.h:1503
MonsterStruct::_mAnimData
unsigned char * _mAnimData
Definition: structs.h:563
CURSOR_TELEPORT
@ CURSOR_TELEPORT
Definition: enums.h:2075
ScrollStruct::_sxoff
int _sxoff
Definition: structs.h:1106
qtextflag
BOOLEAN qtextflag
Definition: minitext.cpp:13
DrawUniqueInfo
void DrawUniqueInfo()
Definition: items.cpp:2974
RedBack
void RedBack()
Definition: control.cpp:1715
BFLAG_MONSTLR
@ BFLAG_MONSTLR
Definition: enums.h:1881
SCREEN_HEIGHT
#define SCREEN_HEIGHT
Definition: defs.h:106
leveltype
BYTE leveltype
Definition: gendung.cpp:39
DrawDeadPlayer
void DrawDeadPlayer(int x, int y, int sx, int sy)
Render a player sprite.
Definition: scrollrt.cpp:426
DrawQText
void DrawQText()
Definition: minitext.cpp:108
MAXMONSTERS
#define MAXMONSTERS
Definition: defs.h:31
visiondebug
BOOL visiondebug
Definition: diablo.cpp:31
dDead
char dDead[MAXDUNX][MAXDUNY]
Definition: gendung.cpp:21
plr
PlayerStruct plr[MAX_PLRS]
Definition: player.cpp:10
PlayerStruct
Definition: structs.h:178
CelBlitOutline
void CelBlitOutline(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Blit a solid colder shape one pixel larger then the given sprite shape, to the back buffer at the giv...
Definition: engine.cpp:549
SDIR_NE
@ SDIR_NE
Definition: enums.h:2096
DrawGame
static void DrawGame(int x, int y)
Configure render and process screen rows.
Definition: scrollrt.cpp:875
MouseX
int MouseX
Definition: diablo.cpp:18
stextflag
char stextflag
Definition: stores.cpp:39
lightmax
char lightmax
Definition: lighting.cpp:17
BFLAG_PLAYERLR
@ BFLAG_PLAYERLR
Definition: enums.h:1882
gmenu_draw
void gmenu_draw()
Definition: gmenu.cpp:155
DoBlitScreen
static void DoBlitScreen(DWORD dwX, DWORD dwY, DWORD dwWdt, DWORD dwHgt)
Update part of the screen from the back buffer.
Definition: scrollrt.cpp:1224
deathflag
BOOL deathflag
Definition: player.cpp:13
cursW
int cursW
Definition: cursor.cpp:12
SDIR_NONE
@ SDIR_NONE
Definition: enums.h:2094
PrintGameStr
void PrintGameStr(int x, int y, const char *str, int color)
Definition: control.cpp:1306
ClearCursor
void ClearCursor()
Clear cursor state.
Definition: scrollrt.cpp:96