summaryrefslogtreecommitdiff
path: root/3dc/win95/MISHCHNK.CPP
diff options
context:
space:
mode:
Diffstat (limited to '3dc/win95/MISHCHNK.CPP')
-rw-r--r--3dc/win95/MISHCHNK.CPP1999
1 files changed, 0 insertions, 1999 deletions
diff --git a/3dc/win95/MISHCHNK.CPP b/3dc/win95/MISHCHNK.CPP
deleted file mode 100644
index 5f4dde3..0000000
--- a/3dc/win95/MISHCHNK.CPP
+++ /dev/null
@@ -1,1999 +0,0 @@
-#include "chunk.hpp"
-#include "chnktype.hpp"
-#include "mishchnk.hpp"
-
-#include "shpchunk.hpp"
-#include "obchunk.hpp"
-
-
-
-#include "huffman.hpp"
-
-
-#include <mbstring.h>
-
-#ifdef cencon
-#define new my_new
-#endif
-
-
-// Class Lockable_Chunk_With_Children functions
-
-#if cencon
-#else
-extern char * users_name;
-#endif
-
-//macro for helping to force inclusion of chunks when using libraries
-FORCE_CHUNK_INCLUDE_IMPLEMENT(mishchnk)
-
-BOOL Lockable_Chunk_With_Children::lock_chunk(File_Chunk & fchunk)
-{
- if (!fchunk.filename) return FALSE;
-
- if (local_lock) return FALSE; // you can't lock a chunk twice
-
- #if DisableLock
- if(external_lock) return FALSE;
- local_lock = TRUE;
- set_lock_user (users_name);
- return TRUE;
- #else
- if (!fchunk.check_file()) return FALSE;
- if (updated_outside || external_lock) return FALSE;
-
- HANDLE rif_file;
- unsigned long bytes_read;
-
- int tries = 0;
-
- rif_file = CreateFile (fchunk.filename, GENERIC_WRITE + GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- while(rif_file == INVALID_HANDLE_VALUE && tries<10)
- {
- rif_file = CreateFile (fchunk.filename, GENERIC_WRITE + GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
- tries ++;
- clock_t ctime = clock();
- double secs = (double)ctime / (double)CLOCKS_PER_SEC;
- double secsgone;
- do
- {
- ctime = clock();
- secsgone = (double)ctime / (double)CLOCKS_PER_SEC;
- }
- while( (secsgone-secs)<1);
- }
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> chfptrs;
- list_chunks_in_file(& chfptrs, rif_file, identifier);
-
- LIF<int> cfpl(&chfptrs);
-
- if (chfptrs.size()) {
- for (; !cfpl.done(); cfpl.next()) {
-
- SetFilePointer (rif_file, cfpl(),0,FILE_BEGIN);
-
- if (file_equals(rif_file)) break;
- }
- }
-
- if (!cfpl.done()) {
-
- // go to start of chunk
- SetFilePointer (rif_file,cfpl(),0,FILE_BEGIN);
-
- // get header list
- if (get_head_id())
- {
- List<int> obhead;
- list_chunks_in_file(& obhead, rif_file, get_head_id());
-
- assert (obhead.size() == 1);
-
- int flags;
-
- // go to lock status in header
- SetFilePointer(rif_file,obhead.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- SetFilePointer(rif_file,-4,0,FILE_CURRENT);
- flags |= GENERAL_FLAG_LOCKED;
- WriteFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- WriteFile (rif_file, (long *) &users_name[0], 16, &bytes_read, 0);
- }
-
- }
-
- local_lock = TRUE;
-
- set_lock_user (users_name);
-
- CloseHandle (rif_file);
- return TRUE;
- #endif
-
-}
-
-BOOL Lockable_Chunk_With_Children::unlock_chunk (File_Chunk & fchunk, BOOL updateyn)
-{
- if (updateyn) {
- updated = TRUE;
- }
- #if DisableLock
- local_lock = FALSE;
- (void)fchunk;
- #else
- else
- {
- fchunk.check_file();
- if (updated_outside || external_lock) return FALSE;
-
- HANDLE rif_file;
- unsigned long bytes_read;
-
- rif_file = CreateFile (fchunk.filename, GENERIC_WRITE + GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- return FALSE;
- }
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> chfptrs;
- list_chunks_in_file(& chfptrs, rif_file, identifier);
-
- List<obinfile> obs;
-
- char name[50];
-
- LIF<int> ofpl(&chfptrs);
-
- if (chfptrs.size()) {
- for (; !ofpl.done(); ofpl.next()) {
-
- SetFilePointer (rif_file, ofpl(),0,FILE_BEGIN);
-
- if (file_equals(rif_file)) break;
- }
- }
-
- if (!ofpl.done()) {
-
- // go to start of chunk
- SetFilePointer (rif_file,ofpl(),0,FILE_BEGIN);
-
- // get header list
- if (get_head_id())
- {
- List<int> obhead;
- list_chunks_in_file(& obhead, rif_file, get_head_id());
-
- assert (obhead.size() == 1);
-
- int flags;
-
- // go to lock status in header
- SetFilePointer(rif_file,obhead.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- SetFilePointer(rif_file,-4,0,FILE_CURRENT);
- flags &= ~GENERAL_FLAG_LOCKED;
- WriteFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- WriteFile (rif_file, (long *) &users_name[0], 16, &bytes_read, 0);
- }
-
- }
-
- local_lock = FALSE;
-
- CloseHandle (rif_file);
- }
- #endif
-
-
- return TRUE;
-
-}
-
-
-BOOL Lockable_Chunk_With_Children::update_chunk_in_file(HANDLE &rif_file)
-{
-
- unsigned long bytes_read;
- int length = 0;
-
- const char * hd_id = get_head_id();
-
- if (!hd_id) return FALSE;
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- //twprintf("\nLooking for chunks in file\n");
-
- List<int> shpfptrs;
- list_chunks_in_file(& shpfptrs, rif_file, identifier);
-
- // look through chunks for the save of our current chunk
-
- //twprintf("Checking each chunk\n");
-
- LIF<int> sfpl(&shpfptrs);
-
- if (shpfptrs.size()) {
- for (; !sfpl.done(); sfpl.next()) {
-
- SetFilePointer (rif_file, sfpl()+8,0,FILE_BEGIN);
-
- ReadFile (rif_file, (long *) &(length), 4, &bytes_read, 0);
-
- SetFilePointer (rif_file, sfpl(),0,FILE_BEGIN);
- if (file_equals(rif_file)) break;
- }
- }
-
- // then load the file after that chunk into a buffer,
- // output the chunk and write the buffer
- // unless the chunk is the last one in the file
-
- //twprintf("Updating file\n");
-
- if (!sfpl.done())
- {
-
- int file_length = GetFileSize(rif_file,0);
-
- if (file_length > (sfpl() + length)) {
-
- SetFilePointer (rif_file, sfpl() + length,0,FILE_BEGIN);
-
- char * tempbuffer;
- tempbuffer = new char [file_length - (sfpl() + length)];
-
- ReadFile (rif_file, (long *) tempbuffer, (file_length - (sfpl() + length)), &bytes_read, 0);
-
- SetFilePointer (rif_file, sfpl() ,0,FILE_BEGIN);
-
- if (!deleted)
- {
- size_chunk();
- output_chunk(rif_file);
- }
-
- WriteFile (rif_file, (long *) tempbuffer, (file_length - (sfpl() + length)), &bytes_read, 0);
-
- delete [] tempbuffer;
-
- SetEndOfFile (rif_file);
- }
- else{
-
- SetFilePointer (rif_file, sfpl() ,0,FILE_BEGIN);
- if (!deleted)
- {
- size_chunk();
- output_chunk(rif_file);
- }
- SetEndOfFile (rif_file);
- }
-
- }
- else {
-
- SetFilePointer (rif_file,0 ,0,FILE_END);
- if (!deleted)
- {
- size_chunk();
- output_chunk(rif_file);
- }
- SetEndOfFile (rif_file);
- }
-
- local_lock = FALSE;
-
- updated = FALSE;
-
- int file_length = GetFileSize(rif_file,0);
- SetFilePointer (rif_file,8,0,FILE_BEGIN);
-
- WriteFile (rif_file, (long *) &file_length, 4, &bytes_read, 0);
-
-
- // DO NOT PUT ANY CODE AFTER THIS
-
- if (deleted) delete this;
-
- // OR ELSE !!!
-
- return TRUE;
-
-}
-
-
-size_t Lockable_Chunk_With_Children::size_chunk_for_process()
-{
- if (output_chunk_for_process)
- return size_chunk();
- return(chunk_size = 0);
-}
-
-
-void Lockable_Chunk_With_Children::fill_data_block_for_process(char * data_start)
-{
- if (output_chunk_for_process)
- {
- fill_data_block(data_start);
- output_chunk_for_process = FALSE;
- }
-}
-
-
-
-
-///////////////////////////////////////
-
-// Class File_Chunk functions
-
-/*
-Children for File_Chunk :
-"REBSHAPE" Shape_Chunk
-"RSPRITES" AllSprites_Chunk
-"RBOBJECT" Object_Chunk
-"RIFVERIN" RIF_Version_Num_Chunk
-"REBENVDT" Environment_Data_Chunk
-"REBENUMS" Enum_Chunk
-"OBJCHIER" Object_Hierarchy_Chunk
-"OBHALTSH" Object_Hierarchy_Alternate_Shape_Set_Chunk
-"HIDEGDIS" Hierarchy_Degradation_Distance_Chunk
-"INDSOUND" Indexed_Sound_Chunk
-"HSETCOLL" Hierarchy_Shape_Set_Collection_Chunk
-"DUMMYOBJ" Dummy_Object_Chunk
-
-*/
-
-File_Chunk::File_Chunk(const char * file_name)
-: Chunk_With_Children (NULL, "REBINFF2")
-{
-// Load in whole chunk and traverse
- char rifIsCompressed = FALSE;
- char *uncompressedData = NULL;
- HANDLE rif_file;
- DWORD file_size;
- DWORD file_size_from_file;
- unsigned long bytes_read;
- char * buffer;
- char * buffer_ptr;
- char id_buffer[9];
-
- Parent_File = this;
-
- error_code = 0;
- object_array_size=0;
- object_array=0;
-
- filename = new char [strlen(file_name) + 1];
-
- strcpy (filename, file_name);
-
- rif_file = CreateFileA (file_name, GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- error_code = CHUNK_FAILED_ON_LOAD;
- return;
- }
-
- file_size = GetFileSize (rif_file, NULL);
-
-
- if (!ReadFile(rif_file, id_buffer, 8, &bytes_read, 0)) {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- return;
- }
-
- #if UseOldChunkLoader
- if (strncmp (id_buffer, "REBINFLF", 8)) {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- CloseHandle (rif_file);
- return;
- }
- #else
- /* KJL 16:46:14 19/09/98 - check for a compressed rif */
- if (!strncmp (id_buffer, COMPRESSED_RIF_IDENTIFIER, 8))
- {
- rifIsCompressed = TRUE;
- }
- else if (strncmp (id_buffer, "REBINFF2", 8))
- {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- CloseHandle (rif_file);
- return;
- }
- #endif
- buffer = new char [file_size];
-
- /* KJL 17:57:44 19/09/98 - if the rif is compressed, we must load the whole
- file in and then pass it to the decompression routine, which will return a
- pointer to the original data. */
- if (rifIsCompressed)
- {
- if (!ReadFile(rif_file, buffer+8, (file_size-8), &bytes_read, 0))
- {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- return;
- }
- uncompressedData = HuffmanDecompress((HuffmanPackage*)buffer);
- file_size = ((HuffmanPackage*)buffer)->UncompressedDataSize;
-
- delete [] buffer; // kill the buffer the compressed file was loaded into
-
- buffer_ptr = buffer = uncompressedData+12; // skip header data
- }
- else // the normal uncompressed approach:
- {
- if (!ReadFile(rif_file, &file_size_from_file, 4, &bytes_read, 0)) {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- return;
- }
-
- if (file_size != file_size_from_file) {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- CloseHandle (rif_file);
- return;
- }
-
- if (!ReadFile(rif_file, buffer, (file_size-12), &bytes_read, 0))
- {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- return;
- }
- buffer_ptr = buffer;
- }
-
- // Process the RIF
- // The start of the first chunk
-
- while ((buffer_ptr-buffer)< ((signed) file_size-12) && !error_code) {
-
- if ((*(int *)(buffer_ptr + 8)) + (buffer_ptr-buffer) > ((signed)file_size-12)) {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- break;
- }
-
- DynCreate(buffer_ptr);
- buffer_ptr += *(int *)(buffer_ptr + 8);
-
- }
-
- /* KJL 17:59:42 19/09/98 - release the memory holding the rif */
- if (rifIsCompressed)
- {
- free(uncompressedData);
- }
- else
- {
- delete [] buffer;
- }
-
- CloseHandle (rif_file);
-
- post_input_processing();
-
-}
-
-File_Chunk::File_Chunk()
-: Chunk_With_Children (NULL, "REBINFF2")
-{
-// Empty File chunk
- new RIF_Version_Num_Chunk (this);
- filename = 0;
-
- object_array_size=0;
- object_array=0;
-}
-
-
-File_Chunk::~File_Chunk()
-{
- if (filename)
- delete [] filename;
-
- if(object_array)
- free(object_array);
-}
-
-#define SAVE_USING_COMPRESSION 1
-
-BOOL File_Chunk::write_file (const char * fname)
-{
- if(!fname) return FALSE;
- //if a read_only file exists with this filename , then abort attempt to save
- DWORD attributes = GetFileAttributesA(fname);
- if (0xffffffff!=attributes)
- {
- if (attributes & FILE_ATTRIBUTE_READONLY)
- {
- return FALSE;
- }
- }
-
-
-
- HANDLE rif_file;
-
- if (filename) delete [] filename;
-
- filename = new char [strlen(fname) + 1];
- strcpy (filename, fname);
-
- //save under a temporary name in case a crash occurs during save;
- int filename_start_pos=0;
- int pos=0;
- while(fname[pos])
- {
- if(fname[pos]=='\\' || fname[pos]==':')
- {
- filename_start_pos=pos+1;
- }
- //go to next MBCS character in string
- pos+=_mbclen((unsigned const char*)&fname[pos]);
- }
- if(!fname[filename_start_pos]) return FALSE;
-
- char* temp_name=new char[strlen(fname)+7];
- strcpy(temp_name,fname);
- strcpy(&temp_name[filename_start_pos],"~temp~");
- strcpy(&temp_name[filename_start_pos+6],&fname[filename_start_pos]);
-
- prepare_for_output();
-
-
- #if SAVE_USING_COMPRESSION
- //create a block containing the uncompressed rif file
- unsigned char* uncompressedData = (unsigned char*) make_data_block_from_chunk();
- if(!uncompressedData) return FALSE;
-
- //do the compression thing
- HuffmanPackage *outPackage = HuffmanCompression(uncompressedData,chunk_size);
- delete [] uncompressedData;
- if(!outPackage) return FALSE;
-
- //and now try to write the file
- rif_file = CreateFileA (temp_name, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- delete [] temp_name;
- free (outPackage);
- return FALSE;
- }
-
- unsigned long junk;
- BOOL ok;
-
- ok = WriteFile (rif_file, (long *) outPackage,outPackage->CompressedDataSize+sizeof(HuffmanPackage), &junk, 0);
-
- CloseHandle (rif_file);
-
- free (outPackage);
-
- if(!ok) return FALSE;
-
-
- #else
- size_chunk();
-
- rif_file = CreateFileA (temp_name, GENERIC_WRITE, 0, 0, CREATE_ALWAYS,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- delete [] temp_name;
- return FALSE;
- }
-
- if (!(this->output_chunk(rif_file)))
- {
- CloseHandle (rif_file);
- delete [] temp_name;
- return FALSE;
- }
-
- CloseHandle (rif_file);
- #endif
-
- //Delete the old file with this name (if it exists) , and rename the temprary file
- DeleteFileA(fname);
- MoveFileA(temp_name,fname);
-
- delete [] temp_name;
-
- return TRUE;
-}
-
-// the file_chunk must link all of its shapes & objects together
-
-void File_Chunk::post_input_processing()
-{
- List<Shape_Chunk *> shplist;
- List<Object_Chunk *> objlist;
-
- List<Chunk *> child_lists;
-
- lookup_child("REBSHAPE",child_lists);
-
- while (child_lists.size()) {
- shplist.add_entry((Shape_Chunk *)child_lists.first_entry());
- child_lists.delete_first_entry();
- }
-
- lookup_child("RBOBJECT",child_lists);
-
- while (child_lists.size()) {
- objlist.add_entry((Object_Chunk *)child_lists.first_entry());
- child_lists.delete_first_entry();
- }
-
- for (LIF<Shape_Chunk *> sli(&shplist); !sli.done(); sli.next())
- {
- Shape_Chunk::max_id = max (Shape_Chunk::max_id,sli()->get_header()->file_id_num);
- }
- Shape_Chunk** shape_array=new Shape_Chunk*[Shape_Chunk::max_id+1];
-
- for(sli.restart();!sli.done();sli.next())
- {
- shape_array[sli()->get_header()->file_id_num]=sli();
- }
-
- for (LIF<Object_Chunk *> ol(&objlist); !ol.done(); ol.next())
- {
- ol()->assoc_with_shape(shape_array[ol()->get_header()->shape_id_no]);
- }
-
- delete shape_array;
-
-
- Chunk_With_Children::post_input_processing();
-}
-
-
-
-BOOL File_Chunk::check_file()
-{
- if (!filename) return TRUE;
-
- #if DisableLock
- return(TRUE);
- #else
-
- int flags;
- int v_no;
- char locker[17];
-
-
- HANDLE rif_file;
- unsigned long bytes_read;
-
- int tries = 0;
-
- rif_file = CreateFileA (filename, GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- while(rif_file == INVALID_HANDLE_VALUE && tries<10)
- {
- rif_file = CreateFileA (filename, GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
- tries ++;
- clock_t ctime = clock();
- double secs = (double)ctime / (double)CLOCKS_PER_SEC;
- double secsgone;
- do
- {
- ctime = clock();
- secsgone = (double)ctime / (double)CLOCKS_PER_SEC;
- }
- while( (secsgone-secs)<1);
- }
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- error_code = CHECK_FAILED_NOT_OPEN;
- return FALSE;
- }
-
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- error_code = CHECK_FAILED_NOT_OPEN;
- return FALSE;
- }
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> obfptrs;
- list_chunks_in_file(& obfptrs, rif_file, "RBOBJECT");
-
-// ok, go through the objects, first locate the header and find
-// the associated object.
-
- if (obfptrs.size()) {
-
- for (LIF<int> obflst(&obfptrs); !obflst.done(); obflst.next()) {
-
- // go to start of chunk
- SetFilePointer (rif_file,obflst(),0,FILE_BEGIN);
-
- // get header list
- List<int> obhead;
- list_chunks_in_file(& obhead, rif_file, "OBJHEAD1");
-
- assert (obhead.size() == 1);
-
- // go to lock status in header
- SetFilePointer(rif_file,obhead.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- ReadFile (rif_file, (long *) locker, 16, &bytes_read, 0);
-
- // go to version number
- SetFilePointer(rif_file,obhead.first_entry() + 88,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &v_no, 4, &bytes_read, 0);
-
- char name[50];
-
- // get object identifier
- SetFilePointer(rif_file,obhead.first_entry() + 96,0,FILE_BEGIN);
- int i = 0;
- do ReadFile (rif_file, (long *) (name + i), 1, &bytes_read, 0);
- while (name[i++] != 0);
-
- Object_Chunk * tmpob;
- Object_Header_Chunk * tmpobh;
- List<Chunk *> obchs;
- lookup_child ("RBOBJECT",obchs);
-
- if (obchs.size()){
- for (LIF<Chunk *> obchls(&obchs); !obchls.done(); obchls.next()){
- tmpob = (Object_Chunk *)obchls();
- // if this is the same object
- if (!strcmp (name, tmpob->object_data.o_name)) break;
- }
- if (!obchls.done()) {
- tmpobh = tmpob->get_header();
- if (tmpobh) {
- if (tmpobh->version_no < v_no)
- tmpob->updated_outside = TRUE;
- if (flags & GENERAL_FLAG_LOCKED) {
- // do the lock check
- if (!tmpob->local_lock) {
- tmpob->external_lock = TRUE;
- strncpy(tmpobh->lock_user, locker,16);
- tmpobh->lock_user[16] = '\0';
- }
- else if (strncmp(tmpobh->lock_user, locker,16)) {
- tmpob->external_lock = TRUE;
- strncpy(tmpobh->lock_user, locker,16);
- tmpobh->lock_user[16] = '\0';
- }
- }
- }
-
- }
-
- }
-
- }
-
- }
-
- // shapes
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> shpfptrs;
- list_chunks_in_file(& shpfptrs, rif_file, "REBSHAPE");
-
- if (shpfptrs.size()) {
-
- for (LIF<int> shpflst(&shpfptrs); !shpflst.done(); shpflst.next()) {
-
- // go to start of chunk
- SetFilePointer (rif_file,shpflst(),0,FILE_BEGIN);
-
- // get header list
- List<int> shphead;
- list_chunks_in_file(& shphead, rif_file, "SHPHEAD1");
-
- assert (shphead.size() == 1);
-
- // go to lock status in header
- SetFilePointer(rif_file,shphead.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- ReadFile (rif_file, (long *) locker, 16, &bytes_read, 0);
-
- int id;
- // get shape identifier
- ReadFile (rif_file, (long *) &id, 4, &bytes_read, 0);
-
-
- // Here we update max_id
- Shape_Chunk::max_id = max (Shape_Chunk::max_id,id);
-
- // go to version number
- SetFilePointer(rif_file,shphead.first_entry() + 100,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &v_no, 4, &bytes_read, 0);
-
- Shape_Chunk * tmpshp;
- Shape_Header_Chunk * tmpshph;
- List<Chunk *> shpchs;
- lookup_child ("REBSHAPE",shpchs);
-
- if (shpchs.size()){
- for (LIF<Chunk *> shpchls(&shpchs); !shpchls.done(); shpchls.next()){
- tmpshp = (Shape_Chunk *)shpchls();
- tmpshph = tmpshp->get_header();
- // if this is the same object
- if (tmpshph)
- if (id == tmpshph->file_id_num) break;
- }
- if (!shpchls.done()) {
- if (tmpshph->version_no < v_no)
- tmpshp->updated_outside = TRUE;
- if (flags & GENERAL_FLAG_LOCKED) {
- // do the lock check
- if (!tmpshp->local_lock) {
- tmpshp->external_lock = TRUE;
- strncpy(tmpshph->lock_user, locker,16);
- tmpshph->lock_user[16] = '\0';
- }
- else if (strncmp(tmpshph->lock_user, locker,16)) {
- tmpshp->external_lock = TRUE;
- strncpy(tmpshph->lock_user, locker,16);
- tmpshph->lock_user[16] = '\0';
- }
- }
-
- }
-
- }
-
- }
-
- }
-
- // sprites
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> sprfptrs;
- list_chunks_in_file(& sprfptrs, rif_file, "RSPRITES");
- List<Chunk *> sprchlst;
- lookup_child("RSPRITES",sprchlst);
-
- AllSprites_Chunk * sprch;
- AllSprites_Header_Chunk * sprhead = 0;
-
- if (sprchlst.size())
- {
- sprch = (AllSprites_Chunk *)sprchlst.first_entry();
- sprhead = sprch->get_header();
- }
-
- if (sprhead)
- {
- if (sprfptrs.size())
- {
- SetFilePointer (rif_file,sprfptrs.first_entry(),0,FILE_BEGIN);
-
- // get header list
- List<int> sprchhl;
- list_chunks_in_file(& sprchhl, rif_file, "ASPRHEAD");
-
- assert (sprchhl.size() == 1);
-
- // go to lock status in header
- SetFilePointer(rif_file,sprchhl.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- ReadFile (rif_file, (long *) locker, 16, &bytes_read, 0);
-
- // go to version number
- SetFilePointer(rif_file,sprchhl.first_entry() + 32,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &v_no, 4, &bytes_read, 0);
-
- if (sprhead->version_no < v_no)
- {
- sprch->updated_outside = TRUE;
- }
- if (flags & GENERAL_FLAG_LOCKED)
- {
- if (!sprch->local_lock) {
- sprch->external_lock = TRUE;
- strncpy(sprhead->lock_user, locker,16);
- sprhead->lock_user[16] = '\0';
- }
- else if (strncmp(sprhead->lock_user, locker,16)) {
- sprch->external_lock = TRUE;
- strncpy(sprhead->lock_user, locker,16);
- sprhead->lock_user[16] = '\0';
- }
- }
- }
- }
-
- // environment data
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> edfptrs;
- list_chunks_in_file(& edfptrs, rif_file, "REBENVDT");
-
- Environment_Data_Chunk * ed;
- Environment_Data_Header_Chunk * edhead = 0;
-
-
- ed = (Environment_Data_Chunk *)lookup_single_child("REBENVDT");
- if (ed)
- {
- edhead = ed->get_header();
- }
-
- if (edhead)
- {
- if (edfptrs.size())
- {
- SetFilePointer (rif_file,edfptrs.first_entry(),0,FILE_BEGIN);
-
- // get header list
- List<int> edhl; list_chunks_in_file(& edhl, rif_file, "ENDTHEAD");
-
- assert (edhl.size() == 1);
-
- // go to lock status in header
- SetFilePointer(rif_file,edhl.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- ReadFile (rif_file, (long *) locker, 16, &bytes_read, 0);
-
- // go to version number
- SetFilePointer(rif_file,edhl.first_entry() + 32,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &v_no, 4, &bytes_read, 0);
-
- if (edhead->version_no < v_no)
- {
- ed->updated_outside = TRUE;
- }
- if (flags & GENERAL_FLAG_LOCKED)
- {
- if (!ed->local_lock) {
- ed->external_lock = TRUE;
- strncpy(edhead->lock_user, locker,16);
- edhead->lock_user[16] = '\0';
- }
- else if (strncmp(edhead->lock_user, locker,16)) {
- ed->external_lock = TRUE;
- strncpy(edhead->lock_user, locker,16);
- edhead->lock_user[16] = '\0';
- }
- }
- }
- }
-
- // check file for REBENUMS chunk
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> enumfptrs; list_chunks_in_file(& enumfptrs, rif_file, "REBENUMS");
-
- Enum_Chunk * enumch;
- Enum_Header_Chunk * enumhead = 0;
-
- enumch = (Enum_Chunk *)lookup_single_child("REBENUMS");
- if (enumch)
- {
- enumhead = enumch->get_header();
- }
-
- if (enumhead)
- {
- if (enumfptrs.size())
- {
- SetFilePointer (rif_file,enumfptrs.first_entry(),0,FILE_BEGIN);
-
- // get header list
- List<int> enumchhl; list_chunks_in_file(& enumchhl, rif_file, "ENUMHEAD");
-
- assert (enumchhl.size() == 1);
-
- // go to lock status in header
- SetFilePointer(rif_file,enumchhl.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &flags, 4, &bytes_read, 0);
- ReadFile (rif_file, (long *) locker, 16, &bytes_read, 0);
-
- // go to version number
- SetFilePointer(rif_file,enumchhl.first_entry() + 32,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &v_no, 4, &bytes_read, 0);
-
- if (enumhead->version_no < v_no)
- {
- enumch->updated_outside = TRUE;
- }
- if (flags & GENERAL_FLAG_LOCKED)
- {
- if (!enumch->local_lock) {
- enumch->external_lock = TRUE;
- strncpy(enumhead->lock_user, locker,16);
- enumhead->lock_user[16] = '\0';
- }
- else if (strncmp(enumhead->lock_user, locker,16)) {
- enumch->external_lock = TRUE;
- strncpy(enumhead->lock_user, locker,16);
- enumhead->lock_user[16] = '\0';
- }
- }
- }
- }
-
- CloseHandle (rif_file);
-
- return TRUE;
- #endif
-}
-
-
-#if InterfaceEngine
-
- extern File_Chunk * Env_Chunk;
-
-#endif
-
-BOOL File_Chunk::update_file()
-{
-
- #if DisableLock
- if (!filename) return FALSE;
-
- char tempname [256];
- strcpy (tempname, filename);
-
- List<Shape_Chunk *> slist;
- list_shapes(&slist);
- List<Object_Chunk *> olist;
- list_objects(&olist);
-
- for (LIF<Shape_Chunk *> sli(&slist); !sli.done(); sli.next())
- {
- if (sli()->deleted)
- {
- delete sli();
- }
- }
-
- for (LIF<Object_Chunk *> oli(&olist); !oli.done(); oli.next())
- {
- if (oli()->deleted)
- {
- delete oli();
- }
- }
-
-
- return(write_file(tempname));
-
- #else
-
-#if InterfaceEngine
-
- // log, to track error
- char fname [256];
- char * dotpos;
-
- strcpy (fname, filename);
-
- dotpos = strrchr (fname, '.');
-
- sprintf (dotpos, ".log");
-
- FILE * log = fopen (fname, "a");
-
-#endif
-
- if (!filename) return FALSE;
-
- twprintf("Updating %s\n",filename);
-
- check_file();
-
- HANDLE rif_file;
- unsigned long bytes_read;
-
- int tries = 0;
-
- //twprintf("Opening file\n");
-
- rif_file = CreateFileA (filename, GENERIC_WRITE + GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- if (rif_file == INVALID_HANDLE_VALUE)
- {
- DWORD error_num = GetLastError();
- switch (error_num)
- {
- case ERROR_SHARING_VIOLATION:
- twprintf("Sharing violation - retrying\n");
- break;
- case ERROR_ACCESS_DENIED:
- twprintf("File is Read Only\n");
- return FALSE;
- default:
- twprintf("Unknown error updating file, Error code %#08x\n",error_num);
- return FALSE;
- }
- }
-
- while(rif_file == INVALID_HANDLE_VALUE && tries<10)
- {
- twprintf("Again...\n");
- rif_file = CreateFileA (filename, GENERIC_WRITE + GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
- tries ++;
- clock_t ctime = clock();
- double secs = (double)ctime / (double)CLOCKS_PER_SEC;
- double secsgone;
- do
- {
- ctime = clock();
- secsgone = (double)ctime / (double)CLOCKS_PER_SEC;
- }
- while( (secsgone-secs)<1);
- }
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- error_code = CHECK_FAILED_NOT_OPEN;
- twprintf("ERROR - SHARING VIOLATION UNRESOLVED\n\n");
- return FALSE;
- }
-
- //twprintf("Opened\n\n");
-
- prepare_for_output();
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- //twprintf("Version info\n");
-
- List<int> verinf; list_chunks_in_file(& verinf, rif_file, "RIFVERIN");
-
-// taking first entry of this list, if there are more - tough ha ha
-// there shouldn't be
-
-// Just increment it by one and reoutput
-// check_file sets the internal copy of the chunk to the current file
-// setting, so we need to increment that as well
-
- if (verinf.size()) {
-
- int f_version_num;
- SetFilePointer (rif_file,verinf.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &f_version_num, 4, &bytes_read, 0);
-
- SetFilePointer (rif_file,verinf.first_entry() + 12,0,FILE_BEGIN);
-
- RIF_Version_Num_Chunk* rvnc=(RIF_Version_Num_Chunk*)lookup_single_child ("RIFVERIN");
-
- if (rvnc)
- rvnc->file_version_no++;
-
- f_version_num++;
-
- WriteFile (rif_file, (long *) &f_version_num, 4, &bytes_read, 0);
-
- }
-
-// go through the list of shape chunks looking for shape chunks to output
- //twprintf("\nShapes\n");
-
- List<Chunk *> shplst;
- lookup_child ("REBSHAPE",shplst);
-
- if (shplst.size())
- for (LIF<Chunk *> sli(&shplst); !sli.done(); sli.next()) {
-
- Shape_Chunk * tmpshpptr = ((Shape_Chunk *)sli());
-
- if (tmpshpptr->updated &&
- !(tmpshpptr->updated_outside || tmpshpptr->external_lock))
- tmpshpptr->update_chunk_in_file(rif_file);
- }
-
-
-// go through the list of object chunks looking for chunks to output
- //twprintf("\nObjects\n");
-
- List<Chunk *> oblst;
- lookup_child ("RBOBJECT",oblst);
-
- if (oblst.size())
- for (LIF<Chunk *> oli(&oblst); !oli.done(); oli.next()) {
-
- Object_Chunk * tmpobptr = ((Object_Chunk *)oli());
-
- if (tmpobptr->updated && !(tmpobptr->updated_outside || tmpobptr->external_lock))
- tmpobptr->update_chunk_in_file(rif_file);
-
- }
-
-
- //twprintf("\nSprites\n");
-
- List<Chunk *> sprfptrs;
- lookup_child ("RSPRITES",sprfptrs);
- AllSprites_Chunk * sprch;
-
- if (sprfptrs.size())
- {
- sprch = (AllSprites_Chunk *)sprfptrs.first_entry();
- if (sprch->updated &&
- !(sprch->updated_outside || sprch->external_lock))
- sprch->update_chunk_in_file(rif_file);
- }
-
- //twprintf("\nEnvironment data\n");
-
- Environment_Data_Chunk * ed;
-
- ed = (Environment_Data_Chunk *)lookup_single_child ("REBENVDT");
- if (ed)
- {
-
-#if InterfaceEngine
-
- fprintf (log, "Env_Data %d %d %d %d", ed->updated, ed->local_lock, ed->updated_outside, ed->external_lock);
-
-#endif
-
- if (ed->updated &&
- !(ed->updated_outside || ed->external_lock))
- ed->update_chunk_in_file(rif_file);
- }
-
- //twprintf("\nEnum data\n");
-
- List<Chunk *> enumfptrs;
- lookup_child ("REBENUMS",enumfptrs);
- Enum_Chunk * enumch;
-
- if (enumfptrs.size())
- {
- enumch = (Enum_Chunk *)enumfptrs.first_entry();
- if (enumch->updated &&
- !(enumch->updated_outside || enumch->external_lock))
- enumch->update_chunk_in_file(rif_file);
- }
-
- //
-
- int file_length = GetFileSize(rif_file,0);
- SetFilePointer (rif_file,8,0,FILE_BEGIN);
-
- WriteFile (rif_file, (long *) &file_length, 4, &bytes_read, 0);
-
- CloseHandle (rif_file);
-
-#if InterfaceEngine
-
- fclose (log);
-
-#endif
- return TRUE;
-
- #endif //DisableLock
-}
-
-BOOL File_Chunk::update_chunks_from_file()
-{
- #if DisableLock
- return(TRUE);
- #endif
-
- if (!filename) return FALSE;
- check_file();
-
- HANDLE rif_file;
- unsigned long bytes_read;
-
- rif_file = CreateFileA (filename, GENERIC_WRITE + GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- error_code = CHECK_FAILED_NOT_OPEN;
- return FALSE;
- }
-
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> verinf; list_chunks_in_file(& verinf, rif_file, "RIFVERIN");
-
- if (verinf.size()) {
-
- int f_version_num;
- SetFilePointer (rif_file,verinf.first_entry() + 12,0,FILE_BEGIN);
- ReadFile (rif_file, (long *) &f_version_num, 4, &bytes_read, 0);
-
- SetFilePointer (rif_file,verinf.first_entry() + 12,0,FILE_BEGIN);
-
- List<Chunk *> lverinf;
- lookup_child ("RIFVERIN",lverinf);
-
- if (lverinf.size())
- if (f_version_num == ((RIF_Version_Num_Chunk *)(lverinf.first_entry()))->file_version_no){
- CloseHandle (rif_file);
- return TRUE;
- }
-
- }
-
- // go through the list of object chunks looking for chunks to input
-
- List<Chunk *> oblst;
- lookup_child ("RBOBJECT",oblst);
-
- if (oblst.size())
- for (LIF<Chunk *> oli(&oblst); !oli.done(); oli.next()) {
-
- Object_Chunk * tmpobptr = ((Object_Chunk *)oli());
-
- if (tmpobptr->updated_outside) {
- // find the chunk, then input it to a buffer and create a new object
- // from the buffer
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> obfptrs; list_chunks_in_file(& obfptrs, rif_file, "RBOBJECT");
-
- char name[50];
-
- LIF<int> ofpl(&obfptrs);
-
- if (obfptrs.size()) {
- for (; !ofpl.done(); ofpl.next()) {
-
- SetFilePointer (rif_file, ofpl(),0,FILE_BEGIN);
- // get header list
- List<int> obhead; list_chunks_in_file(& obhead, rif_file, "OBJHEAD1");
-
- assert (obhead.size() == 1);
-
- // get object identifier
- SetFilePointer(rif_file,obhead.first_entry() + 96,0,FILE_BEGIN);
- int i = 0;
- do ReadFile (rif_file, (long *) (name + i), 1, &bytes_read, 0);
- while (name[i++] != 0);
-
- if (!strcmp(name, tmpobptr->object_data.o_name)) break;
- }
- }
-
- if (!ofpl.done()) {
-
- char * buffer;
-
- SetFilePointer (rif_file,ofpl()+8,0,FILE_BEGIN);
- int length;
- ReadFile(rif_file, (long *) &length, 4, &bytes_read, 0);
- buffer = new char [length];
- ReadFile(rif_file, (long *) buffer, length-12, &bytes_read, 0);
- new Object_Chunk (this, buffer, length-12);
- delete [] buffer;
- if (tmpobptr->get_header())
- if (tmpobptr->get_header()->associated_shape)
- tmpobptr->deassoc_with_shape(tmpobptr->get_header()->associated_shape);
- delete tmpobptr;
-
- }
-
-
- }
-
- }
-
-// go through the list of shape chunks looking for shape chunks to input
-
- List<Chunk *> shplst;
- lookup_child ("REBSHAPE",shplst);
-
- if (shplst.size())
- for (LIF<Chunk *> sli(&shplst); !sli.done(); sli.next()) {
-
- Shape_Chunk * tmpshpptr = ((Shape_Chunk *)sli());
-
- Shape_Header_Chunk * shhead = tmpshpptr->get_header();
-
- if (!shhead) continue;
-
- if (tmpshpptr->updated_outside) {
- // find the chunk, then input it to a buffer and create a new object
- // from the buffer
- SetFilePointer (rif_file,0,0,FILE_BEGIN);
-
- List<int> shfptrs; list_chunks_in_file(& shfptrs, rif_file, "REBSHAPE");
-
- LIF<int> sfpl(&shfptrs);
-
- if (shfptrs.size()) {
- for (sfpl.restart(); !sfpl.done(); sfpl.next()) {
-
- SetFilePointer (rif_file, sfpl(),0,FILE_BEGIN);
- // get header list
- List<int> shphead; list_chunks_in_file(& shphead, rif_file, "SHPHEAD1");
-
- assert (shphead.size() == 1);
-
- // get object identifier
- SetFilePointer(rif_file,shphead.first_entry() + 32,0,FILE_BEGIN);
- int sh_number;
- ReadFile (rif_file, (long *) &sh_number, 4, &bytes_read, 0);
-
- if (sh_number == shhead->file_id_num) break;
- }
- }
-
- if (!sfpl.done()) {
-
- char * buffer;
-
- SetFilePointer (rif_file,sfpl()+8,0,FILE_BEGIN);
- int length;
- ReadFile(rif_file, (long *) &length, 4, &bytes_read, 0);
- buffer = new char [length];
- ReadFile(rif_file, (long *) buffer, length-12, &bytes_read, 0);
- new Shape_Chunk (this, buffer, length-12);
- delete [] buffer;
- // Associate with the new objects
- if ((shhead->associated_objects_store).size())
- {
- for (LIF<Object_Chunk *> aol(&(shhead->associated_objects_store)); !aol.done(); aol.next())
- {
- tmpshpptr->deassoc_with_object(aol());
- }
- }
- delete tmpshpptr;
- }
- }
- }
-
- post_input_processing();
-
- CloseHandle(rif_file);
-
- return TRUE;
-
-}
-
-void File_Chunk::list_objects(List<Object_Chunk *> * pList)
-{
- Chunk * child_ptr = children;
-
- while (pList->size())
- pList->delete_first_entry();
-
- if (children)
- while (child_ptr != NULL) {
- if (strncmp ("RBOBJECT", child_ptr->identifier, 8) == NULL)
- {
- assert (!child_ptr->r_u_miscellaneous());
- pList->add_entry((Object_Chunk *)child_ptr);
- }
- child_ptr = child_ptr->next;
- }
-
-}
-
-void File_Chunk::list_shapes(List<Shape_Chunk *> * pList)
-{
- Chunk * child_ptr = children;
-
- while (pList->size())
- pList->delete_first_entry();
-
- if (children)
- while (child_ptr != NULL) {
- if (strncmp ("REBSHAPE", child_ptr->identifier, 8) == NULL)
- {
- assert (!child_ptr->r_u_miscellaneous());
- pList->add_entry((Shape_Chunk *)child_ptr);
- }
- child_ptr = child_ptr->next;
- }
-
-}
-
-void File_Chunk::list_dummy_objects(List<Dummy_Object_Chunk *> * pList){
- Chunk * child_ptr = children;
-
- while (pList->size())
- pList->delete_first_entry();
-
- if (children)
- while (child_ptr != NULL) {
- if (strncmp ("DUMMYOBJ", child_ptr->identifier, 8) == NULL)
- {
- assert (!child_ptr->r_u_miscellaneous());
- pList->add_entry((Dummy_Object_Chunk *)child_ptr);
- }
- child_ptr = child_ptr->next;
- }
-
-}
-
-Environment_Data_Chunk * File_Chunk::get_env_data()
-{
- List<Environment_Data_Chunk *> e_list;
- Chunk * child_ptr = children;
-
- if (children)
- while (child_ptr != NULL) {
- if (strncmp ("REBENVDT", child_ptr->identifier, 8) == NULL)
- {
- assert (!child_ptr->r_u_miscellaneous());
- e_list.add_entry((Environment_Data_Chunk *)child_ptr);
- }
- child_ptr = child_ptr->next;
- }
-
- // There can be only ONE.
- assert (e_list.size() < 2);
-
- if (e_list.size())
- return e_list.first_entry();
- else
- {
- return(0);
- }
-}
-
-void File_Chunk::build_object_array()
-{
- List<Object_Chunk*> oblist;
- list_objects(&oblist);
-
- if(object_array)
- {
- free(object_array);
- object_array=0;
- }
- object_array_size=0;
-
- LIF<Object_Chunk*> oblif(&oblist);
-
- //find the highest object index
- for(oblif.restart();!oblif.done();oblif.next())
- {
- object_array_size=max(object_array_size,oblif()->object_data.index_num+1);
- }
-
- if(object_array_size<=0) return;
-
- object_array = (Object_Chunk**) malloc(sizeof(Object_Chunk*)*object_array_size);
- for(int i=0;i<object_array_size;i++)
- {
- object_array[i]=0;
- }
-
- //now fill in object array
-
- for(oblif.restart();!oblif.done();oblif.next())
- {
- int index=oblif()->object_data.index_num;
- if(index>=0)
- {
- object_array[index]=oblif();
- }
- }
-}
-
-Object_Chunk* File_Chunk::get_object_by_index(int index)
-{
- if(!object_array) build_object_array();
- if(index<0 || index>=object_array_size)return 0;
- return object_array[index];
-}
-
-void File_Chunk::assign_index_to_object(Object_Chunk* object)
-{
- assert(object);
-
- if(!object_array) build_object_array();
- //see if there is a free index
-
- for(int i=0;i<object_array_size;i++)
- {
- if(!object_array[i])
- {
- object->object_data_store->index_num=i;
- object_array[i]=object;
- return;
- }
- }
-
- //add a new entry on the end of the array
- object_array_size++;
-
- object_array=(Object_Chunk**) realloc(object_array,sizeof(Object_Chunk*)*object_array_size);
-
-
- object->object_data_store->index_num=object_array_size-1;;
- object_array[object_array_size-1]=object;
-}
-
-/////////////////////////////////////////
-
-// Class GodFather_Chunk functions
-
-/*
-Children for GodFather_Chunk :
-"REBSHAPE" Shape_Chunk
-"RSPRITES" AllSprites_Chunk
-"RBOBJECT" Object_Chunk
-"RIFVERIN" RIF_Version_Num_Chunk
-"REBENVDT" Environment_Data_Chunk
-"REBENUMS" Enum_Chunk
-"OBJCHIER" Object_Hierarchy_Chunk
-"OBHALTSH" Object_Hierarchy_Alternate_Shape_Set_Chunk
-
-*/
-
-GodFather_Chunk::GodFather_Chunk(char * buffer, size_t size)
-: Chunk_With_Children (NULL, "REBINFF2")
-{
- Parent_File = this;
-
- char * buffer_ptr = buffer;
-
- // The start of the first chunk
-
- while ((buffer_ptr-buffer)< ((signed)size-12) && !error_code) {
-
- if ((*(int *)(buffer_ptr + 8)) + (buffer_ptr-buffer) > ((signed)size-12)) {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- break;
- }
-
- DynCreate(buffer_ptr);
- buffer_ptr += *(int *)(buffer_ptr + 8);
-
- }
-
-}
-
-/////////////////////////////////////////
-
-// Class RIF_Version_Num_Chunk functions
-
-RIF_IMPLEMENT_DYNCREATE("RIFVERIN",RIF_Version_Num_Chunk)
-
-void RIF_Version_Num_Chunk::fill_data_block(char * data_start)
-{
- strncpy (data_start, identifier, 8);
-
- data_start += 8;
-
- *((int *) data_start) = chunk_size;
-
- data_start += 4;
-
- *((int *) data_start) = file_version_no;
-
-}
-
-
-/////////////////////////////////////////
-
-// Class RIF_Name_Chunk functions
-RIF_IMPLEMENT_DYNCREATE("RIFFNAME",RIF_Name_Chunk)
-
-RIF_Name_Chunk::RIF_Name_Chunk (Chunk_With_Children * parent, const char * rname)
-: Chunk (parent, "RIFFNAME")
-{
- rif_name = new char [strlen(rname)+1];
- strcpy (rif_name, rname);
-}
-
-RIF_Name_Chunk::RIF_Name_Chunk (Chunk_With_Children * parent, const char * rdata, size_t /*rsize*/)
-: Chunk (parent, "RIFFNAME")
-{
- rif_name = new char [strlen(rdata)+1];
- strcpy (rif_name, rdata);
-}
-
-RIF_Name_Chunk::~RIF_Name_Chunk ()
-{
- if (rif_name)
- delete [] rif_name;
-}
-
-
-void RIF_Name_Chunk::fill_data_block (char * data_start)
-{
- strncpy (data_start, identifier, 8);
-
- data_start += 8;
-
- *((int *) data_start) = chunk_size;
-
- data_start += 4;
-
- strcpy (data_start, rif_name);
-
-}
-
-
-///////////////////////////////////////
-
-/*
-Children for RIF_File_Chunk :
-"REBSHAPE" Shape_Chunk
-"RSPRITES" AllSprites_Chunk
-"RBOBJECT" Object_Chunk
-"RIFVERIN" RIF_Version_Num_Chunk
-"REBENVDT" Environment_Data_Chunk
-"OBJCHIER" Object_Hierarchy_Chunk
-"OBHALTSH" Object_Hierarchy_Alternate_Shape_Set_Chunk
-
-*/
-
-
-RIF_File_Chunk::RIF_File_Chunk (Chunk_With_Children * parent, const char * file_name)
-: Chunk_With_Children (parent, "SUBRIFFL")
-{
- char rifIsCompressed = FALSE;
- char *uncompressedData = NULL;
- HANDLE rif_file;
- DWORD file_size;
- DWORD file_size_from_file;
- unsigned long bytes_read;
- char * buffer;
- char * buffer_ptr;
- char id_buffer[9];
-
-
- Chunk * ParentFileStore = Parent_File;
-
- Parent_File = this;
-
- error_code = 0;
-
- rif_file = CreateFileA (file_name, GENERIC_READ, 0, 0, OPEN_EXISTING,
- FILE_FLAG_RANDOM_ACCESS, 0);
-
-
- if (rif_file == INVALID_HANDLE_VALUE) {
- error_code = CHUNK_FAILED_ON_LOAD;
- Parent_File = ParentFileStore;
- return;
- }
-
- file_size = GetFileSize (rif_file, NULL);
-
- if (!ReadFile(rif_file, id_buffer, 8, &bytes_read, 0)) {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- Parent_File = ParentFileStore;
- return;
- }
-
- //check for compressed rif
- if (!strncmp (id_buffer, COMPRESSED_RIF_IDENTIFIER, 8))
- {
- rifIsCompressed = TRUE;
- }
- else if (strncmp (id_buffer, "REBINFF2", 8)) {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- CloseHandle (rif_file);
- Parent_File = ParentFileStore;
- return;
- }
-
- buffer = new char [file_size];
-
- /* KJL 17:57:44 19/09/98 - if the rif is compressed, we must load the whole
- file in and then pass it to the decompression routine, which will return a
- pointer to the original data. */
- if (rifIsCompressed)
- {
- if (!ReadFile(rif_file, buffer+8, (file_size-8), &bytes_read, 0))
- {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- Parent_File = ParentFileStore;
- delete [] buffer;
- return;
- }
- uncompressedData = HuffmanDecompress((HuffmanPackage*)buffer);
- file_size = ((HuffmanPackage*)buffer)->UncompressedDataSize;
-
- delete [] buffer; // kill the buffer the compressed file was loaded into
-
- buffer_ptr = buffer = uncompressedData+12; // skip header data
- }
- else // the normal uncompressed approach:
- {
- //get the file size stored in the rif file
- if (!ReadFile(rif_file, &file_size_from_file, 4, &bytes_read, 0)) {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- Parent_File = ParentFileStore;
- delete [] buffer;
- return;
- }
-
- //and compare with the actual file size
- if (file_size != file_size_from_file) {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- CloseHandle (rif_file);
- Parent_File = ParentFileStore;
- delete [] buffer;
- return;
- }
-
- //read the rest of the file into the buffer
- if (!ReadFile(rif_file, buffer, (file_size-12), &bytes_read, 0))
- {
- error_code = CHUNK_FAILED_ON_LOAD;
- CloseHandle (rif_file);
- Parent_File = ParentFileStore;
- delete [] buffer;
- return;
- }
- buffer_ptr = buffer;
- }
-
-
-
-
- // Process the RIF
-
- // The start of the first chunk
-
- while ((buffer_ptr-buffer)< ((signed) file_size-12) && !error_code) {
-
- if ((*(int *)(buffer_ptr + 8)) + (buffer_ptr-buffer) > ((signed)file_size-12)) {
- error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
- break;
- }
-
- DynCreate(buffer_ptr);
- buffer_ptr += *(int *)(buffer_ptr + 8);
- }
-
- /* KJL 17:59:42 19/09/98 - release the memory holding the rif */
- if (rifIsCompressed)
- {
- free(uncompressedData);
- }
- else
- {
- delete [] buffer;
- }
-
- CloseHandle (rif_file);
-
- post_input_processing();
-
- Parent_File = ParentFileStore;
-
-}
-
-void RIF_File_Chunk::post_input_processing()
-{
- List<Shape_Chunk *> shplist;
- List<Object_Chunk *> objlist;
-
- List<Chunk *> child_lists;
-
- lookup_child("REBSHAPE",child_lists);
-
- while (child_lists.size()) {
- shplist.add_entry((Shape_Chunk *)child_lists.first_entry());
- child_lists.delete_first_entry();
- }
-
- lookup_child("RBOBJECT",child_lists);
-
-
- while (child_lists.size()) {
- objlist.add_entry((Object_Chunk *)child_lists.first_entry());
- child_lists.delete_first_entry();
- }
-
- for (LIF<Object_Chunk *> ol(&objlist); !ol.done(); ol.next()) {
-
- if (ol()->get_header()) {
-
- for (LIF<Shape_Chunk *> sl(&shplist);
- !sl.done(); sl.next()) {
- if (sl()->get_header())
- if (sl()->get_header()->file_id_num == ol()->get_header()->shape_id_no){
- ol()->assoc_with_shape(sl());
- break;
- }
- }
- }
-
- }
-
- for (LIF<Shape_Chunk *> sli(&shplist); !sli.done(); sli.next())
- {
- Shape_Chunk::max_id = max (Shape_Chunk::max_id,sli()->get_header()->file_id_num);
- }
-
- Chunk_With_Children::post_input_processing();
-}
-
-
-void RIF_File_Chunk::list_objects(List<Object_Chunk *> * pList)
-{
- Chunk * child_ptr = children;
-
- while (pList->size())
- pList->delete_first_entry();
-
- if (children)
- while (child_ptr != NULL) {
- if (strncmp ("RBOBJECT", child_ptr->identifier, 8) == NULL)
- {
- assert (!child_ptr->r_u_miscellaneous());
- pList->add_entry((Object_Chunk *)child_ptr);
- }
- child_ptr = child_ptr->next;
- }
-}
-
-void RIF_File_Chunk::list_shapes(List<Shape_Chunk *> * pList)
-{
- Chunk * child_ptr = children;
-
- while (pList->size())
- pList->delete_first_entry();
-
- if (children)
- while (child_ptr != NULL) {
- if (strncmp ("REBSHAPE", child_ptr->identifier, 8) == NULL)
- {
- assert (!child_ptr->r_u_miscellaneous());
- pList->add_entry((Shape_Chunk *)child_ptr);
- }
- child_ptr = child_ptr->next;
- }
-
-}
-
-Environment_Data_Chunk * RIF_File_Chunk::get_env_data()
-{
- List<Environment_Data_Chunk *> e_list;
- Chunk * child_ptr = children;
-
- if (children)
- while (child_ptr != NULL) {
- if (strncmp ("REBENVDT", child_ptr->identifier, 8) == NULL)
- {
- assert (!child_ptr->r_u_miscellaneous());
- e_list.add_entry((Environment_Data_Chunk *)child_ptr);
- }
- child_ptr = child_ptr->next;
- }
-
- // There can be only ONE.
- assert (e_list.size() < 2);
-
- if (e_list.size())
- return e_list.first_entry();
- else
- {
- return(0);
- }
-}