168 lines
6.5 KiB
C++
168 lines
6.5 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** 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 3 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. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/***********************************************************************************************
|
|
*** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
|
|
***********************************************************************************************
|
|
* *
|
|
* Project Name : Command & Conquer *
|
|
* *
|
|
* $Archive:: /Commando/Code/Library/PCX.cpp $*
|
|
* *
|
|
* $Author:: Greg_h $*
|
|
* *
|
|
* $Modtime:: 9/28/98 12:06p $*
|
|
* *
|
|
* $Revision:: 2 $*
|
|
* *
|
|
*---------------------------------------------------------------------------------------------*
|
|
* Functions: *
|
|
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
|
|
|
#include "always.h"
|
|
#include "pcx.h"
|
|
#include <stdlib.h>
|
|
|
|
|
|
/***************************************************************************
|
|
* READ_PCX_FILE -- read a pcx file into a Graphic Buffer *
|
|
* *
|
|
* GraphicBufferClass* Read_PCX_File (char* name, char* palette,void *Buff, long size ); *
|
|
* *
|
|
* *
|
|
* INPUT: name is a NULL terminated string of the format [xxxx.pcx] *
|
|
* palette is optional, if palette != NULL the the color palette of *
|
|
* the pcx file will be place in the memory block pointed *
|
|
* by palette. *
|
|
* Buff is optional, if Buff == NULL a new memory Buffer *
|
|
* will be allocated, otherwise the file will be placed *
|
|
* at location pointed by Buffer; *
|
|
* Size is the size in bytes of the memory block pointed by Buff *
|
|
* is also optional; * *
|
|
* OUTPUT: on success a pointer to a GraphicBufferClass containing the *
|
|
* pcx file, NULL otherwise. *
|
|
* *
|
|
* WARNINGS: *
|
|
* Appears to be a comment-free zone *
|
|
* *
|
|
* HISTORY: *
|
|
* 05/03/1995 JRJ : Created. *
|
|
* 04/30/1996 ST : Tidied up and modified to use CCFileClass *
|
|
*=========================================================================*/
|
|
#define POOL_SIZE 2048
|
|
#define READ_CHAR() *file_ptr++ ; \
|
|
if ( file_ptr >= & pool [ POOL_SIZE ] ) { \
|
|
file_handle.Read (pool, POOL_SIZE ); \
|
|
file_ptr = pool ; \
|
|
}
|
|
#define READ_CHARx() *file_ptr++ ; \
|
|
if ( file_ptr >= & pool [ POOL_SIZE ] ) { \
|
|
file_handle.Read (pool, POOL_SIZE ); \
|
|
}
|
|
|
|
|
|
Surface * Read_PCX_File(FileClass & file_handle, PaletteClass * palette, void * Buff, long Size)
|
|
{
|
|
unsigned i, j;
|
|
unsigned rle;
|
|
unsigned color;
|
|
unsigned scan_pos;
|
|
char *file_ptr;
|
|
unsigned width;
|
|
unsigned height;
|
|
char *buffer;
|
|
PCX_HEADER header;
|
|
char pool [POOL_SIZE];
|
|
BSurface * pic;
|
|
|
|
if (!file_handle.Is_Available()) return (NULL);
|
|
|
|
file_handle.Open(FileClass::READ);
|
|
|
|
file_handle.Read (&header, sizeof (PCX_HEADER));
|
|
|
|
if (header.id != 10 && header.version != 5 && header.pixelsize != 8 ) return NULL ;
|
|
|
|
width = header.width - header.x + 1;
|
|
height = header.height - header.y + 1;
|
|
|
|
if (Buff != NULL) {
|
|
i = Size / width;
|
|
height = MIN ((int)(i - 1), (int)height);
|
|
Buffer b(Buff, Size);
|
|
pic = new BSurface(width, height, 1, &b);
|
|
if (pic == NULL) return NULL ;
|
|
} else {
|
|
pic = new BSurface(width, height, 1);
|
|
if (pic == NULL) return NULL ;
|
|
}
|
|
|
|
buffer = (char *)pic->Lock();
|
|
if (buffer != NULL) {
|
|
file_ptr = pool ;
|
|
file_handle.Read (pool, POOL_SIZE);
|
|
|
|
if ( header.byte_per_line != width ) {
|
|
|
|
i = 0;
|
|
rle = 0;
|
|
for ( scan_pos = j = 0 ; j < height ; j ++, scan_pos += width ) {
|
|
for ( i = 0 ; i < width ; ) {
|
|
rle = READ_CHAR ();
|
|
if ( rle > 192 ) {
|
|
rle -= 192 ;
|
|
color = READ_CHAR (); ;
|
|
memset ( buffer + scan_pos + i, color, rle );
|
|
i += rle;
|
|
} else {
|
|
*(buffer+scan_pos + i++ ) = (char)rle;
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( i == width ) rle = READ_CHAR ();
|
|
if ( rle > 192 ) READ_CHARx();
|
|
|
|
} else {
|
|
|
|
for ( i = 0 ; i < width * height ; ) {
|
|
rle = READ_CHAR ();
|
|
rle &= 0xff;
|
|
if ( rle > 192 ) {
|
|
rle -= 192 ;
|
|
color = READ_CHAR ();
|
|
memset ( buffer + i, color, rle );
|
|
i += rle ;
|
|
} else {
|
|
*(buffer + i++) = (char)rle;
|
|
}
|
|
}
|
|
}
|
|
pic->Unlock();
|
|
}
|
|
|
|
if ( palette ) {
|
|
file_handle.Seek (- (256 * (int)sizeof(RGB)), SEEK_END );
|
|
file_handle.Read (palette, 256L * sizeof ( RGB ));
|
|
}
|
|
|
|
file_handle.Close();
|
|
return pic;
|
|
}
|
|
|
|
|