mirror of
https://gitlab.com/xCrystal/pokecrystal-board.git
synced 2024-09-09 09:51:34 -07:00
Rewrite tool png_dimensions.c, and start using common.h more
This commit is contained in:
parent
8f88e04401
commit
313deab552
@ -1,40 +1,102 @@
|
|||||||
#ifndef GUARD_COMMON_H
|
#ifndef GUARD_COMMON_H
|
||||||
#define GUARD_COMMON_H
|
#define GUARD_COMMON_H
|
||||||
|
|
||||||
int __getopt_long_i__;
|
#include <stdio.h>
|
||||||
#define getopt_long(c, v, s, l) getopt_long(c, v, s, l, &__getopt_long_i__)
|
#include <stdlib.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
FILE *fopen_verbose(char *filename, char *mode) {
|
int getopt_long_index;
|
||||||
|
#define getopt_long(c, v, s, l) getopt_long(c, v, s, l, &getopt_long_index)
|
||||||
|
|
||||||
|
void *malloc_verbose(size_t size) {
|
||||||
|
void *m = malloc(size);
|
||||||
|
if (!m) {
|
||||||
|
fprintf(stderr, "Could not allocate %zu bytes: %s\n", size, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE *fopen_verbose(const char *filename, char rw) {
|
||||||
|
char mode[3] = {rw, 'b', '\0'};
|
||||||
FILE *f = fopen(filename, mode);
|
FILE *f = fopen(filename, mode);
|
||||||
if (!f) {
|
if (!f) {
|
||||||
fprintf(stderr, "Could not open file: \"%s\"\n", filename);
|
fprintf(stderr, "Could not open file \"%s\": %s\n", filename, strerror(errno));
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t *read_u8(char *filename, int *size) {
|
void fread_verbose(uint8_t *data, size_t size, const char *filename, FILE *f) {
|
||||||
FILE *f = fopen_verbose(filename, "rb");
|
if (fread(data, 1, size, f) != size) {
|
||||||
if (!f) {
|
fprintf(stderr, "Could not read from file \"%s\": %s\n", filename, strerror(errno));
|
||||||
|
fclose(f);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
fseek(f, 0, SEEK_END);
|
}
|
||||||
*size = ftell(f);
|
|
||||||
rewind(f);
|
void fwrite_verbose(const uint8_t *data, size_t size, const char *filename, FILE *f) {
|
||||||
uint8_t *data = malloc(*size);
|
if (fwrite(data, 1, size, f) != size) {
|
||||||
if (*size != (int)fread(data, 1, *size, f)) {
|
fprintf(stderr, "Could not write to file \"%s\": %s\n", filename, strerror(errno));
|
||||||
fprintf(stderr, "Could not read file: \"%s\"\n", filename);
|
fclose(f);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long file_size(const char *filename, FILE *f) {
|
||||||
|
long size = 0;
|
||||||
|
if (!fseek(f, 0, SEEK_END)) {
|
||||||
|
size = ftell(f);
|
||||||
|
if (size != -1) {
|
||||||
|
rewind(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (errno) {
|
||||||
|
fprintf(stderr, "Could not measure file \"%s\": %s\n", filename, strerror(errno));
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t *read_u8(const char *filename, long *size) {
|
||||||
|
FILE *f = fopen_verbose(filename, 'r');
|
||||||
|
*size = file_size(filename, f);
|
||||||
|
uint8_t *data = malloc_verbose(*size);
|
||||||
|
fread_verbose(data, *size, filename, f);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_u8(char *filename, uint8_t *data, int size) {
|
void write_u8(const char *filename, uint8_t *data, size_t size) {
|
||||||
FILE *f = fopen_verbose(filename, "wb");
|
FILE *f = fopen_verbose(filename, 'w');
|
||||||
if (f) {
|
fwrite_verbose(data, size, filename, f);
|
||||||
fwrite(data, 1, size, f);
|
fclose(f);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t read_png_width_verbose(const char *filename) {
|
||||||
|
FILE *f = fopen_verbose(filename, 'r');
|
||||||
|
uint8_t header[16] = {0};
|
||||||
|
fread_verbose(header, sizeof(header), filename, f);
|
||||||
|
static uint8_t expected_header[16] = {
|
||||||
|
0x89, 'P', 'N', 'G', '\r', '\n', 0x1A, '\n', // signature
|
||||||
|
0, 0, 0, 13, // IHDR chunk length
|
||||||
|
'I', 'H', 'D', 'R', // IHDR chunk type
|
||||||
|
};
|
||||||
|
if (memcmp(header, expected_header, sizeof(header))) {
|
||||||
|
fprintf(stderr, "Not a valid PNG file: \"%s\"\n", filename);
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
|
uint8_t bytes[4] = {0};
|
||||||
|
fread_verbose(bytes, sizeof(bytes), filename, f);
|
||||||
|
fclose(f);
|
||||||
|
return (bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3];
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // GUARD_COMMON_H
|
#endif // GUARD_COMMON_H
|
||||||
|
29
tools/gfx.c
29
tools/gfx.c
@ -104,7 +104,7 @@ void shift_preserved(int removed_index) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct Graphic {
|
struct Graphic {
|
||||||
int size;
|
long size;
|
||||||
uint8_t *data;
|
uint8_t *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -270,31 +270,6 @@ void interleave(struct Graphic *graphic, int width) {
|
|||||||
free(interleaved);
|
free(interleaved);
|
||||||
}
|
}
|
||||||
|
|
||||||
int png_get_width(char *filename) {
|
|
||||||
FILE *f = fopen_verbose(filename, "rb");
|
|
||||||
if (!f) {
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const int OFFSET_WIDTH = 16;
|
|
||||||
uint8_t bytes[4];
|
|
||||||
fseek(f, OFFSET_WIDTH, SEEK_SET);
|
|
||||||
size_t size = 4;
|
|
||||||
size_t result = fread(bytes, 1, size, f);
|
|
||||||
fclose(f);
|
|
||||||
if (result != size) {
|
|
||||||
fprintf(stderr, "Could not read file at offset 0x%x: \"%s\"\n", OFFSET_WIDTH, filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int width = 0;
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
width |= bytes[i] << (8 * (3 - i));
|
|
||||||
}
|
|
||||||
return width;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
get_args(argc, argv);
|
get_args(argc, argv);
|
||||||
argc -= optind;
|
argc -= optind;
|
||||||
@ -319,7 +294,7 @@ int main(int argc, char *argv[]) {
|
|||||||
usage();
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
int width = png_get_width(Options.png_file);
|
int width = read_png_width_verbose(Options.png_file);
|
||||||
interleave(&graphic, width);
|
interleave(&graphic, width);
|
||||||
}
|
}
|
||||||
if (Options.remove_duplicates) {
|
if (Options.remove_duplicates) {
|
||||||
|
@ -1,57 +1,25 @@
|
|||||||
#include <stdio.h>
|
#include "common.h"
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
void usage(void) {
|
void usage() {
|
||||||
fprintf(stderr, "Usage: png_dimensions infile outfile\n");
|
fprintf(stderr, "Usage: png_dimensions in.png out.dimensions\n");
|
||||||
exit(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void output_dimensions(char* png_filename, char* out_filename) {
|
uint8_t read_dimensions(const char *filename) {
|
||||||
FILE* f;
|
uint32_t width_px = read_png_width_verbose(filename);
|
||||||
int width, height;
|
if (width_px != 40 && width_px != 48 && width_px != 56) {
|
||||||
int i;
|
fprintf(stderr, "Not a valid width for \"%s\": %" PRIu32 " px\n", filename, width_px);
|
||||||
uint8_t bytes[4];
|
|
||||||
uint8_t output;
|
|
||||||
|
|
||||||
f = fopen(png_filename, "rb");
|
|
||||||
if (f == NULL) {
|
|
||||||
fprintf(stderr, "failed to open file %s\n", png_filename);
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
uint8_t width_tiles = (uint8_t)(width_px / 8);
|
||||||
// width
|
return (width_tiles << 4) | width_tiles;
|
||||||
fseek(f, 16, SEEK_SET);
|
|
||||||
int size = fread(bytes, 1, 4, f);
|
|
||||||
fclose(f);
|
|
||||||
if (size != 4) {
|
|
||||||
fprintf(stderr, "failed to read at offset 0x10 in file %s\n", png_filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
width = 0;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
width |= bytes[i] << (8 * (3 - i));
|
|
||||||
}
|
|
||||||
width >>= 3;
|
|
||||||
height = width;
|
|
||||||
|
|
||||||
output = width & 0xf;
|
|
||||||
output |= (height & 0xf) << 4;
|
|
||||||
|
|
||||||
f = fopen(out_filename, "wb");
|
|
||||||
if (f == NULL) {
|
|
||||||
fprintf(stderr, "failed to open file %s\n", out_filename);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
fwrite(&output, 1, 1, f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char* argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc < 3) {
|
if (argc < 3) {
|
||||||
usage();
|
usage();
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
output_dimensions(argv[1], argv[2]);
|
uint8_t output_byte = read_dimensions(argv[1]);
|
||||||
|
write_u8(argv[2], &output_byte, 1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,3 @@
|
|||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include <getopt.h>
|
|
||||||
|
|
||||||
#include "common.h"
|
#include "common.h"
|
||||||
|
|
||||||
// The Game Boy cartridge header stores a global checksum at 0x014E-0x014F
|
// The Game Boy cartridge header stores a global checksum at 0x014E-0x014F
|
||||||
@ -160,7 +153,7 @@ int main(int argc, char *argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
char *filename = argv[0];
|
char *filename = argv[0];
|
||||||
int filesize;
|
long filesize;
|
||||||
uint8_t *file = read_u8(filename, &filesize);
|
uint8_t *file = read_u8(filename, &filesize);
|
||||||
calculate_checksums(file, filesize, base);
|
calculate_checksums(file, filesize, base);
|
||||||
write_u8(filename, file, filesize);
|
write_u8(filename, file, filesize);
|
||||||
|
Loading…
Reference in New Issue
Block a user