warehouse/importer/main.c
2020-07-26 20:37:46 -05:00

115 lines
2.4 KiB
C

#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define MAX_WIDTH 20
#define MAX_HEIGHT 12
#define MAX_LINE 8192
int isLegal(char c) {
int x;
char legal[] = { "_# .$@+*" };
if (c == '-') c = ' ';
for (x=0; x<(int)strlen(legal); x++) {
if (legal[x] == c) {
return x + 1;
}
}
return 0;
}
int main(int argc, char *argv[]) {
char puzzle[MAX_WIDTH][MAX_WIDTH];
char line[MAX_LINE]; // Ooo! Look! Potential buffer overflow!
char height;
unsigned char width;
int16_t x;
int16_t y;
int16_t count = 0;
int32_t bytes = 0;
FILE *in;
FILE *out;
if (argc != 3) {
printf("%s: [letslogic.txt] [puzzles.dat]\n", argv[0]);
return 1;
}
in = fopen(argv[1], "rt");
if (!in) {
printf("Unable to read %s\n", argv[1]);
return 2;
}
out = fopen(argv[2], "wb");
if (!out) {
fclose(in);
printf("Unable to write %s\n", argv[2]);
return 2;
}
// Skip two bytes at the front of the file to later write the puzzle count into.
fputc(0, out);
fputc(0, out);
bytes = 2;
count = 0;
height = -1;
width = 0;
while (fgets(line, MAX_LINE, in)) {
// Is there anything on this line?
if (strlen(line) > 0) {
// Is this a puzzle line?
if (isLegal(line[0]) > 0) {
// Got it. Read this line.
if (width < strlen(line)) width = strlen(line);
height++;
for (x=0; x<width; x++) {
puzzle[x][(int)height] = line[x];
}
} else {
// Not a puzzle line. Were we currently reading a puzzle?
if (height >= 0) {
// Yep! Output it!
if ((width & 1) == 1) {
// Width must be even - fill new column with zeros.
for (y=0; y<height; y++) puzzle[width][y] = 0;
width++;
}
fputc(width, out);
fputc(height + 1, out);
bytes += 2;
// Write out the puzzle data, two tiles to a byte.
for (y=0; y<height; y++) {
for (x=0; x<width; x+=2) {
fputc((isLegal(puzzle[x][y]) << 4) + isLegal(puzzle[x + 1][y]), out);
bytes++;
}
}
// Reset for next pass.
count++;
width = 0;
height = -1;
printf("Puzzle %d imported, %d total bytes written.\n", count, bytes);
}
}
}
}
// Seek back to the top and write the number of puzzles found.
fflush(out);
fseek(out, 0, SEEK_SET);
fwrite(&count, sizeof(int16_t), 1, out);
fclose(out);
fclose(in);
return 0;
}