/* This file is part of Advanced Strategic Command; http://www.asc-hq.de Copyright (C) 1994-1999 Martin Bickel and Marc Schellenberger This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; see the file COPYING. If not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include "../basestrm.h" #include "../tpascal.inc" #include "../basegfx.h" #include "../misc.h" typedef struct tpcxheader{ char manufacturer; char version ; char encoding ; char bitsperpixel; word xmin,ymin ; word xmax,ymax ; word hdpi,vdpi ; char colormap[48]; char reserved ; char nplanes ; word bytesperline; word paletteinfo ; word hscreensize ; word vscreensize ; char dummy[50] ; int size; }tpcxheader; word columncount; extern "C" word planenum; extern "C" void* scratch; extern "C" integer linelength; integer spacelengthp; integer spacelength; extern "C" int datatoread; extern "C" int dataread; extern "C" int scanlineret[3]; extern "C" size_t datalength; const buffsize = 2000; extern "C" void decode_pcx256(); #pragma aux decode_pcx256 parm [ eax ] modify [ ebx ecx edx esi edi ] extern "C" void resetdata(int start); #pragma aux resetdata modify [ eax ebx ecx edx ] char loadpcxxy(char *name, char setpal, word x, word y) { ///////////// //variablen //////////// tpcxheader header; FILE *fp; dacpalette256 pal; word b,c; int m; fpos_t l; int colors; /////////// /// code ////////// m = y * agmp-> scanlinelength * agmp->byteperpix + x; fp = fopen(name, filereadmode ); if (fp == NULL) { return(100); } /* endif */ fread(&header,sizeof(header),1,fp); if (header.manufacturer != 10 || header.bitsperpixel != 8 || header.xmax-header.xmin > agmp-> scanlinelength ) { fclose(fp); return(11); } colors = header.nplanes * header.bitsperpixel; planenum = header.nplanes; if (colors == 8) { fgetpos( fp, &l ); b=0; fseek(fp, filesize( name ) - 769, SEEK_SET ); fread( &b, 1, 1, fp ); if (b != 12) { fclose( fp ); return(10); } /* endif */ fread( pal, 1, sizeof( pal ), fp ); for (b=0;b <=255 ;b++ ) { for (c=0;c<=2 ;c++ ) { pal[b][c]>>= 2; } /* endfor */ } /* endfor */ if (setpal) { setvgapalette256(pal); } /* endif */ fseek( fp,l, SEEK_SET ); } linelength = header.bytesperline; if (agmp->byteperpix > 1) { scanlineret[0] =agmp-> redfieldposition / 8; scanlineret[1] = linelength * agmp->byteperpix - agmp->greenfieldposition / 8 + agmp-> redfieldposition / 8; scanlineret[2] = linelength * agmp->byteperpix - agmp->bluefieldposition / 8 + agmp-> greenfieldposition / 8; scanlineret[3] = agmp-> scanlinelength - linelength* agmp->byteperpix + agmp->redfieldposition / 8 - agmp->bluefieldposition / 8; } else { scanlineret[0]=0; scanlineret[1]=agmp-> scanlinelength - linelength* agmp->byteperpix; } /* if (maxavail < buffsize) { buffsize=maxavail; } */ datatoread=(header.ymax-header.ymin+1) * header.bytesperline * header.nplanes; dataread=datatoread; if ( agmp->windowstatus == 100 ) resetdata( m ); else { setvirtualpagepos( m >> 16 ); resetdata( m & 0xffff ); } scratch = new char [ buffsize*2 ]; do { datalength = fread( scratch, 1, buffsize,fp) + 1; decode_pcx256(); } while ( !feof(fp) && dataread > 0); /* enddo */ int a = ftell ( fp ); fclose(fp); delete[] scratch; return(0); } /* endif */ char loadpcxxy( pnstream stream, int x, int y, int setpalette ) { int read = 0; int m = y * agmp-> scanlinelength * agmp->byteperpix + x; tpcxheader header; stream->readdata ( &header, sizeof(header) ); read += sizeof(header); if ( !header.size ) return 12; int dataend = header.size; if ( header.manufacturer != 10 || header.bitsperpixel != 8 || header.xmax-header.xmin > agmp-> scanlinelength ) return 11; int colors = header.nplanes * header.bitsperpixel; if ( colors == 8 ) dataend -= (sizeof ( dacpalette256 ) + 1); planenum = header.nplanes; linelength = header.bytesperline; if (agmp->byteperpix > 1) { scanlineret[0] = agmp-> redfieldposition / 8; scanlineret[1] = linelength * agmp->byteperpix - agmp->greenfieldposition / 8 + agmp-> redfieldposition / 8; scanlineret[2] = linelength * agmp->byteperpix - agmp->bluefieldposition / 8 + agmp-> greenfieldposition / 8; scanlineret[3] = agmp-> scanlinelength - linelength* agmp->byteperpix + agmp->redfieldposition / 8 - agmp->bluefieldposition / 8; } else { scanlineret[0]=0; scanlineret[1]=agmp-> scanlinelength - linelength* agmp->byteperpix; } datatoread=(header.ymax-header.ymin+1) * header.bytesperline * header.nplanes; dataread=datatoread; if ( agmp->windowstatus == 100 ) resetdata( m ); else { setvirtualpagepos( m >> 16 ); resetdata( m & 0xffff ); } scratch = new char [ buffsize ]; do { if ( buffsize > dataend - read ) datalength = dataend - read; else datalength = buffsize; stream->readdata ( scratch, datalength ); read += datalength; datalength ++ ; decode_pcx256(); } while ( header.size > read && dataread ); /* enddo */ if ( setpalette && colors == 8 ) { while ( read < dataend ) { if ( buffsize > dataend - read ) datalength = dataend - read; else datalength = buffsize; stream->readdata ( scratch, datalength ); } char c; stream->readdata ( &c, 1 ); if ( c == 12 ) { dacpalette256 pal; stream->readdata ( pal, sizeof ( pal ) ); for ( int i = 0; i < 3; i++ ) for ( int j = 0; j < 256; j++ ) pal[j][i] >>= 2; setvgapalette256 ( pal ); } } delete[] scratch; return 0; } #define writedata2(a) writedata ( &(a), sizeof(a) ) #define readdata2(a) readdata ( &(a), sizeof(a) ) void writepcx ( char* name, int x1, int y1, int x2, int y2, dacpalette256 pal ) { tpcxheader header; memset ( &header, 0, sizeof (header )); header.manufacturer = 10; header.version = 5; header.encoding = 1; header.bitsperpixel = 8; header.xmin = 0; header.xmax = x2 - x1 ; header.ymin = 0; header.ymax = y2 - y1 ; header.hdpi = 0; header.vdpi = 0; if ( agmp->byteperpix == 1 ) header.nplanes = 1; else header.nplanes = 3; // header.bytesperline = ((header.xmax - header.xmin) + 1) & 0xFFFE; header.bytesperline = x2 - x1 + 1 ; if ( header.bytesperline & 1 ) header.bytesperline++; header.paletteinfo = 1; int fsize = 0; tn_file_buf_stream stream ( name, 2 ); stream.writedata2 ( header ); fsize += sizeof ( header ); for ( int y = y1; y <= y2; y++ ) for ( int plane = 0; plane < header.nplanes; plane++ ) { int lastbyte = -1; int count = 0; for ( int x = x1; x < x1 + header.bytesperline; x++ ) { char c = (getpixel( x, y ) >> ( plane * 8 )) & 0xff; if ( (lastbyte == c && count < 63) || lastbyte == -1 ) { count ++; lastbyte = c; } else { if ( count > 1 || lastbyte >= 192 ) { char d = 192 + count; stream.writedata2 ( d ); fsize += sizeof ( d ); } char lstbyte = lastbyte; stream.writedata2 ( lstbyte ); fsize += sizeof ( lstbyte ); count = 1; lastbyte = c; } } if ( count > 1 || lastbyte >= 192 ) { char d = 192 + count; stream.writedata2 ( d ); fsize += sizeof ( d ); } char lstbyte = lastbyte; stream.writedata2 ( lstbyte ); fsize += sizeof ( lstbyte ); } if ( header.nplanes == 1 ) { char d = 12; stream.writedata2 ( d ); fsize += sizeof ( d ); dacpalette256 pal2; for ( int i = 0; i < 3; i++ ) for ( int j = 0; j < 256; j++ ) pal2[j][i] = pal[j][i] << 2; stream.writedata ( &pal2, 768 ); fsize += 768 ; } stream.seek ( 0 ); header.size = fsize; stream.writedata2 ( header ); } structure_size_tester sst2;