mirror of
https://github.com/simtactics/niotso.git
synced 2025-03-22 10:52:20 +00:00
Sprite formats are now completely supported (PNGs work great too)!
The sprite loader code has been prettied up and rennovated quite a bit. *NOTE: Fatbag, TSO sometimes has palette (PALT) resources that are not the same as those described at simtec. Since you want to do the real figuring out, well, have fun :)
This commit is contained in:
parent
6c85920535
commit
2a87e619ae
3 changed files with 240 additions and 189 deletions
|
@ -165,7 +165,7 @@ IFFChunk *iff_find_first_chunk(IFFFile *IFFFileInfo, const char *type, uint16_t
|
||||||
|
|
||||||
currentNode = currentNode->NextChunk;
|
currentNode = currentNode->NextChunk;
|
||||||
}
|
}
|
||||||
while (currentNode != IFFFileInfo->LastChunk);
|
while (currentNode != IFFFileInfo->LastChunk && currentNode != NULL);
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
|
@ -12,10 +12,11 @@
|
||||||
|
|
||||||
|
|
||||||
int sprite_frame_set_texel(IFFSpriteFrame *frame, uint32_t column, uint32_t row, IFFSpriteColor color);
|
int sprite_frame_set_texel(IFFSpriteFrame *frame, uint32_t column, uint32_t row, IFFSpriteColor color);
|
||||||
|
int sprite_frame_set_texel_alpha(IFFSpriteFrame *frame, uint32_t column, uint32_t row, IFFSpriteColor color, uint8_t alpha);
|
||||||
int sprite_frame_export_as_targa(IFFSpriteFrame *frame, const char *filename);
|
int sprite_frame_export_as_targa(IFFSpriteFrame *frame, const char *filename);
|
||||||
int sprite_frame_export_as_png(IFFSpriteFrame *frame, const char *filename);
|
int sprite_frame_export_as_png(IFFSpriteFrame *frame, const char *filename);
|
||||||
|
|
||||||
int iff_parse_sprite(IFFChunk * ChunkInfo, const uint8_t * Buffer, IFFFile *SourceFile)
|
int iff_parse_sprite(IFFChunk * ChunkInfo, const uint8_t * pBuffer, IFFFile *SourceFile)
|
||||||
{
|
{
|
||||||
uint32_t frameCount = 0;
|
uint32_t frameCount = 0;
|
||||||
uint32_t paletteID = 0;
|
uint32_t paletteID = 0;
|
||||||
|
@ -30,28 +31,23 @@ int iff_parse_sprite(IFFChunk * ChunkInfo, const uint8_t * Buffer, IFFFile *Sour
|
||||||
|
|
||||||
uint32_t i = 0;
|
uint32_t i = 0;
|
||||||
uint32_t l = 0;
|
uint32_t l = 0;
|
||||||
|
uint32_t j = 0;
|
||||||
|
|
||||||
uint32_t row = 0;
|
uint32_t iRow = 0;
|
||||||
uint32_t column = 0;
|
uint32_t cPixelsSet = 0;
|
||||||
uint8_t quit = 0;
|
uint8_t bQuit = 0;
|
||||||
uint32_t numCodesTillNewline = 0;
|
|
||||||
|
|
||||||
uint16_t encrypted = 0;
|
uint32_t cBytesReadInitial = 0;
|
||||||
uint16_t encryptedb = 0;
|
|
||||||
uint16_t decrypted1 = 0;
|
uint32_t cBytesRead = 0;
|
||||||
uint16_t decrypted2 = 0;
|
uint16_t mRowHeader = 0;
|
||||||
uint16_t decryptedb3 = 0;
|
uint16_t mColumnHeader = 0;
|
||||||
uint16_t decryptedb4 = 0;
|
uint16_t eRowControlCode = 0;
|
||||||
|
uint16_t eColumnControlCode = 0;
|
||||||
|
uint16_t cBytesInThisRow = 0;
|
||||||
|
uint16_t cPixelCount = 0; /* Per-control-code pixel count*/
|
||||||
|
|
||||||
uint32_t bytesRead = 0;
|
|
||||||
uint8_t Z;
|
uint8_t Z;
|
||||||
IFFSpriteColor clr;
|
|
||||||
|
|
||||||
uint32_t rowHeader[2];
|
|
||||||
uint32_t rowHeader2[2];
|
|
||||||
|
|
||||||
uint8_t b;
|
|
||||||
uint8_t b1;
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef IFF2HTML
|
#ifdef IFF2HTML
|
||||||
|
@ -60,35 +56,47 @@ int iff_parse_sprite(IFFChunk * ChunkInfo, const uint8_t * Buffer, IFFFile *Sour
|
||||||
char *folderName;
|
char *folderName;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
uint32_t version = read_uint32le(Buffer);
|
uint32_t version = read_uint32le(pBuffer);
|
||||||
Buffer += 4;
|
pBuffer += 4;
|
||||||
|
|
||||||
if (version == 1001)
|
if (version == 1001)
|
||||||
{
|
{
|
||||||
paletteID = read_uint32le(Buffer);
|
paletteID = read_uint32le(pBuffer);
|
||||||
Buffer += 4;
|
pBuffer += 4;
|
||||||
frameCount = read_uint32le(Buffer);
|
frameCount = read_uint32le(pBuffer);
|
||||||
Buffer += 4;
|
pBuffer += 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
frameCount = read_uint32le(Buffer);
|
frameCount = read_uint32le(pBuffer);
|
||||||
Buffer += 4;
|
pBuffer += 4;
|
||||||
paletteID = read_uint32le(Buffer);
|
paletteID = read_uint32le(pBuffer);
|
||||||
Buffer += 4;
|
pBuffer += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* Try to load the appropriate palette */
|
/* Try to load the appropriate palette */
|
||||||
PaletteMap = iff_find_first_chunk(SourceFile, "PALT", paletteID);
|
PaletteMap = iff_find_first_chunk(SourceFile, "PALT", paletteID);
|
||||||
/* If that didn't work, try loading any palette from the IFF file */
|
/* If that didn't work, try loading any palette from the IFF file */
|
||||||
/* Some sprites in IFFs containing only one PALT don't bother to specify a correct PALT ID */
|
/* Some sprites in IFFs containing only one PALT don't bother to specify a correct PALT ID */
|
||||||
if (PaletteMap == NULL)
|
if (PaletteMap == NULL)
|
||||||
{
|
{
|
||||||
|
printf("ERR");
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
PaletteMap = iff_find_first_chunk(SourceFile, "PALT", 0);
|
PaletteMap = iff_find_first_chunk(SourceFile, "PALT", 0);
|
||||||
/* If there is no existing palette data, there can be no coherent image. */
|
/* If there is no existing palette data, there can be no coherent image. */
|
||||||
if (PaletteMap == NULL)
|
if (PaletteMap == NULL)
|
||||||
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
if (PaletteMap->FormattedData == NULL)
|
||||||
|
{
|
||||||
|
printf("HERE");
|
||||||
|
fflush(stdout);
|
||||||
|
iff_parse_pmap(PaletteMap, PaletteMap->Data);
|
||||||
|
}
|
||||||
PMap = (IFFPMap *)PaletteMap->FormattedData;
|
PMap = (IFFPMap *)PaletteMap->FormattedData;
|
||||||
|
|
||||||
offsets = (uint32_t *)malloc(sizeof(uint32_t) * frameCount);
|
offsets = (uint32_t *)malloc(sizeof(uint32_t) * frameCount);
|
||||||
|
@ -98,8 +106,8 @@ int iff_parse_sprite(IFFChunk * ChunkInfo, const uint8_t * Buffer, IFFFile *Sour
|
||||||
{
|
{
|
||||||
for (i = 0; i < frameCount; i++)
|
for (i = 0; i < frameCount; i++)
|
||||||
{
|
{
|
||||||
offsets[i] = read_uint32le(Buffer);
|
offsets[i] = read_uint32le(pBuffer);
|
||||||
Buffer += 4;
|
pBuffer += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,249 +125,276 @@ int iff_parse_sprite(IFFChunk * ChunkInfo, const uint8_t * Buffer, IFFFile *Sour
|
||||||
|
|
||||||
/* Version 1000 specifies offsets for each frame of image data */
|
/* Version 1000 specifies offsets for each frame of image data */
|
||||||
if (version == 1000)
|
if (version == 1000)
|
||||||
Buffer = ChunkInfo->Data + offsets[l];
|
pBuffer = ChunkInfo->Data + offsets[l];
|
||||||
|
|
||||||
/* There are two "+=" statements here for clarity. That is optimized away by a decent compiler */
|
/* There are two "+=" statements here for clarity. That is optimized away by a decent compiler */
|
||||||
if (version == 1001)
|
if (version == 1001)
|
||||||
{
|
{
|
||||||
Buffer += 4; /* Version */
|
pBuffer += 4; /* Version */
|
||||||
Buffer += 4; /* Size */
|
pBuffer += 4; /* Size */
|
||||||
}
|
}
|
||||||
if (version != 1000 && version != 1001) /* for SPR# resources */
|
if (version != 1000 && version != 1001) /* for SPR# resources */
|
||||||
{
|
{
|
||||||
Frame->YLocation = read_uint16le(Buffer);
|
Frame->YLocation = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->YLocation = read_uint16le(Buffer);
|
Frame->YLocation = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->Height = read_uint16le(Buffer);
|
Frame->Height = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->Width = read_uint16le(Buffer);
|
Frame->Width = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Frame->Width = read_uint16le(Buffer);
|
Frame->Width = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->Height = read_uint16le(Buffer);
|
Frame->Height = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Frame->Flag = read_uint16le(Buffer);
|
Frame->Flag = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
|
|
||||||
if (version == 1000 || version == 1001)
|
if (version == 1000 || version == 1001)
|
||||||
{
|
{
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->PaletteID = read_uint16le(Buffer); /* This is unused or the same as the master PALT ID */
|
Frame->PaletteID = read_uint16le(pBuffer); /* This is unused or the same as the master PALT ID */
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->TransparentPixel = PMap->Colors[read_uint16le(Buffer)];
|
Frame->TransparentPixel = PMap->Colors[read_uint16le(pBuffer)];
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->YLocation = read_uint16le(Buffer);
|
Frame->YLocation = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
Frame->XLocation = read_uint16le(Buffer);
|
Frame->XLocation = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
pBuffer += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (Frame->PaletteID != 0xA3A3)
|
||||||
|
{
|
||||||
|
/* Try to load the appropriate palette */
|
||||||
|
PaletteMap = iff_find_first_chunk(SourceFile, "PALT", Frame->PaletteID);
|
||||||
|
/* If that didn't work, try loading any palette from the IFF file */
|
||||||
|
/* Some sprites in IFFs containing only one PALT don't bother to specify a correct PALT ID */
|
||||||
|
if (PaletteMap == NULL)
|
||||||
|
{
|
||||||
|
PaletteMap = iff_find_first_chunk(SourceFile, "PALT", 0);
|
||||||
|
/* If there is no existing palette data, there can be no coherent image. */
|
||||||
|
if (PaletteMap == NULL)
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
PMap = (IFFPMap *)PaletteMap->FormattedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now that we know the frame size, allocate the buffer to hold its texels */
|
/* Now that we know the frame size, allocate the buffer to hold its texels */
|
||||||
Frame->Texels = (IFFSpriteColor *)malloc(sizeof(IFFSpriteColor) * Frame->Width * Frame->Height);
|
Frame->Texels = (IFFSpriteColor *)malloc(sizeof(IFFSpriteColor) * Frame->Width * Frame->Height);
|
||||||
|
|
||||||
|
|
||||||
|
iRow = 0;
|
||||||
|
cPixelsSet = 0;
|
||||||
|
bQuit = 0;
|
||||||
|
|
||||||
|
cBytesReadInitial = 0;
|
||||||
|
|
||||||
|
cBytesRead = 0;
|
||||||
|
mRowHeader = 0;
|
||||||
|
mColumnHeader = 0;
|
||||||
|
eRowControlCode = 0;
|
||||||
|
eColumnControlCode = 0;
|
||||||
|
cBytesInThisRow = 0;
|
||||||
|
cPixelCount = 0;
|
||||||
if (version == 1000 || version == 1001)
|
if (version == 1000 || version == 1001)
|
||||||
{
|
{
|
||||||
while (quit == 0)
|
while (!bQuit)
|
||||||
{
|
{
|
||||||
encrypted = read_uint16le(Buffer);
|
mRowHeader = read_uint16le(pBuffer);
|
||||||
encryptedb = 0;
|
eRowControlCode = mRowHeader>>13;
|
||||||
decrypted1 = encrypted>>13;
|
cBytesInThisRow = mRowHeader&0x1FFF;
|
||||||
decrypted2 = encrypted&0x1FFF;
|
pBuffer += 2;
|
||||||
|
cBytesRead = 2; /* We just read the row header, which is included in cBytesInThisRow */
|
||||||
|
cPixelsSet = 0;
|
||||||
|
switch (eRowControlCode)
|
||||||
decryptedb3 = 0;
|
|
||||||
decryptedb4 = 0;
|
|
||||||
Buffer += 2;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
switch (decrypted1)
|
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
column = 0;
|
while (cBytesRead < cBytesInThisRow)
|
||||||
numCodesTillNewline = decrypted2;
|
|
||||||
|
|
||||||
bytesRead = 0;
|
|
||||||
for (bytesRead = 0; bytesRead < numCodesTillNewline - 2; bytesRead += 2)
|
|
||||||
{
|
{
|
||||||
encryptedb = read_uint16le(Buffer);
|
mColumnHeader = read_uint16le(pBuffer);
|
||||||
Buffer += 2;
|
eColumnControlCode = mColumnHeader>>13;
|
||||||
|
cPixelCount = mColumnHeader&0x1FFF;
|
||||||
|
pBuffer += 2;
|
||||||
|
cBytesRead += 2;
|
||||||
|
|
||||||
decryptedb3 = encryptedb>>13;
|
|
||||||
decryptedb4 = encryptedb&0x1FFF;
|
|
||||||
|
|
||||||
switch (decryptedb3)
|
switch (eColumnControlCode)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1: /* Add cPixelCount ZRGB pixels */
|
||||||
|
|
||||||
for (i = 0; i < decryptedb4; i++)
|
for (i = 0; i < cPixelCount; i++)
|
||||||
{
|
{
|
||||||
Z = *Buffer++; /* TODO: Use the z-buffer */
|
Z = *pBuffer++; /* TODO: Use the z-buffer */
|
||||||
b = *Buffer++;
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, PMap->Colors[*pBuffer++]);
|
||||||
sprite_frame_set_texel(Frame, column++, row, PMap->Colors[b]);
|
cBytesRead += 2;
|
||||||
/*c = PMap->Colors[b]; This variable is not used */
|
|
||||||
bytesRead += 2;
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2: /* Add cPixelCount ZRGBA pixels */
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i = 0; i < decryptedb4; i++)
|
for (i = 0; i < cPixelCount; i++)
|
||||||
{
|
{
|
||||||
Z = *Buffer++; /* TODO: Use the z-buffer */
|
Z = *pBuffer++; /* TODO: Use the z-buffer */
|
||||||
b = *Buffer++;
|
sprite_frame_set_texel_alpha(Frame, cPixelsSet++, iRow, PMap->Colors[*pBuffer++], (uint8_t)*pBuffer++);/* Read and set the alpha channel's value */
|
||||||
|
cBytesRead += 3;
|
||||||
clr = PMap->Colors[b];
|
|
||||||
clr.A = *Buffer++;
|
|
||||||
sprite_frame_set_texel(Frame, column++, row, clr);
|
|
||||||
bytesRead += 3;
|
|
||||||
}
|
}
|
||||||
if ((Buffer - ChunkInfo->Data) % 2 == 1)
|
/* Read EA's padding byte if the current position is not a multiple of 2 */
|
||||||
|
if ((pBuffer - ChunkInfo->Data) % 2 == 1)
|
||||||
{
|
{
|
||||||
Buffer++;
|
pBuffer++;
|
||||||
bytesRead++;
|
cBytesRead++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3: /* Add cPixelCount transparent pixels */
|
||||||
column += decryptedb4;
|
for (i = 0; i < cPixelCount; i++)
|
||||||
|
{
|
||||||
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, Frame->TransparentPixel);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 6:
|
case 6: /* Add cPixelCount RGB pixels */
|
||||||
i = 0;
|
i = 0;
|
||||||
for (i = 0; i < decryptedb4; i++)
|
for (i = 0; i < cPixelCount; i++)
|
||||||
{
|
{
|
||||||
b = *Buffer++;
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, PMap->Colors[*pBuffer++]);
|
||||||
sprite_frame_set_texel(Frame, column++, row, PMap->Colors[b]);
|
cBytesRead++;
|
||||||
bytesRead++;
|
|
||||||
}
|
}
|
||||||
|
/* Read EA's padding byte if the current position is not a multiple of 2 */
|
||||||
if ((Buffer - ChunkInfo->Data) % 2 == 1)
|
if ((pBuffer - ChunkInfo->Data) % 2 == 1)
|
||||||
{
|
{
|
||||||
Buffer++;
|
pBuffer++;
|
||||||
bytesRead++;
|
cBytesRead++;
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
/* Error reading column code */
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
row++;
|
/* Set any extra (unread) texels in the current row to transparent */
|
||||||
|
while (cPixelsSet < Frame->Width) { sprite_frame_set_texel(Frame, cPixelsSet++, iRow, Frame->TransparentPixel); }
|
||||||
|
iRow++;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
i = 0;
|
for (i = 0; i < cBytesInThisRow; i++) /* cBytesInThisRow is used as the count of rows to fill with the transparent color in this case */
|
||||||
for (i = 0; i < decrypted2; i++)
|
|
||||||
{
|
{
|
||||||
row++;
|
for (cPixelsSet = 0; cPixelsSet < Frame->Width; cPixelsSet++)
|
||||||
column = 0;
|
{
|
||||||
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, Frame->TransparentPixel);
|
||||||
|
}
|
||||||
|
iRow++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5: /* This means to stop reading */
|
||||||
quit = 1;
|
bQuit = 1;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Error reading code */
|
/* Error reading row code */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uint32_t)(Buffer - ChunkInfo->Data) == ChunkInfo->Size)
|
if ((uint32_t)(pBuffer - ChunkInfo->Data) == ChunkInfo->Size)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
while (quit == 0)
|
while (bQuit == 0)
|
||||||
{
|
{
|
||||||
b = 0;
|
eRowControlCode = *pBuffer++;
|
||||||
b1 = 0;
|
cBytesInThisRow = *pBuffer++;
|
||||||
/*b2 = 0; This variable is unused */
|
cBytesRead = 2;
|
||||||
rowHeader[0] = *Buffer++;
|
cPixelsSet = 0;
|
||||||
rowHeader[1] = *Buffer++;
|
switch (eRowControlCode)
|
||||||
switch (rowHeader[0])
|
|
||||||
{
|
{
|
||||||
case 4:
|
case 4:
|
||||||
column = 0;
|
for (cBytesInThisRow = 0; cBytesInThisRow < cBytesInThisRow;)
|
||||||
numCodesTillNewline = rowHeader[1];
|
|
||||||
|
|
||||||
bytesRead = 0;
|
|
||||||
for (bytesRead = 0; bytesRead < numCodesTillNewline - 2; bytesRead += 2)
|
|
||||||
{
|
{
|
||||||
rowHeader2[0] = *Buffer++;
|
eColumnControlCode = *pBuffer++;
|
||||||
rowHeader2[1] = *Buffer++;
|
cPixelCount = *pBuffer++;
|
||||||
|
cBytesRead += 2;
|
||||||
|
|
||||||
switch (rowHeader2[0])
|
switch (eColumnControlCode)
|
||||||
{
|
{
|
||||||
case 3:
|
case 3:
|
||||||
i = 0;
|
for (i = 0; i < cPixelCount; i++)
|
||||||
for (i = 0; i < rowHeader2[1]; i++)
|
|
||||||
{
|
{
|
||||||
b = *Buffer++;
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, PMap->Colors[*pBuffer++]);
|
||||||
sprite_frame_set_texel(Frame, column++, row, PMap->Colors[b]);
|
cBytesRead++;
|
||||||
/*c = PMap->Colors[b]; This variable is not used */
|
|
||||||
bytesRead += 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((Buffer - ChunkInfo->Data) % 2 == 1)
|
if ((pBuffer - ChunkInfo->Data) % 2 == 1)
|
||||||
{
|
{
|
||||||
Buffer++;
|
pBuffer++;
|
||||||
bytesRead++;
|
cBytesRead++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
b1 = *Buffer++;
|
for (i = 0; i < cPixelCount; i++)
|
||||||
/*b2 = *Buffer++; this variable is unused */
|
|
||||||
Buffer++;
|
|
||||||
|
|
||||||
clr = PMap->Colors[b1];
|
|
||||||
i = 0;
|
|
||||||
for (i = 0; i < rowHeader2[1]; i++)
|
|
||||||
{
|
{
|
||||||
sprite_frame_set_texel(Frame, column++, row, clr);
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, PMap->Colors[*pBuffer++]);
|
||||||
|
pBuffer++; /* Unused value */
|
||||||
|
cBytesRead += 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
bytesRead += 2;
|
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
column += rowHeader2[1];
|
for (i = 0; i < cPixelCount; i++)
|
||||||
|
{
|
||||||
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, Frame->TransparentPixel);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Error */
|
/* Error reading column code */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* Set any extra (unread) texels in the current row to transparent */
|
||||||
row++;
|
while (cPixelsSet < Frame->Width) { sprite_frame_set_texel(Frame, cPixelsSet++, iRow, Frame->TransparentPixel); }
|
||||||
|
iRow++;
|
||||||
break;
|
break;
|
||||||
case 9:
|
case 9:
|
||||||
i = 0;
|
for (i = 0; i < cBytesInThisRow; i++) /* cBytesInThisRow is used as the count of rows to fill with the transparent color in this case */
|
||||||
for (i = 0; i < rowHeader[1]; i++)
|
|
||||||
{
|
{
|
||||||
row++;
|
for (cPixelsSet = 0; cPixelsSet < Frame->Width; cPixelsSet++)
|
||||||
column = 0;
|
{
|
||||||
|
sprite_frame_set_texel(Frame, cPixelsSet++, iRow, Frame->TransparentPixel);
|
||||||
|
}
|
||||||
|
iRow++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 5:
|
case 5:
|
||||||
quit = 1;
|
bQuit = 1;
|
||||||
|
printf("END");
|
||||||
|
fflush(stdout);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* Error */
|
/* Error reading row code */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((uint32_t)(Buffer - ChunkInfo->Data) == ChunkInfo->Size)
|
/*if ((uint32_t)(pBuffer - ChunkInfo->Data) == ChunkInfo->Size)
|
||||||
break;
|
break; */
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < Frame->Height; i++) /* cBytesInThisRow is used as the count of rows to fill with the transparent color in this case */
|
||||||
|
{
|
||||||
|
for (j = 0; j < Frame->Width; j++)
|
||||||
|
{
|
||||||
|
if (sprite_are_colors_equal_rgb(Frame->Texels[i*Frame->Width+j], Frame->TransparentPixel))
|
||||||
|
Frame->Texels[i*Frame->Width+j].A = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef IFF2HTML
|
#ifdef IFF2HTML
|
||||||
outputPath = (char *)malloc(sizeof(char) * 255);
|
outputPath = (char *)malloc(sizeof(char) * 255);
|
||||||
|
|
||||||
|
@ -383,28 +418,36 @@ int iff_parse_sprite(IFFChunk * ChunkInfo, const uint8_t * Buffer, IFFFile *Sour
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This function never returns zero because it is capable of producing logical output independent of the input's validity. */
|
/* This function never returns zero because it is capable of producing logical output independent of the input's validity. */
|
||||||
int iff_parse_pmap(IFFChunk * ChunkInfo, uint8_t * Buffer)
|
int sprite_are_colors_equal_rgb(IFFSpriteColor clr1, IFFSpriteColor clr2)
|
||||||
|
{
|
||||||
|
return clr1.R == clr2.R && clr1.G == clr2.G && clr1.B == clr2.B;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This function never returns zero because it is capable of producing logical output independent of the input's validity. */
|
||||||
|
int iff_parse_pmap(IFFChunk * ChunkInfo, uint8_t * pBuffer)
|
||||||
{
|
{
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
uint32_t indicator;
|
||||||
|
|
||||||
IFFPMap *PMap = malloc(sizeof(IFFPMap));
|
IFFPMap *PMap = malloc(sizeof(IFFPMap));
|
||||||
Buffer = ChunkInfo->Data;
|
pBuffer = ChunkInfo->Data;
|
||||||
|
|
||||||
PMap->Colors = (IFFSpriteColor *)malloc(sizeof(IFFSpriteColor) * 256);
|
PMap->Colors = (IFFSpriteColor *)malloc(sizeof(IFFSpriteColor) * 256);
|
||||||
|
|
||||||
Buffer += 16;
|
indicator = read_uint32le(pBuffer);
|
||||||
if (*Buffer == 0)
|
if (indicator != 1)
|
||||||
Buffer += 64; /* TSO-only (this took a while to figure out) Why EA does this is beyond me... */
|
pBuffer += (indicator>>24) - 8;
|
||||||
|
else
|
||||||
|
pBuffer += 12;
|
||||||
|
|
||||||
/* In every single one of EA's PALT resources, there have been 256 colors. */
|
/* In every single one of EA's PALT resources, there have been 256 colors. */
|
||||||
for (i = 0; i < 256; i++)
|
for (i = 0; i < 256; i++)
|
||||||
{
|
{
|
||||||
if ((uint32_t)(Buffer - ChunkInfo->Data) < ChunkInfo->Size + 3) /* Are there 3 more bytes left to read? */
|
if ((uint32_t)(pBuffer - ChunkInfo->Data) < ChunkInfo->Size + 3) /* Are there 3 more bytes left to read? */
|
||||||
{
|
{
|
||||||
PMap->Colors[i].R = *(Buffer++);
|
PMap->Colors[i].R = *(pBuffer++);
|
||||||
PMap->Colors[i].G = *(Buffer++);
|
PMap->Colors[i].G = *(pBuffer++);
|
||||||
PMap->Colors[i].B = *(Buffer++);
|
PMap->Colors[i].B = *(pBuffer++);
|
||||||
PMap->Colors[i].A = 255;
|
PMap->Colors[i].A = 255;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -430,6 +473,16 @@ int sprite_frame_set_texel(IFFSpriteFrame *frame, uint32_t column, uint32_t row,
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int sprite_frame_set_texel_alpha(IFFSpriteFrame *frame, uint32_t column, uint32_t row, IFFSpriteColor color, uint8_t alpha)
|
||||||
|
{
|
||||||
|
/*printf("Index: %d out of %d", frame->Width * row + column, frame->Width*frame->Height);*/
|
||||||
|
|
||||||
|
memcpy(&frame->Texels[frame->Width * row + column], &color, sizeof(IFFSpriteColor));
|
||||||
|
frame->Texels[frame->Width * row + column].A = alpha;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
int sprite_frame_export_as_targa(IFFSpriteFrame *frame, const char *filename)
|
int sprite_frame_export_as_targa(IFFSpriteFrame *frame, const char *filename)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -492,12 +545,12 @@ int sprite_frame_export_as_png(IFFSpriteFrame *frame, const char *filename)
|
||||||
|
|
||||||
row_pointers = (png_bytepp) malloc (frame->Height * sizeof (png_bytep));
|
row_pointers = (png_bytepp) malloc (frame->Height * sizeof (png_bytep));
|
||||||
for (h = 0; h < frame->Height; h++) {
|
for (h = 0; h < frame->Height; h++) {
|
||||||
row_pointers[frame->Height-h-1] = (png_bytep) malloc (frame->Width*4);
|
row_pointers[h] = (png_bytep) malloc (frame->Width*4);
|
||||||
for (w = 0; w < frame->Width; w++) {
|
for (w = 0; w < frame->Width; w++) {
|
||||||
row_pointers[frame->Height-h-1][w*4] = frame->Texels[frame->Width*h + w].R;
|
row_pointers[h][w*4] = frame->Texels[frame->Width*h + w].R;
|
||||||
row_pointers[frame->Height-h-1][w*4+1] = frame->Texels[frame->Width*h + w].G;
|
row_pointers[h][w*4+1] = frame->Texels[frame->Width*h + w].G;
|
||||||
row_pointers[frame->Height-h-1][w*4+2] = frame->Texels[frame->Width*h + w].B;
|
row_pointers[h][w*4+2] = frame->Texels[frame->Width*h + w].B;
|
||||||
row_pointers[frame->Height-h-1][w*4+3] = frame->Texels[frame->Width*h + w].A;
|
row_pointers[h][w*4+3] = frame->Texels[frame->Width*h + w].A;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -106,8 +106,6 @@ int main(int argc, char *argv[]){
|
||||||
resourceDir[0] = '.';
|
resourceDir[0] = '.';
|
||||||
resourceDir[1] = '/';
|
resourceDir[1] = '/';
|
||||||
CreateDirectory(resourceDir, NULL);
|
CreateDirectory(resourceDir, NULL);
|
||||||
printf(resourceDir);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
hFile = CreateFile(InFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
hFile = CreateFile(InFile, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||||
hFile = fopen(InFile, "rb");
|
hFile = fopen(InFile, "rb");
|
||||||
|
|
Loading…
Add table
Reference in a new issue