mirror of
https://gitlab.com/skmp/dca3-game.git
synced 2025-04-28 13:07:59 +03:00
88 lines
2.5 KiB
C
88 lines
2.5 KiB
C
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include "pvr_texture_encoder.h"
|
|
#include "file_common.h"
|
|
#include "file_dctex.h"
|
|
|
|
static int convert_size(int size) {
|
|
if (size > 512)
|
|
return 7;
|
|
else if (size > 256)
|
|
return 6;
|
|
else if (size > 128)
|
|
return 5;
|
|
else if (size > 64)
|
|
return 4;
|
|
else if (size > 32)
|
|
return 3;
|
|
else if (size > 16)
|
|
return 2;
|
|
else if (size > 8)
|
|
return 1;
|
|
else
|
|
return 0;
|
|
|
|
}
|
|
|
|
void fDtWrite(const PvrTexEncoder *pte, const char *outfname) {
|
|
assert(pte);
|
|
|
|
FILE *f = fopen(outfname, "w");
|
|
assert(f);
|
|
|
|
unsigned textype = 0;
|
|
textype |= pteHasMips(pte) << FDT_MIPMAP_SHIFT;
|
|
textype |= pteIsCompressed(pte) << FDT_VQ_SHIFT;
|
|
textype |= pte->pixel_format << FDT_PIXEL_FORMAT_SHIFT;
|
|
textype |= !pte->raw_is_twiddled << FDT_NOT_TWIDDLED_SHIFT;
|
|
|
|
//If the width is a power of two, we don't need the stride bit set
|
|
textype |= (pteIsStrided(pte) && !IsPow2(pte->w)) << FDT_STRIDE_SHIFT;
|
|
|
|
textype |= ((pte->w / 32) & FDT_STRIDE_VAL_MASK) << FDT_STRIDE_VAL_SHIFT;
|
|
textype |= !IsPow2(pte->h) << FDT_PARTIAL_SHIFT;
|
|
textype |= convert_size(pte->w) << FDT_WIDTH_SHIFT;
|
|
textype |= convert_size(pte->h) << FDT_HEIGHT_SHIFT;
|
|
|
|
//Include size of header
|
|
unsigned origsize = 32 + CalcTextureSize(pte->w, pte->h, pte->pixel_format, pteHasMips(pte), pteIsCompressed(pte), pte->codebook_size * 8);
|
|
unsigned size = ROUND_UP_POW2(origsize, 32);
|
|
unsigned paddingamt = size - origsize;
|
|
pteLog(LOG_DEBUG, "File size: %u orig + %u pad = %u total\n", origsize, paddingamt, size);
|
|
|
|
WriteFourCC("DcTx", f);
|
|
Write32LE(size, f);
|
|
Write8(0, f); //Version
|
|
Write8(0, f); //Header size is (32 bytes / 32 - 1) = 0
|
|
Write8(pteIsCompressed(pte) ? pte->codebook_size - 1 : 0, f);
|
|
Write8(pteIsPalettized(pte) ? pte->palette_size - 1 : 0, f);
|
|
Write16LE(pte->w, f);
|
|
Write16LE(pte->h, f);
|
|
Write32LE(textype, f);
|
|
Write32LE(0, f);
|
|
Write32LE(0, f);
|
|
Write32LE(0, f);
|
|
|
|
WritePvrTexEncoder(pte, f, PTEW_FILE_DCTEX_SMALL_VQ, 0);
|
|
|
|
//Pad to 32 bytes
|
|
WritePadZero(paddingamt, f);
|
|
fclose(f);
|
|
|
|
//Validate resulting file
|
|
unsigned resultsize = FileSize(outfname);
|
|
ErrorExitOn(resultsize != size, "Size of file written for \"%s\" was incorrect. Expected file to be %u bytes, but result was %u bytes.\n", outfname, size, resultsize);
|
|
|
|
f = fopen(outfname, "r");
|
|
void *readbuff = malloc(size);
|
|
if (fread(readbuff, size, 1, f) == 1) {
|
|
if (!fDtValidateHeader(readbuff)) {
|
|
pteLog(LOG_WARNING, "**Error validating output for .DT**\n");
|
|
}
|
|
} else {
|
|
pteLog(LOG_WARNING, "**Error reading file during validation check for .DT output**\n");
|
|
}
|
|
fclose(f);
|
|
free(readbuff);
|
|
}
|
|
|