Files
sibo-playground/code/SIBOSDK/demo/pcxsave.c
T
2026-07-06 18:01:36 +01:00

140 lines
2.6 KiB
C

/*
Save the screen to PCX file
*/
#include <plib.h>
#include <wlib.h>
#define BUFLEN 256
GLREF_D WSERV_SPEC *wserv_channel;
LOCAL_D VOID *fcb;
LOCAL_D UBYTE *pbuf;
LOCAL_D UBYTE *pobuf;
LOCAL_D UBYTE obuf[BUFLEN];
LOCAL_C VOID FlushBuffer(VOID)
{
f_write(fcb,&obuf[0],pobuf-&obuf[0]);
pobuf=&obuf[0];
}
LOCAL_C VOID putb(INT b)
{
*pobuf++=b;
if (pobuf==&obuf[BUFLEN])
FlushBuffer();
}
LOCAL_C INT rev(INT dat)
{
INT i;
INT rdat;
rdat=0;
for (i=0;i<8;i++)
rdat|=((dat>>i)&1)<<(7-i);
return(rdat^0xff);
}
LOCAL_C VOID WritePCXLine(UBYTE *buf,UINT len)
{
UBYTE *p;
UINT end;
UINT count;
INT byte;
p=buf;
byte=*p++;
count=1;
do
{
end=(p==(&buf[0]+len));
if (byte==*p && count<0x3f && !end)
{
count++;
p++;
}
else
{
byte=rev(byte);
if (count>1 || (byte&0xC0)==0xC0)
putb(count+0xC0);
putb(byte);
byte=*p++;
count=1;
}
} while (!end);
}
LOCAL_C VOID WriteHeader(TEXT *name,UINT width,UINT height,UINT bytewid)
{
struct
{
UBYTE manuf;
UBYTE hard;
UBYTE encod;
UBYTE bitpx;
P_RECT rect;
WORD hres;
WORD vres;
UBYTE clrma[48];
UBYTE vmode;
UBYTE nplanes;
WORD bplin;
UBYTE padding[60];
} header;
f_open(&fcb,name,P_FREPLACE|P_FSTREAM|P_FUPDATE);
p_bfil(&header,sizeof(header),0);
header.manuf=10;
header.hard=3;
header.encod=TRUE;
header.bitpx=1;
header.rect.br.x=width-1;
header.rect.br.y=height-1;
header.hres=640;
header.vres=480;
header.nplanes=1;
header.bplin=bytewid;
f_write(fcb,&header,sizeof(header));
}
#pragma save, ENTER_CALL
LOCAL_C INT WritePCXFile(TEXT *name)
{
UINT len;
P_POINT size;
P_POINT line;
size=wserv_channel->conn.info.pixels;
len=((size.x+15)>>3)&~1;
WriteHeader(name,size.x,size.y,len);
pbuf=f_alloc(len);
line.x=0;
for (line.y=0;line.y<size.y;line.y++)
{
gPeekBit(0,&line,size.x,pbuf);
WritePCXLine(pbuf,len);
}
FlushBuffer();
return(0);
}
#pragma restore
GLDEF_C INT pcxScreenSave(TEXT *name)
{
INT ret;
fcb=NULL;
pbuf=NULL;
pobuf=&obuf[0];
ret=p_enter2((VOID *)WritePCXFile,name);
p_free(pbuf);
p_close(fcb);
return(ret);
}