mirror of
https://github.com/simtactics/niotso.git
synced 2025-07-13 09:41:55 -04:00
* Libraries are now being compiled only as static or as shared, not both, quickening the compile process.
* Implemented the rewrite of the iff library, submitted by Propeng. The linked list has been completely replaced with vectors or normal arrays. * Started work on the cur and tga parsers
This commit is contained in:
parent
5c7a36592e
commit
55659f43b5
25 changed files with 685 additions and 525 deletions
|
@ -14,25 +14,57 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include "iff.h"
|
||||
|
||||
#ifndef __inline
|
||||
#define __inline
|
||||
#endif
|
||||
#ifndef __restrict
|
||||
#define __restrict
|
||||
#endif
|
||||
/****
|
||||
** Supported Chunks
|
||||
*/
|
||||
|
||||
#define iff_register(x) \
|
||||
int iff_parse_##x(IFFChunk *, const uint8_t *); \
|
||||
void iff_free_##x(void *)
|
||||
|
||||
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned IFFSize);
|
||||
int iff_free_rsmp(void * FormattedData);
|
||||
|
||||
/* The order of these chunks must remain the same throughout this block: */
|
||||
iff_register(bcon);
|
||||
iff_register(str);
|
||||
iff_register(trcn);
|
||||
|
||||
const char chunktypes[] =
|
||||
"STR#" "CTSS" "FAMs" "TTAs"
|
||||
"BCON"
|
||||
"TRCN"
|
||||
;
|
||||
int (* const iff_parse_function[])(IFFChunk*, const uint8_t*) = {
|
||||
iff_parse_str, iff_parse_str, iff_parse_str, iff_parse_str,
|
||||
iff_parse_bcon,
|
||||
iff_parse_trcn
|
||||
};
|
||||
void (* const iff_free_function[])(void*) = {
|
||||
iff_free_str, iff_free_str, iff_free_str, iff_free_str,
|
||||
iff_free_bcon,
|
||||
iff_free_trcn
|
||||
};
|
||||
/* End */
|
||||
|
||||
|
||||
/****
|
||||
** API public functions
|
||||
*/
|
||||
|
||||
IFFFile * iff_create()
|
||||
{
|
||||
IFFFile *ptr = malloc(sizeof(IFFFile));
|
||||
IFFFile *ptr = calloc(1, sizeof(IFFFile));
|
||||
if(ptr == NULL) return NULL;
|
||||
|
||||
memset(ptr, 0, sizeof(IFFFile));
|
||||
|
||||
|
||||
ptr->Chunks = malloc(sizeof(IFFChunk));
|
||||
if(ptr->Chunks == NULL){
|
||||
free(ptr);
|
||||
return NULL;
|
||||
}
|
||||
ptr->SizeAllocated = sizeof(IFFChunk);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
@ -55,55 +87,20 @@ int iff_read_header(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned File
|
|||
return 1;
|
||||
}
|
||||
|
||||
IFFChunkNode * iff_add_chunk(IFFFile * IFFFileInfo, int Position)
|
||||
IFFChunk * iff_add_chunk(IFFFile * IFFFileInfo)
|
||||
{
|
||||
IFFChunkNode *ptr = malloc(sizeof(IFFChunkNode)), *node;
|
||||
if(ptr == NULL) return NULL;
|
||||
memset(ptr, 0, sizeof(IFFChunkNode));
|
||||
if(IFFFileInfo == NULL) return ptr;
|
||||
|
||||
if(Position >= 0){
|
||||
node = IFFFileInfo->FirstChunk;
|
||||
|
||||
if(node == NULL){
|
||||
IFFFileInfo->FirstChunk = ptr;
|
||||
IFFFileInfo->LastChunk = ptr;
|
||||
}else{
|
||||
/* Find the node we will take the place of */
|
||||
while(Position-- && node->NextChunk != NULL)
|
||||
node = node->NextChunk;
|
||||
|
||||
if(node->PrevChunk == NULL)
|
||||
IFFFileInfo->FirstChunk = ptr;
|
||||
|
||||
/* Shift this node and all nodes after it above us */
|
||||
ptr->PrevChunk = node->PrevChunk;
|
||||
ptr->NextChunk = node;
|
||||
node->PrevChunk = ptr;
|
||||
}
|
||||
}else{
|
||||
node = IFFFileInfo->LastChunk;
|
||||
|
||||
if(node == NULL){
|
||||
IFFFileInfo->FirstChunk = ptr;
|
||||
IFFFileInfo->LastChunk = ptr;
|
||||
}else{
|
||||
/* Find the node we will take the place of */
|
||||
while(++Position && node->PrevChunk != NULL)
|
||||
node = node->PrevChunk;
|
||||
|
||||
if(node->NextChunk == NULL)
|
||||
IFFFileInfo->LastChunk = ptr;
|
||||
|
||||
/* Shift this node and all nodes before it below us */
|
||||
ptr->PrevChunk = node;
|
||||
ptr->NextChunk = node->NextChunk;
|
||||
node->NextChunk = ptr;
|
||||
}
|
||||
if((IFFFileInfo->ChunkCount+1)*sizeof(IFFChunk) > IFFFileInfo->SizeAllocated){
|
||||
IFFChunk * ptr;
|
||||
if(IFFFileInfo->SizeAllocated > SIZE_MAX/2) return NULL;
|
||||
ptr = realloc(IFFFileInfo->Chunks, IFFFileInfo->SizeAllocated<<1);
|
||||
if(ptr == NULL) return NULL;
|
||||
|
||||
IFFFileInfo->Chunks = ptr;
|
||||
IFFFileInfo->SizeAllocated<<=1;
|
||||
}
|
||||
|
||||
IFFFileInfo->ChunkCount++;
|
||||
return ptr;
|
||||
return IFFFileInfo->Chunks + IFFFileInfo->ChunkCount-1;
|
||||
}
|
||||
|
||||
int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize)
|
||||
|
@ -114,6 +111,7 @@ int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChu
|
|||
return 0;
|
||||
|
||||
memcpy(ChunkInfo->Type, Buffer+0, 4);
|
||||
ChunkInfo->Type[4] = 0x00;
|
||||
ChunkInfo->Size = read_uint32be(Buffer+4);
|
||||
ChunkInfo->ChunkID = read_uint16be(Buffer+8);
|
||||
ChunkInfo->Flags = read_uint16be(Buffer+10);
|
||||
|
@ -135,16 +133,62 @@ int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChu
|
|||
int iff_enumerate_chunks(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned BufferSize)
|
||||
{
|
||||
while(BufferSize){
|
||||
IFFChunkNode * chunk = iff_add_chunk(IFFFileInfo, -1);
|
||||
IFFChunk * chunk = iff_add_chunk(IFFFileInfo);
|
||||
if(chunk == NULL)
|
||||
return 0;
|
||||
if(!iff_read_chunk(&chunk->Chunk, Buffer, BufferSize)){
|
||||
free(chunk);
|
||||
if(!iff_read_chunk(chunk, Buffer, BufferSize))
|
||||
return 0;
|
||||
}
|
||||
|
||||
Buffer += chunk->Chunk.Size;
|
||||
BufferSize -= chunk->Chunk.Size;
|
||||
Buffer += chunk->Size;
|
||||
BufferSize -= chunk->Size;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
unsigned i;
|
||||
for(i=0; chunktypes[i*4] != '\0'; i++){
|
||||
if(!memcmp(ChunkInfo->Type, chunktypes+i*4, 4)){
|
||||
if(iff_parse_function[i](ChunkInfo, Buffer)) return 1;
|
||||
iff_free_chunk(ChunkInfo->FormattedData);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void iff_free_chunk(IFFChunk * ChunkInfo){
|
||||
unsigned i;
|
||||
if(ChunkInfo == NULL || ChunkInfo->FormattedData) return;
|
||||
|
||||
for(i=0; chunktypes[i*4] != '\0'; i++){
|
||||
if(!memcmp(ChunkInfo->Type, chunktypes+i*4, 4)){
|
||||
if(iff_free_function[i])
|
||||
iff_free_function[i](ChunkInfo->FormattedData);
|
||||
free(ChunkInfo->FormattedData);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void iff_delete(IFFFile * IFFFileInfo){
|
||||
unsigned i;
|
||||
if(IFFFileInfo == NULL) return;
|
||||
|
||||
if(IFFFileInfo->Chunks != NULL){
|
||||
for(i=0; i<IFFFileInfo->ChunkCount; i++){
|
||||
iff_free_chunk(IFFFileInfo->Chunks+i);
|
||||
free(IFFFileInfo->Chunks[i].Data);
|
||||
}
|
||||
free(IFFFileInfo->Chunks);
|
||||
}
|
||||
|
||||
if(IFFFileInfo->ResourceMap != NULL){
|
||||
free(IFFFileInfo->ResourceMap->Data);
|
||||
free(IFFFileInfo->ResourceMap->FormattedData);
|
||||
free(IFFFileInfo->ResourceMap);
|
||||
}
|
||||
|
||||
free(IFFFileInfo);
|
||||
IFFFileInfo = NULL;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue