dethrace/tga.c

201 lines
5.6 KiB
C

#include <stdio.h>
#define BYTE_RANGE 256;
typedef struct {
char id_length; // length of id field (number of bytes - max 255)
char map_type; // colormap field (0 or 1; no map or 256 entry palette)
char image_type; // ( 0 - no image data included
// 1 - uncompressed, color mapped image
// 2 - uncompressed, RGB image
// 3 - uncompressed, black & white image
// 9 - run-length encoded(RLE-lossless compression),color mapped image
// 10 - RLE, RGB image
// 11 - compressed, black & white image )
int map_first; // first entry index for color map
int map_length; // total number of entries in color map
char map_entry_size; // number of bits per entry
int x; // x cooridinate of origin
int y; // y cooridinate of origin
int width; // width in pixels
int height; // height in pixels
char bits_per_pixel; // number of bits per pixel
char misc; // srsly? "scan origin and alpha bits" this example uses scan origin
// honestly, don't know what's going on here. we pass in a hex value
// :shrug_emoji:
} targa_header;
int little_endianify(int number) {
return number % BYTE_RANGE;
}
int big_endianify(int number) {
return number / BYTE_RANGE;
}
////// write header function
void write_header(targa_header header, FILE* tga) {
fputc(header.id_length, tga);
fputc(header.map_type, tga);
fputc(header.image_type, tga);
fputc(little_endianify(header.map_first), tga);
fputc(big_endianify(header.map_first), tga);
fputc(little_endianify(header.map_length), tga);
fputc(big_endianify(header.map_length), tga);
fputc(header.map_entry_size, tga);
fputc(little_endianify(header.x), tga);
fputc(big_endianify(header.x), tga);
fputc(little_endianify(header.y), tga);
fputc(big_endianify(header.y), tga);
fputc(little_endianify(header.width), tga);
fputc(big_endianify(header.width), tga);
fputc(little_endianify(header.height), tga);
fputc(big_endianify(header.height), tga);
fputc(header.bits_per_pixel, tga);
fputc(header.misc, tga);
}
int dump_palette(void) {
FILE* tga;
targa_header header;
int block_size = 10;
header.id_length = 0;
header.map_type = 1;
header.image_type = 1; // uncompressed RGB image
header.map_first = 0;
header.map_length = 256;
header.map_entry_size = 24;
header.x = 0;
header.y = 0;
int orig_width = 16;
int orig_height = 16;
header.width = orig_width * block_size + orig_width;
header.height = orig_height * block_size + orig_height + 1;
header.bits_per_pixel = 8;
header.misc = 0x20; // scan from upper left corner
tga = fopen("palette.tga", "wb");
write_header(header, tga);
FILE* palfile = fopen("/opt/carma1sp/DATA/REG/PALETTES/DRRENDER.PAL", "rb");
char pal[256 * 4];
fseek(palfile, 64, SEEK_SET);
fread(&pal, 4, 256, palfile);
for (int i = 0; i < 256; i++) {
fputc(pal[i * 4 + 3], tga);
fputc(pal[i * 4 + 2], tga);
fputc(pal[i * 4 + 1], tga);
printf("%d: %c %c %c\n", i, pal[i * 4 + 1], pal[i * 4 + 2], pal[i * 4 + 3]);
}
for (int black_line = 0; black_line < header.width; black_line++) {
fputc(0, tga);
}
for (int row = 0; row < orig_height; row++) {
for (int block_line = 0; block_line < block_size; block_line++) {
for (int col = 0; col < orig_width; col++) {
for (int b = 0; b < block_size; b++) {
fputc(row * orig_width + col, tga);
}
fputc(0, tga);
}
}
for (int black_line = 0; black_line < header.width; black_line++) {
fputc(0, tga);
}
}
fclose(tga);
return 0;
}
int dump_shadetable(void) {
FILE* tga;
targa_header header;
int block_size = 10;
header.id_length = 0;
header.map_type = 1;
header.image_type = 1; // uncompressed RGB image
header.map_first = 0;
header.map_length = 256;
header.map_entry_size = 24;
header.x = 0;
header.y = 0;
int orig_width = 256;
int orig_height = 16;
header.width = orig_width * block_size + orig_width;
header.height = orig_height * block_size + orig_height + 1;
header.bits_per_pixel = 8;
header.misc = 0x20; // scan from upper left corner
tga = fopen("shadetable.tga", "wb");
write_header(header, tga);
FILE* palfile = fopen("/opt/carma1sp/DATA/REG/PALETTES/DRRENDER.PAL", "rb");
char pal[256 * 4];
fseek(palfile, 64, SEEK_SET);
fread(&pal, 4, 256, palfile);
for (int i = 0; i < 256; i++) {
fputc(pal[i * 4 + 3], tga);
fputc(pal[i * 4 + 2], tga);
fputc(pal[i * 4 + 1], tga);
}
FILE* stfile = fopen("/opt/carma1sp/DATA/SHADETAB/STAAAAAA.TAB", "rb");
fseek(stfile, 52, SEEK_SET);
char st[256 * 16];
fread(&st, 256 * 16, 1, stfile);
for (int black_line = 0; black_line < header.width; black_line++) {
fputc(0, tga);
}
for (int row = 0; row < orig_height; row++) {
for (int block_line = 0; block_line < block_size; block_line++) {
for (int col = 0; col < orig_width; col++) {
for (int b = 0; b < block_size; b++) {
fputc(st[row * orig_width + col], tga);
}
fputc(0, tga);
}
}
for (int black_line = 0; black_line < header.width; black_line++) {
fputc(0, tga);
}
}
fclose(tga);
return 0;
}
int main() {
// dump_palette();
dump_shadetable();
return 0;
}