warehouse/importer/main.c
2020-07-27 19:41:23 -05:00

158 lines
3.9 KiB
C

/*
* Warehouse for JoeyLib - A Sokoban Clone
* Copyright (C) 2020 Scott Duensing <scott@kangaroopunch.com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#define MAX_WIDTH 20
#define MAX_HEIGHT 12
#define MAX_LINE 8192
static char puzzleChars[] = { "_# .$@+*" };
int isLegal(char c) {
int x;
if (c == '-') c = ' ';
for (x=0; x<(int)strlen(puzzleChars); x++) {
if (puzzleChars[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;
unsigned char b1;
unsigned char b2;
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 a newline to remove?
if ((strlen(line) > 0) && (line[strlen(line) - 1] == '\n')) {
line[strlen(line) - 1] = 0;
}
// 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);
printf("Width %d\n", width);
}
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!
height++; // Make it 1 based ('width' has been 1 based the whole time)
if ((width & 1) == 1) {
// Width must be even - fill new column with 1, which will become zero below.
for (y=0; y<height; y++) {
puzzle[width][y] = 1;
}
width++;
printf("Increased width to %d\n", width);
}
fputc(width, out);
fputc(height, out);
bytes += 2;
// Write out the puzzle data, two tiles to a byte.
printf("%dx%d\n", width, height);
for (y=0; y<height; y++) {
for (x=0; x<width; x+=2) {
b1 = isLegal(puzzle[x][y]) - 1;
b2 = isLegal(puzzle[x + 1][y]) - 1;
printf("%c%c", puzzleChars[b1], puzzleChars[b2]);
fputc((b1 << 4) + b2, out);
bytes++;
}
printf("\n");
}
// Reset for next pass.
count++;
width = 0;
height = -1;
printf("Puzzle %d imported, %d total bytes written.\n", count, bytes);
break;
}
}
}
}
// 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;
}