mirror of
https://github.com/jmarshall23/Hellfire.git
synced 2026-08-11 23:40:51 +02:00
Initial commit.
This commit is contained in:
+263
@@ -0,0 +1,263 @@
|
||||
//***************************************************************************
|
||||
// capture.c
|
||||
// created 4.14.95
|
||||
// written by Patrick Wyatt
|
||||
//***************************************************************************
|
||||
|
||||
|
||||
#include "diablo.h"
|
||||
#pragma hdrstop
|
||||
#include <io.h>
|
||||
#include <ctype.h>
|
||||
#include "engine.h"
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// externs
|
||||
//***************************************************************************
|
||||
void DrawAndBlit();
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// constants
|
||||
//***************************************************************************
|
||||
#define PCX_HEADER 10
|
||||
#define PCX_VERSION 5
|
||||
#define PCX_ENCODE 1
|
||||
|
||||
#define PCX_MAX_REP 63
|
||||
|
||||
#define PCX_X_PAL 12
|
||||
#define PCX_COLORS 16
|
||||
#define X_PCX_COLORS 256
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
// types
|
||||
//***************************************************************************
|
||||
#pragma pack(push,1)
|
||||
typedef struct PCXHeader {
|
||||
BYTE nHeader; // 10 for valid PCX files
|
||||
BYTE nVersion; // 5 for version 3.0 with palette
|
||||
BYTE nEncode; // file encoding mode
|
||||
BYTE nBits; // 8 for 256 color mode
|
||||
WORD x1;
|
||||
WORD y1;
|
||||
WORD x2;
|
||||
WORD y2;
|
||||
WORD nScrWid;
|
||||
WORD nScrHgt;
|
||||
} PCXHeader;
|
||||
|
||||
typedef struct PCXInfo {
|
||||
BYTE nMode; // always 0
|
||||
BYTE nPlanes; // number of bit planes
|
||||
WORD nLine; // bytes per line
|
||||
BYTE unused[60]; // fill out to 128 bytes
|
||||
} PCXInfo;
|
||||
|
||||
typedef struct TPCX_RGB {
|
||||
BYTE r;
|
||||
BYTE g;
|
||||
BYTE b;
|
||||
} TPCX_RGB;
|
||||
|
||||
typedef struct TPCX_XPal {
|
||||
BYTE nPal;
|
||||
TPCX_RGB rgb[X_PCX_COLORS];
|
||||
} TPCX_XPal;
|
||||
|
||||
typedef struct TPCX {
|
||||
PCXHeader Header;
|
||||
TPCX_RGB Pal16[PCX_COLORS];
|
||||
PCXInfo Info;
|
||||
} TPCX;
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
static BOOL pcx_write_header(HANDLE hFile,WORD wWdt,WORD wHgt) {
|
||||
TPCX pcx;
|
||||
|
||||
ZeroMemory(&pcx,sizeof(pcx));
|
||||
|
||||
// initialize header
|
||||
pcx.Header.nHeader = PCX_HEADER;
|
||||
pcx.Header.nVersion = PCX_VERSION;
|
||||
pcx.Header.nEncode = PCX_ENCODE;
|
||||
pcx.Header.nBits = 8;
|
||||
//pcx.Header.x1 = 0;
|
||||
//pcx.Header.y1 = 0;
|
||||
pcx.Header.x2 = wWdt - 1;
|
||||
pcx.Header.y2 = wHgt - 1;
|
||||
pcx.Header.nScrWid = wWdt;
|
||||
pcx.Header.nScrHgt = wHgt;
|
||||
|
||||
//pcx.Info.nMode = 0;
|
||||
pcx.Info.nPlanes = 1;
|
||||
pcx.Info.nLine = wWdt;
|
||||
|
||||
DWORD dwBytes;
|
||||
return WriteFile(hFile,&pcx,sizeof(pcx),&dwBytes,NULL)
|
||||
&& (dwBytes == sizeof(pcx));
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
static BOOL pcx_write_pal(HANDLE hFile,const PALETTEENTRY pal[256]) {
|
||||
// setup extended palette header
|
||||
TPCX_XPal xpal;
|
||||
xpal.nPal = PCX_X_PAL;
|
||||
|
||||
// copy palette colors
|
||||
for (int i = 0; i < X_PCX_COLORS; i++) {
|
||||
xpal.rgb[i].r = pal[i].peRed;
|
||||
xpal.rgb[i].g = pal[i].peGreen;
|
||||
xpal.rgb[i].b = pal[i].peBlue;
|
||||
}
|
||||
|
||||
// write it
|
||||
DWORD dwBytes;
|
||||
return WriteFile(hFile,&xpal,sizeof(xpal),&dwBytes,NULL)
|
||||
&& (dwBytes == sizeof(xpal));
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
static BYTE * pcx_compress_line(const BYTE * pSrc,BYTE * pDst,int nWdt) {
|
||||
BYTE c;
|
||||
int nCount;
|
||||
|
||||
do {
|
||||
// get next character
|
||||
c = *pSrc++;
|
||||
nCount = 1;
|
||||
nWdt--;
|
||||
|
||||
// see how long the sequence is
|
||||
while ((c == *pSrc) && (nCount < PCX_MAX_REP) && nWdt) {
|
||||
nCount++;
|
||||
nWdt--;
|
||||
pSrc++;
|
||||
}
|
||||
|
||||
// write repeat count (if needed)
|
||||
if ((nCount > 1) || (c > 0xbf)) {
|
||||
nCount |= 0xc0;
|
||||
*pDst++ = (BYTE) nCount;
|
||||
}
|
||||
|
||||
*pDst++ = c;
|
||||
} while (nWdt);
|
||||
|
||||
return pDst;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
static BOOL pcx_write_image(HANDLE hFile,WORD wDstWdt,WORD wDstHgt,WORD wSrcWdt,const BYTE * pSrc) {
|
||||
BYTE * pDstEnd;
|
||||
BYTE * pDstBase;
|
||||
DWORD dwWrite;
|
||||
DWORD dwBytes;
|
||||
|
||||
// allocate line buffer -- line cannot be more than 2x larger
|
||||
pDstBase = (BYTE *) DiabloAllocPtrSig(2 * wDstWdt,'CAPt');
|
||||
|
||||
while (wDstHgt--) {
|
||||
pDstEnd = pcx_compress_line(pSrc,pDstBase,wDstWdt);
|
||||
pSrc += wSrcWdt;
|
||||
dwWrite = pDstEnd - pDstBase;
|
||||
if (! WriteFile(hFile,pDstBase,dwWrite,&dwBytes,NULL)) return FALSE;
|
||||
if (dwBytes != dwWrite) return FALSE;
|
||||
}
|
||||
|
||||
DiabloFreePtr(pDstBase);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
#define MAX_CAPTURE 100
|
||||
#define DIG_OFF 6
|
||||
static const char szCAPTURE[] = "screen??.PCX";
|
||||
static const char szCAPTUREfmt[] = "screen%02d.PCX";
|
||||
static HANDLE open_capture_file(char szFileName[MAX_PATH]) {
|
||||
int nValue;
|
||||
BYTE bUsedTbl[MAX_CAPTURE];
|
||||
|
||||
ZeroMemory(bUsedTbl,sizeof(bUsedTbl));
|
||||
struct _finddata_t ffblk;
|
||||
long lHandle = _findfirst(szCAPTURE,&ffblk);
|
||||
if (lHandle != -1) {
|
||||
do {
|
||||
if (! isdigit(ffblk.name[DIG_OFF+0]))
|
||||
continue;
|
||||
if (! isdigit(ffblk.name[DIG_OFF+1]))
|
||||
continue;
|
||||
|
||||
nValue = (ffblk.name[DIG_OFF + 0] - '0') * 10;
|
||||
nValue += ffblk.name[DIG_OFF + 1] - '0';
|
||||
bUsedTbl[nValue] = 1;
|
||||
} while (! _findnext(lHandle,&ffblk));
|
||||
}
|
||||
|
||||
for (nValue = 0; nValue < MAX_CAPTURE; nValue++) {
|
||||
if (bUsedTbl[nValue]) continue;
|
||||
sprintf(szFileName,szCAPTUREfmt,nValue);
|
||||
return CreateFile(szFileName,GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL);
|
||||
}
|
||||
|
||||
return INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
static void red_palette(const PALETTEENTRY src[256]) {
|
||||
PALETTEENTRY dst[256];
|
||||
for (int i = 0; i < 256; i++) {
|
||||
dst[i].peRed = src[i].peRed;
|
||||
dst[i].peGreen = 0;
|
||||
dst[i].peBlue = 0;
|
||||
dst[i].peFlags = 0;
|
||||
}
|
||||
lpDDPal->SetEntries(0,0,256,dst);
|
||||
}
|
||||
|
||||
|
||||
//***************************************************************************
|
||||
//***************************************************************************
|
||||
void screen_capture(void) {
|
||||
HANDLE hFile;
|
||||
char szFileName[MAX_PATH];
|
||||
PALETTEENTRY pal[256];
|
||||
|
||||
if (INVALID_HANDLE_VALUE == (hFile = open_capture_file(szFileName)))
|
||||
return;
|
||||
|
||||
// get the current palette, then flash the screen red
|
||||
DrawAndBlit();
|
||||
lpDDPal->GetEntries(0,0,256,pal);
|
||||
red_palette(pal);
|
||||
|
||||
lock_buf(2);
|
||||
app_assert(gpBuffer);
|
||||
BOOL bOK = pcx_write_header(hFile,TOTALX,TOTALY);
|
||||
if (bOK) bOK = pcx_write_image(hFile,TOTALX,TOTALY,BUFFERX,gpBuffer + 122944);
|
||||
if (bOK) bOK = pcx_write_pal(hFile,pal);
|
||||
unlock_buf(2);
|
||||
|
||||
CloseHandle(hFile);
|
||||
if (! bOK)
|
||||
DeleteFile(szFileName);
|
||||
|
||||
// restore palette
|
||||
Sleep(300);
|
||||
lpDDPal->SetEntries(0,0,256,pal);
|
||||
}
|
||||
Reference in New Issue
Block a user