Initial Source Code commit
Initial commit of original Tiberian Dawn and Red Alert source code converted to build as DLLs, and compatible with the release version of Command & Conquer Remastered.
This commit is contained in:
parent
ea8ecc76fa
commit
03416d24e1
1038 changed files with 629779 additions and 0 deletions
325
REDALERT/WIN32LIB/IFF.CPP
Normal file
325
REDALERT/WIN32LIB/IFF.CPP
Normal file
|
@ -0,0 +1,325 @@
|
|||
//
|
||||
// Copyright 2020 Electronic Arts Inc.
|
||||
//
|
||||
// TiberianDawn.DLL and RedAlert.dll and corresponding source code 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.
|
||||
|
||||
// TiberianDawn.DLL and RedAlert.dll and corresponding source code is distributed
|
||||
// in the hope that it will be useful, but with permitted additional restrictions
|
||||
// under Section 7 of the GPL. See the GNU General Public License in LICENSE.TXT
|
||||
// distributed with this program. You should have received a copy of the
|
||||
// GNU General Public License along with permitted additional restrictions
|
||||
// with this program. If not, see https://github.com/electronicarts/CnC_Remastered_Collection
|
||||
|
||||
/***************************************************************************
|
||||
** C O N F I D E N T I A L --- W E S T W O O D A S S O C I A T E S **
|
||||
***************************************************************************
|
||||
* *
|
||||
* Project Name : Westwood Library *
|
||||
* *
|
||||
* File Name : IFF.C *
|
||||
* *
|
||||
* Programmer : Joe L. Bostic *
|
||||
* *
|
||||
* Start Date : May 16, 1991 *
|
||||
* *
|
||||
* Last Update : April 19, 1994 [SKB] *
|
||||
* *
|
||||
* *
|
||||
* IFF reader code designed for loading pictures (ILBM or PBM). *
|
||||
* *
|
||||
*-------------------------------------------------------------------------*
|
||||
* Functions: *
|
||||
* Close_Iff_File -- Closes an IFF file handle. *
|
||||
* Get_Iff_Chunk_Size -- Get the size of the given IFF chunk. *
|
||||
* Open_Iff_File -- Opens an IFF file for reading. *
|
||||
* Read_Iff_Chunk -- Reads a chunk from an IFF file. *
|
||||
* Write_Iff_Chunk -- Writes an IFF chuck out. *
|
||||
* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
|
||||
|
||||
#include "iff.h"
|
||||
#include "file.h"
|
||||
|
||||
#define ID_FORM MAKE_ID('F','O','R','M')
|
||||
|
||||
#ifdef MIN
|
||||
#undef MIN
|
||||
#endif
|
||||
|
||||
/***************************************************************************
|
||||
* OPEN_IFF_FILE -- Opens an IFF file for reading. *
|
||||
* *
|
||||
* This function will open an IFF file for reading. It will perform *
|
||||
* a the simple validity test of checking the first four bytes to make *
|
||||
* sure they are "FORM". The value returned is the filehandle of the *
|
||||
* opened file. *
|
||||
* *
|
||||
* INPUT: filename - ASCII name of the IFF file to be opened. *
|
||||
* *
|
||||
* OUTPUT: Returns the filehandle. If there is an error or the file *
|
||||
* is not an IFF FORM then -1 will be returned. *
|
||||
* *
|
||||
* WARNINGS: You are responsible for error handling if this function *
|
||||
* returns -1 (not an IFF file). *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
int __cdecl Open_Iff_File(char const *filename)
|
||||
{
|
||||
int fh; // File handle.
|
||||
long type; // IFF file type.
|
||||
|
||||
|
||||
/* We want to be able to open the file for READ | WRITE, but we do not
|
||||
want the Open_File to create it. So check to see if it exists before
|
||||
the Open_File */
|
||||
|
||||
// fh = Open_File(filename, READ); // Open the source file for READ
|
||||
// Close_File(fh);
|
||||
|
||||
//fh = Open_File(filename, READ | WRITE); // Open the source file again
|
||||
fh = Open_File(filename, READ); // Open the source file again
|
||||
|
||||
// Validate that it is a FORM type.
|
||||
|
||||
Read_File(fh, &type, 4L);
|
||||
|
||||
if (type == ID_FORM) {
|
||||
|
||||
// The file is valid (so far). Position the read so that the actual
|
||||
// IFF file type code can be read.
|
||||
|
||||
Seek_File(fh, 4L, SEEK_CUR); // Skip the filesize bytes.
|
||||
|
||||
} else {
|
||||
|
||||
// This is NOT an IFF file. Close the source file and return with
|
||||
// the error code.
|
||||
Close_File(fh);
|
||||
fh = WW_ERROR;
|
||||
}
|
||||
return fh;
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* CLOSE_IFF_FILE -- Closes an IFF file handle. *
|
||||
* *
|
||||
* The routine will close the file that was opened with the *
|
||||
* Open_Iff_File() function. *
|
||||
* *
|
||||
* INPUT: fh - File handle that was returned from Open_Iff_File(). *
|
||||
* *
|
||||
* OUTPUT: none *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
void __cdecl Close_Iff_File(int fh)
|
||||
{
|
||||
if (fh != WW_ERROR) Close_File(fh);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* GET_IFF_CHUNK_SIZE -- Get the size of the given IFF chunk. *
|
||||
* *
|
||||
* INPUT: int file handle to open IFF file, long id to get size of *
|
||||
* *
|
||||
* OUTPUT: long size of the chunk or 0L if it was not found *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 06/03/1991 CY : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Get_Iff_Chunk_Size(int fh, long id)
|
||||
{
|
||||
long form; // Chunk iff form name.
|
||||
long chunksize; // Size of the chunk.
|
||||
char first_iteration; // Check once the current chunk name
|
||||
|
||||
|
||||
first_iteration = TRUE;
|
||||
|
||||
for (;;) {
|
||||
if (Read_File(fh, &form, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
|
||||
if (Read_File(fh, (char *) &chunksize, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
#if(IBM)
|
||||
chunksize = Reverse_Long(chunksize);
|
||||
#endif
|
||||
|
||||
if (id == form) {
|
||||
Seek_File(fh, -8L, SEEK_CUR); // Seek back to the start of
|
||||
return(chunksize); // the chunk & return size
|
||||
} else {
|
||||
|
||||
if (first_iteration) {
|
||||
Seek_File(fh, 12L, SEEK_SET); // Start at beginning of file.
|
||||
first_iteration = FALSE; // Don't do this again
|
||||
} else {
|
||||
|
||||
/* Otherwise, go to the next chunk in the file */
|
||||
|
||||
chunksize = (chunksize + 1) & 0xFFFFFFFEL;
|
||||
Seek_File(fh, chunksize, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0L);
|
||||
}
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* READ_IFF_CHUNK -- Reads a chunk from an IFF file. *
|
||||
* *
|
||||
* Once an IFF file is opened, various chunks must be read from it. *
|
||||
* This routine will search through the IFF file and load in the *
|
||||
* specified chunk. It will scan through the entire file when *
|
||||
* searching for the chunk. It will load the FIRST chunk of the given *
|
||||
* type. *
|
||||
* *
|
||||
* INPUT: fh - File handle of IFF file. *
|
||||
* *
|
||||
* id - Chunk ID code. *
|
||||
* *
|
||||
* buffer - Pointer to buffer to load the chunk. *
|
||||
* *
|
||||
* maxsize - Maximum data bytes to read. *
|
||||
* *
|
||||
* OUTPUT: Returns with the number of bytes read from the chunk. *
|
||||
* If 0 is returned, this indicates that the chunk wasn't *
|
||||
* found. *
|
||||
* *
|
||||
* WARNINGS: none *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 05/16/1991 JLB : Created. *
|
||||
* 04/19/1994 SKB : Update to 32 bit library. *
|
||||
*=========================================================================*/
|
||||
unsigned long __cdecl Read_Iff_Chunk(int fh, long id, void *buffer, unsigned long maxsize)
|
||||
{
|
||||
long form; // Chunk iff form name.
|
||||
unsigned long chunksize; // Size of the chunk.
|
||||
char first_iteration; // Check once the current chunk name
|
||||
|
||||
first_iteration = TRUE;
|
||||
|
||||
for (;;) {
|
||||
if (Read_File(fh, &form, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
if (Read_File(fh, (char *) &chunksize, 4L) != 4L && !first_iteration) break;
|
||||
|
||||
#if(IBM)
|
||||
chunksize = Reverse_Long(chunksize);
|
||||
#endif
|
||||
|
||||
if (id == form) {
|
||||
|
||||
maxsize = MIN(maxsize, chunksize);
|
||||
Read_File(fh, buffer, maxsize); // Read the buffer.
|
||||
|
||||
chunksize = (chunksize + 1) & 0xFFFFFFFEL;
|
||||
if (maxsize < chunksize) {
|
||||
Seek_File(fh, chunksize - maxsize, SEEK_CUR);
|
||||
}
|
||||
return(maxsize);
|
||||
} else {
|
||||
|
||||
if (first_iteration) {
|
||||
Seek_File(fh, 12L, SEEK_SET); // Start at beginning of file.
|
||||
first_iteration = FALSE; // Don't do this again
|
||||
|
||||
} else {
|
||||
|
||||
/* Otherwise, go to the next chunk in the file */
|
||||
|
||||
chunksize = (chunksize + 1) & 0xFFFFFFFEL;
|
||||
Seek_File(fh, chunksize, SEEK_CUR);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(0L);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/***************************************************************************
|
||||
* WRITE_IFF_CHUNK -- Writes an IFF chuck out. *
|
||||
* *
|
||||
* INPUT: *
|
||||
* *
|
||||
* OUTPUT: *
|
||||
* *
|
||||
* WARNINGS: *
|
||||
* *
|
||||
* HISTORY: *
|
||||
* 04/19/1994 SKB : Created. *
|
||||
*=========================================================================*/
|
||||
void __cdecl Write_Iff_Chunk(int file, long id, void *buffer, long length)
|
||||
{
|
||||
long pos; // Current position in the IFF file.
|
||||
long oldpos; // Record of start of chunk offset.
|
||||
long endpos; // end of file offset before we write our data
|
||||
long value;
|
||||
BOOL odd; // Is length odd?
|
||||
char pad = 0; // Optional padding byte for even sized chunks.
|
||||
|
||||
/*
|
||||
** Get the current end of file (before we write more data to the file)
|
||||
*/
|
||||
pos = Seek_File (file, 0L, SEEK_CUR);
|
||||
endpos = Seek_File (file, 0L, SEEK_END);
|
||||
Seek_File (file, pos, SEEK_SET);
|
||||
|
||||
if (length) {
|
||||
value = id;
|
||||
odd = (short)length & 0x01;
|
||||
|
||||
Write_File(file, &value, 4L);
|
||||
oldpos = Seek_File(file, 0L, SEEK_CUR);
|
||||
Write_File(file, &value, 4L);
|
||||
Write_File(file, buffer, length);
|
||||
pos = Seek_File(file, 0L, SEEK_CUR);
|
||||
if (odd) {
|
||||
Write_File(file, &pad, 1L);
|
||||
}
|
||||
|
||||
/*
|
||||
** Update the chunk size long.
|
||||
*/
|
||||
Seek_File(file, oldpos, SEEK_SET);
|
||||
value = IFFize_LONG((pos - oldpos)-4);
|
||||
Write_File(file, &value, 4L);
|
||||
|
||||
/*
|
||||
** Update the file size LONG. if we are not just overwriting existing data
|
||||
*/
|
||||
// (MCC)
|
||||
if ( endpos < pos ) {
|
||||
Seek_File(file, 4L, SEEK_SET);
|
||||
value = IFFize_LONG((pos+odd) - 8);
|
||||
Write_File(file, &value, 4L);
|
||||
}
|
||||
|
||||
/*
|
||||
** Return to end of file.
|
||||
*/
|
||||
Seek_File(file, 0L, SEEK_END);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in a new issue