Devilution
Diablo devolved - magic behind the 1996 computer game
engine.cpp
Go to the documentation of this file.
1 
13 #include "all.h"
14 #include "../3rdParty/Storm/Source/storm.h"
15 
17 
18 char gbPixelCol; // automap pixel color 8-bit (palette entry)
19 BOOL gbRotateMap; // flip - if y < x
20 int orgseed;
25 static CCritSect sgMemCrit;
27 BOOL gbNotInView; // valid - if x/y are in bounds
28 
32 const int RndInc = 1;
33 
37 const int RndMult = 0x015A4E35;
38 
47 void CelDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
48 {
49  CelBlitFrame(&gpBuffer[sx + BUFFER_WIDTH * sy], pCelBuff, nCel, nWidth);
50 }
51 
59 void CelBlitFrame(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
60 {
61  int nDataSize;
62  BYTE *pRLEBytes;
63 
64  assert(pCelBuff != NULL);
65  assert(pBuff != NULL);
66 
67  pRLEBytes = CelGetFrame(pCelBuff, nCel, &nDataSize);
68  CelBlitSafe(pBuff, pRLEBytes, nDataSize, nWidth);
69 }
70 
79 void CelClippedDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
80 {
81  BYTE *pRLEBytes;
82  int nDataSize;
83 
85  assert(pCelBuff != NULL);
86 
87  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
88 
90  &gpBuffer[sx + BUFFER_WIDTH * sy],
91  pRLEBytes,
92  nDataSize,
93  nWidth);
94 }
95 
104 void CelDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, BYTE *tbl)
105 {
106  int nDataSize;
107  BYTE *pDecodeTo, *pRLEBytes;
108 
109  assert(gpBuffer);
110  assert(pCelBuff != NULL);
111 
112  pRLEBytes = CelGetFrame(pCelBuff, nCel, &nDataSize);
113  pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
114 
115  if (light_table_index || tbl)
116  CelBlitLightSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth, tbl);
117  else
118  CelBlitSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth);
119 }
120 
129 void CelClippedDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
130 {
131  int nDataSize;
132  BYTE *pRLEBytes, *pDecodeTo;
133 
134  assert(gpBuffer);
135  assert(pCelBuff != NULL);
136 
137  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
138  pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
139 
140  if (light_table_index)
141  CelBlitLightSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth, NULL);
142  else
143  CelBlitSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth);
144 }
145 
155 void CelDrawLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
156 {
157  int nDataSize, w, idx;
158  BYTE *pRLEBytes, *dst, *tbl;
159 
160  assert(gpBuffer);
161  assert(pCelBuff != NULL);
162 
163  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
164  dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
165 
166  idx = light4flag ? 1024 : 4096;
167  if (light == 2)
168  idx += 256;
169  if (light >= 4)
170  idx += (light - 1) << 8;
171 
172  BYTE width;
173  BYTE *end;
174 
175  tbl = &pLightTbl[idx];
176  end = &pRLEBytes[nDataSize];
177 
178  for (; pRLEBytes != end; dst -= BUFFER_WIDTH + nWidth) {
179  for (w = nWidth; w;) {
180  width = *pRLEBytes++;
181  if (!(width & 0x80)) {
182  w -= width;
183  while (width) {
184  *dst = tbl[*pRLEBytes];
185  pRLEBytes++;
186  dst++;
187  width--;
188  }
189  } else {
190  width = -(char)width;
191  dst += width;
192  w -= width;
193  }
194  }
195  }
196 }
197 
205 void CelBlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
206 {
207  int i, w;
208  BYTE width;
209  BYTE *src, *dst;
210 
211  assert(pDecodeTo != NULL);
212  assert(pRLEBytes != NULL);
213  assert(gpBuffer);
214 
215  src = pRLEBytes;
216  dst = pDecodeTo;
217  w = nWidth;
218 
219  for (; src != &pRLEBytes[nDataSize]; dst -= BUFFER_WIDTH + w) {
220  for (i = w; i;) {
221  width = *src++;
222  if (!(width & 0x80)) {
223  i -= width;
224  if (dst < gpBufEnd && dst > gpBufStart) {
225  memcpy(dst, src, width);
226  }
227  src += width;
228  dst += width;
229  } else {
230  width = -(char)width;
231  dst += width;
232  i -= width;
233  }
234  }
235  }
236 }
237 
246 void CelClippedDrawSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
247 {
248  BYTE *pRLEBytes;
249  int nDataSize;
250 
251  assert(gpBuffer);
252  assert(pCelBuff != NULL);
253 
254  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
255 
256  CelBlitSafe(
257  &gpBuffer[sx + BUFFER_WIDTH * sy],
258  pRLEBytes,
259  nDataSize,
260  nWidth);
261 }
262 
271 void CelBlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl)
272 {
273  int i, w;
274  BYTE width;
275  BYTE *src, *dst;
276 
277  assert(pDecodeTo != NULL);
278  assert(pRLEBytes != NULL);
279  assert(gpBuffer);
280 
281  src = pRLEBytes;
282  dst = pDecodeTo;
283  if (tbl == NULL)
284  tbl = &pLightTbl[light_table_index * 256];
285  w = nWidth;
286 
287  for (; src != &pRLEBytes[nDataSize]; dst -= BUFFER_WIDTH + w) {
288  for (i = w; i;) {
289  width = *src++;
290  if (!(width & 0x80)) {
291  i -= width;
292  if (dst < gpBufEnd && dst > gpBufStart) {
293  if (width & 1) {
294  dst[0] = tbl[src[0]];
295  src++;
296  dst++;
297  }
298  width >>= 1;
299  if (width & 1) {
300  dst[0] = tbl[src[0]];
301  dst[1] = tbl[src[1]];
302  src += 2;
303  dst += 2;
304  }
305  width >>= 1;
306  for (; width; width--) {
307  dst[0] = tbl[src[0]];
308  dst[1] = tbl[src[1]];
309  dst[2] = tbl[src[2]];
310  dst[3] = tbl[src[3]];
311  src += 4;
312  dst += 4;
313  }
314  } else {
315  src += width;
316  dst += width;
317  }
318  } else {
319  width = -(char)width;
320  dst += width;
321  i -= width;
322  }
323  }
324  }
325 }
326 
334 void CelBlitLightTransSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
335 {
336  int w;
337  BOOL shift;
338  BYTE *tbl;
339 
340  assert(pDecodeTo != NULL);
341  assert(pRLEBytes != NULL);
342  assert(gpBuffer);
343 
344  int i;
345  BYTE width;
346  BYTE *src, *dst;
347 
348  src = pRLEBytes;
349  dst = pDecodeTo;
350  tbl = &pLightTbl[light_table_index * 256];
351  w = nWidth;
352  shift = (BYTE)(size_t)dst & 1;
353 
354  for (; src != &pRLEBytes[nDataSize]; dst -= BUFFER_WIDTH + w, shift = (shift + 1) & 1) {
355  for (i = w; i;) {
356  width = *src++;
357  if (!(width & 0x80)) {
358  i -= width;
359  if (dst < gpBufEnd && dst > gpBufStart) {
360  if (((BYTE)(size_t)dst & 1) == shift) {
361  if (!(width & 1)) {
362  goto L_ODD;
363  } else {
364  src++;
365  dst++;
366  L_EVEN:
367  width >>= 1;
368  if (width & 1) {
369  dst[0] = tbl[src[0]];
370  src += 2;
371  dst += 2;
372  }
373  width >>= 1;
374  for (; width; width--) {
375  dst[0] = tbl[src[0]];
376  dst[2] = tbl[src[2]];
377  src += 4;
378  dst += 4;
379  }
380  }
381  } else {
382  if (!(width & 1)) {
383  goto L_EVEN;
384  } else {
385  dst[0] = tbl[src[0]];
386  src++;
387  dst++;
388  L_ODD:
389  width >>= 1;
390  if (width & 1) {
391  dst[1] = tbl[src[1]];
392  src += 2;
393  dst += 2;
394  }
395  width >>= 1;
396  for (; width; width--) {
397  dst[1] = tbl[src[1]];
398  dst[3] = tbl[src[3]];
399  src += 4;
400  dst += 4;
401  }
402  }
403  }
404  } else {
405  src += width;
406  dst += width;
407  }
408  } else {
409  width = -(char)width;
410  dst += width;
411  i -= width;
412  }
413  }
414  }
415 }
416 
424 void CelClippedBlitLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
425 {
426  int nDataSize;
427  BYTE *pRLEBytes;
428 
429  assert(pCelBuff != NULL);
430 
431  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
432 
434  CelBlitLightTransSafe(pBuff, pRLEBytes, nDataSize, nWidth);
435  else if (light_table_index)
436  CelBlitLightSafe(pBuff, pRLEBytes, nDataSize, nWidth, NULL);
437  else
438  CelBlitSafe(pBuff, pRLEBytes, nDataSize, nWidth);
439 }
440 
450 void CelDrawLightRedSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
451 {
452  int nDataSize, w, idx;
453  BYTE *pRLEBytes, *dst, *tbl;
454 
455  assert(gpBuffer);
456  assert(pCelBuff != NULL);
457 
458  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
459  dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
460 
461  idx = light4flag ? 1024 : 4096;
462  if (light == 2)
463  idx += 256;
464  if (light >= 4)
465  idx += (light - 1) << 8;
466 
467  tbl = &pLightTbl[idx];
468 
469  BYTE width;
470  BYTE *end;
471 
472  end = &pRLEBytes[nDataSize];
473 
474  for (; pRLEBytes != end; dst -= BUFFER_WIDTH + nWidth) {
475  for (w = nWidth; w;) {
476  width = *pRLEBytes++;
477  if (!(width & 0x80)) {
478  w -= width;
479  if (dst < gpBufEnd && dst > gpBufStart) {
480  while (width) {
481  *dst = tbl[*pRLEBytes];
482  pRLEBytes++;
483  dst++;
484  width--;
485  }
486  } else {
487  pRLEBytes += width;
488  dst += width;
489  }
490  } else {
491  width = -(char)width;
492  dst += width;
493  w -= width;
494  }
495  }
496  }
497 }
498 
509 void CelBlitWidth(BYTE *pBuff, int x, int y, int wdt, BYTE *pCelBuff, int nCel, int nWidth)
510 {
511  BYTE *pRLEBytes, *dst, *end;
512 
513  assert(pCelBuff != NULL);
514  assert(pBuff != NULL);
515 
516  int i, nDataSize;
517  BYTE width;
518 
519  pRLEBytes = CelGetFrame(pCelBuff, nCel, &nDataSize);
520  end = &pRLEBytes[nDataSize];
521  dst = &pBuff[y * wdt + x];
522 
523  for (; pRLEBytes != end; dst -= wdt + nWidth) {
524  for (i = nWidth; i;) {
525  width = *pRLEBytes++;
526  if (!(width & 0x80)) {
527  i -= width;
528  memcpy(dst, pRLEBytes, width);
529  dst += width;
530  pRLEBytes += width;
531  } else {
532  width = -(char)width;
533  dst += width;
534  i -= width;
535  }
536  }
537  }
538 }
539 
549 void CelBlitOutline(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
550 {
551  int nDataSize, w;
552  BYTE *src, *dst, *end;
553  BYTE width;
554 
555  assert(pCelBuff != NULL);
556  assert(gpBuffer);
557 
558  src = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
559  end = &src[nDataSize];
560  dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
561 
562  for (; src != end; dst -= BUFFER_WIDTH + nWidth) {
563  for (w = nWidth; w;) {
564  width = *src++;
565  if (!(width & 0x80)) {
566  w -= width;
567  if (dst < gpBufEnd && dst > gpBufStart) {
568  if (dst >= gpBufEnd - BUFFER_WIDTH) {
569  while (width) {
570  if (*src++) {
571  dst[-BUFFER_WIDTH] = col;
572  dst[-1] = col;
573  dst[1] = col;
574  }
575  dst++;
576  width--;
577  }
578  } else {
579  while (width) {
580  if (*src++) {
581  dst[-BUFFER_WIDTH] = col;
582  dst[-1] = col;
583  dst[1] = col;
584  dst[BUFFER_WIDTH] = col;
585  }
586  dst++;
587  width--;
588  }
589  }
590  } else {
591  src += width;
592  dst += width;
593  }
594  } else {
595  width = -(char)width;
596  dst += width;
597  w -= width;
598  }
599  }
600  }
601 }
602 
609 void ENG_set_pixel(int sx, int sy, BYTE col)
610 {
611  BYTE *dst;
612 
613  assert(gpBuffer);
614 
615  if (sy < 0 || sy >= SCREEN_HEIGHT + SCREEN_Y || sx < SCREEN_X || sx >= SCREEN_WIDTH + SCREEN_X)
616  return;
617 
618  dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
619 
620  if (dst < gpBufEnd && dst > gpBufStart)
621  *dst = col;
622 }
623 
629 void engine_draw_pixel(int sx, int sy)
630 {
631  BYTE *dst;
632 
633  assert(gpBuffer);
634 
635  if (gbRotateMap) {
636  if (gbNotInView && (sx < 0 || sx >= SCREEN_HEIGHT + SCREEN_Y || sy < SCREEN_X || sy >= SCREEN_WIDTH + SCREEN_X))
637  return;
638  dst = &gpBuffer[sy + BUFFER_WIDTH * sx];
639  } else {
640  if (gbNotInView && (sy < 0 || sy >= SCREEN_HEIGHT + SCREEN_Y || sx < SCREEN_X || sx >= SCREEN_WIDTH + SCREEN_X))
641  return;
642  dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
643  }
644 
645  if (dst < gpBufEnd && dst > gpBufStart)
646  *dst = gbPixelCol;
647 }
648 
657 void DrawLine(int x0, int y0, int x1, int y1, BYTE col)
658 {
659  int i, dx, dy, steps;
660  float ix, iy, sx, sy;
661 
662  dx = x1 - x0;
663  dy = y1 - y0;
664  steps = abs(dx) > abs(dy) ? abs(dx) : abs(dy);
665  ix = dx / (float)steps;
666  iy = dy / (float)steps;
667  sx = x0;
668  sy = y0;
669 
670  for(i = 0; i <= steps; i++, sx += ix, sy += iy) {
671  ENG_set_pixel(sx, sy, col);
672  }
673 }
674 
683 int GetDirection(int x1, int y1, int x2, int y2)
684 {
685  int mx, my;
686  int md, ny;
687 
688  mx = x2 - x1;
689  my = y2 - y1;
690 
691  if (mx >= 0) {
692  if (my >= 0) {
693  md = DIR_S;
694  if (2 * mx < my)
695  md = DIR_SW;
696  } else {
697  my = -my;
698  md = DIR_E;
699  if (2 * mx < my)
700  md = DIR_NE;
701  }
702  if (2 * my < mx)
703  return DIR_SE;
704  } else {
705  if (my >= 0) {
706  ny = -mx;
707  md = DIR_W;
708  if (2 * ny < my)
709  md = DIR_SW;
710  } else {
711  ny = -mx;
712  my = -my;
713  md = DIR_N;
714  if (2 * ny < my)
715  md = DIR_NE;
716  }
717  if (2 * my < ny)
718  return DIR_NW;
719  }
720 
721  return md;
722 }
723 
728 void SetRndSeed(int s)
729 {
730  SeedCount = 0;
731  sglGameSeed = s;
732  orgseed = s;
733 }
734 
740 {
741  SeedCount++;
742  sglGameSeed = static_cast<unsigned int>(RndMult) * sglGameSeed + RndInc;
743  return abs(sglGameSeed);
744 }
745 
752 int random_(BYTE idx, int v)
753 {
754  if (v <= 0)
755  return 0;
756  if (v < 0xFFFF)
757  return (GetRndSeed() >> 16) % v;
758  return GetRndSeed() % v;
759 }
760 
765 BYTE *DiabloAllocPtr(DWORD dwBytes)
766 {
767  BYTE *buf;
768 
769  sgMemCrit.Enter();
770  buf = (BYTE *)SMemAlloc(dwBytes, __FILE__, __LINE__, 0);
771  sgMemCrit.Leave();
772 
773  if (buf == NULL) {
774  char *text = "System memory exhausted.\n"
775  "Make sure you have at least 64MB of free system memory before running the game";
776  ERR_DLG("Out of Memory Error", text);
777  }
778 
779  return buf;
780 }
781 
786 void mem_free_dbg(void *p)
787 {
788  if (p) {
789  sgMemCrit.Enter();
790  SMemFree(p, __FILE__, __LINE__, 0);
791  sgMemCrit.Leave();
792  }
793 }
794 
801 BYTE *LoadFileInMem(char *pszName, DWORD *pdwFileLen)
802 {
803  HANDLE file;
804  BYTE *buf;
805  int fileLen;
806 
807  WOpenFile(pszName, &file, FALSE);
808  fileLen = WGetFileSize(file, NULL, pszName);
809 
810  if (pdwFileLen)
811  *pdwFileLen = fileLen;
812 
813  if (!fileLen)
814  app_fatal("Zero length SFILE:\n%s", pszName);
815 
816  buf = (BYTE *)DiabloAllocPtr(fileLen);
817 
818  WReadFile(file, buf, fileLen, pszName);
819  WCloseFile(file);
820 
821  return buf;
822 }
823 
830 DWORD LoadFileWithMem(const char *pszName, void *p)
831 {
832  DWORD dwFileLen;
833  HANDLE hsFile;
834 
835  assert(pszName);
836  if (p == NULL) {
837  app_fatal("LoadFileWithMem(NULL):\n%s", pszName);
838  }
839 
840  WOpenFile(pszName, &hsFile, FALSE);
841 
842  dwFileLen = WGetFileSize(hsFile, NULL, pszName);
843  if (dwFileLen == 0) {
844  app_fatal("Zero length SFILE:\n%s", pszName);
845  }
846 
847  WReadFile(hsFile, p, dwFileLen, pszName);
848  WCloseFile(hsFile);
849 
850  return dwFileLen;
851 }
852 
859 void Cl2ApplyTrans(BYTE *p, BYTE *ttbl, int nCel)
860 {
861  int i, nDataSize;
862  char width;
863  BYTE *dst;
864 
865  assert(p != NULL);
866  assert(ttbl != NULL);
867 
868  for (i = 1; i <= nCel; i++) {
869  dst = CelGetFrame(p, i, &nDataSize) + 10;
870  nDataSize -= 10;
871  while (nDataSize) {
872  width = *dst++;
873  nDataSize--;
874  assert(nDataSize >= 0);
875  if (width < 0) {
876  width = -width;
877  if (width > 65) {
878  nDataSize--;
879  assert(nDataSize >= 0);
880  *dst = ttbl[*dst];
881  dst++;
882  } else {
883  nDataSize -= width;
884  assert(nDataSize >= 0);
885  while (width) {
886  *dst = ttbl[*dst];
887  dst++;
888  width--;
889  }
890  }
891  }
892  }
893  }
894 }
895 
904 void Cl2Draw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
905 {
906  BYTE *pRLEBytes;
907  int nDataSize;
908 
909  assert(gpBuffer != NULL);
910  assert(pCelBuff != NULL);
911  assert(nCel > 0);
912 
913  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
914 
915  Cl2BlitSafe(
916  &gpBuffer[sx + BUFFER_WIDTH * sy],
917  pRLEBytes,
918  nDataSize,
919  nWidth);
920 }
921 
929 void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
930 {
931  int w;
932  char width;
933  BYTE fill;
934  BYTE *src, *dst;
935 
936  src = pRLEBytes;
937  dst = pDecodeTo;
938  w = nWidth;
939 
940  while (nDataSize) {
941  width = *src++;
942  nDataSize--;
943  if (width < 0) {
944  width = -width;
945  if (width > 65) {
946  width -= 65;
947  nDataSize--;
948  fill = *src++;
949  if (dst < gpBufEnd && dst > gpBufStart) {
950  w -= width;
951  while (width) {
952  *dst = fill;
953  dst++;
954  width--;
955  }
956  if (!w) {
957  w = nWidth;
958  dst -= BUFFER_WIDTH + w;
959  }
960  continue;
961  }
962  } else {
963  nDataSize -= width;
964  if (dst < gpBufEnd && dst > gpBufStart) {
965  w -= width;
966  while (width) {
967  *dst = *src;
968  src++;
969  dst++;
970  width--;
971  }
972  if (!w) {
973  w = nWidth;
974  dst -= BUFFER_WIDTH + w;
975  }
976  continue;
977  } else {
978  src += width;
979  }
980  }
981  }
982  while (width) {
983  if (width > w) {
984  dst += w;
985  width -= w;
986  w = 0;
987  } else {
988  dst += width;
989  w -= width;
990  width = 0;
991  }
992  if (!w) {
993  w = nWidth;
994  dst -= BUFFER_WIDTH + w;
995  }
996  }
997  }
998 }
999 
1009 void Cl2DrawOutline(char col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
1010 {
1011  int nDataSize;
1012  BYTE *pRLEBytes;
1013 
1014  assert(gpBuffer != NULL);
1015  assert(pCelBuff != NULL);
1016  assert(nCel > 0);
1017 
1018  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
1019 
1022  &gpBuffer[sx + BUFFER_WIDTH * sy],
1023  pRLEBytes,
1024  nDataSize,
1025  nWidth,
1026  col);
1028 }
1029 
1038 void Cl2BlitOutlineSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, char col)
1039 {
1040  int w;
1041  char width;
1042  BYTE *src, *dst;
1043 
1044  src = pRLEBytes;
1045  dst = pDecodeTo;
1046  w = nWidth;
1047 
1048  while (nDataSize) {
1049  width = *src++;
1050  nDataSize--;
1051  if (width < 0) {
1052  width = -width;
1053  if (width > 65) {
1054  width -= 65;
1055  nDataSize--;
1056  if (*src++ && dst < gpBufEnd && dst > gpBufStart) {
1057  w -= width;
1058  dst[-1] = col;
1059  dst[width] = col;
1060  while (width) {
1061  dst[-BUFFER_WIDTH] = col;
1062  dst[BUFFER_WIDTH] = col;
1063  dst++;
1064  width--;
1065  }
1066  if (!w) {
1067  w = nWidth;
1068  dst -= BUFFER_WIDTH + w;
1069  }
1070  continue;
1071  }
1072  } else {
1073  nDataSize -= width;
1074  if (dst < gpBufEnd && dst > gpBufStart) {
1075  w -= width;
1076  while (width) {
1077  if (*src++) {
1078  dst[-1] = col;
1079  dst[1] = col;
1080  dst[-BUFFER_WIDTH] = col;
1081  dst[BUFFER_WIDTH] = col;
1082  }
1083  dst++;
1084  width--;
1085  }
1086  if (!w) {
1087  w = nWidth;
1088  dst -= BUFFER_WIDTH + w;
1089  }
1090  continue;
1091  } else {
1092  src += width;
1093  }
1094  }
1095  }
1096  while (width) {
1097  if (width > w) {
1098  dst += w;
1099  width -= w;
1100  w = 0;
1101  } else {
1102  dst += width;
1103  w -= width;
1104  width = 0;
1105  }
1106  if (!w) {
1107  w = nWidth;
1108  dst -= BUFFER_WIDTH + w;
1109  }
1110  }
1111  }
1112 }
1113 
1123 void Cl2DrawLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
1124 {
1125  int nDataSize, idx;
1126  BYTE *pRLEBytes, *pDecodeTo;
1127 
1128  assert(gpBuffer != NULL);
1129  assert(pCelBuff != NULL);
1130  assert(nCel > 0);
1131 
1132  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
1133  pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
1134 
1135  idx = light4flag ? 1024 : 4096;
1136  if (light == 2)
1137  idx += 256;
1138  if (light >= 4)
1139  idx += (light - 1) << 8;
1140 
1142  pDecodeTo,
1143  pRLEBytes,
1144  nDataSize,
1145  nWidth,
1146  &pLightTbl[idx]);
1147 }
1148 
1157 void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *pTable)
1158 {
1159  int w;
1160  char width;
1161  BYTE fill;
1162  BYTE *src, *dst;
1163 
1164  src = pRLEBytes;
1165  dst = pDecodeTo;
1166  w = nWidth;
1167  sgnWidth = nWidth;
1168 
1169  while (nDataSize) {
1170  width = *src++;
1171  nDataSize--;
1172  if (width < 0) {
1173  width = -width;
1174  if (width > 65) {
1175  width -= 65;
1176  nDataSize--;
1177  fill = pTable[*src++];
1178  if (dst < gpBufEnd && dst > gpBufStart) {
1179  w -= width;
1180  while (width) {
1181  *dst = fill;
1182  dst++;
1183  width--;
1184  }
1185  if (!w) {
1186  w = sgnWidth;
1187  dst -= BUFFER_WIDTH + w;
1188  }
1189  continue;
1190  }
1191  } else {
1192  nDataSize -= width;
1193  if (dst < gpBufEnd && dst > gpBufStart) {
1194  w -= width;
1195  while (width) {
1196  *dst = pTable[*src];
1197  src++;
1198  dst++;
1199  width--;
1200  }
1201  if (!w) {
1202  w = sgnWidth;
1203  dst -= BUFFER_WIDTH + w;
1204  }
1205  continue;
1206  } else {
1207  src += width;
1208  }
1209  }
1210  }
1211  while (width) {
1212  if (width > w) {
1213  dst += w;
1214  width -= w;
1215  w = 0;
1216  } else {
1217  dst += width;
1218  w -= width;
1219  width = 0;
1220  }
1221  if (!w) {
1222  w = sgnWidth;
1223  dst -= BUFFER_WIDTH + w;
1224  }
1225  }
1226  }
1227 }
1228 
1237 void Cl2DrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
1238 {
1239  int nDataSize;
1240  BYTE *pRLEBytes, *pDecodeTo;
1241 
1242  assert(gpBuffer != NULL);
1243  assert(pCelBuff != NULL);
1244  assert(nCel > 0);
1245 
1246  pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
1247  pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
1248 
1249  if (light_table_index)
1250  Cl2BlitLightSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth, &pLightTbl[light_table_index * 256]);
1251  else
1252  Cl2BlitSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth);
1253 }
1254 
1259 void PlayInGameMovie(char *pszMovie)
1260 {
1261  PaletteFadeOut(8);
1262  play_movie(pszMovie, FALSE);
1264  force_redraw = 255;
1266  PaletteFadeIn(8);
1267  force_redraw = 255;
1268 }
1269 
gpBuffer
BYTE * gpBuffer
CelGetFrame
BYTE * CelGetFrame(BYTE *pCelBuff, int nCel, int *nDataSize)
Definition: engine.h:40
play_movie
void play_movie(char *pszMovie, BOOL user_can_close)
Definition: movie.cpp:17
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
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
RndMult
const int RndMult
Specifies the multiplier used in the Borland C/C++ pseudo-random number generator algorithm.
Definition: engine.cpp:37
DIR_W
@ DIR_W
Definition: enums.h:2084
Cl2BlitOutlineSafe
void Cl2BlitOutlineSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, char col)
Blit a solid colder shape one pixel larger then the given sprite shape, to the given buffer.
Definition: engine.cpp:1038
SCREEN_Y
#define SCREEN_Y
Definition: defs.h:126
pLightTbl
BYTE * pLightTbl
Definition: lighting.cpp:21
SetRndSeed
void SetRndSeed(int s)
Set the RNG seed.
Definition: engine.cpp:728
cel_transparency_active
int cel_transparency_active
Specifies whether transparency is active for the current CEL file being decoded.
Definition: scrollrt.cpp:38
Cl2ApplyTrans
void Cl2ApplyTrans(BYTE *p, BYTE *ttbl, int nCel)
Apply the color swaps to a CL2 sprite.
Definition: engine.cpp:859
PaletteFadeIn
void PaletteFadeIn(int fr)
Definition: palette.cpp:166
gbPixelCol
DEVILUTION_BEGIN_NAMESPACE char gbPixelCol
automap pixel color 8-bit (palette entry)
Definition: engine.cpp:18
CelClippedBlitLightTrans
void CelClippedBlitLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
Same as CelBlitLightTransSafe.
Definition: engine.cpp:424
GetDirection
int GetDirection(int x1, int y1, int x2, int y2)
Calculate the best fit direction between two points.
Definition: engine.cpp:683
DIR_N
@ DIR_N
Definition: enums.h:2086
sgMemCrit
static CCritSect sgMemCrit
Definition: engine.cpp:25
CelBlitFrame
void CelBlitFrame(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
Blit a given CEL frame to the given buffer.
Definition: engine.cpp:59
DIR_NW
@ DIR_NW
Definition: enums.h:2085
PlayInGameMovie
void PlayInGameMovie(char *pszMovie)
Fade to black and play a video.
Definition: engine.cpp:1259
Cl2BlitSafe
void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
Blit CL2 sprite to the given buffer.
Definition: engine.cpp:929
WGetFileSize
LONG WGetFileSize(HANDLE hsFile, DWORD *lpFileSizeHigh, const char *FileName)
Definition: wave.cpp:11
sgnWidth
int sgnWidth
Width of sprite being blitted.
Definition: engine.cpp:22
all.h
DIR_SE
@ DIR_SE
Definition: enums.h:2089
orgseed
int orgseed
Seed value before the most recent call to SetRndSeed()
Definition: engine.cpp:20
DIR_SW
@ DIR_SW
Definition: enums.h:2083
sglGameSeed
int sglGameSeed
Current game seed.
Definition: engine.cpp:24
CelBlitSafe
void CelBlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
Blit CEL sprite to the given buffer, checks for drawing outside the buffer.
Definition: engine.cpp:205
Cl2BlitLightSafe
void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *pTable)
Blit CL2 sprite, and apply lighting, to the given buffer.
Definition: engine.cpp:1157
LoadFileWithMem
DWORD LoadFileWithMem(const char *pszName, void *p)
Load a file in to the given buffer.
Definition: engine.cpp:830
WOpenFile
BOOL WOpenFile(const char *FileName, HANDLE *phsFile, BOOL mayNotExist)
Definition: wave.cpp:21
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
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
DIR_NE
@ DIR_NE
Definition: enums.h:2087
gpBufStart
BYTE * gpBufStart
Upper bound of back buffer.
Definition: scrollrt.cpp:15
light4flag
BOOL light4flag
Definition: diablo.cpp:34
ERR_DLG
#define ERR_DLG(title, text)
Definition: defs.h:173
assert
#define assert(exp)
Definition: defs.h:168
SeedCount
int SeedCount
Track number of calls to GetRndSeed() since last call to SetRndSeed()
Definition: engine.cpp:26
gbNotInView
BOOL gbNotInView
valid - if x/y are in bounds
Definition: engine.cpp:27
ENG_set_pixel
void ENG_set_pixel(int sx, int sy, BYTE col)
Set the value of a single pixel in the back buffer, checks bounds.
Definition: engine.cpp:609
app_fatal
void app_fatal(const char *pszFmt,...)
Definition: appfat.cpp:18
DIR_E
@ DIR_E
Definition: enums.h:2088
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
CelGetFrameClipped
BYTE * CelGetFrameClipped(BYTE *pCelBuff, int nCel, int *nDataSize)
Definition: engine.h:49
LoadFileInMem
BYTE * LoadFileInMem(char *pszName, DWORD *pdwFileLen)
Load a file in to a buffer.
Definition: engine.cpp:801
CelDraw
void CelDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
Blit CEL sprite to the back buffer at the given coordinates.
Definition: engine.cpp:47
DrawLine
void DrawLine(int x0, int y0, int x1, int y1, BYTE col)
Draw a line on the back buffer.
Definition: engine.cpp:657
gbRotateMap
BOOL gbRotateMap
flip - if y < x
Definition: engine.cpp:19
GetRndSeed
int GetRndSeed()
Get the current RNG seed.
Definition: engine.cpp:739
gpBufEnd
BYTE * gpBufEnd
Lower bound of back buffer.
Definition: scrollrt.cpp:19
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
CelBlitWidth
void CelBlitWidth(BYTE *pBuff, int x, int y, int wdt, BYTE *pCelBuff, int nCel, int nWidth)
Blit to a buffer at given coordinates.
Definition: engine.cpp:509
WCloseFile
DEVILUTION_BEGIN_NAMESPACE BOOL WCloseFile(HANDLE file)
Definition: wave.cpp:6
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
DiabloAllocPtr
BYTE * DiabloAllocPtr(DWORD dwBytes)
Multithreaded safe malloc.
Definition: engine.cpp:765
PaletteFadeOut
void PaletteFadeOut(int fr)
Definition: palette.cpp:183
scrollrt_draw_game_screen
void scrollrt_draw_game_screen(BOOL draw_cursor)
Redraw screen.
Definition: scrollrt.cpp:1303
DIR_S
@ DIR_S
Definition: enums.h:2082
random_
int random_(BYTE idx, int v)
Main RNG function.
Definition: engine.cpp:752
mem_free_dbg
void mem_free_dbg(void *p)
Multithreaded safe memfree.
Definition: engine.cpp:786
BUFFER_WIDTH
#define BUFFER_WIDTH
Definition: defs.h:128
ClearScreenBuffer
void ClearScreenBuffer()
Render the whole screen black.
Definition: scrollrt.cpp:1084
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
engine_draw_pixel
void engine_draw_pixel(int sx, int sy)
Set the value of a single pixel in the back buffer to that of gbPixelCol, checks bounds.
Definition: engine.cpp:629
DEVILUTION_BEGIN_NAMESPACE
Definition: sha.cpp:10
CelBlitLightSafe
void CelBlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl)
Blit CEL sprite, and apply lighting, to the given buffer, checks for drawing outside the buffer.
Definition: engine.cpp:271
SCREEN_X
#define SCREEN_X
Definition: defs.h:125
CelDrawLightRed
void CelDrawLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates, translated to a red...
Definition: engine.cpp:155
WReadFile
void WReadFile(HANDLE hsFile, LPVOID buf, DWORD to_read, const char *FileName)
Definition: wave.cpp:29
CelBlitLightTransSafe
void CelBlitLightTransSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
Same as CelBlitLightSafe, with transparancy applied.
Definition: engine.cpp:334
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
SCREEN_HEIGHT
#define SCREEN_HEIGHT
Definition: defs.h:106
RndInc
const int RndInc
Specifies the increment used in the Borland C/C++ pseudo-random.
Definition: engine.cpp:32
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
CelDrawLight
void CelDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, BYTE *tbl)
Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates.
Definition: engine.cpp:104