Added support for SPR2, DGRP, and OBJf in the iff library and in iff2html.

This commit is contained in:
Fatbag 2012-06-15 10:18:12 -05:00
parent bc978bfa0b
commit e51ce26db9
11 changed files with 647 additions and 90 deletions

View file

@ -302,26 +302,27 @@ int main(int argc, char *argv[]){
fprintf(hFile, "</div>\n");
fprintf(hFile, "\n");
for(c=1, ChunkData = IFFFileInfo->Chunks; c <= IFFFileInfo->ChunkCount; c++, ChunkData++){
for(c=0, 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",
c, ChunkData->ChunkID, c, ChunkData->Type, ChunkData->ChunkID,
c+1, ChunkData->ChunkID, c+1, ChunkData->Type, ChunkData->ChunkID,
(ChunkData->Label[0] != 0x00) ? " &ndash; " : "", ChunkData->Label,
c, ChunkData->ChunkID);
c+1, ChunkData->ChunkID);
fprintf(hFile, "<div>\n");
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")){
int bmp = !strcmp(ChunkData->Type, "BMP_");
size_t Width, Height;
char filename[32];
sprintf(filename, "%sbmp_%u_%.4x.png", OutDir, c+1, ChunkData->ChunkID);
sprintf(filename, "%s%s_%u_%.4x.png", OutDir, bmp ? "bmp" : "fbmp", c+1, ChunkData->ChunkID);
if(WritePNG(filename, ChunkData, NULL, &Width, &Height)){
if(WritePNG(filename, ChunkData, 0, NULL, &Width, &Height)){
fprintf(hFile, "<table class=\"center centerall\">\n");
fprintf(hFile, "<tr><th>Image</th></tr>\n");
fprintf(hFile, "<tr><td><img src=\"bmp_%u_%.4x.png\" width=\"%u\" height=\"%u\" alt=\"\" /></td></tr>\n",
c+1, ChunkData->ChunkID, Width, Height);
fprintf(hFile, "<tr><td><img src=\"%s_%u_%.4x.png\" width=\"%u\" height=\"%u\" alt=\"\" /></td></tr>\n",
bmp ? "bmp" : "fbmp", c+1, ChunkData->ChunkID, Width, Height);
fprintf(hFile, "</table>\n");
success++;
}
@ -536,11 +537,12 @@ int main(int argc, char *argv[]){
fprintf(hFile, "</tr>\n");
}
fprintf(hFile, "</table>\n");
}else if(!strcmp(ChunkData->Type, "SPR#")){
}else if(!strcmp(ChunkData->Type, "SPR#") || !strcmp(ChunkData->Type, "SPR2")){
/****
** SPR# parsing
** SPR# and SPR2 parsing
*/
int spr1 = !strcmp(ChunkData->Type, "SPR#");
IFFSpriteList * SpriteList = ChunkData->FormattedData;
IFFChunk * Palette = NULL;
IFFPalette BlankPalette;
@ -565,21 +567,98 @@ int main(int argc, char *argv[]){
}else PaletteData = Palette->FormattedData;
fprintf(hFile, "<table class=\"center centerall\">\n");
fprintf(hFile, "<tr><th colspan=\"2\">Sprite</th></tr>\n");
fprintf(hFile, "<tr><th colspan=\"2\">Sprite</th>");
if(!spr1) fprintf(hFile, "<th>Z-Buffer</th>");
fprintf(hFile, "</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+1, ChunkData->ChunkID, i+1);
sprintf(filename, "%s%s_%u_%.4x_%u.png", OutDir, spr1 ? "spr1" : "spr2", c+1, ChunkData->ChunkID, i+1);
fprintf(hFile, "<tr><td>%u</td><td>", i+1);
if(Sprite->IndexData && 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+1, ChunkData->ChunkID, i+1, Sprite->Width, Sprite->Height);
else
fprintf(hFile, Sprite->InvalidDimensions ? "Blank sprite" : "This sprite cannot be displayed.");
fprintf(hFile, "<tr><td>%u</td><td", i+1);
if(Sprite->IndexData && iff_depalette(Sprite, PaletteData)){
WritePNG(filename, NULL, 0, Sprite, NULL, NULL);
fprintf(hFile, "><img src=\"%s_%u_%.4x_%u.png\" width=\"%u\" height=\"%u\" alt=\"\" />",
spr1 ? "spr1" : "spr2", c+1, ChunkData->ChunkID, i+1, Sprite->Width, Sprite->Height);
if(!spr1){
sprintf(filename, "%sspr2_%u_%.4x_%u_z.png", OutDir, c+1, ChunkData->ChunkID, i+1);
if(Sprite->ZBuffer){
WritePNG(filename, NULL, 1, Sprite, NULL, NULL);
fprintf(hFile, "</td><td><img src=\"spr2_%u_%.4x_%u_z.png\" width=\"%u\" height=\"%u\" alt=\"\" />",
c+1, ChunkData->ChunkID, i+1, Sprite->Width, Sprite->Height);
}else
fprintf(hFile, "None provided");
}
}else
fprintf(hFile, Sprite->InvalidDimensions ? "%sBlank sprite" : "%sThis sprite cannot be displayed.",
!spr1 ? " colspan=\"2\">" : "");
fprintf(hFile, "</td></tr>\n");
}
fprintf(hFile, "</table>\n");
}else if(!strcmp(ChunkData->Type, "DGRP")){
/****
** DGRP parsing
*/
IFFDrawGroup * Group = ChunkData->FormattedData;
IFFDrawAngle * Angle;
IFFSpriteInfo * Sprite;
unsigned i,j;
const char * Zooms[] = {"Far", "Middle", "Close"};
fprintf(hFile, "<table>\n");
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", Group->Version);
fprintf(hFile, "</table>\n");
fprintf(hFile, "<br />\n");
fprintf(hFile, "<table class=\"center\">\n");
fprintf(hFile, "<tr><th>Direction</th><th>Zoom</th><th colspan=\"6\">Sprite</th></tr>\n");
for(i=0, Angle=Group->DrawAngles; i<12; i++, Angle++){
const char * Direction =
(Angle->Direction == IFFDIRECTION_NORTHEAST) ? "North east" :
(Angle->Direction == IFFDIRECTION_SOUTHEAST) ? "South east" :
(Angle->Direction == IFFDIRECTION_NORTHWEST) ? "North west" :
"South west";
if(Angle->SpriteCount){
fprintf(hFile,
"<tr><td rowspan=\"%u\">%s</td><td rowspan=\"%u\">%s</td>"
"<th>#</th><th>Type</th><th>Chunk ID</th><th>Sprite index</th>"
"<th>Flags</th><th>Sprite offset</th><th>Object offset</th></tr>\n",
1+Angle->SpriteCount, Direction, 1+Angle->SpriteCount, Zooms[Angle->Zoom-1]);
for(j=0, Sprite = Angle->SpriteInfo; j<Angle->SpriteCount; j++, Sprite++)
fprintf(hFile, "<tr><td>%u</td><td>%u</td><td>%.4X</td><td>%u</td><td>%u</td>"
"<td>(%+d,%+d)</td><td>(%+g,%+g,%+g)</td></tr>",
j+1, Sprite->Type, Sprite->ChunkID, Sprite->SpriteIndex, Sprite->Flags,
Sprite->SpriteX, Sprite->SpriteY, Sprite->ObjectX, Sprite->ObjectY, Sprite->ObjectZ);
}else{
fprintf(hFile, "<tr><td>%s</td><td>%s</td><td>None specified</td></tr>", Direction, Zooms[Angle->Zoom-1]);
}
}
fprintf(hFile, "</table>\n");
}else if(!strcmp(ChunkData->Type, "OBJf")){
/****
** OBJf parsing
*/
IFFFunctionTable * Table = ChunkData->FormattedData;
fprintf(hFile, "<table>\n");
fprintf(hFile, "<tr><td>Version:</td><td>%u</td></tr>\n", Table->Version);
fprintf(hFile, "</table>\n");
if(Table->FunctionCount > 0){
unsigned i;
fprintf(hFile, "<br />\n");
fprintf(hFile, "<table class=\"center\">\n");
fprintf(hFile, "<tr><th colspan=\"2\">Condition function</th><th>Action function</th></tr>\n");
for(i=0; i<Table->FunctionCount; i++)
fprintf(hFile,
"<tr><td>%u</td><td>%.4X</td><td>%.4X</td></tr>\n",
i+1, Table->Functions[i].ConditionID, Table->Functions[i].ActionID);
fprintf(hFile, "</table>\n");
}
}else{
fprintf(hFile, "The contents of this chunk cannot be shown on this page.\n");
}

View file

@ -23,7 +23,8 @@
#include <libpng/png.h>
#include "opngreduc.h"
int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite * Sprite, size_t * Width, size_t * Height){
int WritePNG(const char * OutName, const IFFChunk * ChunkData, int ZBuffer,
const IFFSprite * Sprite, size_t * Width, size_t * Height){
FILE * hFile;
png_structp png_ptr;
png_infop info_ptr;
@ -40,7 +41,7 @@ int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite *
/* BMP_ or FBMP chunk */
bmpheader_t BMPHeader;
if(!bmp_read_header(&BMPHeader, ChunkData->Data, ChunkData->Size - 76))
if(!bmp_read_header(&BMPHeader, ChunkData->Data, ChunkData->Size))
return 0;
Image.Data = malloc(BMPHeader.DecompressedSize);
@ -57,14 +58,16 @@ int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite *
/* SPR# or SPR2 sprite */
Image.Width = Sprite->Width;
Image.Height = Sprite->Height;
Image.Data = Sprite->BGRA32Data;
Image.Data = (!ZBuffer) ? Sprite->BGRA32Data : Sprite->ZBuffer;
/* Swap from BGR to RGB; this cannot be done with libpng when you use opng_reduce_image
** due to the state that it leaves png_ptr in */
for(i=0; i<Image.Width*Image.Height; i++){
uint8_t temp = Image.Data[i*4 + 0];
Image.Data[i*4 + 0] = Image.Data[i*4 + 2];
Image.Data[i*4 + 2] = temp;
if(!ZBuffer){
/* Swap from BGR to RGB; this cannot be done with libpng when you use opng_reduce_image
** due to the state that it leaves png_ptr in */
for(i=0; i<Image.Width*Image.Height; i++){
uint8_t temp = Image.Data[i*4 + 0];
Image.Data[i*4 + 0] = Image.Data[i*4 + 2];
Image.Data[i*4 + 2] = temp;
}
}
}
@ -74,7 +77,7 @@ int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite *
return 0;
}
for(i=0; i<Image.Height; i++)
row_pointers[i] = Image.Data + Image.Width*((ChunkData) ? 3*(Image.Height-i-1) : 4*i);
row_pointers[i] = Image.Data + Image.Width*((ChunkData) ? 3*(Image.Height-i-1) : ((!ZBuffer)?4:1)*i);
/****
** PNG handling
@ -118,7 +121,8 @@ int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite *
png_set_compression_window_bits(png_ptr, 15);
png_set_compression_buffer_size(png_ptr, 32768);
png_set_IHDR(png_ptr, info_ptr, Image.Width, Image.Height, 8, ChunkData ? PNG_COLOR_TYPE_RGB : PNG_COLOR_TYPE_RGB_ALPHA,
png_set_IHDR(png_ptr, info_ptr, Image.Width, Image.Height, 8,
ChunkData ? PNG_COLOR_TYPE_RGB : (!ZBuffer) ? PNG_COLOR_TYPE_RGB_ALPHA : PNG_COLOR_TYPE_GRAY,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
png_set_rows(png_ptr, info_ptr, row_pointers);

View file

@ -16,4 +16,5 @@
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
int WritePNG(const char * OutName, const IFFChunk * ChunkData, const IFFSprite * Sprite, size_t * Width, size_t * Height);
int WritePNG(const char * OutName, const IFFChunk * ChunkData, int ZBuffer,
const IFFSprite * Sprite, size_t * Width, size_t * Height);