mirror of
https://github.com/electronicarts/CnC_Renegade.git
synced 2025-12-16 07:31:40 -05:00
Initial commit of Command & Conquer Renegade source code.
This commit is contained in:
168
Code/wwlib/pcx.cpp
Normal file
168
Code/wwlib/pcx.cpp
Normal file
@@ -0,0 +1,168 @@
|
||||
/*
|
||||
** 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user