aboutsummaryrefslogtreecommitdiff
path: root/dla2csv.c
diff options
context:
space:
mode:
authorB. Watson <urchlay@slackware.uk>2022-11-09 17:12:04 -0500
committerB. Watson <urchlay@slackware.uk>2022-11-09 17:12:04 -0500
commit72e6cbfc6a4b4606f11a6d5285de65238dc0dbd4 (patch)
tree7abed0201fbfb1529c479b1d9f7bed4c77945f69 /dla2csv.c
parent31e99ed8e4f83d98afb744fbc880b1c9685b556b (diff)
downloaddla-asm-72e6cbfc6a4b4606f11a6d5285de65238dc0dbd4.tar.gz
Added dla2csv, dla2img. Split up docs.
Diffstat (limited to 'dla2csv.c')
-rw-r--r--dla2csv.c155
1 files changed, 155 insertions, 0 deletions
diff --git a/dla2csv.c b/dla2csv.c
new file mode 100644
index 0000000..4605761
--- /dev/null
+++ b/dla2csv.c
@@ -0,0 +1,155 @@
+/* dla2csv.c - convert dla.xex save files to CSV.
+ Rather bloated and slow by Atari standards. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define HEIGHT 170
+#define WIDTH 256
+
+/* cc65 doesn't fold constants, it won't let us do this:
+ #define INBUF_SIZE (WIDTH * HEIGHT)
+ ...it has to be a *constant*. */
+#define INBUF_SIZE 5440
+
+/* cc65 doesn't "localize" \b to the Atari backspace character, so: */
+#ifdef __ATARI__
+ #define BS '\x7e'
+#else
+ #define BS '\b'
+#endif
+
+char inbuf[INBUF_SIZE];
+
+FILE *inf, *outf;
+
+char stringbuf[256];
+
+/* don't use "\n" or "\r\n" on the right hand side, use explicit
+ hex codes, to avoid cc65 tampering with them. */
+char *eoltypes[][2] = {
+ { "Atari ($9B)", "\x9b" },
+ { "Unix (\\n)", "\x0a" },
+ { "MS (\\r\\n)", "\x0d\x0a" },
+ { NULL, NULL }
+};
+
+/* read a string from stdin (E: on the Atari). there could
+ be error checking here, but there's not. */
+void readstring(void) {
+ fgets(stringbuf, 256, stdin);
+}
+
+/* prompt for a filename, try to open it. if there's an error,
+ show error message and retry. will not return until it
+ opens the file.
+ there could be code here to prepend D: if it's missing, but
+ there isn't.
+ */
+FILE *prompt_filename(const char *name, const char *mode) {
+ FILE *f = NULL;
+ while(f == NULL) {
+ printf("\n%s file: ", name);
+ fflush(stdout);
+ readstring();
+ stringbuf[strlen(stringbuf) - 1] = '\0';
+ f = fopen(stringbuf, mode);
+ if(!f) perror(stringbuf);
+ }
+ return f;
+}
+
+/* prompt for and read EOL type, retry if needed. will not return
+ until a valid number was entered. */
+char *prompt_eol(void) {
+ int i;
+
+ putchar('\n');
+ for(i = 0; eoltypes[i][0] != NULL; i++) {
+ printf("%d:%s ", i + 1, eoltypes[i][0]);
+ }
+ putchar('\n');
+
+ i = -1;
+ while(i == -1) {
+ printf("Line ending type[1]? ");
+ fflush(stdout);
+ readstring();
+ if(stringbuf[0] == '\n') {
+ i = 0;
+ } else {
+ i = stringbuf[0] - 49; /* ascii 1-3 => 0-2 */
+ if(i < 0 || i > 2)
+ i = -1;
+ }
+ }
+ return eoltypes[i][1];
+}
+
+void backspace3(void) {
+ putchar(BS);
+ putchar(BS);
+ putchar(BS);
+}
+
+int main(int argc, char **argv) {
+ char *inp, *eol;
+ int bytes = 0, x, y, xmask;
+
+ printf("DLA to CSV converter.\n");
+ while(1) {
+ /* read whole input file into memory */
+ inf = prompt_filename("Input DLA", "rb");
+ printf("Reading...");
+ fflush(stdout);
+ bytes = fread(inbuf, 1, INBUF_SIZE, inf);
+ if(bytes <= 0) {
+ perror(stringbuf);
+ continue;
+ }
+ fclose(inf);
+ printf("Read %d bytes.\n", bytes);
+
+ eol = prompt_eol();
+
+ outf = prompt_filename("Output CSV", "wb");
+
+ printf("\nConverting... ");
+ fflush(stdout);
+
+ /* CSV file header row (column names) */
+ fprintf(outf, "x,y%s", eol);
+
+ /* write output file one line at a time */
+ inp = inbuf;
+ xmask = 0x80;
+ bytes = 0;
+ for(y = 0; y < HEIGHT; y++) {
+ backspace3();
+ printf("%02d%%", y * 100 / HEIGHT); /* percentage */
+ fflush(stdout);
+ for(x = 0; x < WIDTH; x++) {
+ if(*inp & xmask) {
+ fprintf(outf, "%d,%d%s", x, y, eol);
+ bytes++;
+ }
+ xmask >>= 1;
+ if(!xmask) {
+ xmask = 0x80;
+ inp++;
+ }
+ }
+ }
+ fclose(outf);
+ backspace3();
+ printf("100%%\n%d particles.\n", bytes);
+
+ printf("\nConvert another file[Y/n]? ");
+ fflush(stdout);
+ readstring();
+ if(stringbuf[0] == 'n' || stringbuf[0] == 'N')
+ return 0;
+ }
+}