* Updated libpng and zlib

* Added SPR# parsing to the iff library
* iff2html now displays BMP_/FBMP, PALT, and SPR# chunks
This commit is contained in:
Fatbag 2012-05-28 23:37:38 -05:00
parent 78f1ca1d6f
commit 1f7061d98a
10 changed files with 219 additions and 41 deletions

View file

@ -16,6 +16,7 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <stdlib.h>
#include <stdint.h> #include <stdint.h>
#include <string.h> #include <string.h>
#include "read_bmp.h" #include "read_bmp.h"
@ -33,6 +34,7 @@
#endif #endif
int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t FileSize){ int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t FileSize){
unsigned padding;
if(FileSize < 54) return 0; if(FileSize < 54) return 0;
BMPHeader->bfType = read_uint16(Buffer); BMPHeader->bfType = read_uint16(Buffer);
BMPHeader->bfSize = read_uint32(Buffer+2); BMPHeader->bfSize = read_uint32(Buffer+2);
@ -52,25 +54,27 @@ int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t File
BMPHeader->biClrUsed = read_uint32(Buffer+46); BMPHeader->biClrUsed = read_uint32(Buffer+46);
BMPHeader->biClrImportant = read_uint32(Buffer+50); BMPHeader->biClrImportant = read_uint32(Buffer+50);
BMPHeader->CompressedSize = FileSize - BMPHeader->bfOffBits; if(BMPHeader->bfSize == 0) BMPHeader->bfSize = FileSize;
BMPHeader->CompressedSize = BMPHeader->bfSize - BMPHeader->bfOffBits;
BMPHeader->DecompressedSize = BMPHeader->biWidth * BMPHeader->biHeight * 3; BMPHeader->DecompressedSize = BMPHeader->biWidth * BMPHeader->biHeight * 3;
padding = BMPHeader->biWidth%4;
if(padding != 0) padding = (BMPHeader->biHeight-1)*(4-padding);
if(BMPHeader->bfType != 0x4D42 || if(BMPHeader->bfType != 0x4D42 ||
BMPHeader->bfSize != FileSize || BMPHeader->bfSize > FileSize ||
BMPHeader->bfReserved1 != 0 || BMPHeader->bfReserved2 != 0 || BMPHeader->bfReserved1 != 0 || BMPHeader->bfReserved2 != 0 ||
BMPHeader->biSize != 40 || BMPHeader->biSize != 40 ||
BMPHeader->biWidth == 0 || BMPHeader->biWidth > 4096 || /*< Includes negative check */ BMPHeader->biWidth == 0 || BMPHeader->biWidth > 4096 || /*< Includes negative check */
BMPHeader->biHeight == 0 || BMPHeader->biHeight > 4096 || /*< by treating as unsigned */ BMPHeader->biHeight == 0 || BMPHeader->biHeight > 4096 || /*< by treating as unsigned */
BMPHeader->biPlanes != 1 || BMPHeader->biPlanes != 1 ||
(BMPHeader->biBitCount != 24 && (BMPHeader->biBitCount != 24 &&
(BMPHeader->biBitCount != 8 || FileSize < 1078 /* We need room for the color palette */)) || (BMPHeader->biBitCount != 8 || BMPHeader->bfSize < 1078 /* We need room for the color palette */)) ||
(BMPHeader->biCompression != BI_RGB && (BMPHeader->biCompression != BI_RGB &&
(BMPHeader->biCompression != BI_RLE8 || BMPHeader->biBitCount > 8)) || (BMPHeader->biCompression != BI_RLE8 || BMPHeader->biBitCount > 8)) ||
BMPHeader->bfOffBits >= FileSize || BMPHeader->bfOffBits >= BMPHeader->bfSize ||
(BMPHeader->biCompression == BI_RGB && (BMPHeader->biCompression == BI_RGB &&
((BMPHeader->biBitCount == 24 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize) || ((BMPHeader->biBitCount == 24 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize + padding) ||
(BMPHeader->biBitCount == 8 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize/3 + (BMPHeader->biBitCount == 8 && BMPHeader->CompressedSize < BMPHeader->DecompressedSize/3 + padding)))
BMPHeader->biHeight*(BMPHeader->biWidth%4) /* Account for padding in 8-bit BMPs */)))
) return 0; ) return 0;
return 1; return 1;
@ -78,7 +82,24 @@ int bmp_read_header(bmpheader_t * BMPHeader, const uint8_t * Buffer, size_t File
int bmp_read_data(bmpheader_t * BMPHeader, const uint8_t *__restrict InBuffer, uint8_t *__restrict OutBuffer){ int bmp_read_data(bmpheader_t * BMPHeader, const uint8_t *__restrict InBuffer, uint8_t *__restrict OutBuffer){
if(BMPHeader->biBitCount == 24 && BMPHeader->biCompression == BI_RGB){ if(BMPHeader->biBitCount == 24 && BMPHeader->biCompression == BI_RGB){
memcpy(OutBuffer, InBuffer+BMPHeader->bfOffBits, BMPHeader->DecompressedSize); unsigned pitch = BMPHeader->biWidth*3;
unsigned i;
unsigned padding = pitch%4;
if(padding != 0) padding = 4-padding;
for(i=0; i<BMPHeader->biHeight; i++)
memcpy(OutBuffer + i*pitch, InBuffer+BMPHeader->bfOffBits + i*(pitch + padding), pitch);
return 1;
}
if(BMPHeader->biBitCount == 32 && BMPHeader->biCompression == BI_RGB){
unsigned i;
for(i=0; i<BMPHeader->biHeight*BMPHeader->biWidth; i++){
*(OutBuffer++) = *(InBuffer++);
*(OutBuffer++) = *(InBuffer++);
*(OutBuffer++) = *(InBuffer++);
InBuffer++;
}
return 1; return 1;
} }
@ -89,6 +110,8 @@ int bmp_read_data(bmpheader_t * BMPHeader, const uint8_t *__restrict InBuffer, u
if(BMPHeader->biCompression == BI_RGB){ if(BMPHeader->biCompression == BI_RGB){
unsigned y, x; unsigned y, x;
unsigned padding = BMPHeader->biWidth % 4; unsigned padding = BMPHeader->biWidth % 4;
if(padding != 0) padding = 4-padding;
for(y=0; y<BMPHeader->biHeight; y++){ for(y=0; y<BMPHeader->biHeight; y++){
for(x=0; x<BMPHeader->biWidth; x++){ for(x=0; x<BMPHeader->biWidth; x++){
unsigned index = 4*(*InBuffer++); unsigned index = 4*(*InBuffer++);

View file

@ -9,6 +9,7 @@ set(IFF_SOURCES
glob.c glob.c
palt.c palt.c
rsmp.c rsmp.c
spr.c
str.c str.c
string.c string.c
tmpl.c tmpl.c

View file

@ -34,6 +34,7 @@ iff_register(c_string);
iff_register(glob); iff_register(glob);
iff_register(fcns); iff_register(fcns);
iff_register(palt); iff_register(palt);
iff_register(spr);
iff_register(tmpl); iff_register(tmpl);
iff_register(trcn); iff_register(trcn);
iff_register(rsmp); iff_register(rsmp);
@ -47,6 +48,7 @@ const char chunktypes[] =
"BCON" "BCON"
"FCNS" "FCNS"
"PALT" "PALT"
"SPR#"
"TMPL" "TMPL"
"TRCN" "TRCN"
"rsmp" "rsmp"
@ -59,6 +61,7 @@ int (* const iff_parse_function[])(IFFChunk*, const uint8_t*) = {
iff_parse_bcon, iff_parse_bcon,
iff_parse_fcns, iff_parse_fcns,
iff_parse_palt, iff_parse_palt,
iff_parse_spr,
iff_parse_tmpl, iff_parse_tmpl,
iff_parse_trcn, iff_parse_trcn,
iff_parse_rsmp iff_parse_rsmp
@ -71,6 +74,7 @@ void (* const iff_free_function[])(void*) = {
iff_free_bcon, iff_free_bcon,
iff_free_fcns, iff_free_fcns,
NULL, NULL,
iff_free_spr,
iff_free_tmpl, iff_free_tmpl,
iff_free_trcn, iff_free_trcn,
iff_free_rsmp iff_free_rsmp
@ -185,6 +189,17 @@ int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer){
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){ void iff_free_chunk(IFFChunk * ChunkInfo){
unsigned i; unsigned i;
if(ChunkInfo == NULL || ChunkInfo->FormattedData == NULL) return; if(ChunkInfo == NULL || ChunkInfo->FormattedData == NULL) return;

View file

@ -109,6 +109,27 @@ typedef struct IFFPalette_s
uint8_t Data[256*3]; uint8_t Data[256*3];
} IFFPalette; } IFFPalette;
/* SPR# chunk */
typedef struct IFFSprite_s
{
uint32_t Reserved;
uint16_t Height;
uint16_t Width;
uint8_t * IndexData;
uint8_t * BGRA32Data;
} IFFSprite;
typedef struct IFFSpriteList_s
{
uint32_t Version;
uint32_t SpriteCount;
uint32_t PaletteID;
IFFSprite * Sprites;
} IFFSpriteList;
int iff_depalette(IFFSprite * Sprite, const IFFPalette * Palette);
/* STR# chunk */ /* STR# chunk */
enum IFFLanguage { enum IFFLanguage {
@ -232,6 +253,7 @@ IFFChunk * iff_add_chunk(IFFFile * IFFFileInfo);
int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize); int iff_read_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer, unsigned MaxChunkSize);
int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer); int iff_parse_chunk(IFFChunk * ChunkInfo, const uint8_t * Buffer);
int iff_enumerate_chunks(IFFFile * IFFFileInfo, const uint8_t * Buffer, unsigned BufferSize); 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_free_chunk(IFFChunk * ChunkInfo);
void iff_delete_chunk(IFFFile * IFFFileInfo, int Position); void iff_delete_chunk(IFFFile * IFFFileInfo, int Position);

View file

@ -266,8 +266,8 @@ void iff_free_str(void * FormattedData){
for(ls=0; ls<20; ls++){ for(ls=0; ls<20; ls++){
IFFLanguageSet * LanguageSet = &StringData->LanguageSets[ls]; IFFLanguageSet * LanguageSet = &StringData->LanguageSets[ls];
unsigned p;
if(LanguageSet->Pairs){ if(LanguageSet->Pairs){
unsigned p;
for(p=0; p<LanguageSet->PairCount; p++){ for(p=0; p<LanguageSet->PairCount; p++){
free(LanguageSet->Pairs[p].Key); free(LanguageSet->Pairs[p].Key);
free(LanguageSet->Pairs[p].Value); free(LanguageSet->Pairs[p].Value);

View file

@ -2,6 +2,7 @@ libvitaboy 1.0.1 (2012-03-10) Fatbag
* Corrected the BlendVertices function; blend vertices tug real vertices, not the other way around * Corrected the BlendVertices function; blend vertices tug real vertices, not the other way around
* Interleaved all vertex data (coords, texcoords, normals, blend weights) into the VertexData array * Interleaved all vertex data (coords, texcoords, normals, blend weights) into the VertexData array
* Made reading floats cross-platform (on modern architectures that use IEEE floats) by using unions
libvitaboy 1.0.0 (2012-03-04) Fatbag libvitaboy 1.0.0 (2012-03-04) Fatbag

View file

@ -70,11 +70,10 @@ class VBFile_t {
} }
inline float readfloat(){ inline float readfloat(){
//Obviously a platform-dependent implementation union { uint32_t i; float f; } value;
float value; value.i = (uint32_t)((Position[0]<<(8*0)) | (Position[1]<<(8*1)) | (Position[2]<<(8*2)) | (Position[3]<<(8*3)));
memcpy(&value, Position, 4);
Position += 4; Position += 4;
return value; return value.f;
} }
inline void readbytes(void* Destination, unsigned length){ inline void readbytes(void* Destination, unsigned length){

View file

@ -16,9 +16,19 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/ */
#include <stdlib.h>
#include <string.h>
#include <stdio.h> #include <stdio.h>
int main(){ int main(int argc, char *argv[]){
unsigned objectcount;
int arg;
/****
** Parameter extraction
*/
if(argc < 3 || !strcmp(argv[1], "-h") || !strcmp(argv[1], "--help")){
printf("Usage: hitld [-f] [-hsm infile.hsm] [-hot infile.hot]\n" printf("Usage: hitld [-f] [-hsm infile.hsm] [-hot infile.hot]\n"
" outfile.hit INFILES\n" " outfile.hit INFILES\n"
"Link object files produced by hitasm into a HIT binary, and\n" "Link object files produced by hitasm into a HIT binary, and\n"
@ -29,4 +39,35 @@ int main(){
"hitutils is maintained by the Niotso project.\n" "hitutils is maintained by the Niotso project.\n"
"Home page: <http://www.niotso.org/>\n"); "Home page: <http://www.niotso.org/>\n");
return 0; return 0;
}
const char * hitfile;
char * hsmfile = NULL, * hotfile = NULL;
bool force = false;
for(arg=1; arg<argc-2; arg++){
if(!strcmp(argv[arg], "-f")) force = true;
else if(arg<argc-3 && !strcmp(argv[arg], "-hsm")) hsmfile = argv[++arg];
else if(arg<argc-3 && !strcmp(argv[arg], "-hot")) hotfile = argv[++arg];
else break;
}
hitfile = argv[arg++];
objectcount = argc-arg; //Guaranteed to be >=1
for(int i=0, length = strlen(hitfile); i<2; i++){
char *& string = (i==0) ? hsmfile : hotfile;
if(!string){
string = (char*) malloc(length+1);
strcpy(string, hitfile);
for(int j=1; j<=3 && j<=length; j++){
const char * ext = "hsmhot";
string[length-j] = ext[3*i + 3-j];
}
}
}
printf("Force: %s\nHSM file: %s\nHOT file: %s\nHIT file: %s\nObject count: %u",
force ? "yes" : "no", hsmfile, hotfile, hitfile, objectcount);
return 0;
} }

View file

@ -4,9 +4,11 @@ project(iff2html)
set(IFF2HTML_SOURCES set(IFF2HTML_SOURCES
iff2html.c iff2html.c
md5.c md5.c
image.c
../../Libraries/FileHandler/bmp/read_bmp.c
) )
include_directories(${CMAKE_SOURCE_DIR}/Libraries/FileHandler) include_directories(${CMAKE_SOURCE_DIR}/Libraries/FileHandler)
add_executable(iff2html ${IFF2HTML_SOURCES}) add_executable(iff2html ${IFF2HTML_SOURCES})
target_link_libraries(iff2html iff_static) target_link_libraries(iff2html iff_static libpng_static zlib_static)

View file

@ -21,6 +21,7 @@
#include <stdint.h> #include <stdint.h>
#include <iff/iff.h> #include <iff/iff.h>
#include "md5.h" #include "md5.h"
#include "image.h"
#ifndef min #ifndef min
#define min(x,y) ((x) < (y) ? (x) : (y)) #define min(x,y) ((x) < (y) ? (x) : (y))
@ -49,15 +50,14 @@ static void printsize(FILE * hFile, size_t FileSize){
} }
int main(int argc, char *argv[]){ int main(int argc, char *argv[]){
unsigned i; unsigned c, slash;
FILE * hFile; FILE * hFile;
int overwrite = 0; int overwrite = 0;
char *InFile, *OutFile = NULL; char *InFile, *OutFile = NULL, *OutDir = NULL;
size_t FileSize; size_t FileSize;
struct MD5Context md5c; struct MD5Context md5c;
unsigned char digest[16]; unsigned char digest[16];
uint8_t * IFFData; uint8_t * IFFData;
unsigned chunk = 0;
IFFFile * IFFFileInfo; IFFFile * IFFFileInfo;
IFFChunk * ChunkData; IFFChunk * ChunkData;
@ -93,6 +93,14 @@ int main(int argc, char *argv[]){
strcpy(max(OutFile+length-4, OutFile), ".html"); strcpy(max(OutFile+length-4, OutFile), ".html");
} }
for(c=0, slash=0; OutFile[c]; c++)
if(OutFile[c] == '/' || OutFile[c] == '\\') slash = c;
if(slash != 0){
OutDir = malloc(slash+2);
memcpy(OutDir, OutFile, slash+1);
OutDir[slash+1] = 0x00;
}else OutDir = "";
/**** /****
** Open the file and read in entire contents to memory ** Open the file and read in entire contents to memory
*/ */
@ -150,7 +158,7 @@ int main(int argc, char *argv[]){
MD5Final(digest, &md5c); MD5Final(digest, &md5c);
free(IFFData); free(IFFData);
for(chunk = 0, ChunkData = IFFFileInfo->Chunks; chunk < IFFFileInfo->ChunkCount; chunk++, ChunkData++) for(c = 0, ChunkData = IFFFileInfo->Chunks; c < IFFFileInfo->ChunkCount; c++, ChunkData++)
iff_parse_chunk(ChunkData, ChunkData->Data); iff_parse_chunk(ChunkData, ChunkData->Data);
/**** /****
@ -184,8 +192,8 @@ int main(int argc, char *argv[]){
"<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n"); "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
fprintf(hFile, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">\n"); fprintf(hFile, "<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\" lang=\"en\" dir=\"ltr\">\n");
fprintf(hFile, "<head>\n"); fprintf(hFile, "<head>\n");
fprintf(hFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\n"); fprintf(hFile, "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\" />\n");
fprintf(hFile, "<meta http-equiv=\"Content-Style-Type\" content=\"text/css; charset=utf-8\" />\n"); fprintf(hFile, "<meta http-equiv=\"Content-Style-Type\" content=\"text/css; charset=iso-8859-1\" />\n");
fprintf(hFile, "<meta http-equiv=\"Content-Language\" content=\"en\" />\n"); fprintf(hFile, "<meta http-equiv=\"Content-Language\" content=\"en\" />\n");
fprintf(hFile, "<meta name=\"description\" content=\"%s (iff2html)\" />\n", InFile); fprintf(hFile, "<meta name=\"description\" content=\"%s (iff2html)\" />\n", InFile);
fprintf(hFile, "<meta name=\"generator\" content=\"iff2html\" />\n"); fprintf(hFile, "<meta name=\"generator\" content=\"iff2html\" />\n");
@ -243,6 +251,10 @@ int main(int argc, char *argv[]){
fprintf(hFile, ".center {\n"); fprintf(hFile, ".center {\n");
fprintf(hFile, " margin: auto auto;\n"); fprintf(hFile, " margin: auto auto;\n");
fprintf(hFile, "}\n"); fprintf(hFile, "}\n");
fprintf(hFile, ".centerall * {\n");
fprintf(hFile, " text-align: center;\n");
fprintf(hFile, " vertical-align: middle;\n");
fprintf(hFile, "}\n");
fprintf(hFile, "\n"); fprintf(hFile, "\n");
fprintf(hFile, ".palette td, .palette th {\n"); fprintf(hFile, ".palette td, .palette th {\n");
fprintf(hFile, " border: none;\n"); fprintf(hFile, " border: none;\n");
@ -267,8 +279,8 @@ int main(int argc, char *argv[]){
fprintf(hFile, "<h1>%s</h1>\n", InFile); fprintf(hFile, "<h1>%s</h1>\n", InFile);
fprintf(hFile, "<div id=\"attributes\">\n"); fprintf(hFile, "<div id=\"attributes\">\n");
fprintf(hFile, "<div>"); fprintf(hFile, "<div>");
for(i=0; i<16; i++) for(c=0; c<16; c++)
fprintf(hFile, "%.2x", digest[i]); fprintf(hFile, "%.2x", digest[c]);
fprintf(hFile, " (md5), "); fprintf(hFile, " (md5), ");
printsize(hFile, FileSize); printsize(hFile, FileSize);
fprintf(hFile, "</div>\n"); fprintf(hFile, "</div>\n");
@ -276,22 +288,39 @@ int main(int argc, char *argv[]){
fprintf(hFile, "\n"); fprintf(hFile, "\n");
fprintf(hFile, "<div id=\"toc\"><div><b>Contents</b> &ndash; %u chunks</div>\n", IFFFileInfo->ChunkCount); fprintf(hFile, "<div id=\"toc\"><div><b>Contents</b> &ndash; %u chunks</div>\n", IFFFileInfo->ChunkCount);
fprintf(hFile, "<ul>\n"); fprintf(hFile, "<ul>\n");
for(i=1, ChunkData = IFFFileInfo->Chunks; i <= IFFFileInfo->ChunkCount; i++, ChunkData++) for(c=1, ChunkData = IFFFileInfo->Chunks; c <= IFFFileInfo->ChunkCount; c++, ChunkData++)
fprintf(hFile, "<li><a href=\"#chunk%u_%.4x\">%u [%s] (%.4X)%s%s</a></li>\n", fprintf(hFile, "<li><a href=\"#chunk%u_%.4x\">%u [%s] (%.4X)%s%s</a></li>\n",
i, ChunkData->ChunkID, i, ChunkData->Type, ChunkData->ChunkID, c, ChunkData->ChunkID, c, ChunkData->Type, ChunkData->ChunkID,
(ChunkData->Label[0] != 0x00) ? " &ndash; " : "", ChunkData->Label); (ChunkData->Label[0] != 0x00) ? " &ndash; " : "", ChunkData->Label);
fprintf(hFile, "</ul>\n"); fprintf(hFile, "</ul>\n");
fprintf(hFile, "</div>\n"); fprintf(hFile, "</div>\n");
fprintf(hFile, "\n"); fprintf(hFile, "\n");
for(i=1, ChunkData = IFFFileInfo->Chunks; i <= IFFFileInfo->ChunkCount; i++, ChunkData++){ for(c=1, ChunkData = IFFFileInfo->Chunks; c <= IFFFileInfo->ChunkCount; c++, ChunkData++){
fprintf(hFile, "<h2 id=\"chunk%u_%.4x\">%u [%s] (%.4X)%s%s <a href=\"#chunk%u_%.4x\">(Jump)</a></h2>\n", fprintf(hFile, "<h2 id=\"chunk%u_%.4x\">%u [%s] (%.4X)%s%s <a href=\"#chunk%u_%.4x\">(Jump)</a></h2>\n",
i, ChunkData->ChunkID, i, ChunkData->Type, ChunkData->ChunkID, c, ChunkData->ChunkID, c, ChunkData->Type, ChunkData->ChunkID,
(ChunkData->Label[0] != 0x00) ? " &ndash; " : "", ChunkData->Label, (ChunkData->Label[0] != 0x00) ? " &ndash; " : "", ChunkData->Label,
i, ChunkData->ChunkID); c, ChunkData->ChunkID);
fprintf(hFile, "<div>\n"); fprintf(hFile, "<div>\n");
if(ChunkData->FormattedData == NULL){ if(ChunkData->FormattedData == NULL){
int success = 0;
/* The iff library does not parse BMP_ or FBMP chunks */
if(!strcmp(ChunkData->Type, "BMP_") || !strcmp(ChunkData->Type, "FBMP")){
size_t Width, Height;
char filename[32];
sprintf(filename, "%simg_%u_%.4x.png", OutDir, c, ChunkData->ChunkID);
if(WritePNG(filename, ChunkData, NULL, &Width, &Height)){
fprintf(hFile, "<table class=\"center centerall\">\n");
fprintf(hFile, "<tr><th>Image</th></tr>\n");
fprintf(hFile, "<tr><td><img src=\"img_%u_%.4x.png\" width=\"%u\" height=\"%u\" alt=\"\" /></td></tr>\n",
c, ChunkData->ChunkID, Width, Height);
fprintf(hFile, "</table>\n");
success++;
}
}
if(!success)
fprintf(hFile, "The contents of this chunk could not be parsed.\n"); fprintf(hFile, "The contents of this chunk could not be parsed.\n");
}else if(!strcmp(ChunkData->Type, "STR#") || }else if(!strcmp(ChunkData->Type, "STR#") ||
!strcmp(ChunkData->Type, "CTSS") || !strcmp(ChunkData->Type, "CTSS") ||
@ -462,7 +491,8 @@ int main(int argc, char *argv[]){
fprintf(hFile, "<tr><th colspan=\"2\">In use</th><th>Default value</th><th>Name</th>" fprintf(hFile, "<tr><th colspan=\"2\">In use</th><th>Default value</th><th>Name</th>"
"<th>Comment</th><th>Range is enforced</th><th>Minimum</th><th>Maximum</th></tr>\n"); "<th>Comment</th><th>Range is enforced</th><th>Minimum</th><th>Maximum</th></tr>\n");
for(i=0, Range=RangeSet->Ranges; i<RangeSet->RangeCount; i++, Range++) for(i=0, Range=RangeSet->Ranges; i<RangeSet->RangeCount; i++, Range++)
fprintf(hFile, "<tr><td>%u</td><td>%s</td><td>%u</td><td>%s</td><td>%s</td><td>%s</td><td>%u</td><td>%u</td></tr>\n", fprintf(hFile,
"<tr><td>%u</td><td>%s</td><td>%u</td><td>%s</td><td>%s</td><td>%s</td><td>%u</td><td>%u</td></tr>\n",
i+1, i+1,
Range->IsUsed ? "Yes" : "No", Range->DefaultValue, Range->IsUsed ? "Yes" : "No", Range->DefaultValue,
Range->Name ? Range->Name : "", Range->Name ? Range->Name : "",
@ -488,9 +518,9 @@ int main(int argc, char *argv[]){
fprintf(hFile, "<tr><th>%X</th>", i); fprintf(hFile, "<tr><th>%X</th>", i);
for(j=0; j<16; j++){ for(j=0; j<16; j++){
if(i*16 + j < Palette->ColorCount){ if(i*16 + j < Palette->ColorCount){
unsigned blue = *(Data++);
unsigned green = *(Data++);
unsigned red = *(Data++); unsigned red = *(Data++);
unsigned green = *(Data++);
unsigned blue = *(Data++);
fprintf(hFile, "\n<td style=\"background:#%.2x%.2x%.2x\" title=\"%u: #%.2x%.2x%.2x\"></td>", fprintf(hFile, "\n<td style=\"background:#%.2x%.2x%.2x\" title=\"%u: #%.2x%.2x%.2x\"></td>",
red, green, blue, i*16 + j, red, green, blue); red, green, blue, i*16 + j, red, green, blue);
@ -500,6 +530,50 @@ int main(int argc, char *argv[]){
fprintf(hFile, "</tr>\n"); fprintf(hFile, "</tr>\n");
} }
fprintf(hFile, "</table>\n"); fprintf(hFile, "</table>\n");
}else if(!strcmp(ChunkData->Type, "SPR#")){
/****
** SPR# parsing
*/
IFFSpriteList * SpriteList = ChunkData->FormattedData;
IFFChunk * Palette = NULL;
IFFPalette BlankPalette;
IFFPalette * PaletteData;
unsigned i;
fprintf(hFile, "<table>\n");
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", SpriteList->Version);
fprintf(hFile, "<tr><td>Palette ID:</td><td>%.4X</td></tr>\n", SpriteList->PaletteID);
fprintf(hFile, "</table>\n");
if(SpriteList->PaletteID < 0xFFFF){
Palette = iff_find_chunk(IFFFileInfo, "PALT", SpriteList->PaletteID);
if(!Palette || !Palette->FormattedData) Palette = iff_find_chunk(IFFFileInfo, "PALT", ChunkData->ChunkID);
if(!Palette || !Palette->FormattedData) Palette = iff_find_chunk(IFFFileInfo, "PALT", -1);
}
if(!Palette || !Palette->FormattedData){
memset(&BlankPalette, 0, sizeof(IFFPalette));
BlankPalette.Version = 1;
BlankPalette.ColorCount = 256;
PaletteData = &BlankPalette;
}else PaletteData = Palette->FormattedData;
fprintf(hFile, "<table class=\"center centerall\">\n");
fprintf(hFile, "<tr><th colspan=\"2\">Sprite</th></tr>\n");
for(i=0; i<SpriteList->SpriteCount; i++){
IFFSprite * Sprite = &SpriteList->Sprites[i];
char filename[32];
sprintf(filename, "%sspr1_%u_%.4x_%u.png", OutDir, c, ChunkData->ChunkID, i+1);
fprintf(hFile, "<tr><td>%u</td><td>", i+1);
if(iff_depalette(Sprite, PaletteData) && WritePNG(filename, NULL, Sprite, NULL, NULL))
fprintf(hFile, "<img src=\"spr1_%u_%.4x_%u.png\" width=\"%u\" height=\"%u\" alt=\"\" />",
c, ChunkData->ChunkID, i+1, Sprite->Width, Sprite->Height);
else
fprintf(hFile, "This sprite cannot be displayed.");
fprintf(hFile, "</td></tr>\n");
}
fprintf(hFile, "</table>\n");
}else{ }else{
fprintf(hFile, "The contents of this chunk cannot be shown on this page.\n"); fprintf(hFile, "The contents of this chunk cannot be shown on this page.\n");
} }