140 lines
2.6 KiB
C
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);
|
||
|
|
}
|