diff options
Diffstat (limited to 'ascii2map.c')
-rw-r--r-- | ascii2map.c | 350 |
1 files changed, 350 insertions, 0 deletions
diff --git a/ascii2map.c b/ascii2map.c new file mode 100644 index 0000000..d545782 --- /dev/null +++ b/ascii2map.c @@ -0,0 +1,350 @@ +/* + + ascii2map - Simple ASCII map converter aimed at retro code + + Copyright (C) 2003-2015 Ian Cowburn (ianc@noddybox.co.uk) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + + ------------------------------------------------------------------------- + + Main + +*/ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> + +/* ---------------------------------------- VERSION INFO +*/ + +static const char *usage = +"Version 0.0 development\n" +"\n" +"This program is distributed in the hope that it will be useful,\n" +"but WITHOUT ANY WARRANTY; without even the implied warranty of\n" +"MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" +"GNU General Public License (Version 3) for more details.\n" +"\n" +"usage: ascii2map [-a|-b|-c] [-d directive] [input-file [output-file]]\n"; + + +/* ---------------------------------------- TYPES +*/ +typedef unsigned char uchar; + +typedef enum +{ + Assembly, + Binary, + CSource +} Mode; + + +/* ---------------------------------------- GLOBALS +*/ +static int code_point = 'A'; +static uchar point[256]; +static uchar used[256]; +static const char *directive = "byte"; +static Mode mode = Assembly; + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static void Chomp(char *p) +{ + size_t l = strlen(p); + + while(l && (p[l-1] == '\n' || p[l-1] == '\r')) + { + p[--l] = 0; + } +} + + +static void StartOutput(FILE *fp) +{ + switch(mode) + { + case CSource: + fprintf(fp, "int map[] =\n{\n"); + break; + + default: + break; + } +} + + +static void EndOutput(FILE *fp) +{ + switch(mode) + { + case Assembly: + fprintf(fp, "\n"); + break; + + case CSource: + fprintf(fp, "\n};\n"); + break; + + default: + break; + } +} + + +static void Output(FILE *fp, char c) +{ + static int column; + static int first = 1; + + if (c < 0 || c > 255) + { + return; + } + + switch(mode) + { + case Assembly: + if (column == 0) + { + if (!first) + { + fprintf(fp, "\n"); + } + + fprintf(fp, "\t%s\t", directive); + } + else + { + fprintf(fp, ", "); + } + + if (used[c]) + { + fprintf(fp, "%u", point[c]); + } + else + { + fprintf(fp, "%u", c - code_point); + } + + break; + + case Binary: + if (used[c]) + { + putc(point[c], fp); + } + else + { + putc(c - code_point, fp); + } + + break; + + case CSource: + if (!first) + { + fprintf(fp, ", "); + } + + if (column == 0) + { + if (!first) + { + fprintf(fp, "\n"); + } + + fprintf(fp, "\t"); + } + + if (used[c]) + { + fprintf(fp, "%u", point[c]); + } + else + { + fprintf(fp, "%u", c - code_point); + } + + break; + } + + column = (column + 1) % 8; + + if (first) + { + first = 0; + } +} + + +/* ---------------------------------------- MAIN +*/ +int main(int argc, char *argv[]) +{ + FILE *in; + FILE *out; + char line[1024]; + int f; + int in_map = 0; + + f = 1; + + /* Process switches + */ + while(argv[f] && argv[f][0] == '-') + { + int handled = 1; + + switch(argv[f][1]) + { + case 'a': + mode = Assembly; + break; + + case 'b': + mode = Binary; + break; + + case 'c': + mode = CSource; + break; + + case 'd': + if (argv[f+1]) + { + directive = argv[++f]; + } + else + { + handled = 0; + } + break; + + default: + handled = 0; + break; + } + + if (!handled) + { + fprintf(stderr,"%s\n", usage); + exit(EXIT_FAILURE); + } + + f++; + } + + /* Handle file args + */ + if (argv[f]) + { + in = fopen(argv[f], "r"); + + if (!in) + { + fprintf(stderr,"Failed to open %s\n", argv[f]); + exit(EXIT_FAILURE); + } + + f++; + } + else + { + in = stdin; + } + + if (argv[f]) + { + if (mode == Binary) + { + out = fopen(argv[f], "wb"); + } + else + { + out = fopen(argv[f], "w"); + } + + if (!in) + { + fprintf(stderr,"Failed to open %s\n", argv[f]); + exit(EXIT_FAILURE); + } + } + else + { + out = stdout; + } + + /* Process input + */ + used[' '] = 1; + + while(fgets(line, sizeof line, in)) + { + Chomp(line); + + if (in_map) + { + char *p; + + p = line; + + while(*p) + { + Output(out, *p++); + } + } + else + { + if (strcmp(line, "~") == 0) + { + StartOutput(out); + in_map = 1; + } + + if (line[0] == '!') + { + code_point = atoi(line + 1); + } + + if (line[0] && line[1] == ':' && line[2]) + { + char c; + int i; + + c = line[0]; + i = atoi(line + 2); + + if (c >= 0 && c <= 255) + { + point[c] = i; + used[c] = 1; + } + } + } + } + + EndOutput(out); + + return EXIT_SUCCESS; +} + + +/* +vim: ai sw=4 ts=8 expandtab +*/ |