Browse Source

Engine: Functions to render to any buffer

Refactor the rendering functions to allow rendering to any output
buffer.

New functions that accept a buffer have the `To` suffix.

The functions that render to the global buffer now always accept
coordinates.
pull/1066/head
Gleb Mazovetskiy 5 years ago committed by Anders Jenbo
parent
commit
8283f85e24
  1. 44
      Source/control.cpp
  2. 419
      Source/engine.cpp
  3. 320
      Source/engine.h
  4. 9
      Source/inv.cpp
  5. 15
      Source/minitext.cpp
  6. 4
      Source/scrollrt.cpp

44
Source/control.cpp

@ -5,6 +5,8 @@
*/
#include "all.h"
#include <cstddef>
DEVILUTION_BEGIN_NAMESPACE
BYTE sgbNextTalkSave;
@ -775,22 +777,20 @@ void UpdateManaFlask()
DrawSpell();
}
static CelOutputBuffer AllocCelOutputBuffer(BYTE **raw, size_t width, size_t height) {
const std::size_t size = width * height;
*raw = DiabloAllocPtr(size);
memset(*raw, 0, size);
return CelOutputBuffer{*raw, *raw + size, static_cast<int>(width)};
}
void InitControlPan()
{
int i;
BYTE *tBuff;
const CelOutputBuffer btm_buf = AllocCelOutputBuffer(&pBtmBuff, PANEL_WIDTH, (PANEL_HEIGHT + 16) * (gbIsMultiplayer ? 2 : 1));
const CelOutputBuffer mana_buf = AllocCelOutputBuffer(&pManaBuff, 88, 88);
const CelOutputBuffer life_buf = AllocCelOutputBuffer(&pLifeBuff, 88, 88);
if (!gbIsMultiplayer) {
pBtmBuff = DiabloAllocPtr((PANEL_HEIGHT + 16) * PANEL_WIDTH);
memset(pBtmBuff, 0, (PANEL_HEIGHT + 16) * PANEL_WIDTH);
} else {
pBtmBuff = DiabloAllocPtr((PANEL_HEIGHT + 16) * 2 * PANEL_WIDTH);
memset(pBtmBuff, 0, (PANEL_HEIGHT + 16) * 2 * PANEL_WIDTH);
}
pManaBuff = DiabloAllocPtr(88 * 88);
memset(pManaBuff, 0, 88 * 88);
pLifeBuff = DiabloAllocPtr(88 * 88);
memset(pLifeBuff, 0, 88 * 88);
pPanelText = LoadFileInMem("CtrlPan\\SmalText.CEL", NULL);
pChrPanel = LoadFileInMem("Data\\Char.CEL", NULL);
if (!gbIsHellfire)
@ -798,18 +798,18 @@ void InitControlPan()
else
pSpellCels = LoadFileInMem("Data\\SpelIcon.CEL", NULL);
SetSpellTrans(RSPLTYPE_SKILL);
tBuff = LoadFileInMem("CtrlPan\\Panel8.CEL", NULL);
CelBlitWidth(pBtmBuff, 0, (PANEL_HEIGHT + 16) - 1, PANEL_WIDTH, tBuff, 1, PANEL_WIDTH);
MemFreeDbg(tBuff);
tBuff = LoadFileInMem("CtrlPan\\P8Bulbs.CEL", NULL);
CelBlitWidth(pLifeBuff, 0, 87, 88, tBuff, 1, 88);
CelBlitWidth(pManaBuff, 0, 87, 88, tBuff, 2, 88);
MemFreeDbg(tBuff);
BYTE *pStatusPanel = LoadFileInMem("CtrlPan\\Panel8.CEL", NULL);
CelDrawUnsafeTo(btm_buf, 0, (PANEL_HEIGHT + 16) - 1, pStatusPanel, 1, PANEL_WIDTH);
MemFreeDbg(pStatusPanel);
pStatusPanel = LoadFileInMem("CtrlPan\\P8Bulbs.CEL", NULL);
CelDrawUnsafeTo(life_buf, 0, 87, pStatusPanel, 1, 88);
CelDrawUnsafeTo(mana_buf, 0, 87, pStatusPanel, 2, 88);
MemFreeDbg(pStatusPanel);
talkflag = FALSE;
if (gbIsMultiplayer) {
tBuff = LoadFileInMem("CtrlPan\\TalkPanl.CEL", NULL);
CelBlitWidth(pBtmBuff, 0, (PANEL_HEIGHT + 16) * 2 - 1, PANEL_WIDTH, tBuff, 1, PANEL_WIDTH);
MemFreeDbg(tBuff);
BYTE * pTalkPanel = LoadFileInMem("CtrlPan\\TalkPanl.CEL", NULL);
CelDrawUnsafeTo(btm_buf, 0, (PANEL_HEIGHT + 16) * 2 - 1, pTalkPanel, 1, PANEL_WIDTH);
MemFreeDbg(pTalkPanel);
pMultiBtns = LoadFileInMem("CtrlPan\\P8But2.CEL", NULL);
pTalkBtns = LoadFileInMem("CtrlPan\\TalkButt.CEL", NULL);
sgbPlrTalkTbl = 0;

419
Source/engine.cpp

@ -31,132 +31,73 @@ const int RndInc = 1;
*/
const int RndMult = 0x015A4E35;
/**
* @brief Blit CEL sprite to the back buffer at the given coordinates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
CelBlitFrame(&gpBuffer[sx + BUFFER_WIDTH * sy], pCelBuff, nCel, nWidth);
}
/**
* @brief Blit a given CEL frame to the given buffer
* @param pBuff Target buffer
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelBlitFrame(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
void CelDrawTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
int nDataSize;
BYTE *pRLEBytes;
assert(pCelBuff != NULL);
assert(pBuff != NULL);
assert(out.begin != NULL);
pRLEBytes = CelGetFrame(pCelBuff, nCel, &nDataSize);
CelBlitSafe(pBuff, pRLEBytes, nDataSize, nWidth);
CelBlitSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Same as CelDraw but with the option to skip parts of the top and bottom of the sprite
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
void CelClippedDrawTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
BYTE *pRLEBytes;
int nDataSize;
assert(gpBuffer);
assert(out.begin != NULL);
assert(pCelBuff != NULL);
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
CelBlitSafe(
&gpBuffer[sx + BUFFER_WIDTH * sy],
pRLEBytes,
nDataSize,
nWidth);
CelBlitSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, BYTE *tbl)
void CelDrawLightTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, BYTE *tbl)
{
int nDataSize;
BYTE *pDecodeTo, *pRLEBytes;
BYTE *pRLEBytes;
assert(gpBuffer);
assert(out.begin != NULL);
assert(pCelBuff != NULL);
pRLEBytes = CelGetFrame(pCelBuff, nCel, &nDataSize);
pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
if (light_table_index || tbl)
CelBlitLightSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth, tbl);
CelBlitLightSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth, tbl);
else
CelBlitSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth);
CelBlitSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Same as CelDrawLight but with the option to skip parts of the top and bottom of the sprite
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
void CelClippedDrawLightTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
int nDataSize;
BYTE *pRLEBytes, *pDecodeTo;
BYTE *pRLEBytes;
assert(gpBuffer);
assert(out.begin != NULL);
assert(pCelBuff != NULL);
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
if (light_table_index)
CelBlitLightSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth, NULL);
CelBlitLightSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth, NULL);
else
CelBlitSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth);
CelBlitSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates, translated to a red hue
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
* @param light Light shade to use
*/
void CelDrawLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
void CelDrawLightRedTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
{
int nDataSize, w, idx;
BYTE *pRLEBytes, *dst, *tbl;
assert(gpBuffer);
assert(out.begin != NULL);
assert(pCelBuff != NULL);
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
dst = out.at(sx, sy);
idx = light4flag ? 1024 : 4096;
if (light == 2)
@ -170,7 +111,7 @@ void CelDrawLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char
tbl = &pLightTbl[idx];
end = &pRLEBytes[nDataSize];
for (; pRLEBytes != end; dst -= BUFFER_WIDTH + nWidth) {
for (; pRLEBytes != end; dst -= out.line_width + nWidth) {
for (w = nWidth; w;) {
width = *pRLEBytes++;
if (!(width & 0x80)) {
@ -190,33 +131,25 @@ void CelDrawLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char
}
}
/**
* @brief Blit CEL sprite to the given buffer, checks for drawing outside the buffer
* @param pDecodeTo The output buffer
* @param pRLEBytes CEL pixel stream (run-length encoded)
* @param nDataSize Size of CEL in bytes
* @param nWidth Width of sprite
*/
void CelBlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
void CelBlitSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth)
{
int i, w;
BYTE width;
BYTE *src, *dst;
assert(pDecodeTo != NULL);
assert(out.begin != NULL);
assert(pRLEBytes != NULL);
assert(gpBuffer);
src = pRLEBytes;
dst = pDecodeTo;
dst = out.at(sx, sy);
w = nWidth;
for (; src != &pRLEBytes[nDataSize]; dst -= BUFFER_WIDTH + w) {
for (; src != &pRLEBytes[nDataSize]; dst -= out.line_width + w) {
for (i = w; i;) {
width = *src++;
if (!(width & 0x80)) {
i -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
memcpy(dst, src, width);
}
src += width;
@ -230,61 +163,39 @@ void CelBlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
}
}
/**
* @brief Same as CelClippedDraw but checks for drawing outside the buffer
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedDrawSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
void CelClippedDrawSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
BYTE *pRLEBytes;
int nDataSize;
assert(gpBuffer);
assert(out.begin != NULL);
assert(pCelBuff != NULL);
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
CelBlitSafe(
&gpBuffer[sx + BUFFER_WIDTH * sy],
pRLEBytes,
nDataSize,
nWidth);
CelBlitSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Blit CEL sprite, and apply lighting, to the given buffer, checks for drawing outside the buffer
* @param pDecodeTo The output buffer
* @param pRLEBytes CEL pixel stream (run-length encoded)
* @param nDataSize Size of CEL in bytes
* @param nWidth Width of sprite
* @param tbl Palette translation table
*/
void CelBlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl)
void CelBlitLightSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl)
{
int i, w;
BYTE width;
BYTE *src, *dst;
assert(pDecodeTo != NULL);
assert(out.begin != NULL);
assert(pRLEBytes != NULL);
assert(gpBuffer);
src = pRLEBytes;
dst = pDecodeTo;
dst = out.at(sx, sy);
if (tbl == NULL)
tbl = &pLightTbl[light_table_index * 256];
w = nWidth;
for (; src != &pRLEBytes[nDataSize]; dst -= BUFFER_WIDTH + w) {
for (; src != &pRLEBytes[nDataSize]; dst -= out.line_width + w) {
for (i = w; i;) {
width = *src++;
if (!(width & 0x80)) {
i -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
if (width & 1) {
dst[0] = tbl[src[0]];
src++;
@ -319,39 +230,31 @@ void CelBlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidt
}
}
/**
* @brief Same as CelBlitLightSafe, with stippled transparancy applied
* @param pDecodeTo The output buffer
* @param pRLEBytes CEL pixel stream (run-length encoded)
* @param nDataSize Size of CEL in bytes
* @param nWidth Width of sprite
*/
static void CelBlitLightTransSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
void CelBlitLightTransSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth)
{
int w;
BOOL shift;
BYTE *tbl;
assert(pDecodeTo != NULL);
assert(pRLEBytes != NULL);
assert(gpBuffer);
assert(out.begin != NULL);
int i;
BYTE width;
BYTE *src, *dst;
src = pRLEBytes;
dst = pDecodeTo;
dst = out.at(sx, sy);
tbl = &pLightTbl[light_table_index * 256];
w = nWidth;
shift = (BYTE)(size_t)dst & 1;
for (; src != &pRLEBytes[nDataSize]; dst -= BUFFER_WIDTH + w, shift = (shift + 1) & 1) {
for (; src != &pRLEBytes[nDataSize]; dst -= out.line_width + w, shift = (shift + 1) & 1) {
for (i = w; i;) {
width = *src++;
if (!(width & 0x80)) {
i -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
if (((BYTE)(size_t)dst & 1) == shift) {
if (!(width & 1)) {
goto L_ODD;
@ -417,18 +320,17 @@ static void CelBlitLightTransSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSiz
* @param nWidth Width of sprite
* @param tbl Palette translation table
*/
static void CelBlitLightBlendedSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl)
static void CelBlitLightBlendedSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl)
{
int i, w;
BYTE width;
BYTE *src, *dst;
assert(pDecodeTo != NULL);
assert(out.begin != NULL);
assert(pRLEBytes != NULL);
assert(gpBuffer);
src = pRLEBytes;
dst = pDecodeTo;
dst = out.at(sx, sy);
if (tbl == NULL)
tbl = &pLightTbl[light_table_index * 256];
w = nWidth;
@ -473,14 +375,7 @@ static void CelBlitLightBlendedSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataS
}
}
/**
* @brief Same as CelBlitLightSafe, with stippled transparancy applied
* @param pBuff Target buffer
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedBlitLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
void CelClippedBlitLightTransTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
int nDataSize;
BYTE *pRLEBytes;
@ -491,34 +386,25 @@ void CelClippedBlitLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth)
if (cel_transparency_active) {
if (sgOptions.blendedTransparancy)
CelBlitLightBlendedSafe(pBuff, pRLEBytes, nDataSize, nWidth, NULL);
CelBlitLightBlendedSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth, NULL);
else
CelBlitLightTransSafe(pBuff, pRLEBytes, nDataSize, nWidth);
CelBlitLightTransSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth);
} else if (light_table_index)
CelBlitLightSafe(pBuff, pRLEBytes, nDataSize, nWidth, NULL);
CelBlitLightSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth, NULL);
else
CelBlitSafe(pBuff, pRLEBytes, nDataSize, nWidth);
CelBlitSafeTo(out, sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Same as CelDrawLightRed but checks for drawing outside the buffer
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of cel
* @param light Light shade to use
*/
void CelDrawLightRedSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
void CelDrawLightRedSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
{
int nDataSize, w, idx;
BYTE *pRLEBytes, *dst, *tbl;
assert(gpBuffer);
assert(out.begin != NULL);
assert(pCelBuff != NULL);
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
dst = out.at(sx, sy);
idx = light4flag ? 1024 : 4096;
if (light == 2)
@ -533,12 +419,12 @@ void CelDrawLightRedSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, c
end = &pRLEBytes[nDataSize];
for (; pRLEBytes != end; dst -= BUFFER_WIDTH + nWidth) {
for (; pRLEBytes != end; dst -= out.line_width + nWidth) {
for (w = nWidth; w;) {
width = *pRLEBytes++;
if (!(width & 0x80)) {
w -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
while (width) {
*dst = tbl[*pRLEBytes];
pRLEBytes++;
@ -558,31 +444,21 @@ void CelDrawLightRedSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, c
}
}
/**
* @brief Blit to a buffer at given coordinates
* @param pBuff Target buffer
* @param x Cordinate in pBuff buffer
* @param y Cordinate in pBuff buffer
* @param wdt Width of pBuff
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of cel
*/
void CelBlitWidth(BYTE *pBuff, int x, int y, int wdt, BYTE *pCelBuff, int nCel, int nWidth)
void CelDrawUnsafeTo(CelOutputBuffer out, int x, int y, BYTE *pCelBuff, int nCel, int nWidth)
{
BYTE *pRLEBytes, *dst, *end;
assert(pCelBuff != NULL);
assert(pBuff != NULL);
assert(out.begin != NULL);
int i, nDataSize;
BYTE width;
pRLEBytes = CelGetFrame(pCelBuff, nCel, &nDataSize);
end = &pRLEBytes[nDataSize];
dst = &pBuff[y * wdt + x];
dst = out.at(x, y);
for (; pRLEBytes != end; dst -= wdt + nWidth) {
for (; pRLEBytes != end; dst -= out.line_width + nWidth) {
for (i = nWidth; i;) {
width = *pRLEBytes++;
if (!(width & 0x80)) {
@ -599,38 +475,29 @@ void CelBlitWidth(BYTE *pBuff, int x, int y, int wdt, BYTE *pCelBuff, int nCel,
}
}
/**
* @brief Blit a solid colder shape one pixel larger then the given sprite shape, to the back buffer at the given coordianates
* @param col Color index from current palette
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CEL buffer
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelBlitOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
void CelBlitOutlineTo(CelOutputBuffer out, BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
int nDataSize, w;
BYTE *src, *dst, *end;
BYTE width;
assert(pCelBuff != NULL);
assert(gpBuffer);
assert(out.begin != NULL);
src = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
end = &src[nDataSize];
dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
dst = out.at(sx, sy);
for (; src != end; dst -= BUFFER_WIDTH + nWidth) {
for (; src != end; dst -= out.line_width + nWidth) {
for (w = nWidth; w;) {
width = *src++;
if (!(width & 0x80)) {
w -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst >= gpBufEnd - BUFFER_WIDTH) {
if (dst < out.end && dst > out.begin) {
if (dst >= out.end - out.line_width) {
while (width) {
if (*src++) {
dst[-BUFFER_WIDTH] = col;
dst[-out.line_width] = col;
dst[-1] = col;
dst[1] = col;
}
@ -640,10 +507,10 @@ void CelBlitOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWid
} else {
while (width) {
if (*src++) {
dst[-BUFFER_WIDTH] = col;
dst[-out.line_width] = col;
dst[-1] = col;
dst[1] = col;
dst[BUFFER_WIDTH] = col;
dst[out.line_width] = col;
}
dst++;
width--;
@ -662,35 +529,14 @@ void CelBlitOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWid
}
}
/**
* @brief Set the value of a single pixel in the back buffer, checks bounds
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param col Color index from current palette
*/
void ENG_set_pixel(int sx, int sy, BYTE col)
void SetPixel(CelOutputBuffer out, int sx, int sy, BYTE col)
{
BYTE *dst;
assert(gpBuffer);
if (sy < 0 || sy >= SCREEN_HEIGHT + SCREEN_Y || sx < SCREEN_X || sx >= SCREEN_WIDTH + SCREEN_X)
assert(out.begin != NULL);
if (!out.in_bounds(sx, sy))
return;
dst = &gpBuffer[sx + BUFFER_WIDTH * sy];
if (dst < gpBufEnd && dst > gpBufStart)
*dst = col;
*out.at(sx, sy) = col;
}
/**
* @brief Draw a line on the back buffer
* @param x0 Back buffer coordinate
* @param y0 Back buffer coordinate
* @param x1 Back buffer coordinate
* @param y1 Back buffer coordinate
* @param col Color index from current palette
*/
void DrawLine(int x0, int y0, int x1, int y1, BYTE col)
{
int i, dx, dy, steps;
@ -709,14 +555,6 @@ void DrawLine(int x0, int y0, int x1, int y1, BYTE col)
}
}
/**
* @brief Calculate the best fit direction between two points
* @param x1 Tile coordinate
* @param y1 Tile coordinate
* @param x2 Tile coordinate
* @param y2 Tile coordinate
* @return A value from the direction enum
*/
int GetDirection(int x1, int y1, int x2, int y2)
{
int mx, my;
@ -938,12 +776,14 @@ void Cl2ApplyTrans(BYTE *p, BYTE *ttbl, int nCel)
/**
* @brief Blit CL2 sprite to the given buffer
* @param pDecodeTo The output buffer
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pRLEBytes CL2 pixel stream (run-length encoded)
* @param nDataSize Size of CL2 in bytes
* @param nWidth Width of sprite
*/
static void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth)
static void Cl2BlitSafe(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth)
{
int w;
char width;
@ -951,7 +791,7 @@ static void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWi
BYTE *src, *dst;
src = pRLEBytes;
dst = pDecodeTo;
dst = out.at(sx, sy);
w = nWidth;
while (nDataSize) {
@ -963,7 +803,7 @@ static void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWi
width -= 65;
nDataSize--;
fill = *src++;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
w -= width;
while (width) {
*dst = fill;
@ -972,13 +812,13 @@ static void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWi
}
if (!w) {
w = nWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
continue;
}
} else {
nDataSize -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
w -= width;
while (width) {
*dst = *src;
@ -988,7 +828,7 @@ static void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWi
}
if (!w) {
w = nWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
continue;
} else {
@ -1008,7 +848,7 @@ static void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWi
}
if (!w) {
w = nWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
}
}
@ -1016,20 +856,22 @@ static void Cl2BlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWi
/**
* @brief Blit a solid colder shape one pixel larger then the given sprite shape, to the given buffer
* @param pDecodeTo The output buffer
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pRLEBytes CL2 pixel stream (run-length encoded)
* @param nDataSize Size of CL2 in bytes
* @param nWidth Width of sprite
* @param col Color index from current palette
*/
static void Cl2BlitOutlineSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE col)
static void Cl2BlitOutlineSafe(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE col)
{
int w;
char width;
BYTE *src, *dst;
src = pRLEBytes;
dst = pDecodeTo;
dst = out.at(sx, sy);
w = nWidth;
while (nDataSize) {
@ -1040,40 +882,40 @@ static void Cl2BlitOutlineSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize,
if (width > 65) {
width -= 65;
nDataSize--;
if (*src++ && dst < gpBufEnd && dst > gpBufStart) {
if (*src++ && dst < out.end && dst > out.begin) {
w -= width;
dst[-1] = col;
dst[width] = col;
while (width) {
dst[-BUFFER_WIDTH] = col;
dst[BUFFER_WIDTH] = col;
dst[-out.line_width] = col;
dst[out.line_width] = col;
dst++;
width--;
}
if (!w) {
w = nWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
continue;
}
} else {
nDataSize -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
w -= width;
while (width) {
if (*src++) {
dst[-1] = col;
dst[1] = col;
dst[-BUFFER_WIDTH] = col;
dst[-out.line_width] = col;
// BUGFIX: only set `if (dst+BUFFER_WIDTH < gpBufEnd)`
dst[BUFFER_WIDTH] = col;
dst[out.line_width] = col;
}
dst++;
width--;
}
if (!w) {
w = nWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
continue;
} else {
@ -1093,7 +935,7 @@ static void Cl2BlitOutlineSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize,
}
if (!w) {
w = nWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
}
}
@ -1101,13 +943,15 @@ static void Cl2BlitOutlineSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize,
/**
* @brief Blit CL2 sprite, and apply lighting, to the given buffer
* @param pDecodeTo The output buffer
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pRLEBytes CL2 pixel stream (run-length encoded)
* @param nDataSize Size of CL2 in bytes
* @param nWidth With of CL2 sprite
* @param pTable Light color table
*/
static void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *pTable)
static void Cl2BlitLightSafe(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *pTable)
{
int w, spriteWidth;
char width;
@ -1115,7 +959,7 @@ static void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, in
BYTE *src, *dst;
src = pRLEBytes;
dst = pDecodeTo;
dst = out.at(sx, sy);
w = nWidth;
spriteWidth = nWidth;
@ -1128,7 +972,7 @@ static void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, in
width -= 65;
nDataSize--;
fill = pTable[*src++];
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
w -= width;
while (width) {
*dst = fill;
@ -1137,13 +981,13 @@ static void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, in
}
if (w == 0) {
w = spriteWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
continue;
}
} else {
nDataSize -= width;
if (dst < gpBufEnd && dst > gpBufStart) {
if (dst < out.end && dst > out.begin) {
w -= width;
while (width) {
*dst = pTable[*src];
@ -1153,7 +997,7 @@ static void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, in
}
if (w == 0) {
w = spriteWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
continue;
} else {
@ -1173,20 +1017,12 @@ static void Cl2BlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, in
}
if (w == 0) {
w = spriteWidth;
dst -= BUFFER_WIDTH + w;
dst -= out.line_width + w;
}
}
}
}
/**
* @brief Blit CL2 sprite, to the back buffer at the given coordianates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CL2 buffer
* @param nCel CL2 frame number
* @param nWidth Width of sprite
*/
void Cl2Draw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
BYTE *pRLEBytes;
@ -1198,11 +1034,7 @@ void Cl2Draw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
Cl2BlitSafe(
&gpBuffer[sx + BUFFER_WIDTH * sy],
pRLEBytes,
nDataSize,
nWidth);
Cl2BlitSafe(GlobalBackBuffer(), sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Blit a solid colder shape one pixel larger then the given sprite shape, to the back buffer at the given coordianates
@ -1224,36 +1056,21 @@ void Cl2DrawOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWid
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
gpBufEnd -= BUFFER_WIDTH;
Cl2BlitOutlineSafe(
&gpBuffer[sx + BUFFER_WIDTH * sy],
pRLEBytes,
nDataSize,
nWidth,
col);
gpBufEnd += BUFFER_WIDTH;
CelOutputBuffer out = GlobalBackBuffer();
out.end -= out.line_width;
Cl2BlitOutlineSafe(out, sx, sy, pRLEBytes, nDataSize, nWidth, col);
}
/**
* @brief Blit CL2 sprite, and apply a given lighting, to the back buffer at the given coordianates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CL2 buffer
* @param nCel CL2 frame number
* @param nWidth Width of sprite
* @param light Light shade to use
*/
void Cl2DrawLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
{
int nDataSize, idx;
BYTE *pRLEBytes, *pDecodeTo;
BYTE *pRLEBytes;
assert(gpBuffer != NULL);
assert(pCelBuff != NULL);
assert(nCel > 0);
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
idx = light4flag ? 1024 : 4096;
if (light == 2)
@ -1261,38 +1078,24 @@ void Cl2DrawLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char
if (light >= 4)
idx += (light - 1) << 8;
Cl2BlitLightSafe(
pDecodeTo,
pRLEBytes,
nDataSize,
nWidth,
&pLightTbl[idx]);
Cl2BlitLightSafe(GlobalBackBuffer(), sx, sy, pRLEBytes, nDataSize, nWidth, &pLightTbl[idx]);
}
/**
* @brief Blit CL2 sprite, and apply lighting, to the back buffer at the given coordinates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CL2 buffer
* @param nCel CL2 frame number
* @param nWidth Width of sprite
*/
void Cl2DrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
int nDataSize;
BYTE *pRLEBytes, *pDecodeTo;
BYTE *pRLEBytes;
assert(gpBuffer != NULL);
assert(pCelBuff != NULL);
assert(nCel > 0);
pRLEBytes = CelGetFrameClipped(pCelBuff, nCel, &nDataSize);
pDecodeTo = &gpBuffer[sx + BUFFER_WIDTH * sy];
if (light_table_index)
Cl2BlitLightSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth, &pLightTbl[light_table_index * 256]);
Cl2BlitLightSafe(GlobalBackBuffer(), sx, sy, pRLEBytes, nDataSize, nWidth, &pLightTbl[light_table_index * 256]);
else
Cl2BlitSafe(pDecodeTo, pRLEBytes, nDataSize, nWidth);
Cl2BlitSafe(GlobalBackBuffer(), sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**

320
Source/engine.h

@ -13,6 +13,10 @@
#ifndef __ENGINE_H__
#define __ENGINE_H__
#ifdef __cplusplus
#include <algorithm>
#endif
DEVILUTION_BEGIN_NAMESPACE
#ifdef __cplusplus
@ -49,22 +53,306 @@ inline BYTE *CelGetFrameClipped(BYTE *pCelBuff, int nCel, int *nDataSize)
return pRLEBytes + nDataStart;
}
void CelDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void CelBlitFrame(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth);
void CelClippedDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void CelDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, BYTE *tbl);
void CelClippedDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void CelClippedBlitLightTrans(BYTE *pBuff, BYTE *pCelBuff, int nCel, int nWidth);
void CelDrawLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light);
void CelBlitSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth);
void CelClippedDrawSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void CelBlitLightSafe(BYTE *pDecodeTo, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl);
void CelDrawLightRedSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light);
void CelBlitWidth(BYTE *pBuff, int x, int y, int wdt, BYTE *pCelBuff, int nCel, int nWidth);
void CelBlitOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void ENG_set_pixel(int sx, int sy, BYTE col);
struct CelOutputBuffer {
BYTE *begin;
BYTE *end;
int line_width;
#ifdef __cplusplus
BYTE *at(int x, int y) const
{
return &begin[x + line_width * y];
}
bool in_bounds(int x, int y) const
{
return x >= 0 && y >= 0 && begin + x + line_width * y < end;
}
CelOutputBuffer subregion(int x0, int y0, int x1, int y1) const
{
return CelOutputBuffer { at(x0, y0), std::min(at(x1, y1), end), line_width };
}
#endif
};
inline CelOutputBuffer GlobalBackBuffer()
{
extern BYTE *gpBuffer;
extern BYTE *gpBufEnd;
return CelOutputBuffer { gpBuffer, gpBufEnd, BUFFER_WIDTH };
}
/**
* @brief Blit CEL sprite to the back buffer at the given coordinates
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelDrawTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
inline void CelDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
CelDrawTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth);
}
/**
* @briefBlit CEL sprite to the given buffer, does not perform bounds-checking.
* @param out Target buffer
* @param x Cordinate in the target buffer
* @param y Cordinate in the target buffer
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of cel
*/
void CelDrawUnsafeTo(CelOutputBuffer out, int x, int y, BYTE *pCelBuff, int nCel, int nWidth);
/**
* @brief Same as CelDrawTo but with the option to skip parts of the top and bottom of the sprite
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedDrawTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
inline void CelClippedDraw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
CelClippedDrawTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth);
}
/**
* @brief Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelDrawLightTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, BYTE *tbl);
inline void CelDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, BYTE *tbl)
{
CelDrawLightTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth, tbl);
}
/**
* @brief Same as CelDrawLightTo but with the option to skip parts of the top and bottom of the sprite
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedDrawLightTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
inline void CelClippedDrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
return CelClippedDrawLightTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth);
}
/**
* @brief Same as CelBlitLightTransSafeTo
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedBlitLightTransTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
inline void CelClippedBlitLightTrans(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
return CelClippedBlitLightTransTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth);
}
/**
* @brief Blit CEL sprite, and apply lighting, to the back buffer at the given coordinates, translated to a red hue
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
* @param light Light shade to use
*/
void CelDrawLightRedTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light);
inline void CelDrawLightRed(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
{
return CelDrawLightRedTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth, light);
}
/**
* @brief Blit CEL sprite to the given buffer, checks for drawing outside the buffer.
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pRLEBytes CEL pixel stream (run-length encoded)
* @param nDataSize Size of CEL in bytes
* @param nWidth Width of sprite
*/
void CelBlitSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth);
inline void CelBlitSafe(int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth)
{
return CelBlitSafeTo(GlobalBackBuffer(), sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Same as CelClippedDrawTo but checks for drawing outside the buffer
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelClippedDrawSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
inline void CelClippedDrawSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
return CelClippedDrawSafeTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth);
}
/**
* @brief Blit CEL sprite, and apply lighting, to the given buffer, checks for drawing outside the buffer
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pRLEBytes CEL pixel stream (run-length encoded)
* @param nDataSize Size of CEL in bytes
* @param nWidth Width of sprite
* @param tbl Palette translation table
*/
void CelBlitLightSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl);
inline void CelBlitLightSafe(int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth, BYTE *tbl)
{
return CelBlitLightSafeTo(GlobalBackBuffer(), sx, sy, pRLEBytes, nDataSize, nWidth, tbl);
}
/**
* @brief Same as CelBlitLightSafeTo but with stippled transparancy applied
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pRLEBytes CEL pixel stream (run-length encoded)
* @param nDataSize Size of CEL in bytes
* @param nWidth Width of sprite
*/
void CelBlitLightTransSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth);
inline void CelBlitLightTransSafe(int sx, int sy, BYTE *pRLEBytes, int nDataSize, int nWidth)
{
return CelBlitLightTransSafeTo(GlobalBackBuffer(), sx, sy, pRLEBytes, nDataSize, nWidth);
}
/**
* @brief Same as CelDrawLightRedTo but checks for drawing outside the buffer
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff Cel data
* @param nCel CEL frame number
* @param nWidth Width of cel
* @param light Light shade to use
*/
void CelDrawLightRedSafeTo(CelOutputBuffer out, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light);
inline void CelDrawLightRedSafe(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light)
{
return CelDrawLightRedSafeTo(GlobalBackBuffer(), sx, sy, pCelBuff, nCel, nWidth, light);
}
/**
* @brief Blit a solid colder shape one pixel larger then the given sprite shape, to the target buffer at the given coordianates
* @param out Target buffer
* @param col Color index from current palette
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param pCelBuff CEL buffer
* @param nCel CEL frame number
* @param nWidth Width of sprite
*/
void CelBlitOutlineTo(CelOutputBuffer out, BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
inline void CelBlitOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth)
{
return CelBlitOutlineTo(GlobalBackBuffer(), col, sx, sy, pCelBuff, nCel, nWidth);
}
/**
* @brief Set the value of a single pixel in the back buffer, checks bounds
* @param out Target buffer
* @param sx Target buffer coordinate
* @param sy Target buffer coordinate
* @param col Color index from current palette
*/
void SetPixel(CelOutputBuffer out, int sx, int sy, BYTE col);
inline void ENG_set_pixel(int sx, int sy, BYTE col)
{
return SetPixel(GlobalBackBuffer(), sx, sy, col);
}
/**
* @brief Blit CL2 sprite, to the back buffer at the given coordianates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CL2 buffer
* @param nCel CL2 frame number
* @param nWidth Width of sprite
*/
void Cl2Draw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
/**
* @brief Blit a solid colder shape one pixel larger then the given sprite shape, to the back buffer at the given coordianates
* @param col Color index from current palette
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CL2 buffer
* @param nCel CL2 frame number
* @param nWidth Width of sprite
*/
void Cl2DrawOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
/**
* @brief Blit CL2 sprite, and apply a given lighting, to the back buffer at the given coordianates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CL2 buffer
* @param nCel CL2 frame number
* @param nWidth Width of sprite
* @param light Light shade to use
*/
void Cl2DrawLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light);
/**
* @brief Blit CL2 sprite, and apply lighting, to the back buffer at the given coordinates
* @param sx Back buffer coordinate
* @param sy Back buffer coordinate
* @param pCelBuff CL2 buffer
* @param nCel CL2 frame number
* @param nWidth Width of sprite
*/
void Cl2DrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
/**
* @brief Draw a line on the back buffer
* @param x0 Back buffer coordinate
* @param y0 Back buffer coordinate
* @param x1 Back buffer coordinate
* @param y1 Back buffer coordinate
* @param col Color index from current palette
*/
void DrawLine(int x0, int y0, int x1, int y1, BYTE col);
/**
* @brief Calculate the best fit direction between two points
* @param x1 Tile coordinate
* @param y1 Tile coordinate
* @param x2 Tile coordinate
* @param y2 Tile coordinate
* @return A value from the direction enum
*/
int GetDirection(int x1, int y1, int x2, int y2);
void SetRndSeed(int s);
int AdvanceRndSeed();
int GetRndSeed();
@ -74,10 +362,6 @@ void mem_free_dbg(void *p);
BYTE *LoadFileInMem(const char *pszName, DWORD *pdwFileLen);
DWORD LoadFileWithMem(const char *pszName, BYTE *p);
void Cl2ApplyTrans(BYTE *p, BYTE *ttbl, int nCel);
void Cl2Draw(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void Cl2DrawOutline(BYTE col, int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void Cl2DrawLightTbl(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth, char light);
void Cl2DrawLight(int sx, int sy, BYTE *pCelBuff, int nCel, int nWidth);
void PlayInGameMovie(const char *pszMovie);
#ifdef __cplusplus

9
Source/inv.cpp

@ -365,13 +365,12 @@ void DrawInv()
light_table_index = 0;
cel_transparency_active = TRUE;
pBuff = frame_width == INV_SLOT_SIZE_PX
? &gpBuffer[SCREENXY(RIGHT_PANEL_X + 197, SCREEN_Y)]
: &gpBuffer[SCREENXY(RIGHT_PANEL_X + 183, SCREEN_Y)];
const int dst_x = SCREEN_X + RIGHT_PANEL_X + (frame_width == INV_SLOT_SIZE_PX ? 197 : 183);
const int dst_y = SCREEN_Y;
if (frame <= 179) {
CelClippedBlitLightTrans(pBuff, pCursCels, frame, frame_width);
CelClippedBlitLightTrans(dst_x, dst_y, pCursCels, frame, frame_width);
} else {
CelClippedBlitLightTrans(pBuff, pCursCels2, frame - 179, frame_width);
CelClippedBlitLightTrans(dst_x, dst_y, pCursCels2, frame - 179, frame_width);
}
cel_transparency_active = FALSE;

15
Source/minitext.cpp

@ -144,17 +144,10 @@ int CalcTextSpeed(int nSFX)
*/
void PrintQTextChr(int sx, int sy, Uint8 *pCelBuff, int nCel)
{
Uint8 *pStart, *pEnd;
assert(gpBuffer);
pStart = gpBufStart;
gpBufStart = &gpBuffer[BUFFER_WIDTH * (49 + SCREEN_Y + UI_OFFSET_Y)];
pEnd = gpBufEnd;
gpBufEnd = &gpBuffer[BUFFER_WIDTH * (309 + SCREEN_Y + UI_OFFSET_Y)];
CelDraw(sx, sy, pCelBuff, nCel, 22);
gpBufStart = pStart;
gpBufEnd = pEnd;
CelOutputBuffer buf = GlobalBackBuffer();
const int start_y = 49 + SCREEN_Y + UI_OFFSET_Y;
buf = buf.subregion(0, start_y, buf.line_width, 309 + SCREEN_Y + UI_OFFSET_Y);
CelDrawTo(buf, sx, sy - start_y, pCelBuff, nCel, 22);
}
/**

4
Source/scrollrt.cpp

@ -815,7 +815,7 @@ static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy)
cel_transparency_active = 0; // Turn transparency off here for debugging
}
#endif
CelClippedBlitLightTrans(&gpBuffer[dx + BUFFER_WIDTH * dy], pSpecialCels, bArch, 64);
CelClippedBlitLightTrans(dx, dy, pSpecialCels, bArch, 64);
#ifdef _DEBUG
if (GetAsyncKeyState(DVL_VK_MENU) & 0x8000) {
cel_transparency_active = TransList[bMap]; // Turn transparency back to its normal state
@ -829,7 +829,7 @@ static void scrollrt_draw_dungeon(int sx, int sy, int dx, int dy)
if (sx > 0 && sy > 0 && dy > TILE_HEIGHT + SCREEN_Y) {
bArch = dSpecial[sx - 1][sy - 1];
if (bArch != 0) {
CelBlitFrame(&gpBuffer[dx + BUFFER_WIDTH * (dy - TILE_HEIGHT)], pSpecialCels, bArch, 64);
CelDraw(dx, dy - TILE_HEIGHT, pSpecialCels, bArch, 64);
}
}
}

Loading…
Cancel
Save