168 lines
5.0 KiB
C
168 lines
5.0 KiB
C
#include "HMT_Parser.h"
|
|
|
|
|
|
HMT_FILE *parseHMTFile(FILE *hmt_src) {
|
|
int i;
|
|
HMT_FILE *_buff = NULL;
|
|
|
|
if (hmt_src == NULL) return NULL;
|
|
_buff = calloc(1, sizeof(HMT_FILE));
|
|
|
|
rewind(hmt_src); //Rewind file at the start
|
|
fread(&(_buff->material_count), 4, 1, hmt_src); // Extract first usefull datas
|
|
fread(&(_buff->texture_offset), 4, 1, hmt_src);
|
|
|
|
// Read materials
|
|
printf("[INFO] Materials detected: %d\n", _buff->material_count);
|
|
_buff->materials_list = calloc(_buff->material_count, sizeof(HMT_MATERIAL)); // Create a big list of materials entries
|
|
for (i=0; i<_buff->material_count; i++) {
|
|
// Extract materials datas
|
|
if (readMaterial(&(_buff->materials_list[i]), hmt_src) != 0) {
|
|
purgeHMTFromMemory(_buff);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
// Read textures
|
|
fseek(hmt_src, _buff->texture_offset, SEEK_SET);
|
|
fread(&(_buff->texture_count), 4, 1, hmt_src);
|
|
printf("[INFO] Textures detected: %d\n", _buff->texture_count);
|
|
if (_buff->texture_count > 0) {
|
|
_buff->textures_list = calloc(_buff->texture_count, sizeof(HMT_TEXTURE)); // Create a big list of textures entries
|
|
for (i=0; i<_buff->texture_count; i++) {
|
|
// Extract textures datas
|
|
if (readTexture(&(_buff->textures_list[i]), hmt_src) != 0) {
|
|
purgeHMTFromMemory(_buff);
|
|
return NULL;
|
|
}
|
|
}
|
|
}
|
|
|
|
return _buff;
|
|
}
|
|
|
|
int readMaterial(HMT_MATERIAL *mat, FILE *hmt_src) {
|
|
if (mat == NULL || hmt_src == NULL) return EXIT_FAILURE;
|
|
|
|
fread(mat, sizeof(HMT_MATERIAL), 1, hmt_src);
|
|
|
|
if (_options & 0x1) {
|
|
if (mat->zero != 0 || mat->hex_a != 0x0A) printf("\n Uncommon file detected!\n");
|
|
printf(" Material type: %d\n Texture index: %d\n\n", mat->type_, mat->texture_index); //TODO: To develop?!
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
int readTexture(HMT_TEXTURE *tex, FILE *hmt_src) {
|
|
unsigned char u0,u1,bpp;
|
|
long pos;
|
|
RS_IMAGE_DESC desc;
|
|
|
|
fread(&(tex->data_offset), 4, 1, hmt_src);
|
|
fseek(hmt_src, 28, SEEK_CUR); // Skip zeros area
|
|
fread(&(tex->palette_offset), 4, 1, hmt_src);
|
|
fread(&(tex->textureName_offset), 4, 1, hmt_src);
|
|
fread(&(tex->width), 2, 1, hmt_src);
|
|
fread(&(tex->height), 2, 1, hmt_src);
|
|
|
|
fread(&u0, 1, 1, hmt_src);
|
|
fread(&bpp, 1, 1, hmt_src);
|
|
fread(&(tex->image.type_), 1, 1, hmt_src);
|
|
fread(&u1, 1, 1, hmt_src);
|
|
fread(&(tex->image.alpha_color._red), 1, 1, hmt_src);
|
|
fread(&(tex->image.alpha_color._green), 1, 1, hmt_src);
|
|
fread(&(tex->image.alpha_color._blue), 1, 1, hmt_src);
|
|
fread(&(tex->image.alpha_color._alpha), 1, 1, hmt_src);
|
|
|
|
pos = ftell(hmt_src);
|
|
fseek(hmt_src, tex->textureName_offset, SEEK_SET);
|
|
fread(&(tex->name), 16, 1, hmt_src);
|
|
fseek(hmt_src, pos, SEEK_SET);
|
|
|
|
desc = getImageDescFromType(tex->image.type_);
|
|
tex->image.paletteEntries = desc.palette_entries;
|
|
tex->image.sampleBits = desc.sample_bits;
|
|
tex->image.width = tex->width;
|
|
tex->image.height = tex->height;
|
|
|
|
if (_options & VERBOSE_ENABLED) {
|
|
printf(" Texture name: %s\n", tex->name);
|
|
printf(" Size w: %ld h: %ld\n", tex->width, tex->height);
|
|
printf(" u0: %d u1: %d\n", u0, u1);
|
|
printf(" Texture type: %d\n", tex->image.type_);
|
|
printf(" Samplebits: %d\n", tex->image.sampleBits);
|
|
printf(" Palette entries: %d\n", tex->image.paletteEntries);
|
|
printf(" Transparent color (RGB): %X %X %X\n", tex->image.alpha_color._red, tex->image.alpha_color._green, tex->image.alpha_color._blue);
|
|
printf(" Palette offset: %d\n", tex->palette_offset);
|
|
printf(" Data offset: %d\n", tex->data_offset);
|
|
printf("\n");
|
|
}
|
|
|
|
if (tex->palette_offset > 0) {
|
|
if (_options & VERBOSE_ENABLED) printf("\nPalette entries: %d\n", tex->image.paletteEntries);
|
|
fseek(hmt_src, tex->palette_offset, SEEK_SET);
|
|
getPaletteFromFile(&(tex->image), hmt_src);
|
|
}
|
|
fseek(hmt_src, tex->data_offset, SEEK_SET);
|
|
getSamplesFromFile(&(tex->image), hmt_src);
|
|
decodePixels(&(tex->image));
|
|
|
|
fseek(hmt_src, pos, SEEK_SET);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
int getPaletteFromFile(RS_IMAGE *img, FILE *f) {
|
|
int entries = img->paletteEntries;
|
|
|
|
switch (entries) {
|
|
case 16:
|
|
case 256:
|
|
fread(img->palette, sizeof(PIXEL), entries, f);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
int getSamplesFromFile(RS_IMAGE *img, FILE *f) {
|
|
int sample_bits = img->sampleBits;
|
|
int size = div(img->width*img->height*sample_bits, 8).quot;
|
|
|
|
#ifdef _WIN32
|
|
if (f->_bufsiz >= ftell(f)+size) {
|
|
printf("[ERR] WARNING! Please fix size/sample.");
|
|
return EXIT_FAILURE;
|
|
}
|
|
#else
|
|
if (__fbufsize(f) >= ftell(f)+size) {
|
|
printf("[ERR] WARNING! Please fix size/sample.");
|
|
return EXIT_FAILURE;
|
|
}
|
|
#endif
|
|
|
|
|
|
img->samples = calloc(1, size);
|
|
fread(img->samples, size, 1, f);
|
|
if (img->type_ == 2) fread(img->samples, div(size, 4).quot, 1, f);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
void purgeHMTFromMemory(HMT_FILE *_f) {
|
|
if (_f == NULL) return;
|
|
|
|
if (_f->textures_list != NULL) {
|
|
if (_f->textures_list->image.pixels != NULL) free(_f->textures_list->image.pixels);
|
|
if (_f->textures_list->image.samples != NULL) free(_f->textures_list->image.samples);
|
|
}
|
|
free(_f->textures_list);
|
|
|
|
if (_f->materials_list != NULL) free(_f->materials_list);
|
|
|
|
free(_f);
|
|
}
|