158 lines
3.9 KiB
C
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;
|
|
}
|