mirror of
https://github.com/simtactics/niotso.git
synced 2025-03-15 08:11:22 +00:00
Tools completly moved outside of niotso now
This commit is contained in:
parent
01d8cb2539
commit
e6eb0fedaa
52 changed files with 45 additions and 3039 deletions
|
@ -1,4 +1,6 @@
|
|||
add_subdirectory(far-extract)
|
||||
#archive
|
||||
add_subdirectory(archive)
|
||||
add_subdirectory(format)
|
||||
add_subdirectory(vitaboy-parse)
|
||||
|
||||
#add_subdirectory(FARDive)
|
||||
|
|
3
Tools/archive/CMakeLists.txt
Normal file
3
Tools/archive/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
#archive
|
||||
add_subdirectory(far-extract)
|
||||
add_subdirectory(iff-export)
|
|
@ -1,8 +1,8 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(far-extract)
|
||||
|
||||
include_directories(${format_SOURCE_DIR})
|
||||
include_directories(${far_SOURCE_DIR})
|
||||
add_executable(farextract farextract.c)
|
||||
target_link_libraries(farextract far)
|
||||
|
||||
set_target_properties(farextract PROPERTIES FOLDER tools)
|
||||
set_target_properties(farextract PROPERTIES FOLDER tools/archive)
|
|
@ -23,7 +23,7 @@
|
|||
#include <time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include "far/far.h"
|
||||
#include <far.h>
|
||||
|
||||
#ifndef read_uint32
|
||||
#define read_uint32(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
8
Tools/archive/iff-export/CMakeLists.txt
Normal file
8
Tools/archive/iff-export/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(iff-export)
|
||||
|
||||
include_directories(${iff_SOURCE_DIR})
|
||||
add_executable(iffexport iffexport.c)
|
||||
target_link_libraries(iffexport iff)
|
||||
|
||||
set_target_properties(iffexport PROPERTIES FOLDER tools/archive)
|
3
Tools/format/CMakeLists.txt
Normal file
3
Tools/format/CMakeLists.txt
Normal file
|
@ -0,0 +1,3 @@
|
|||
#format
|
||||
add_subdirectory(xa-decode)
|
||||
add_subdirectory(utk-decode)
|
8
Tools/format/utk-decode/CMakeLists.txt
Normal file
8
Tools/format/utk-decode/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(utk-decode)
|
||||
|
||||
include_directories(${format_SOURCE_DIR})
|
||||
add_executable(utk-decode utkdecode.c)
|
||||
target_link_libraries(utk-decode format)
|
||||
|
||||
set_target_properties(utk-decode PROPERTIES FOLDER tools/format)
|
|
@ -19,7 +19,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include "read_utk.h"
|
||||
#include <utk/read_utk.h>
|
||||
|
||||
#ifndef write_int32
|
||||
#define write_uint32(dest, src) do {\
|
8
Tools/format/xa-decode/CMakeLists.txt
Normal file
8
Tools/format/xa-decode/CMakeLists.txt
Normal file
|
@ -0,0 +1,8 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(xa-decode)
|
||||
|
||||
include_directories(${format_SOURCE_DIR})
|
||||
add_executable(xa-decode xadecode.c)
|
||||
target_link_libraries(xa-decode format)
|
||||
|
||||
set_target_properties(xa-decode PROPERTIES FOLDER tools/format)
|
|
@ -19,7 +19,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <time.h>
|
||||
#include "read_xa.h"
|
||||
#include <xa/read_xa.h>
|
||||
|
||||
#ifndef write_int32
|
||||
#define write_uint32(dest, src) do {\
|
|
@ -1,5 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(iff-export)
|
||||
|
||||
add_executable(iffexport iffexport.c)
|
||||
target_link_libraries(iffexport iff)
|
|
@ -1,9 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(utk)
|
||||
|
||||
set(UTK_SOURCES
|
||||
read_utk.c
|
||||
utkdecode.c
|
||||
)
|
||||
|
||||
add_executable(utkdecode ${UTK_SOURCES})
|
|
@ -1,7 +1,7 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(vitaboy-parse)
|
||||
|
||||
include_directories(${vitaboy_SOURCE_DIR} ${filehandler_SOURCE_DIR})
|
||||
include_directories(${libvitaboy_SOURCE_DIR} ${filehandler_SOURCE_DIR})
|
||||
|
||||
add_executable(vbparse vbparse.cpp)
|
||||
target_link_libraries(vbparse libvitaboy FileHandler)
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <FileHandler.hpp>
|
||||
#include "libvitaboy.hpp"
|
||||
#include <libvitaboy.hpp>
|
||||
|
||||
enum VBFileType {
|
||||
VBFILE_ANIM,
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(xa)
|
||||
|
||||
set(XA_SOURCES
|
||||
read_xa.c
|
||||
xadecode.c
|
||||
)
|
||||
|
||||
add_executable(xadecode ${XA_SOURCES})
|
|
@ -1,10 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(far)
|
||||
|
||||
set(FAR_SOURCES
|
||||
far.c
|
||||
refpack_dec.c
|
||||
)
|
||||
|
||||
add_library(far STATIC ${FAR_SOURCES}) # remove static, cmake should take care of that
|
||||
target_include_directories(far PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
|
@ -1,24 +0,0 @@
|
|||
/* config.h - far build configuration */
|
||||
|
||||
/* Define if you have the <stdint.h> header file. */
|
||||
#define HAVE_STDINT_H
|
||||
|
||||
/* compile-in support */
|
||||
#define FAR_ARCHIVEREAD
|
||||
#define FAR_ARCHIVEWRITE
|
||||
#define FAR_REFPACK_DECOMPRESS
|
||||
#define FAR_REFPACK_COMPRESS
|
||||
#define FAR_SUPPORT_FAR
|
||||
#define FAR_SUPPORT_DBPF
|
||||
#define FAR_SUPPORT_PERSIST
|
||||
#define FAR_DEBUGSUPPORT
|
||||
#define FAR_FILEIO
|
||||
#define FAR_EMBEDDEDFUNCTIONS
|
||||
/* end of compile-in support */
|
||||
|
||||
/* preferences -- on non-numerical definitions, define to 1 for "yes", 0 for "no" */
|
||||
#define FAR_DEFAULT_1A 0
|
||||
#define FAR_DEFAULT_DBPF_COMPRESSED 0
|
||||
#define FAR_DEFAULT_MAX_FILE_NAME_LENGTH 255
|
||||
#define FAR_DEFAULT_REFPACK_HNSV 0xFB
|
||||
/* end of default preferences */
|
|
@ -1,446 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
far.c - Copyright (c) 2011-2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "far.h"
|
||||
|
||||
#if defined(FAR_SUPPORT_PERSIST)
|
||||
#define FAR_MINSIZE_ANY MINSIZE_PERSIST
|
||||
#elif defined(FAR_SUPPORT_FAR)
|
||||
#define FAR_MINSIZE_ANY MINSIZE_FAR
|
||||
#else
|
||||
#define FAR_MINSIZE_ANY MINSIZE_DBPF
|
||||
#endif
|
||||
|
||||
#ifndef read_int32
|
||||
#define read_int32(x) (int)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
|
||||
#define read_int24(x) (int)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)))
|
||||
#define read_int16(x) (int)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#define read_int8(x) (int)(((x)[0]<<(8*0)))
|
||||
#define read_uint32(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
|
||||
#define read_uint24(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)))
|
||||
#define read_uint16(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#define read_uint8(x) (unsigned)(((x)[0]<<(8*0)))
|
||||
#endif
|
||||
|
||||
#ifndef max
|
||||
#define max(a,b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#ifndef min
|
||||
#define min(a,b) (((a) < (b)) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* These options can be changed during runtime */
|
||||
static int libfarOptions[] = {
|
||||
FAR_DEFAULT_1A,
|
||||
FAR_DEFAULT_DBPF_COMPRESSED,
|
||||
FAR_DEFAULT_MAX_FILE_NAME_LENGTH,
|
||||
FAR_DEFAULT_REFPACK_HNSV
|
||||
};
|
||||
|
||||
void libfar_set_option(int Option, int Value){
|
||||
libfarOptions[Option] = Value;
|
||||
}
|
||||
int libfar_get_option(int Option){
|
||||
return libfarOptions[Option];
|
||||
}
|
||||
|
||||
int far_identify(const uint8_t * Buffer, unsigned FileSize)
|
||||
{
|
||||
if(!FileSize) FileSize = ~0;
|
||||
else if(FileSize < FAR_MINSIZE_ANY)
|
||||
return FAR_TYPE_INVALID;
|
||||
|
||||
#ifdef FAR_SUPPORT_FAR
|
||||
if(FileSize >= MINSIZE_FAR && !memcmp(Buffer, Header_FAR, 8))
|
||||
return FAR_TYPE_FAR;
|
||||
#endif
|
||||
|
||||
#ifdef FAR_SUPPORT_DBPF
|
||||
if(FileSize >= MINSIZE_DBPF && !memcmp(Buffer, Header_DBPF, 4))
|
||||
return FAR_TYPE_DBPF;
|
||||
#endif
|
||||
|
||||
#ifdef FAR_SUPPORT_PERSIST
|
||||
if(FileSize >= MINSIZE_PERSIST && Buffer[0] == 0x01)
|
||||
return FAR_TYPE_PERSIST;
|
||||
#endif
|
||||
|
||||
return FAR_TYPE_INVALID;
|
||||
}
|
||||
|
||||
FARFile * far_create_archive(int Type)
|
||||
{
|
||||
FARFile *ptr = calloc(1, sizeof(FARFile));
|
||||
if(ptr == NULL) return NULL;
|
||||
ptr->Type = Type;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
PersistFile * far_create_persist()
|
||||
{
|
||||
return calloc(1, sizeof(PersistFile));
|
||||
}
|
||||
|
||||
FAREntryNode * far_add_entry(FARFile * FARFileInfo, int Position)
|
||||
{
|
||||
FAREntryNode *ptr = calloc(1, sizeof(FAREntryNode)), *node;
|
||||
if(ptr == NULL) return NULL;
|
||||
if(FARFileInfo == NULL) return ptr;
|
||||
|
||||
if(Position >= 0){
|
||||
node = FARFileInfo->FirstEntry;
|
||||
|
||||
if(node == NULL){
|
||||
FARFileInfo->FirstEntry = ptr;
|
||||
FARFileInfo->LastEntry = ptr;
|
||||
}else{
|
||||
/* Find the node we will take the place of */
|
||||
while(Position-- && node->NextEntry != NULL)
|
||||
node = node->NextEntry;
|
||||
|
||||
if(node->PrevEntry == NULL)
|
||||
FARFileInfo->FirstEntry = ptr;
|
||||
|
||||
/* Shift this node and all nodes after it above us */
|
||||
ptr->PrevEntry = node->PrevEntry;
|
||||
ptr->NextEntry = node;
|
||||
node->PrevEntry = ptr;
|
||||
}
|
||||
}else{
|
||||
node = FARFileInfo->LastEntry;
|
||||
|
||||
if(node == NULL){
|
||||
FARFileInfo->FirstEntry = ptr;
|
||||
FARFileInfo->LastEntry = ptr;
|
||||
}else{
|
||||
/* Find the node we will take the place of */
|
||||
while(++Position && node->PrevEntry != NULL)
|
||||
node = node->PrevEntry;
|
||||
|
||||
if(node->NextEntry == NULL)
|
||||
FARFileInfo->LastEntry = ptr;
|
||||
|
||||
/* Shift this node and all nodes before it below us */
|
||||
ptr->PrevEntry = node;
|
||||
ptr->NextEntry = node->NextEntry;
|
||||
node->NextEntry = ptr;
|
||||
}
|
||||
}
|
||||
|
||||
FARFileInfo->Files++;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int far_read_header(FARFile * FARFileInfo, const uint8_t * Buffer, unsigned FileSize)
|
||||
{
|
||||
if(!FileSize) FileSize = ~0;
|
||||
else if(FileSize < FAR_MINSIZE_ANY)
|
||||
return 0;
|
||||
|
||||
#ifdef FAR_SUPPORT_FAR
|
||||
if(FARFileInfo->Type == FAR_TYPE_FAR){
|
||||
FARFileInfo->MajorVersion = read_uint32(Buffer+8);
|
||||
FARFileInfo->IndexOffset = read_uint32(Buffer+12);
|
||||
|
||||
if(FARFileInfo->MajorVersion != 1 && FARFileInfo->MajorVersion != 3)
|
||||
return 0;
|
||||
|
||||
if(FARFileInfo->MajorVersion == 1)
|
||||
FARFileInfo->Revision = !libfarOptions[FAR_CONFIG_DEFAULT_TO_1A];
|
||||
|
||||
if(FARFileInfo->IndexOffset > FileSize-4)
|
||||
return 0;
|
||||
|
||||
FARFileInfo->Files = read_uint32(Buffer + FARFileInfo->IndexOffset);
|
||||
|
||||
if(FARFileInfo->Files > (FileSize-FARFileInfo->IndexOffset) / (
|
||||
(FARFileInfo->MajorVersion == 1) ? (
|
||||
(FARFileInfo->Revision == 0) ? MINSIZE_ENTRY_FAR_1A : MINSIZE_ENTRY_FAR_1B
|
||||
) : MINSIZE_ENTRY_FAR_3)
|
||||
) return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FAR_SUPPORT_DBPF
|
||||
if(FARFileInfo->Type == FAR_TYPE_DBPF){
|
||||
int i;
|
||||
|
||||
FARFileInfo->MajorVersion = read_uint32(Buffer+4);
|
||||
FARFileInfo->MinorVersion = read_uint32(Buffer+8);
|
||||
FARFileInfo->DateCreated = read_uint32(Buffer+24);
|
||||
FARFileInfo->DateModified = read_uint32(Buffer+28);
|
||||
FARFileInfo->IndexMajorVersion = read_uint32(Buffer+32);
|
||||
FARFileInfo->Files = read_uint32(Buffer+36);
|
||||
FARFileInfo->IndexOffset = read_uint32(Buffer+40);
|
||||
FARFileInfo->IndexSize = read_uint32(Buffer+44);
|
||||
FARFileInfo->TrashCount = read_uint32(Buffer+48);
|
||||
FARFileInfo->TrashOffset = read_uint32(Buffer+52);
|
||||
FARFileInfo->TrashSize = read_uint32(Buffer+56);
|
||||
FARFileInfo->IndexMinorVersion = read_uint32(Buffer+60);
|
||||
|
||||
if(FARFileInfo->MajorVersion != 1) return 0;
|
||||
if(FARFileInfo->MinorVersion != 0) return 0;
|
||||
if(FARFileInfo->IndexMajorVersion != 7) return 0;
|
||||
if(FARFileInfo->IndexMinorVersion != 0) return 0;
|
||||
|
||||
for(i=12; i<24; i++)
|
||||
if(Buffer[i] != 0x00) return 0;
|
||||
|
||||
if(FARFileInfo->Files){
|
||||
if(FARFileInfo->Files > MAX_ENTRIES_DBPF) return 0;
|
||||
if(FARFileInfo->IndexSize != FARFileInfo->Files*SIZEOF_ENTRY_DBPF) return 0;
|
||||
if(FARFileInfo->IndexOffset > FileSize) return 0;
|
||||
if(FARFileInfo->IndexSize > FileSize - FARFileInfo->IndexOffset) return 0;
|
||||
}
|
||||
if(FARFileInfo->TrashCount){
|
||||
if(FARFileInfo->TrashCount > MAX_ENTRIES_DBPF) return 0;
|
||||
if(FARFileInfo->TrashSize != FARFileInfo->TrashCount*SIZEOF_ENTRY_DBPF) return 0;
|
||||
if(FARFileInfo->TrashOffset > FileSize) return 0;
|
||||
if(FARFileInfo->TrashSize > FileSize - FARFileInfo->TrashOffset) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int far_read_entry(const FARFile * FARFileInfo, FAREntry * FAREntryInfo,
|
||||
const uint8_t * Buffer, unsigned MaxEntrySize, unsigned ArchiveSize)
|
||||
{
|
||||
int MajorVersion = FARFileInfo->MajorVersion, Revision = FARFileInfo->Revision;
|
||||
if(MaxEntrySize == 0) MaxEntrySize = ~0;
|
||||
if(ArchiveSize == 0) ArchiveSize = ~0;
|
||||
|
||||
#ifdef FAR_SUPPORT_FAR
|
||||
if(FARFileInfo->Type == FAR_TYPE_FAR){
|
||||
unsigned MinEntrySize =
|
||||
(MajorVersion == 1) ? (
|
||||
(Revision == 0) ? MINSIZE_ENTRY_FAR_1A : MINSIZE_ENTRY_FAR_1B
|
||||
) : MINSIZE_ENTRY_FAR_3;
|
||||
|
||||
if(MaxEntrySize < MinEntrySize)
|
||||
return 0;
|
||||
|
||||
if(MajorVersion == 1){
|
||||
FAREntryInfo->DecompressedSize = read_uint32(Buffer+0);
|
||||
FAREntryInfo->CompressedSize = read_uint32(Buffer+4);
|
||||
FAREntryInfo->DataOffset = read_uint32(Buffer+8);
|
||||
if(Revision == 0)
|
||||
FAREntryInfo->FilenameLength = read_uint32(Buffer+12);
|
||||
else
|
||||
FAREntryInfo->FilenameLength = read_uint16(Buffer+12);
|
||||
}else if(MajorVersion == 3){
|
||||
FAREntryInfo->DecompressedSize = read_uint32(Buffer+0);
|
||||
FAREntryInfo->CompressedSize = read_uint24(Buffer+4);
|
||||
FAREntryInfo->DataType = read_uint8(Buffer+7);
|
||||
FAREntryInfo->DataOffset = read_uint32(Buffer+8);
|
||||
FAREntryInfo->HasFilename = read_uint16(Buffer+12);
|
||||
FAREntryInfo->FilenameLength = read_uint16(Buffer+14);
|
||||
FAREntryInfo->TypeID = read_uint32(Buffer+16);
|
||||
FAREntryInfo->FileID = read_uint32(Buffer+20);
|
||||
}
|
||||
|
||||
if(FAREntryInfo->FilenameLength > MaxEntrySize - MinEntrySize) return 0;
|
||||
if(FAREntryInfo->FilenameLength > (unsigned)libfarOptions[FAR_CONFIG_MAX_FILE_NAME_LENGTH]) return 0;
|
||||
|
||||
if(FAREntryInfo->CompressedSize > FAREntryInfo->DecompressedSize) return 0;
|
||||
if(FAREntryInfo->DecompressedSize != 0){
|
||||
if(FAREntryInfo->DataOffset > ArchiveSize) return 0;
|
||||
if(FAREntryInfo->CompressedSize > ArchiveSize - FAREntryInfo->DataOffset) return 0;
|
||||
}else if(MajorVersion == 3 && FAREntryInfo->DataType != 0) return 0;
|
||||
|
||||
FAREntryInfo->Filename = malloc(FAREntryInfo->FilenameLength + 1);
|
||||
if(FAREntryInfo->Filename == NULL) return 0;
|
||||
if(FAREntryInfo->FilenameLength != 0)
|
||||
memcpy(FAREntryInfo->Filename, Buffer+MinEntrySize, FAREntryInfo->FilenameLength);
|
||||
FAREntryInfo->Filename[FAREntryInfo->FilenameLength] = '\0';
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FAR_SUPPORT_DBPF
|
||||
if(FARFileInfo->Type == FAR_TYPE_DBPF){
|
||||
if(MaxEntrySize < SIZEOF_ENTRY_DBPF) return 0;
|
||||
|
||||
FAREntryInfo->TypeID = read_uint32(Buffer+0);
|
||||
FAREntryInfo->GroupID = read_uint32(Buffer+4);
|
||||
FAREntryInfo->FileID = read_uint32(Buffer+8);
|
||||
FAREntryInfo->DataOffset = read_uint32(Buffer+12);
|
||||
FAREntryInfo->CompressedSize = read_uint32(Buffer+16);
|
||||
FAREntryInfo->DecompressedSize = FAREntryInfo->CompressedSize;
|
||||
|
||||
if(FAREntryInfo->CompressedSize != 0){
|
||||
if(FAREntryInfo->CompressedSize > ArchiveSize - FAREntryInfo->DataOffset) return 0;
|
||||
if(FAREntryInfo->DataOffset > ArchiveSize) return 0;
|
||||
if(FAREntryInfo->CompressedSize > ArchiveSize - FAREntryInfo->DataOffset) return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int far_read_persist_header(PersistFile * PersistData, const uint8_t * Buffer, unsigned FileSize)
|
||||
{
|
||||
RefPackParameters * Parameters;
|
||||
PersistData->BodyType = read_uint8(Buffer);
|
||||
PersistData->DecompressedSize = read_uint32(Buffer+1);
|
||||
PersistData->CompressedSize = read_uint32(Buffer+5);
|
||||
PersistData->StreamBodySize = read_uint32(Buffer+9);
|
||||
PersistData->Compressor = read_uint8(Buffer+13);
|
||||
|
||||
if(PersistData->BodyType != 1)
|
||||
return 0;
|
||||
if(PersistData->CompressedSize < FileSize-9)
|
||||
return 0;
|
||||
|
||||
if(PersistData->CompressedSize != PersistData->StreamBodySize)
|
||||
return 0;
|
||||
|
||||
PersistData->Parameters = malloc(sizeof(RefPackParameters));
|
||||
if(PersistData->Parameters == NULL)
|
||||
return 0;
|
||||
|
||||
Parameters = (RefPackParameters *) PersistData->Parameters;
|
||||
Parameters->hnsv = read_uint8(Buffer+14);
|
||||
Parameters->DecompressedSize = (Buffer[15]<<16) | (Buffer[16]<<8) | Buffer[17]; /* Big endian */
|
||||
|
||||
if((PersistData->DecompressedSize&0x00FFFFFF) != Parameters->DecompressedSize){
|
||||
free(PersistData->Parameters); return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int far_read_entry_data(const FARFile * FARFileInfo, FAREntry * FAREntryInfo, uint8_t * Buffer)
|
||||
{
|
||||
int Compressed = (FARFileInfo->Type == FAR_TYPE_FAR) ? (
|
||||
(FARFileInfo->MajorVersion == 1) ? (
|
||||
FAREntryInfo->DecompressedSize != FAREntryInfo->CompressedSize
|
||||
) : FAREntryInfo->DataType == 0x80) : libfarOptions[FAR_CONFIG_DBPF_COMPRESSED];
|
||||
|
||||
FAREntryInfo->CompressedData = Buffer+FAREntryInfo->DataOffset;
|
||||
|
||||
if(!Compressed)
|
||||
FAREntryInfo->DecompressedData = FAREntryInfo->CompressedData;
|
||||
else{
|
||||
PersistFile * PersistInfo = &(FAREntryInfo->PersistData);
|
||||
if(far_identify(FAREntryInfo->CompressedData, FAREntryInfo->CompressedSize) != FAR_TYPE_PERSIST)
|
||||
return 0;
|
||||
|
||||
if(!far_read_persist_header(PersistInfo, FAREntryInfo->CompressedData, FAREntryInfo->CompressedSize))
|
||||
return 0;
|
||||
|
||||
/* Verify that the Persist data agrees with the entry data */
|
||||
if(PersistInfo->DecompressedSize != FAREntryInfo->DecompressedSize){
|
||||
free(PersistInfo->Parameters); return 0;
|
||||
}if(PersistInfo->CompressedSize != FAREntryInfo->CompressedSize - 9){
|
||||
free(PersistInfo->Parameters); return 0;
|
||||
}if(PersistInfo->Compressor != 0x10){
|
||||
free(PersistInfo->Parameters); return 0;
|
||||
}
|
||||
|
||||
PersistInfo->DecompressedData = FAREntryInfo->DecompressedData;
|
||||
|
||||
if(!far_read_persist_data(PersistInfo, FAREntryInfo->CompressedData+18)){
|
||||
free(PersistInfo->Parameters); return 0;
|
||||
}
|
||||
FAREntryInfo->DecompressedData = PersistInfo->DecompressedData;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int far_read_persist_data(PersistFile * PersistData, uint8_t * CompressedData)
|
||||
{
|
||||
if(CompressedData != NULL) PersistData->CompressedData = CompressedData;
|
||||
|
||||
PersistData->DecompressedData = malloc(PersistData->DecompressedSize);
|
||||
if(PersistData->DecompressedData == NULL)
|
||||
return 0;
|
||||
|
||||
if(!RefPackDecompress(PersistData->CompressedData, PersistData->CompressedSize-9,
|
||||
PersistData->DecompressedData, PersistData->DecompressedSize,
|
||||
libfarOptions[FAR_CONFIG_REFPACK_HNSV])){
|
||||
free(PersistData->DecompressedData);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int far_enumerate_entries(FARFile * FARFileInfo, const uint8_t * Index, unsigned IndexSize, unsigned ArchiveSize)
|
||||
{
|
||||
unsigned Files = FARFileInfo->Files;
|
||||
int ArchiveType = FARFileInfo->Type;
|
||||
unsigned MinEntrySize = (ArchiveType == FAR_TYPE_FAR) ? (
|
||||
(FARFileInfo->MajorVersion == 1) ? (
|
||||
(FARFileInfo->Revision == 0) ? MINSIZE_ENTRY_FAR_1A : MINSIZE_ENTRY_FAR_1B
|
||||
) : MINSIZE_ENTRY_FAR_3) : SIZEOF_ENTRY_DBPF;
|
||||
unsigned EntriesAdded = 0;
|
||||
FARFileInfo->Files = 0;
|
||||
|
||||
if(FARFileInfo->Type == FAR_TYPE_FAR)
|
||||
Index += 4;
|
||||
|
||||
while(EntriesAdded < Files){
|
||||
FAREntryNode * node = far_add_entry(FARFileInfo, -1);
|
||||
if(node == NULL)
|
||||
return 0;
|
||||
if(!far_read_entry(FARFileInfo, &(node->Entry), Index, IndexSize, ArchiveSize)){
|
||||
free(node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EntriesAdded++;
|
||||
Index += MinEntrySize;
|
||||
IndexSize -= MinEntrySize;
|
||||
if(ArchiveType != FAR_TYPE_DBPF){
|
||||
Index += node->Entry.FilenameLength;
|
||||
IndexSize -= node->Entry.FilenameLength;
|
||||
}
|
||||
}
|
||||
|
||||
return (EntriesAdded == FARFileInfo->Files);
|
||||
}
|
||||
|
||||
int far_enumerate_entry_data(const FARFile * FARFileInfo, uint8_t * Buffer)
|
||||
{
|
||||
FAREntryNode * node = FARFileInfo->FirstEntry;
|
||||
while(node){
|
||||
if(!far_read_entry_data(FARFileInfo, &(node->Entry), Buffer))
|
||||
return 0;
|
||||
node = node->NextEntry;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void libfar_free(void * ptr)
|
||||
{
|
||||
free(ptr);
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
far.h - Copyright (c) 2011 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
/****
|
||||
** Constants
|
||||
*/
|
||||
|
||||
/* libfarOptions array members */
|
||||
#define FAR_CONFIG_DEFAULT_TO_1A 0
|
||||
#define FAR_CONFIG_DBPF_COMPRESSED 1
|
||||
#define FAR_CONFIG_MAX_FILE_NAME_LENGTH 2
|
||||
#define FAR_CONFIG_REFPACK_HNSV 3
|
||||
|
||||
/* Archive types */
|
||||
#define FAR_TYPE_INVALID 0
|
||||
#define FAR_TYPE_FAR 1
|
||||
#define FAR_TYPE_DBPF 2
|
||||
#define FAR_TYPE_PERSIST 3
|
||||
|
||||
/* Numerical constants */
|
||||
#define FAR_ARCHIVE_MINIMUM_SIZE 14
|
||||
#define MINSIZE_FAR 20
|
||||
#define MINSIZE_DBPF 64
|
||||
#define MINSIZE_ENTRY_FAR_1A 16
|
||||
#define MINSIZE_ENTRY_FAR_1B 14
|
||||
#define MINSIZE_ENTRY_FAR_3 24
|
||||
#define SIZEOF_ENTRY_DBPF 20
|
||||
#define MAX_ENTRIES_FAR_1A 268435455
|
||||
#define MAX_ENTRIES_FAR_1B 306783377
|
||||
#define MAX_ENTRIES_FAR_3 178956970
|
||||
#define MAX_ENTRIES_DBPF 214748364
|
||||
#define MINSIZE_PERSIST 18
|
||||
#define MAXSIZE_REFPACK_UNCOMPRESSED 16777215
|
||||
#define MAXSIZE_REFPACK_COMPRESSED 16777215
|
||||
|
||||
/* Header bytes */
|
||||
static const uint8_t Header_FAR[] = {'F','A','R','!','b','y','A','Z'};
|
||||
static const uint8_t Header_DBPF[] = {'D','B','P','F'};
|
||||
|
||||
/****
|
||||
** Data structures
|
||||
*/
|
||||
|
||||
typedef struct PersistFile_s
|
||||
{
|
||||
uint8_t BodyType;
|
||||
uint32_t DecompressedSize;
|
||||
uint32_t CompressedSize;
|
||||
uint32_t StreamBodySize;
|
||||
uint8_t Compressor;
|
||||
uint8_t * Parameters;
|
||||
uint8_t * CompressedData;
|
||||
uint8_t * DecompressedData;
|
||||
} PersistFile;
|
||||
|
||||
typedef struct RefPackParameters_s
|
||||
{
|
||||
uint8_t hnsv;
|
||||
uint32_t DecompressedSize;
|
||||
} RefPackParameters;
|
||||
|
||||
typedef struct FAREntry_s
|
||||
{
|
||||
uint32_t DecompressedSize;
|
||||
uint32_t CompressedSize;
|
||||
uint8_t DataType;
|
||||
uint32_t DataOffset;
|
||||
uint16_t HasFilename;
|
||||
uint32_t FilenameLength;
|
||||
uint32_t TypeID;
|
||||
uint32_t GroupID;
|
||||
uint32_t FileID;
|
||||
char * Filename;
|
||||
PersistFile PersistData;
|
||||
uint8_t * CompressedData;
|
||||
uint8_t * DecompressedData;
|
||||
} FAREntry;
|
||||
|
||||
typedef struct FAREntryNode_s
|
||||
{
|
||||
FAREntry Entry;
|
||||
struct FAREntryNode_s * PrevEntry;
|
||||
struct FAREntryNode_s * NextEntry;
|
||||
} FAREntryNode;
|
||||
|
||||
typedef struct FARFile_s
|
||||
{
|
||||
int32_t Type;
|
||||
|
||||
/* Header */
|
||||
uint32_t MajorVersion;
|
||||
uint32_t MinorVersion;
|
||||
uint32_t Revision;
|
||||
uint32_t IndexOffset;
|
||||
/* DBPF */
|
||||
uint32_t DateCreated;
|
||||
uint32_t DateModified;
|
||||
uint32_t IndexMajorVersion;
|
||||
uint32_t IndexSize;
|
||||
uint32_t TrashCount;
|
||||
uint32_t TrashOffset;
|
||||
uint32_t TrashSize;
|
||||
uint32_t IndexMinorVersion;
|
||||
|
||||
/* Regular index */
|
||||
uint32_t Files;
|
||||
FAREntryNode * FirstEntry;
|
||||
FAREntryNode * LastEntry;
|
||||
struct { /* DIR index for DBPF */
|
||||
FAREntryNode * FirstEntry;
|
||||
FAREntryNode * LastEntry;
|
||||
} Dir;
|
||||
struct { /* Trash index for DBPF */
|
||||
FAREntryNode * FirstEntry;
|
||||
FAREntryNode * LastEntry;
|
||||
} Trash;
|
||||
} FARFile;
|
||||
|
||||
/****
|
||||
** Exported functions
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void libfar_set_option(int Option, int Value);
|
||||
int libfar_get_option(int Option);
|
||||
|
||||
int far_identify(const uint8_t * Buffer, unsigned FileSize);
|
||||
|
||||
FARFile * far_create_archive(int Type);
|
||||
PersistFile * far_create_persist();
|
||||
|
||||
FAREntryNode * far_add_entry(FARFile * FARFileInfo, int Position);
|
||||
|
||||
int far_read_header(FARFile * FARFileInfo, const uint8_t * Buffer, unsigned FileSize);
|
||||
int far_read_entry(const FARFile * FARFileInfo, FAREntry * FAREntryInfo,
|
||||
const uint8_t * Buffer, unsigned MaxEntrySize, unsigned ArchiveSize);
|
||||
int far_read_persist_header(PersistFile * PersistData, const uint8_t * Buffer, unsigned FileSize);
|
||||
int far_read_entry_data(const FARFile * FARFileInfo, FAREntry * FAREntryInfo, uint8_t * Buffer);
|
||||
int far_read_persist_data(PersistFile * PersistData, uint8_t * CompressedData);
|
||||
|
||||
int far_enumerate_entries(FARFile * FARFileInfo, const uint8_t * Index, unsigned IndexSize, unsigned ArchiveSize);
|
||||
int far_enumerate_entry_data(const FARFile * FARFileInfo, uint8_t * Buffer);
|
||||
|
||||
FAREntryNode * far_search_id();
|
||||
FAREntryNode * far_search_name();
|
||||
FAREntryNode * far_search_multi();
|
||||
|
||||
void far_delete_entry(FARFile * FARFileInfo, int Position);
|
||||
void far_delete_archive(FARFile * FARFileInfo);
|
||||
void far_delete_persist(FARFile * FARFileInfo);
|
||||
void libfar_free(void * ptr);
|
||||
|
||||
int RefPackDecompress(const uint8_t * CompressedData, size_t CompressedSize,
|
||||
uint8_t * DecompressedData, size_t DecompressedSize, unsigned HNSV);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -1,163 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
refpack_dec.c - Copyright (c) 2011 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int RefPackDecompress(const uint8_t *__restrict CompressedData, size_t CompressedSize,
|
||||
uint8_t *__restrict DecompressedData, size_t DecompressedSize, unsigned HNSV){
|
||||
unsigned datawritten = 0;
|
||||
int stopflag = 0, StopFlagData;
|
||||
|
||||
if(HNSV == 0) HNSV = 0xFB; /* EA default */
|
||||
if (HNSV >= 0xFF) StopFlagData = 0x1F;
|
||||
else if(HNSV >= 0xFE) StopFlagData = 0x00;
|
||||
else if(HNSV >= 0xFD) StopFlagData = 0x01;
|
||||
else if(HNSV >= 0xFB) StopFlagData = 0x03;
|
||||
else if(HNSV >= 0xF7) StopFlagData = 0x07;
|
||||
else StopFlagData = 0x0F;
|
||||
|
||||
while(CompressedSize > 0 && !stopflag){
|
||||
unsigned ProceedingDataLength, ReferencedDataLength, ReferencedDataOffset;
|
||||
unsigned currentbyte = *(CompressedData++);
|
||||
CompressedSize--;
|
||||
|
||||
/****
|
||||
** Fetch the opcode
|
||||
*/
|
||||
|
||||
/* The first byte determines the size of the entire opcode. */
|
||||
|
||||
if(currentbyte <= 0x7F){ /* 2 bytes */
|
||||
if(CompressedSize < 1) return 0;
|
||||
CompressedSize -= 1;
|
||||
|
||||
/* First byte */
|
||||
ProceedingDataLength = currentbyte & 0x03;
|
||||
ReferencedDataLength = ((currentbyte & 0x1C) >> 2) + 3;
|
||||
ReferencedDataOffset = (currentbyte & 0x60) << 3;
|
||||
|
||||
/* Second byte */
|
||||
currentbyte = *(CompressedData++);
|
||||
ReferencedDataOffset += currentbyte;
|
||||
}else if(currentbyte <= 0xBF){ /* 3 bytes */
|
||||
if(CompressedSize < 2) return 0;
|
||||
CompressedSize -= 2;
|
||||
|
||||
/* First byte */
|
||||
ReferencedDataLength = (currentbyte & 0x3F) + 4;
|
||||
|
||||
/* Second byte */
|
||||
currentbyte = *(CompressedData++);
|
||||
ProceedingDataLength = (currentbyte & 0xC0) >> 6;
|
||||
ReferencedDataOffset = (currentbyte & 0x3F) << 8;
|
||||
|
||||
/* Third byte */
|
||||
currentbyte = *(CompressedData++);
|
||||
ReferencedDataOffset += currentbyte;
|
||||
}else if(currentbyte <= 0xDF){ /* 4 bytes */
|
||||
if(CompressedSize < 3) return 0;
|
||||
CompressedSize -= 3;
|
||||
|
||||
/* First byte */
|
||||
ProceedingDataLength = currentbyte & 0x03;
|
||||
ReferencedDataLength = ((currentbyte & 0x0C) << 6) + 5;
|
||||
ReferencedDataOffset = (currentbyte & 0x10) << 12;
|
||||
|
||||
/* Second byte */
|
||||
currentbyte = *(CompressedData++);
|
||||
ReferencedDataOffset += currentbyte << 8;
|
||||
|
||||
/* Third byte */
|
||||
currentbyte = *(CompressedData++);
|
||||
ReferencedDataOffset += currentbyte;
|
||||
|
||||
/* Fourth byte */
|
||||
currentbyte = *(CompressedData++);
|
||||
ReferencedDataLength += currentbyte;
|
||||
}else{ /* 1 byte: Two different opcode types fall into this category */
|
||||
if(currentbyte <= HNSV){
|
||||
ProceedingDataLength = ((currentbyte & 0x1F) + 1) << 2;
|
||||
}else{
|
||||
ProceedingDataLength = currentbyte & StopFlagData;
|
||||
stopflag++;
|
||||
}
|
||||
ReferencedDataLength = 0;
|
||||
}
|
||||
|
||||
/****
|
||||
** Copy proceeding data
|
||||
*/
|
||||
|
||||
if(ProceedingDataLength != 0){
|
||||
if(ProceedingDataLength > CompressedSize || ProceedingDataLength > DecompressedSize)
|
||||
return 0;
|
||||
|
||||
memcpy(DecompressedData, CompressedData, ProceedingDataLength);
|
||||
DecompressedSize -= ProceedingDataLength;
|
||||
CompressedSize -= ProceedingDataLength;
|
||||
datawritten += ProceedingDataLength;
|
||||
DecompressedData += ProceedingDataLength;
|
||||
CompressedData += ProceedingDataLength;
|
||||
}
|
||||
|
||||
/****
|
||||
** Copy referenced data
|
||||
*/
|
||||
|
||||
if(ReferencedDataLength != 0){
|
||||
/* It is possible that the offset specified does not provide for a large enough buffer to copy all at once from.
|
||||
This event would be caused when the referenced data offset is set smaller than the referenced data length.
|
||||
When this occurs, the decoder is to repeatedly copy/paste the referenced data until the length is satisfied.
|
||||
We will do this in a way so that we call memcpy ceil(log2(N)) times instead of N times. */
|
||||
|
||||
ReferencedDataOffset++;
|
||||
if(ReferencedDataLength > DecompressedSize || ReferencedDataOffset > datawritten)
|
||||
return 0;
|
||||
|
||||
DecompressedSize -= ReferencedDataLength;
|
||||
datawritten += ReferencedDataLength;
|
||||
|
||||
if(ReferencedDataOffset == 1){
|
||||
memset(DecompressedData, *(DecompressedData-1), ReferencedDataLength);
|
||||
DecompressedData += ReferencedDataLength;
|
||||
}else{
|
||||
unsigned copylength =
|
||||
(ReferencedDataOffset < ReferencedDataLength) ? ReferencedDataOffset : ReferencedDataLength;
|
||||
uint8_t *__restrict copysource = DecompressedData;
|
||||
|
||||
memcpy(DecompressedData, DecompressedData-ReferencedDataOffset, copylength);
|
||||
DecompressedData += copylength;
|
||||
ReferencedDataLength -= copylength;
|
||||
|
||||
while(ReferencedDataLength){
|
||||
if(copylength > ReferencedDataLength)
|
||||
copylength = ReferencedDataLength;
|
||||
|
||||
memcpy(DecompressedData, copysource, copylength);
|
||||
DecompressedData += copylength;
|
||||
ReferencedDataLength -= copylength;
|
||||
|
||||
if(!(copylength&0x80000000)) copylength <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (stopflag && !CompressedSize && !DecompressedSize);
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
cmake_minimum_required(VERSION 2.6...3.29)
|
||||
project(iff)
|
||||
|
||||
set(IFF_SOURCES
|
||||
bhav.c
|
||||
cats.c
|
||||
iff.c
|
||||
bcon.c
|
||||
dgrp.c
|
||||
fcns.c
|
||||
glob.c
|
||||
objf.c
|
||||
palt.c
|
||||
rsmp.c
|
||||
spr.c
|
||||
spr2.c
|
||||
str.c
|
||||
string.c
|
||||
tmpl.c
|
||||
trcn.c
|
||||
)
|
||||
|
||||
add_library(iff STATIC ${IFF_SOURCES}) #remove static, cmake should deal with that
|
|
@ -1,53 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
bcon.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_bcon(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFF_BCON *BCONData;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 2)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFF_BCON));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
BCONData = ChunkInfo->FormattedData;
|
||||
BCONData->ConstantCount = read_uint8le(Buffer);
|
||||
BCONData->Flags = read_uint8le(Buffer + 1);
|
||||
if(BCONData->ConstantCount == 0)
|
||||
return 1;
|
||||
if(BCONData->ConstantCount * 2 /* bytes */ > ChunkInfo->Size - 2)
|
||||
return 0;
|
||||
|
||||
BCONData->Constants = malloc(BCONData->ConstantCount * sizeof(uint16_t));
|
||||
if(BCONData->Constants == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += 2;
|
||||
for(i=0; i<BCONData->ConstantCount; i++, Buffer += 2)
|
||||
BCONData->Constants[i] = read_uint16le(Buffer);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_bcon(void * FormattedData){
|
||||
IFF_BCON *BCONData = FormattedData;
|
||||
free(BCONData->Constants);
|
||||
}
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
bhav.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
#define HEADER_SIZE (12 + (Behavior->Version == 0x8003))
|
||||
|
||||
int iff_parse_bhav(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFBehavior *Behavior;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 12)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFBehavior));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Behavior = ChunkInfo->FormattedData;
|
||||
Behavior->Version = read_uint16le(Buffer);
|
||||
if(Behavior->Version < 0x8000 || Behavior->Version > 0x8003 || (Behavior->Version == 0x8003 && ChunkInfo->Size < 13))
|
||||
return 0;
|
||||
|
||||
switch(Behavior->Version){
|
||||
case 0x8000: {
|
||||
Behavior->InstructionCount = read_uint16le(Buffer+2);
|
||||
} break;
|
||||
|
||||
case 0x8001: {
|
||||
Behavior->InstructionCount = read_uint16le(Buffer+2);
|
||||
} break;
|
||||
|
||||
case 0x8002: {
|
||||
Behavior->InstructionCount = read_uint16le(Buffer+2);
|
||||
Behavior->Type = read_uint8le(Buffer+4);
|
||||
Behavior->ArgumentCount = read_uint8le(Buffer+5);
|
||||
Behavior->LocalCount = read_uint16le(Buffer+6);
|
||||
Behavior->Flags = read_uint16le(Buffer+8);
|
||||
} break;
|
||||
|
||||
default: {
|
||||
Behavior->Type = read_uint8le(Buffer+2);
|
||||
Behavior->ArgumentCount = read_uint8le(Buffer+3);
|
||||
Behavior->LocalCount = read_uint8le(Buffer+4);
|
||||
Behavior->Flags = read_uint16le(Buffer+7);
|
||||
Behavior->InstructionCount = read_uint32le(Buffer+9);
|
||||
} break;
|
||||
}
|
||||
|
||||
if(Behavior->InstructionCount == 0)
|
||||
return 1;
|
||||
if(Behavior->InstructionCount > 255 || Behavior->InstructionCount*12 > ChunkInfo->Size - HEADER_SIZE)
|
||||
return 0;
|
||||
|
||||
Behavior->Instructions = calloc(Behavior->InstructionCount, sizeof(IFFInstruction));
|
||||
if(Behavior->Instructions == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += HEADER_SIZE;
|
||||
|
||||
for(i=0; i<Behavior->InstructionCount; i++){
|
||||
Behavior->Instructions[i].Opcode = read_uint16le(Buffer);
|
||||
Behavior->Instructions[i].TDest = read_uint8le(Buffer+2);
|
||||
Behavior->Instructions[i].FDest = read_uint8le(Buffer+3);
|
||||
memcpy(Behavior->Instructions[i].Operands, Buffer+4, 8);
|
||||
|
||||
Buffer += 12;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_bhav(void * FormattedData){
|
||||
IFFBehavior *Behavior = FormattedData;
|
||||
free(Behavior->Instructions);
|
||||
}
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
cats.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_cats(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFStringPair * StringData;
|
||||
bytestream b;
|
||||
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFStringPair));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
StringData = ChunkInfo->FormattedData;
|
||||
return (read_c_string(&b, &StringData->Key) && read_c_string(&b, &StringData->Value));
|
||||
}
|
||||
|
||||
void iff_free_cats(void * FormattedData){
|
||||
IFFStringPair * StringData = FormattedData;
|
||||
free(StringData->Key);
|
||||
free(StringData->Value);
|
||||
}
|
|
@ -1,108 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
dgrp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
#define read_split(x, y, z) \
|
||||
(largefields ? read_uint##z(x) : read_uint##y(x))
|
||||
|
||||
int iff_parse_dgrp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFDrawGroup *Group;
|
||||
bytestream b;
|
||||
int largefields;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 52)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFDrawGroup));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Group = ChunkInfo->FormattedData;
|
||||
Group->Version = read_uint16(&b);
|
||||
if(Group->Version < 20000 || Group->Version > 20004 || Group->Version == 20002)
|
||||
return 0;
|
||||
largefields = (Group->Version >= 20003);
|
||||
Group->AngleCount = read_split(&b, 16, 32);
|
||||
if(Group->AngleCount != 12)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<12; i++){
|
||||
IFFDrawAngle * Angle = &Group->DrawAngles[i];
|
||||
unsigned j;
|
||||
|
||||
if(b.Size < ((!largefields) ? 4 : 12))
|
||||
return 0;
|
||||
|
||||
if(!largefields)
|
||||
Angle->SpriteCount = read_uint16(&b);
|
||||
Angle->Direction = read_split(&b, 8, 32);
|
||||
Angle->Zoom = read_split(&b, 8, 32);
|
||||
if(largefields)
|
||||
Angle->SpriteCount = read_uint32(&b);
|
||||
|
||||
if((Angle->Direction != 1 && Angle->Direction != 4 && Angle->Direction != 16 && Angle->Direction != 64)
|
||||
|| (!Angle->Zoom || Angle->Zoom > 3))
|
||||
return 0;
|
||||
if(Angle->SpriteCount == 0)
|
||||
continue;
|
||||
|
||||
Angle->SpriteInfo = calloc(Angle->SpriteCount, sizeof(IFFSpriteInfo));
|
||||
if(Angle->SpriteInfo == NULL)
|
||||
return 0;
|
||||
|
||||
for(j=0; j<Angle->SpriteCount; j++){
|
||||
IFFSpriteInfo * Sprite = &Angle->SpriteInfo[j];
|
||||
const uint8_t size[5] = {12, 16, 0, 24, 32};
|
||||
|
||||
if(b.Size < size[Group->Version - 20000])
|
||||
return 0;
|
||||
|
||||
if(!largefields)
|
||||
Sprite->Type = read_uint16(&b);
|
||||
Sprite->ChunkID = read_split(&b, 16, 32);
|
||||
Sprite->SpriteIndex = read_split(&b, 16, 32);
|
||||
if(!largefields)
|
||||
Sprite->Flags = read_uint16(&b);
|
||||
Sprite->SpriteX = read_split(&b, 16, 32);
|
||||
Sprite->SpriteY = read_split(&b, 16, 32);
|
||||
if(Group->Version >= 20001){
|
||||
Sprite->ObjectZ = read_float(&b);
|
||||
if(Group->Version >= 20003){
|
||||
Sprite->Flags = read_uint32(&b);
|
||||
if(Group->Version == 20004){
|
||||
Sprite->ObjectX = read_float(&b);
|
||||
Sprite->ObjectY = read_float(&b);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_dgrp(void * FormattedData){
|
||||
IFFDrawGroup *Group = FormattedData;
|
||||
int i;
|
||||
for(i=0; i<12; i++){
|
||||
IFFDrawAngle *Angle = &Group->DrawAngles[i];
|
||||
free(Angle->SpriteInfo);
|
||||
}
|
||||
}
|
|
@ -1,86 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
fcns.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_fcns(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFConstantList *List;
|
||||
bytestream b;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 16)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFConstantList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
List = ChunkInfo->FormattedData;
|
||||
List->Reserved = read_uint32(&b);
|
||||
List->Version = read_uint32(&b);
|
||||
memcpy(List->MagicNumber, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
List->ConstantCount = read_uint32(&b);
|
||||
if(List->Reserved != 0 || List->Version == 0 || List->Version > 2)
|
||||
return 0;
|
||||
|
||||
List->Constants = calloc(List->ConstantCount, sizeof(IFFConstant));
|
||||
if(List->Constants == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<List->ConstantCount; i++){
|
||||
IFFConstant * Constant = &List->Constants[i];
|
||||
unsigned s;
|
||||
for(s=0; s<2; s++){
|
||||
char ** string = (s==0) ? &Constant->Name : &Constant->Description;
|
||||
if(List->Version < 2){
|
||||
/* C string, possible padding */
|
||||
if(!read_c_string(&b, string))
|
||||
return 0;
|
||||
|
||||
/* Skip past the 0xA3 character;
|
||||
** see global.iff chunk 546 for why you can't do modulo-2 to detect this */
|
||||
if(b.Size && *b.Buffer == 0xA3)
|
||||
skipbytes(&b, 1);
|
||||
}else{
|
||||
/* Extended Pascal string, no padding */
|
||||
if(!read_pascal2_string(&b, string))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(s == 0){
|
||||
if(b.Size < 4) return 0;
|
||||
Constant->Value = read_float(&b);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_fcns(void * FormattedData){
|
||||
IFFConstantList * List = FormattedData;
|
||||
if(List->Constants){
|
||||
unsigned c;
|
||||
for(c=0; c<List->ConstantCount; c++){
|
||||
free(List->Constants[c].Name);
|
||||
free(List->Constants[c].Description);
|
||||
}
|
||||
free(List->Constants);
|
||||
}
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
glob.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_glob(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
bytestream b;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
|
||||
/* Try reading as a C string, and if that fails, again as a Pascal string */
|
||||
return (read_c_string(&b, (char**) &ChunkInfo->FormattedData) ||
|
||||
read_pascal_string(&b, (char**) &ChunkInfo->FormattedData));
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
iff.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
/****
|
||||
** Supported Chunks
|
||||
*/
|
||||
|
||||
#define iff_register(x) \
|
||||
int iff_parse_##x(IFFChunk *, const uint8_t *); \
|
||||
void iff_free_##x(void *)
|
||||
|
||||
iff_register(bcon);
|
||||
iff_register(dgrp);
|
||||
iff_register(str);
|
||||
iff_register(cats);
|
||||
iff_register(c_string);
|
||||
iff_register(glob);
|
||||
iff_register(fcns);
|
||||
iff_register(palt);
|
||||
iff_register(bhav);
|
||||
iff_register(objf);
|
||||
iff_register(spr);
|
||||
iff_register(spr2);
|
||||
iff_register(tmpl);
|
||||
iff_register(trcn);
|
||||
iff_register(rsmp);
|
||||
|
||||
/* The ordering of these chunk types must match throughout this block: */
|
||||
const char chunktypes[] =
|
||||
"STR#" "CTSS" "FAMs" "TTAs" "CST\0"
|
||||
"CATS"
|
||||
"FWAV"
|
||||
"GLOB"
|
||||
"BCON"
|
||||
"FCNS"
|
||||
"PALT"
|
||||
"SPR#"
|
||||
"SPR2"
|
||||
"DGRP"
|
||||
"TMPL"
|
||||
"TRCN"
|
||||
"BHAV"
|
||||
"OBJf"
|
||||
"rsmp"
|
||||
;
|
||||
int (* const iff_parse_function[])(IFFChunk*, const uint8_t*) = {
|
||||
iff_parse_str, iff_parse_str, iff_parse_str, iff_parse_str, iff_parse_str,
|
||||
iff_parse_cats,
|
||||
iff_parse_c_string,
|
||||
iff_parse_glob,
|
||||
iff_parse_bcon,
|
||||
iff_parse_fcns,
|
||||
iff_parse_palt,
|
||||
iff_parse_spr,
|
||||
iff_parse_spr2,
|
||||
iff_parse_dgrp,
|
||||
iff_parse_tmpl,
|
||||
iff_parse_trcn,
|
||||
iff_parse_bhav,
|
||||
iff_parse_objf,
|
||||
iff_parse_rsmp
|
||||
};
|
||||
void (* const iff_free_function[])(void*) = {
|
||||
iff_free_str, iff_free_str, iff_free_str, iff_free_str, iff_free_str,
|
||||
iff_free_cats,
|
||||
NULL,
|
||||
NULL,
|
||||
iff_free_bcon,
|
||||
iff_free_fcns,
|
||||
NULL,
|
||||
iff_free_spr,
|
||||
iff_free_spr,
|
||||
iff_free_dgrp,
|
||||
iff_free_tmpl,
|
||||
iff_free_trcn,
|
||||
iff_free_bhav,
|
||||
iff_free_objf,
|
||||
iff_free_rsmp
|
||||
};
|
||||
/* End */
|
||||
|
||||
|
||||
/****
|
||||
** API public functions
|
||||
*/
|
||||
|
||||
int iff_create(IFFFile * IFFFileInfo)
|
||||
{
|
||||
memset(IFFFileInfo, 0, sizeof(IFFFile));
|
||||
|
||||
IFFFileInfo->Chunks = calloc(1, sizeof(IFFChunk));
|
||||
if(IFFFileInfo->Chunks == NULL)
|
||||
return 0;
|
||||
IFFFileInfo->SizeAllocated = sizeof(IFFChunk);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iff_read_header(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned FileSize)
|
||||
{
|
||||
unsigned offset;
|
||||
|
||||
if(!FileSize) FileSize = ~0;
|
||||
else if(FileSize < 64)
|
||||
return 0;
|
||||
|
||||
if(memcmp(Buffer, Header_IFF, 60))
|
||||
return 0;
|
||||
memcpy(IFFFileInfo->Header, Buffer, 60);
|
||||
|
||||
offset = read_uint32be(Buffer+60);
|
||||
if(offset > FileSize - 28)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
IFFChunk * iff_add_chunk(IFFFile * IFFFileInfo)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
return &IFFFileInfo->Chunks[IFFFileInfo->ChunkCount++];
|
||||
}
|
||||
|
||||
int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize)
|
||||
{
|
||||
if(MaxChunkSize == 0) MaxChunkSize = ~0;
|
||||
|
||||
if(MaxChunkSize < 76)
|
||||
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);
|
||||
memcpy(ChunkInfo->Label, Buffer+12, 64);
|
||||
|
||||
if(ChunkInfo->Size < 76 || ChunkInfo->Size > MaxChunkSize)
|
||||
return 0;
|
||||
|
||||
ChunkInfo->Size -= 76;
|
||||
|
||||
if(ChunkInfo->Size){
|
||||
ChunkInfo->Data = malloc(ChunkInfo->Size);
|
||||
if(ChunkInfo->Data == NULL)
|
||||
return 0;
|
||||
memcpy(ChunkInfo->Data, Buffer+76, ChunkInfo->Size);
|
||||
}
|
||||
ChunkInfo->FormattedData = NULL;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int iff_enumerate_chunks(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned BufferSize)
|
||||
{
|
||||
while(BufferSize){
|
||||
IFFChunk * chunk = iff_add_chunk(IFFFileInfo);
|
||||
if(chunk == NULL)
|
||||
return 0;
|
||||
if(!iff_read_chunk(chunk, Buffer, BufferSize))
|
||||
return 0;
|
||||
|
||||
Buffer += chunk->Size + 76;
|
||||
BufferSize -= chunk->Size + 76;
|
||||
}
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
IFFChunk * iff_find_chunk(IFFFile * IFFFileInfo, const char * Type, int ChunkID){
|
||||
unsigned i;
|
||||
for(i=0; i<IFFFileInfo->ChunkCount; i++){
|
||||
IFFChunk * Chunk = &IFFFileInfo->Chunks[i];
|
||||
if((Type == NULL || !strcmp(Chunk->Type, Type)) &&
|
||||
(ChunkID == -1 || Chunk->ChunkID == ChunkID))
|
||||
return Chunk;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void iff_free_chunk(IFFChunk * ChunkInfo){
|
||||
unsigned i;
|
||||
if(ChunkInfo == NULL || ChunkInfo->FormattedData == NULL) 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);
|
||||
ChunkInfo->FormattedData = NULL;
|
||||
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);
|
||||
}
|
||||
}
|
|
@ -1,365 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
iff.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef IFF_H
|
||||
#define IFF_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef read_uint32be
|
||||
#define read_int32be(x) (signed)(((x)[0]<<(8*3)) | ((x)[1]<<(8*2)) | ((x)[2]<<(8*1)) | ((x)[3]<<(8*0)))
|
||||
#define read_int24be(x) (signed)(((x)[0]<<(8*2)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*0)))
|
||||
#define read_int16be(x) (signed)(((x)[0]<<(8*1)) | ((x)[1]<<(8*0)))
|
||||
#define read_int8be(x) (signed)(((x)[0]<<(8*0)))
|
||||
#define read_int32le(x) (signed)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
|
||||
#define read_int24le(x) (signed)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)))
|
||||
#define read_int16le(x) (signed)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#define read_int8le(x) (signed)(((x)[0]<<(8*0)))
|
||||
#define read_uint32be(x) (unsigned)(((x)[0]<<(8*3)) | ((x)[1]<<(8*2)) | ((x)[2]<<(8*1)) | ((x)[3]<<(8*0)))
|
||||
#define read_uint24be(x) (unsigned)(((x)[0]<<(8*2)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*0)))
|
||||
#define read_uint16be(x) (unsigned)(((x)[0]<<(8*1)) | ((x)[1]<<(8*0)))
|
||||
#define read_uint8be(x) (unsigned)(((x)[0]<<(8*0)))
|
||||
#define read_uint32le(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)) | ((x)[3]<<(8*3)))
|
||||
#define read_uint24le(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)) | ((x)[2]<<(8*2)))
|
||||
#define read_uint16le(x) (unsigned)(((x)[0]<<(8*0)) | ((x)[1]<<(8*1)))
|
||||
#define read_uint8le(x) (unsigned)(((x)[0]<<(8*0)))
|
||||
#endif
|
||||
|
||||
/*
|
||||
** IFF file structs
|
||||
*/
|
||||
|
||||
typedef struct IFFChunk_s
|
||||
{
|
||||
char Type[5];
|
||||
uint32_t Size; /* After subtracting the 76-byte header */
|
||||
uint16_t ChunkID;
|
||||
uint16_t Flags;
|
||||
char Label[65];
|
||||
uint8_t * Data;
|
||||
void * FormattedData;
|
||||
} IFFChunk;
|
||||
|
||||
typedef struct IFFFile_s
|
||||
{
|
||||
uint8_t Header[64];
|
||||
|
||||
uint32_t ChunkCount;
|
||||
size_t SizeAllocated;
|
||||
IFFChunk * Chunks;
|
||||
IFFChunk * ResourceMap;
|
||||
} IFFFile;
|
||||
|
||||
static const uint8_t Header_IFF[] = "IFF FILE 2.5:TYPE FOLLOWED BY SIZE\0 JAMIE DOORNBOS & MAXIS 1";
|
||||
|
||||
/*
|
||||
** IFF chunk structs
|
||||
*/
|
||||
|
||||
/* BCON chunk */
|
||||
|
||||
typedef struct IFF_BCON_s
|
||||
{
|
||||
uint8_t ConstantCount;
|
||||
uint8_t Flags;
|
||||
uint16_t * Constants;
|
||||
} IFF_BCON;
|
||||
|
||||
/* BHAV chunk */
|
||||
|
||||
typedef struct IFFInstruction_s
|
||||
{
|
||||
uint16_t Opcode;
|
||||
uint8_t TDest;
|
||||
uint8_t FDest;
|
||||
uint8_t Operands[8];
|
||||
} IFFInstruction;
|
||||
|
||||
typedef struct IFFBehavior_s
|
||||
{
|
||||
uint16_t Version;
|
||||
uint32_t InstructionCount;
|
||||
uint8_t Type;
|
||||
uint8_t ArgumentCount;
|
||||
uint16_t LocalCount;
|
||||
uint16_t Flags;
|
||||
IFFInstruction * Instructions;
|
||||
} IFFBehavior;
|
||||
|
||||
/* DGRP chunk */
|
||||
|
||||
typedef struct IFFSpriteInfo_s
|
||||
{
|
||||
uint16_t Type;
|
||||
uint32_t ChunkID;
|
||||
uint32_t SpriteIndex;
|
||||
uint16_t Flags;
|
||||
int32_t SpriteX;
|
||||
int32_t SpriteY;
|
||||
float ObjectZ;
|
||||
float ObjectX;
|
||||
float ObjectY;
|
||||
} IFFSpriteInfo;
|
||||
|
||||
typedef struct IFFDrawAngle_s
|
||||
{
|
||||
uint16_t SpriteCount;
|
||||
uint32_t Direction;
|
||||
uint32_t Zoom;
|
||||
IFFSpriteInfo * SpriteInfo;
|
||||
} IFFDrawAngle;
|
||||
|
||||
typedef struct IFFDrawGroup_s
|
||||
{
|
||||
uint16_t Version;
|
||||
uint32_t AngleCount;
|
||||
IFFDrawAngle DrawAngles[12];
|
||||
} IFFDrawGroup;
|
||||
|
||||
enum IFFDrawDirection {
|
||||
IFFDIRECTION_NORTHEAST = 1,
|
||||
IFFDIRECTION_SOUTHEAST = 4,
|
||||
IFFDIRECTION_NORTHWEST = 16,
|
||||
IFFDIRECTION_SOUTHWEST = 64
|
||||
};
|
||||
|
||||
enum IFFDrawZoom {
|
||||
IFFZOOM_FAR = 1,
|
||||
IFFZOOM_MIDDLE,
|
||||
IFFZOOM_CLOSE
|
||||
};
|
||||
|
||||
/* FCNS chunk */
|
||||
|
||||
typedef struct IFFConstant_s
|
||||
{
|
||||
char * Name;
|
||||
float Value;
|
||||
char * Description;
|
||||
} IFFConstant;
|
||||
|
||||
typedef struct IFFConstantList_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint32_t Version;
|
||||
char MagicNumber[5];
|
||||
uint32_t ConstantCount;
|
||||
IFFConstant * Constants;
|
||||
} IFFConstantList;
|
||||
|
||||
/* OBJf chunk */
|
||||
|
||||
typedef struct IFFFunction_s
|
||||
{
|
||||
uint16_t ConditionID;
|
||||
uint16_t ActionID;
|
||||
} IFFFunction;
|
||||
|
||||
typedef struct IFFFunctionTable_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint32_t Version;
|
||||
char MagicNumber[5];
|
||||
uint32_t FunctionCount;
|
||||
IFFFunction * Functions;
|
||||
} IFFFunctionTable;
|
||||
|
||||
/* PALT chunk */
|
||||
|
||||
typedef struct IFFPalette_s
|
||||
{
|
||||
uint32_t Version;
|
||||
uint32_t ColorCount;
|
||||
uint32_t Reserved1;
|
||||
uint32_t Reserved2;
|
||||
uint8_t Data[256*3];
|
||||
} IFFPalette;
|
||||
|
||||
/* SPR#/SPR2 chunk */
|
||||
|
||||
typedef struct IFFSprite_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint16_t Height;
|
||||
uint16_t Width;
|
||||
uint32_t Flags;
|
||||
uint16_t PaletteID;
|
||||
uint16_t TransparentColor;
|
||||
int16_t YLoc;
|
||||
int16_t XLoc;
|
||||
uint8_t * IndexData;
|
||||
uint8_t * BGRA32Data;
|
||||
uint8_t * ZBuffer;
|
||||
|
||||
uint8_t InvalidDimensions;
|
||||
} IFFSprite;
|
||||
|
||||
typedef struct IFFSpriteList_s
|
||||
{
|
||||
uint32_t Version;
|
||||
uint32_t SpriteCount;
|
||||
uint32_t PaletteID;
|
||||
IFFSprite * Sprites;
|
||||
} IFFSpriteList;
|
||||
|
||||
enum IFFSpriteFlags {
|
||||
IFFSPRITE_FLAG_COLOR = 1,
|
||||
IFFSPRITE_FLAG_ZBUFFER = 2,
|
||||
IFFSPRITE_FLAG_ALPHA = 4
|
||||
};
|
||||
|
||||
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette);
|
||||
|
||||
/* STR# chunk */
|
||||
|
||||
enum IFFLanguage {
|
||||
IFFLANG_DEFAULT = 0,
|
||||
IFFLANG_EN_US = 1,
|
||||
IFFLANG_EN_INTERNATIONAL = 2,
|
||||
IFFLANG_FRENCH = 3,
|
||||
IFFLANG_GERMAN = 4,
|
||||
IFFLANG_ITALIAN = 5,
|
||||
IFFLANG_SPANISH = 6,
|
||||
IFFLANG_DUTCH = 7,
|
||||
IFFLANG_DANISH = 8,
|
||||
IFFLANG_SWEDISH = 9,
|
||||
IFFLANG_NORWEGIAN = 10,
|
||||
IFFLANG_FINNISH = 11,
|
||||
IFFLANG_HEBREW = 12,
|
||||
IFFLANG_RUSSIAN = 13,
|
||||
IFFLANG_PORTUGUESE = 14,
|
||||
IFFLANG_JAPANESE = 15,
|
||||
IFFLANG_POLISH = 16,
|
||||
IFFLANG_CHINESE_SIMPLIFIED = 17,
|
||||
IFFLANG_CHINESE_TRADITIONAL = 18,
|
||||
IFFLANG_THAI = 19,
|
||||
IFFLANG_KOREAN = 20
|
||||
};
|
||||
|
||||
typedef struct IFFStringPair_s
|
||||
{
|
||||
uint8_t LanguageSet;
|
||||
char * Key;
|
||||
char * Value;
|
||||
} IFFStringPair;
|
||||
|
||||
typedef struct IFFLanguageSet_s
|
||||
{
|
||||
uint16_t PairCount;
|
||||
IFFStringPair * Pairs;
|
||||
} IFFLanguageSet;
|
||||
|
||||
typedef struct IFF_STR_s
|
||||
{
|
||||
int16_t Format;
|
||||
IFFLanguageSet LanguageSets[20];
|
||||
} IFFString;
|
||||
|
||||
/* TMPL chunk */
|
||||
|
||||
typedef struct IFFTemplateField_s
|
||||
{
|
||||
char * Name;
|
||||
char Type[5];
|
||||
} IFFTemplateField;
|
||||
|
||||
typedef struct IFFTemplate_s
|
||||
{
|
||||
uint32_t FieldCount;
|
||||
IFFTemplateField * Fields;
|
||||
} IFFTemplate;
|
||||
|
||||
/* TRCN chunk */
|
||||
|
||||
typedef struct IFFRangeEntry_s
|
||||
{
|
||||
uint32_t IsUsed;
|
||||
uint32_t DefaultValue;
|
||||
char * Name;
|
||||
char * Comment;
|
||||
uint8_t Enforced;
|
||||
uint16_t RangeMin;
|
||||
uint16_t RangeMax;
|
||||
} IFFRangeEntry;
|
||||
|
||||
typedef struct IFFRangeSet_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint32_t Version;
|
||||
char MagicNumber[5];
|
||||
uint32_t RangeCount;
|
||||
IFFRangeEntry * Ranges;
|
||||
} IFFRangeSet;
|
||||
|
||||
/* rsmp chunk */
|
||||
|
||||
typedef struct IFFResource_s
|
||||
{
|
||||
uint32_t Offset;
|
||||
uint32_t ChunkID;
|
||||
uint16_t Flags;
|
||||
char * Label;
|
||||
} IFFResource;
|
||||
|
||||
typedef struct IFFResouceType_s
|
||||
{
|
||||
char Type[5];
|
||||
uint32_t ResourceCount;
|
||||
IFFResource * Resources;
|
||||
} IFFResourceType;
|
||||
|
||||
typedef struct IFFResourceMap_s
|
||||
{
|
||||
uint32_t Reserved;
|
||||
uint32_t Version;
|
||||
char MagicNumber[5];
|
||||
uint32_t IFFSize;
|
||||
uint32_t TypeCount;
|
||||
IFFResourceType * ResourceTypes;
|
||||
} IFFResourceMap;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/*
|
||||
** IFF file functions
|
||||
*/
|
||||
|
||||
int iff_create(IFFFile * IFFFileInfo);
|
||||
int iff_read_header(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned FileSize);
|
||||
|
||||
IFFChunk * iff_add_chunk(IFFFile * IFFFileInfo);
|
||||
int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize);
|
||||
int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer);
|
||||
int iff_enumerate_chunks(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned BufferSize);
|
||||
IFFChunk * iff_find_chunk(IFFFile * IFFFileInfo, const char * Type, int ChunkID);
|
||||
|
||||
void iff_free_chunk(IFFChunk * ChunkInfo);
|
||||
void iff_delete_chunk(IFFFile * IFFFileInfo, int Position);
|
||||
void iff_delete(IFFFile * IFFFileInfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,146 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
iffparser.h - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iff.h"
|
||||
|
||||
typedef struct {
|
||||
const uint8_t * Buffer;
|
||||
size_t Size;
|
||||
const uint8_t * StartPos;
|
||||
size_t TotalSize;
|
||||
uint8_t Endian; /* 0 = little, 1 = big */
|
||||
} bytestream;
|
||||
|
||||
static __inline void set_bytestream(bytestream * b, const uint8_t * Buffer, size_t Size){
|
||||
b->Buffer = Buffer;
|
||||
b->Size = Size;
|
||||
b->StartPos = Buffer;
|
||||
b->TotalSize = Size;
|
||||
b->Endian = 0;
|
||||
}
|
||||
|
||||
static __inline uint32_t read_uint32(bytestream * b){
|
||||
unsigned value = (b->Endian == 0) ? read_uint32le(b->Buffer) : read_uint32be(b->Buffer);
|
||||
b->Buffer += 4;
|
||||
b->Size -= 4;
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline uint16_t read_uint16(bytestream * b){
|
||||
unsigned value = (b->Endian == 0) ? read_uint16le(b->Buffer) : read_uint16be(b->Buffer);
|
||||
b->Buffer += 2;
|
||||
b->Size -= 2;
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline uint8_t read_uint8(bytestream * b){
|
||||
uint8_t value = b->Buffer[0];
|
||||
b->Buffer += 1;
|
||||
b->Size -= 1;
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline float read_float(bytestream *b){
|
||||
union { float f; uint32_t v; } value;
|
||||
value.v = read_uint32(b);
|
||||
return value.f;
|
||||
}
|
||||
|
||||
static __inline int skipbytes(bytestream * b, size_t bytes){
|
||||
if(b->Size < bytes) return 0;
|
||||
b->Buffer += bytes; b->Size -= bytes;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline int seekto(bytestream * b, size_t Position){
|
||||
if(Position > b->TotalSize) return 0;
|
||||
b->Buffer = b->StartPos + Position;
|
||||
b->Size = b->TotalSize - Position;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static __inline size_t read_c_string(bytestream * b, char ** dest){
|
||||
size_t length;
|
||||
for(length=0; length != b->Size && b->Buffer[length]; length++);
|
||||
if(length == b->Size) return 0;
|
||||
|
||||
if(length != 0){
|
||||
*dest = malloc(length+1);
|
||||
if(*dest == NULL) return 0;
|
||||
strcpy(*dest, (char*) b->Buffer);
|
||||
}
|
||||
|
||||
b->Buffer += length + 1;
|
||||
b->Size -= length + 1;
|
||||
return length + 1;
|
||||
}
|
||||
|
||||
static __inline size_t read_pascal_string(bytestream * b, char ** dest){
|
||||
size_t length;
|
||||
if(!b->Size) return 0;
|
||||
length = b->Buffer[0];
|
||||
if(length >= b->Size) return 0;
|
||||
|
||||
if(length > 0){
|
||||
*dest = malloc(length+1);
|
||||
if(*dest == NULL) return 0;
|
||||
memcpy(*dest, b->Buffer+1, length);
|
||||
(*dest)[length] = 0x00;
|
||||
}
|
||||
|
||||
b->Buffer += 1 + length;
|
||||
b->Size -= 1 + length;
|
||||
return 1 + length;
|
||||
}
|
||||
|
||||
static __inline size_t read_pascal2_string(bytestream * b, char ** dest){
|
||||
size_t length;
|
||||
int countbytes = 1;
|
||||
if(!b->Size) return 0;
|
||||
length = b->Buffer[0];
|
||||
|
||||
if(length > 127){
|
||||
/* 2-byte length */
|
||||
if(b->Size == 1) return 0;
|
||||
length = (length&127) | (b->Buffer[1]<<7);
|
||||
countbytes++;
|
||||
}
|
||||
|
||||
if(countbytes+length > b->Size) return 0;
|
||||
|
||||
if(length != 0){
|
||||
*dest = malloc(length+1);
|
||||
if(*dest == NULL) return 0;
|
||||
memcpy(*dest, b->Buffer+countbytes, length);
|
||||
(*dest)[length] = 0x00;
|
||||
}
|
||||
|
||||
b->Buffer += countbytes + length;
|
||||
b->Size -= countbytes + length;
|
||||
return countbytes + length;
|
||||
}
|
||||
|
||||
static __inline size_t skip_padding(bytestream * b){
|
||||
size_t padding = 0;
|
||||
while(b->Size && b->Buffer[0] == 0xA3){
|
||||
padding++;
|
||||
b->Buffer++;
|
||||
b->Size--;
|
||||
}
|
||||
return padding;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
objf.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_objf(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFFunctionTable *Table;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 16)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFFunctionTable));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Table = ChunkInfo->FormattedData;
|
||||
Table->Reserved = read_uint32le(Buffer);
|
||||
Table->Version = read_uint32le(Buffer+4);
|
||||
memcpy(Table->MagicNumber, Buffer+8, 4);
|
||||
Table->MagicNumber[4] = 0x00;
|
||||
Table->FunctionCount = read_uint32le(Buffer+12);
|
||||
if(Table->Reserved != 0 || Table->Version != 0)
|
||||
return 0;
|
||||
if(Table->FunctionCount == 0)
|
||||
return 1;
|
||||
if(Table->FunctionCount > (ChunkInfo->Size - 16)/4)
|
||||
return 0;
|
||||
|
||||
Table->Functions = malloc(Table->FunctionCount * sizeof(IFFFunction));
|
||||
if(Table->Functions == NULL)
|
||||
return 0;
|
||||
|
||||
Buffer += 16;
|
||||
for(i=0; i<Table->FunctionCount; i++, Buffer += 4){
|
||||
Table->Functions[i].ConditionID = read_uint16le(Buffer);
|
||||
Table->Functions[i].ActionID = read_uint16le(Buffer+2);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_objf(void * FormattedData){
|
||||
IFFFunctionTable *Table = FormattedData;
|
||||
free(Table->Functions);
|
||||
}
|
|
@ -1,41 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
palt.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_palt(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFPalette *Palette;
|
||||
|
||||
if(ChunkInfo->Size < 16)
|
||||
return 0;
|
||||
ChunkInfo->FormattedData = malloc(sizeof(IFFPalette));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Palette = ChunkInfo->FormattedData;
|
||||
Palette->Version = read_uint32le(Buffer);
|
||||
Palette->ColorCount = read_uint32le(Buffer+4);
|
||||
Palette->Reserved1 = read_uint32le(Buffer+8);
|
||||
Palette->Reserved2 = read_uint32le(Buffer+12);
|
||||
if(Palette->Version != 1 || Palette->ColorCount == 0 || Palette->ColorCount > 256 ||
|
||||
Palette->Reserved1 != 0 || Palette->Reserved2 != 0 || Palette->ColorCount*3 > ChunkInfo->Size-16)
|
||||
return 0;
|
||||
|
||||
memcpy(Palette->Data, Buffer+16, Palette->ColorCount*3);
|
||||
return 1;
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
rsmp.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_rsmp(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFResourceMap *Map;
|
||||
bytestream b;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 20)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFResourceMap));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Map = ChunkInfo->FormattedData;
|
||||
Map->Reserved = read_uint32(&b);
|
||||
Map->Version = read_uint32(&b);
|
||||
memcpy(Map->MagicNumber, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
Map->IFFSize = read_uint32(&b);
|
||||
Map->TypeCount = read_uint32(&b);
|
||||
if(Map->Reserved != 0 || Map->Version > 1)
|
||||
return 0;
|
||||
|
||||
Map->ResourceTypes = calloc(Map->TypeCount, sizeof(IFFResourceType));
|
||||
if(Map->ResourceTypes == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<Map->TypeCount; i++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[i];
|
||||
unsigned j;
|
||||
if(b.Size < 8) return 0;
|
||||
|
||||
memcpy(Type->Type, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
Type->ResourceCount = read_uint32(&b);
|
||||
Type->Resources = calloc(Type->ResourceCount, sizeof(IFFResource));
|
||||
if(Type->Resources == NULL)
|
||||
return 0;
|
||||
|
||||
for(j=0; j<Type->ResourceCount; j++){
|
||||
IFFResource * Resource = &Type->Resources[j];
|
||||
if(b.Size < ((Map->Version == 0) ? 9 : 11)) return 0;
|
||||
Resource->Offset = read_uint32(&b);
|
||||
Resource->ChunkID = (Map->Version == 0) ? read_uint16(&b) : read_uint32(&b);
|
||||
Resource->Flags = read_uint16(&b);
|
||||
|
||||
if(Map->Version == 0){
|
||||
if(!read_c_string(&b, &Resource->Label))
|
||||
return 0;
|
||||
}else{
|
||||
if(!read_pascal_string(&b, &Resource->Label))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_rsmp(void * FormattedData){
|
||||
IFFResourceMap * Map = FormattedData;
|
||||
if(Map->ResourceTypes){
|
||||
unsigned t;
|
||||
for(t=0; t<Map->TypeCount; t++){
|
||||
IFFResourceType * Type = &Map->ResourceTypes[t];
|
||||
if(Type->Resources){
|
||||
unsigned r;
|
||||
for(r=0; r<Type->ResourceCount; r++)
|
||||
free(Type->Resources[r].Label);
|
||||
free(Type->Resources);
|
||||
}
|
||||
}
|
||||
free(Map->ResourceTypes);
|
||||
}
|
||||
}
|
|
@ -1,221 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
spr.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_spr(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFSpriteList *SpriteList;
|
||||
bytestream b;
|
||||
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 12)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
|
||||
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
SpriteList = ChunkInfo->FormattedData;
|
||||
SpriteList->Version = read_uint32(&b);
|
||||
SpriteList->SpriteCount = read_uint32(&b);
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
if(SpriteList->Version < 502 || (SpriteList->Version > 505 && SpriteList->Version != 1001))
|
||||
return 0;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
if(SpriteList->SpriteCount > b.Size/4)
|
||||
return 0;
|
||||
}else{
|
||||
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
|
||||
** this is easy with the sprite size field */
|
||||
for(SpriteList->SpriteCount = 0; b.Size >= 16; SpriteList->SpriteCount++){
|
||||
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
|
||||
return 0;
|
||||
}
|
||||
NextSpriteOffset = 16;
|
||||
}
|
||||
|
||||
if(SpriteList->SpriteCount == 0)
|
||||
return 1;
|
||||
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
|
||||
if(SpriteList->Sprites == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
unsigned SpriteSize;
|
||||
unsigned row = 0;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
/* Jump to the next sprite using the offset table; this is mandatory */
|
||||
seekto(&b, 12 + 4*i);
|
||||
if(!seekto(&b, read_uint32(&b)) || b.Size < 8)
|
||||
return 0;
|
||||
SpriteSize = b.Size;
|
||||
}else{
|
||||
/* Jump to the next sprite using the sprite size field; this is mandatory */
|
||||
seekto(&b, NextSpriteOffset);
|
||||
SpriteSize = read_uint32(&b);
|
||||
NextSpriteOffset += SpriteSize + 8;
|
||||
}
|
||||
|
||||
Sprite->Reserved = read_uint32(&b);
|
||||
Sprite->Height = read_uint16(&b);
|
||||
Sprite->Width = read_uint16(&b);
|
||||
if(Sprite->Reserved != 0 || Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
|
||||
/* This happens in the third sprite of every SPR# chunk in sprites.iff */
|
||||
Sprite->InvalidDimensions = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
SpriteSize -= 8;
|
||||
|
||||
Sprite->IndexData = calloc(Sprite->Width*Sprite->Height, 2);
|
||||
if(Sprite->IndexData == NULL)
|
||||
return 0;
|
||||
|
||||
while(1){
|
||||
/****
|
||||
** Row command: valid commands are 0, 4, 5, 9, and 16
|
||||
*/
|
||||
|
||||
uint8_t RowCommand, RowCount;
|
||||
|
||||
if(SpriteSize < 2)
|
||||
return 0;
|
||||
RowCommand = *(b.Buffer++);
|
||||
RowCount = *(b.Buffer++);
|
||||
SpriteSize -= 2;
|
||||
|
||||
if(RowCommand == 0 || RowCommand == 16){
|
||||
/* Start marker */
|
||||
}else if(RowCommand == 4){
|
||||
/****
|
||||
** Pixel command: valid commands are 1, 2, and 3
|
||||
*/
|
||||
|
||||
unsigned pixel = 0;
|
||||
|
||||
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
|
||||
return 0;
|
||||
SpriteSize -= RowCount;
|
||||
|
||||
while(RowCount){
|
||||
uint8_t PixelCommand, PixelCount;
|
||||
uint8_t * IndexData;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PixelCommand = *(b.Buffer++);
|
||||
PixelCount = *(b.Buffer++);
|
||||
RowCount -= 2;
|
||||
|
||||
if(PixelCount > Sprite->Width - pixel)
|
||||
return 0;
|
||||
|
||||
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
|
||||
pixel += PixelCount;
|
||||
|
||||
if(PixelCommand == 1){
|
||||
/* Leave next n pixels as transparent */
|
||||
}else if(PixelCommand == 2){
|
||||
/* Set next n pixels to shared palette index */
|
||||
|
||||
uint8_t PaletteIndex;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PaletteIndex = *(b.Buffer++);
|
||||
b.Buffer++; /* Padding byte */
|
||||
RowCount -= 2;
|
||||
|
||||
while(PixelCount--){
|
||||
*IndexData++ = PaletteIndex;
|
||||
*IndexData++ = 0xFF;
|
||||
}
|
||||
}else if(PixelCommand == 3){
|
||||
/* Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(PixelCount + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
*IndexData++ = 0xFF;
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
}else return 0;
|
||||
}
|
||||
row++;
|
||||
}else if(RowCommand == 5){
|
||||
/* End marker */
|
||||
break;
|
||||
}else if(RowCommand == 9){
|
||||
/* Leave rows as transparent */
|
||||
|
||||
if(RowCount > Sprite->Height - row)
|
||||
return 0;
|
||||
row += RowCount;
|
||||
}else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_spr(void * FormattedData){
|
||||
IFFSpriteList *SpriteList = FormattedData;
|
||||
if(SpriteList->Sprites){
|
||||
unsigned s;
|
||||
for(s=0; s<SpriteList->SpriteCount; s++){
|
||||
IFFSprite *Sprite = &SpriteList->Sprites[s];
|
||||
free(Sprite->IndexData);
|
||||
free(Sprite->BGRA32Data);
|
||||
free(Sprite->ZBuffer);
|
||||
}
|
||||
free(SpriteList->Sprites);
|
||||
}
|
||||
}
|
||||
|
||||
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette){
|
||||
unsigned PixelCount = Sprite->Width*Sprite->Height;
|
||||
unsigned i;
|
||||
|
||||
Sprite->BGRA32Data = malloc(PixelCount*4);
|
||||
if(Sprite->BGRA32Data == NULL) return 0;
|
||||
|
||||
for(i=0; i<PixelCount; i++){
|
||||
uint8_t Index = Sprite->IndexData[2*i + 0];
|
||||
if(Index >= Palette->ColorCount){
|
||||
free(Sprite->BGRA32Data);
|
||||
Sprite->BGRA32Data = NULL;
|
||||
return 0;
|
||||
}
|
||||
Sprite->BGRA32Data[4*i + 0] = Palette->Data[3*Index + 2];
|
||||
Sprite->BGRA32Data[4*i + 1] = Palette->Data[3*Index + 1];
|
||||
Sprite->BGRA32Data[4*i + 2] = Palette->Data[3*Index + 0];
|
||||
Sprite->BGRA32Data[4*i + 3] = Sprite->IndexData[2*i + 1];
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,227 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
spr2.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_spr2(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFSpriteList *SpriteList;
|
||||
bytestream b;
|
||||
unsigned NextSpriteOffset; /* Used for Version 1001 in place of the offset table */
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 12)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
if((Buffer[0]|Buffer[1]) == 0) b.Endian++; /* Big endian */
|
||||
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFSpriteList));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
SpriteList = ChunkInfo->FormattedData;
|
||||
SpriteList->Version = read_uint32(&b);
|
||||
if(SpriteList->Version != 1000 && SpriteList->Version != 1001)
|
||||
return 0;
|
||||
|
||||
if(SpriteList->Version == 1000){
|
||||
SpriteList->SpriteCount = read_uint32(&b);
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
if(SpriteList->SpriteCount > b.Size/4)
|
||||
return 0;
|
||||
}else{
|
||||
SpriteList->PaletteID = read_uint32(&b);
|
||||
skipbytes(&b, 4);
|
||||
|
||||
/* Sprite count is blank in version 1001, so we must walk and count up the sprites ourselves;
|
||||
** this is easy with the sprite size field */
|
||||
for(SpriteList->SpriteCount = 0; b.Size >= 24; SpriteList->SpriteCount++){
|
||||
if(read_uint32(&b) != 1001 || !skipbytes(&b, read_uint32(&b)))
|
||||
return 0;
|
||||
}
|
||||
NextSpriteOffset = 16;
|
||||
}
|
||||
|
||||
if(SpriteList->SpriteCount == 0)
|
||||
return 1;
|
||||
SpriteList->Sprites = calloc(SpriteList->SpriteCount, sizeof(IFFSprite));
|
||||
if(SpriteList->Sprites == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<SpriteList->SpriteCount; i++){
|
||||
IFFSprite * Sprite = &SpriteList->Sprites[i];
|
||||
unsigned SpriteSize;
|
||||
unsigned row = 0;
|
||||
int j;
|
||||
|
||||
if(SpriteList->Version != 1001){
|
||||
/* Jump to the next sprite using the offset table; this is mandatory */
|
||||
seekto(&b, 12 + 4*i);
|
||||
if(!seekto(&b, read_uint32(&b)) || b.Size < 16)
|
||||
return 0;
|
||||
SpriteSize = b.Size;
|
||||
}else{
|
||||
/* Jump to the next sprite using the sprite size field; this is mandatory */
|
||||
seekto(&b, NextSpriteOffset);
|
||||
SpriteSize = read_uint32(&b);
|
||||
NextSpriteOffset += SpriteSize + 8;
|
||||
}
|
||||
|
||||
Sprite->Width = read_uint16(&b);
|
||||
Sprite->Height = read_uint16(&b);
|
||||
Sprite->Flags = read_uint32(&b);
|
||||
Sprite->PaletteID = read_uint16(&b);
|
||||
Sprite->TransparentColor = read_uint16(&b);
|
||||
Sprite->YLoc = read_uint16(&b);
|
||||
Sprite->XLoc = read_uint16(&b);
|
||||
if((Sprite->Flags != 1 && Sprite->Flags != 3 && Sprite->Flags != 7) || Sprite->TransparentColor >= 256)
|
||||
return 0;
|
||||
if(Sprite->Height == 0 || Sprite->Width == 0 || Sprite->Height > UINT_MAX/2/Sprite->Width){
|
||||
/* This happens in the many chunks in 2personportal.spf */
|
||||
Sprite->InvalidDimensions = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
SpriteSize -= 16;
|
||||
|
||||
Sprite->IndexData = malloc(Sprite->Width*Sprite->Height*2);
|
||||
if(Sprite->IndexData == NULL)
|
||||
return 0;
|
||||
for(j=0; j<Sprite->Width*Sprite->Height; j++){
|
||||
Sprite->IndexData[2*j + 0] = Sprite->TransparentColor;
|
||||
Sprite->IndexData[2*j + 1] = 0x00;
|
||||
}
|
||||
|
||||
if(Sprite->Flags >= 3){ /* Has the Z-Buffer flag */
|
||||
Sprite->ZBuffer = malloc(Sprite->Width*Sprite->Height);
|
||||
if(Sprite->ZBuffer == NULL)
|
||||
return 0;
|
||||
memset(Sprite->ZBuffer, 0xFF, Sprite->Width*Sprite->Height);
|
||||
}
|
||||
|
||||
while(1){
|
||||
/****
|
||||
** Row command: valid commands are 0, 4, and 5
|
||||
*/
|
||||
|
||||
uint8_t RowCommand; /* 3 bits */
|
||||
uint16_t RowCount; /* 13 bits */
|
||||
|
||||
if(SpriteSize < 2)
|
||||
return 0;
|
||||
RowCount = read_uint16le(b.Buffer);
|
||||
RowCommand = RowCount >> 13;
|
||||
RowCount &= 0x1FFF;
|
||||
|
||||
b.Buffer += 2;
|
||||
SpriteSize -= 2;
|
||||
|
||||
if(RowCommand == 0){
|
||||
/****
|
||||
** Pixel command: valid commands are 1, 2, 3, and 6
|
||||
*/
|
||||
|
||||
unsigned pixel = 0;
|
||||
|
||||
if(row == Sprite->Height || RowCount < 2 || (RowCount -= 2) > SpriteSize || RowCount%2 != 0)
|
||||
return 0;
|
||||
SpriteSize -= RowCount;
|
||||
|
||||
while(RowCount){
|
||||
uint8_t PixelCommand; /* 3 bits */
|
||||
uint16_t PixelCount; /* 13 bits */
|
||||
uint8_t * IndexData, * ZBuffer;
|
||||
if(RowCount < 2)
|
||||
return 0;
|
||||
|
||||
PixelCount = read_uint16le(b.Buffer);
|
||||
PixelCommand = PixelCount >> 13;
|
||||
PixelCount &= 0x1FFF;
|
||||
|
||||
b.Buffer += 2;
|
||||
RowCount -= 2;
|
||||
|
||||
if(PixelCount > Sprite->Width - pixel)
|
||||
return 0;
|
||||
|
||||
IndexData = Sprite->IndexData + (Sprite->Width*row + pixel)*2;
|
||||
ZBuffer = Sprite->ZBuffer + (Sprite->Width*row + pixel)*1;
|
||||
pixel += PixelCount;
|
||||
|
||||
if(PixelCommand == 1){
|
||||
/* color+z-buffer: Set next n pixels to n palette indices */
|
||||
|
||||
if(Sprite->Flags < 3 || PixelCount*2 > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount*2;
|
||||
|
||||
while(PixelCount--){
|
||||
*ZBuffer++ = *(b.Buffer++);
|
||||
IndexData[0] = *(b.Buffer++);
|
||||
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
|
||||
IndexData += 2;
|
||||
}
|
||||
}else if(PixelCommand == 2){
|
||||
/* color+z-buffer+alpha: Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(Sprite->Flags < 7 || PixelCount*3 + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount*3 + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
*ZBuffer++ = *(b.Buffer++);
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
*IndexData++ = *(b.Buffer++);
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
}else if(PixelCommand == 3){
|
||||
/* Leave next n pixels as transparent */
|
||||
}else if(PixelCommand == 6){
|
||||
/* color: Set next n pixels to n palette indices */
|
||||
|
||||
int padding = PixelCount%2;
|
||||
if(PixelCount + padding > RowCount)
|
||||
return 0;
|
||||
RowCount -= PixelCount + padding;
|
||||
|
||||
while(PixelCount--){
|
||||
IndexData[0] = *(b.Buffer++);
|
||||
IndexData[1] = (IndexData[0] != Sprite->TransparentColor) ? 0xFF : 0x00;
|
||||
if(Sprite->Flags >= 3)
|
||||
*ZBuffer++ = (IndexData[0] != Sprite->TransparentColor) ? 0x00 : 0xFF;
|
||||
IndexData += 2;
|
||||
}
|
||||
if(padding) b.Buffer++; /* Padding byte */
|
||||
} else return 0;
|
||||
}
|
||||
row++;
|
||||
}else if(RowCommand == 4){
|
||||
/* Leave rows as transparent */
|
||||
|
||||
if(RowCount > Sprite->Height - row)
|
||||
return 0;
|
||||
row += RowCount;
|
||||
}else if(RowCommand == 5){
|
||||
/* End marker */
|
||||
break;
|
||||
}else return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
|
@ -1,159 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
str.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_str(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFString * StringData;
|
||||
bytestream b;
|
||||
|
||||
if(ChunkInfo->Size < 2)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFString));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
StringData = ChunkInfo->FormattedData;
|
||||
StringData->Format = read_uint16(&b);
|
||||
if(b.Size < 2) /* TSO allows this; as seen in the animations chunk in personglobals.iff */
|
||||
return 1;
|
||||
|
||||
if(StringData->Format < -4 || StringData->Format > 0){
|
||||
/* Seen often in The Sims 1's Behavior.iff */
|
||||
StringData->Format = 0;
|
||||
seekto(&b, 0);
|
||||
b.Endian++;
|
||||
}
|
||||
|
||||
if(StringData->Format != -3){
|
||||
unsigned LanguageSetCount = 1;
|
||||
unsigned ls;
|
||||
|
||||
if(StringData->Format == -4){
|
||||
LanguageSetCount = read_uint8(&b);
|
||||
if(LanguageSetCount > 20) return 0;
|
||||
}
|
||||
|
||||
for(ls=0; ls<LanguageSetCount; ls++){
|
||||
IFFLanguageSet * LanguageSet = &StringData->LanguageSets[ls];
|
||||
unsigned p;
|
||||
|
||||
if(b.Size < 2) return 0;
|
||||
LanguageSet->PairCount = read_uint16(&b);
|
||||
if(LanguageSet->PairCount == 0)
|
||||
continue;
|
||||
|
||||
LanguageSet->Pairs = calloc(LanguageSet->PairCount, sizeof(IFFStringPair));
|
||||
if(LanguageSet->Pairs == NULL)
|
||||
return 0;
|
||||
|
||||
for(p=0; p<LanguageSet->PairCount; p++){
|
||||
IFFStringPair * Pair = &LanguageSet->Pairs[p];
|
||||
if(StringData->Format == 0){
|
||||
if(!read_pascal_string(&b, &Pair->Key))
|
||||
return 0;
|
||||
}else if(StringData->Format >=-2){
|
||||
if(!read_c_string(&b, &Pair->Key))
|
||||
return 0;
|
||||
if(StringData->Format == -2 && !read_c_string(&b, &Pair->Value))
|
||||
return 0;
|
||||
}else{
|
||||
if(!b.Size || read_uint8(&b) != ls)
|
||||
return 0;
|
||||
if(!read_pascal2_string(&b, &Pair->Key) || !read_pascal2_string(&b, &Pair->Value))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}else{
|
||||
/* FD FF requires a lot of extra work -- and isn't even found in TSO */
|
||||
IFFLanguageSet * LanguageSet = StringData->LanguageSets;
|
||||
unsigned TotalPairCount;
|
||||
unsigned Index[20] = {0};
|
||||
unsigned i;
|
||||
|
||||
TotalPairCount = read_uint16(&b);
|
||||
if(TotalPairCount == 0)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
** Scan through the chunk to count up the number of pairs in each LanguageSet,
|
||||
** and then allocate exactly that much and fill in the data on the second pass
|
||||
*/
|
||||
|
||||
/* 1st pass */
|
||||
for(i=0; i<TotalPairCount; i++){
|
||||
unsigned lang, s;
|
||||
if(b.Size == 0) return 0;
|
||||
lang = read_uint8(&b) - 1;
|
||||
if(lang >= 20) return 0;
|
||||
LanguageSet[lang].PairCount++;
|
||||
|
||||
for(s=0; s<2; s++){
|
||||
unsigned length;
|
||||
for(length=0; length != b.Size && b.Buffer[length]; length++);
|
||||
if(length == b.Size) return 0;
|
||||
skipbytes(&b, length+1);
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<20; i++){
|
||||
LanguageSet[i].Pairs = calloc(LanguageSet[i].PairCount, sizeof(IFFStringPair));
|
||||
if(LanguageSet[i].Pairs == NULL) return 0;
|
||||
}
|
||||
|
||||
/* 2nd pass */
|
||||
set_bytestream(&b, Buffer+4, ChunkInfo->Size-4);
|
||||
for(i=0; i<TotalPairCount; i++){
|
||||
IFFStringPair * Pair;
|
||||
unsigned lang;
|
||||
lang = read_uint8(&b) - 1;
|
||||
Pair = &LanguageSet[lang].Pairs[Index[lang]++];
|
||||
|
||||
if(!read_c_string(&b, &Pair->Key) || !read_c_string(&b, &Pair->Value))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_str(void * FormattedData){
|
||||
/*
|
||||
** Requirements:
|
||||
** - PairCount and Pairs must be initialized for all 20 LanguageSets
|
||||
** - If the Pairs pointer is nonzero, there must be PairCount initialized pairs in Pairs
|
||||
*/
|
||||
|
||||
IFFString * StringData = FormattedData;
|
||||
unsigned ls;
|
||||
|
||||
for(ls=0; ls<20; ls++){
|
||||
IFFLanguageSet * LanguageSet = &StringData->LanguageSets[ls];
|
||||
if(LanguageSet->Pairs){
|
||||
unsigned p;
|
||||
for(p=0; p<LanguageSet->PairCount; p++){
|
||||
free(LanguageSet->Pairs[p].Key);
|
||||
free(LanguageSet->Pairs[p].Value);
|
||||
}
|
||||
free(LanguageSet->Pairs);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,25 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
string.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_c_string(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
bytestream b;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
return (read_c_string(&b, (char**) &ChunkInfo->FormattedData) != 0);
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
tmpl.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_tmpl(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFTemplate *Template;
|
||||
bytestream b;
|
||||
const uint8_t * ptr = Buffer;
|
||||
unsigned Size = ChunkInfo->Size;
|
||||
unsigned FieldCount;
|
||||
unsigned i;
|
||||
if(Size == 0) return 1;
|
||||
|
||||
/* Walk through a first-pass to find the total field count */
|
||||
for(FieldCount=0; Size; FieldCount++){
|
||||
unsigned length = *ptr;
|
||||
if(Size < 5 || length > Size-5)
|
||||
return 0;
|
||||
ptr += length+5; Size -= length+5;
|
||||
}
|
||||
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFTemplate));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
Template = ChunkInfo->FormattedData;
|
||||
Template->FieldCount = FieldCount;
|
||||
Template->Fields = calloc(FieldCount, sizeof(IFFTemplateField));
|
||||
if(Template->Fields == NULL)
|
||||
return 0;
|
||||
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
|
||||
for(i=0; i<FieldCount; i++){
|
||||
IFFTemplateField * Field = &Template->Fields[i];
|
||||
if(!read_pascal_string(&b, &Field->Name))
|
||||
return 0;
|
||||
|
||||
memcpy(Field->Type, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_tmpl(void * FormattedData){
|
||||
IFFTemplate * Template = FormattedData;
|
||||
if(Template->Fields){
|
||||
unsigned f;
|
||||
for(f=0; f<Template->FieldCount; f++)
|
||||
free(Template->Fields[f].Name);
|
||||
free(Template->Fields);
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
/*
|
||||
FileHandler - General-purpose file handling library for Niotso
|
||||
trcn.c - Copyright (c) 2012 Niotso Project <http://niotso.org/>
|
||||
Author(s): Ahmed El-Mahdawy <aa.mahdawy.10@gmail.com>
|
||||
Fatbag <X-Fi6@phppoll.org>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "iffparser.h"
|
||||
|
||||
int iff_parse_trcn(IFFChunk * ChunkInfo, const uint8_t * Buffer){
|
||||
IFFRangeSet *RangeSet;
|
||||
bytestream b;
|
||||
unsigned i;
|
||||
|
||||
if(ChunkInfo->Size < 16)
|
||||
return 0;
|
||||
set_bytestream(&b, Buffer, ChunkInfo->Size);
|
||||
ChunkInfo->FormattedData = calloc(1, sizeof(IFFRangeSet));
|
||||
if(ChunkInfo->FormattedData == NULL)
|
||||
return 0;
|
||||
|
||||
RangeSet = ChunkInfo->FormattedData;
|
||||
RangeSet->Reserved = read_uint32(&b);
|
||||
RangeSet->Version = read_uint32(&b);
|
||||
memcpy(RangeSet->MagicNumber, b.Buffer, 4);
|
||||
skipbytes(&b, 4);
|
||||
RangeSet->RangeCount = read_uint32(&b);
|
||||
if(RangeSet->Reserved != 0 || RangeSet->Version > 2)
|
||||
return 0;
|
||||
if(RangeSet->RangeCount == 0)
|
||||
return 1;
|
||||
|
||||
RangeSet->Ranges = calloc(RangeSet->RangeCount, sizeof(IFFRangeEntry));
|
||||
if(RangeSet->Ranges == NULL)
|
||||
return 0;
|
||||
|
||||
for(i=0; i<RangeSet->RangeCount; i++){
|
||||
unsigned s;
|
||||
IFFRangeEntry * Range = &RangeSet->Ranges[i];
|
||||
if(b.Size < 10)
|
||||
return 0;
|
||||
|
||||
Range->IsUsed = read_uint32(&b);
|
||||
Range->DefaultValue = read_uint32(&b);
|
||||
|
||||
for(s=0; s<2; s++){
|
||||
char ** string = (s==0) ? &Range->Name : &Range->Comment;
|
||||
if(b.Size == 0) return 0;
|
||||
|
||||
if(RangeSet->Version < 2){
|
||||
/* C string, possible padding */
|
||||
if(!read_c_string(&b, string))
|
||||
return 0;
|
||||
|
||||
/* Skip past the 0xA3 character;
|
||||
** see global.iff chunk 546 for why you can't do modulo-2 to detect this */
|
||||
if(b.Size && *b.Buffer == 0xA3)
|
||||
skipbytes(&b, 1);
|
||||
}else{
|
||||
/* Extended Pascal string, no padding */
|
||||
if(!read_pascal2_string(&b, string))
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(RangeSet->Version != 0){
|
||||
if(b.Size < 5) return 0;
|
||||
Range->Enforced = read_uint8(&b);
|
||||
Range->RangeMin = read_uint16(&b);
|
||||
Range->RangeMax = read_uint16(&b);
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void iff_free_trcn(void * FormattedData){
|
||||
IFFRangeSet *RangeSet = FormattedData;
|
||||
if(RangeSet->Ranges){
|
||||
unsigned i;
|
||||
for(i=0; i<RangeSet->RangeCount; i++){
|
||||
IFFRangeEntry *Entry = &RangeSet->Ranges[i];
|
||||
free(Entry->Name);
|
||||
free(Entry->Comment);
|
||||
}
|
||||
}
|
||||
free(RangeSet->Ranges);
|
||||
}
|
|
@ -14,4 +14,5 @@
|
|||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
*/
|
||||
#include "uis.h"
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
enum UISTagType {
|
||||
typedef enum UISTagType {
|
||||
UIS_Type_Button,
|
||||
UIS_Type_FormattedText,
|
||||
UIS_Type_ListBox,
|
||||
|
@ -27,8 +27,8 @@ enum UISTagType {
|
|||
UIS_Type_Image,
|
||||
UIS_Type_String,
|
||||
UIS_Type_Custom
|
||||
};
|
||||
} UISTagType;
|
||||
|
||||
typedef struct {
|
||||
UISTagType TagType;
|
||||
} UISTag;
|
||||
} UISTag;
|
||||
|
|
Loading…
Add table
Reference in a new issue