joeylib/vecdraw/main.c
2019-10-03 20:09:18 -05:00

338 lines
7.1 KiB
C

#include <ctype.h>
#include <stdio.h>
#include <string.h>
#include "joey.h"
#define MAX_LINE_SIZE 8192
#define STATE_COMMAND 1
#define STATE_NUMBER 2
#define STATE_EXECUTE 3
#define COMMAND_COLOR 1 // C
#define COMMAND_CLEAR 2 // E
#define COMMAND_PLOT 3 // D (Draw)
#define COMMAND_LINE 4 // L
#define COMMAND_FILL 5 // F
#define COMMAND_PALETTE 6 // P
#define COMMAND_RESET 7 // R
#define COMMAND_HBOX 8 // B (Box)
#define COMMAND_FBOX 9 // S (Solid Box)
#define COMMAND_FILLTO 10 // T (FillTo)
typedef struct {
char *keyword;
byte command;
byte args;
} CommandT;
static CommandT commands[] = {
{ "COLOR", COMMAND_COLOR, 1 },
{ "CLEAR", COMMAND_CLEAR, 0 },
{ "PLOT", COMMAND_PLOT, 2 },
{ "LINE", COMMAND_LINE, 2 },
{ "FILL", COMMAND_FILL, 2 },
{ "PALETTE", COMMAND_PALETTE, 4 },
{ "PAL", COMMAND_PALETTE, 4 },
{ "RESET", COMMAND_RESET, 0 },
{ "BOX", COMMAND_HBOX, 4 },
{ "FILLEDBOX", COMMAND_FBOX, 4 },
{ "FBOX", COMMAND_FBOX, 4 },
{ "FILLTO", COMMAND_FILLTO, 3 }
};
// Ugly Macros
#define EMIT_COMMAND fputc((byte)data[0], out)
#define EMIT_COUNT fputc((byte)count, out)
#define EMIT_BYTE fputc((byte)data[i], out)
#define EMIT_JINT16 _emitJint16(data[i], out);
void _emitJint16(jint16 data, FILE *out) {
#ifdef JOEY_LITLE_ENDIAN
fputc((byte)(data & 0xFF), out);
fputc((byte)(data >> 8), out);
#else
fputc((byte)(data >> 8), out);
fputc((byte)(data & 0xFF), out);
#endif
}
int _stricmp(const char *a, const char *b) {
int ca;
int cb;
do {
ca = (unsigned char)*a++;
cb = (unsigned char)*b++;
if (islower(ca)) ca = toupper(ca);
if (islower(cb)) cb = toupper(cb);
} while (ca == cb && ca != '\0');
return ca - cb;
}
int main(int argc, char *argv[]) {
FILE *in;
FILE *out = NULL;
char line[MAX_LINE_SIZE];
char *token;
int tokenLength;
jint16 data[1024];
int dIndex;
int state;
int args;
int count;
int i;
int x;
jint16 x1;
jint16 y1;
jint16 x2;
jint16 y2;
if (argc < 3) {
printf("Usage: %s [infile] [outfile]\n", argv[0]);
return 1;
}
jlUtilStartup("JoeyLib VecDraw");
jlDisplayBorder(BORDER_BLACK);
while (!jlUtilMustExit()) {
in = fopen(argv[1], "rt");
if (in == NULL) {
jlUtilShutdown();
}
out = fopen(argv[2], "wb");
if (out == NULL) {
fclose(in);
jlUtilShutdown();
}
fputs("VEC", out); // File "Magic"
fputc(0, out); // Version
while (fgets(line, MAX_LINE_SIZE, in) != NULL) {
state = STATE_COMMAND;
dIndex = 0;
token = strtok(line, " ");
while (token != NULL) {
tokenLength = (int)strlen(token);
if (tokenLength > 0) {
// Handle Comments
if (token[0] == '#') {
break;
}
// Handle EOLs
if ((token[tokenLength - 1] == 10) || (token[tokenLength - 1] == 13)) {
tokenLength--;
token[tokenLength] = 0;
}
if (tokenLength > 0) {
//printf("[%s] %d\n", token, dIndex);
// What is this?
if (state == STATE_COMMAND) {
for (i=0; i<(int)(sizeof(commands)/sizeof(CommandT)); i++) {
//printf("Checking [%s] == [%s]\n", token, commands[i].keyword);
if (_stricmp(token, commands[i].keyword) == 0) {
data[dIndex++] = commands[i].command;
state = (commands[i].args == 0 ? STATE_EXECUTE : STATE_NUMBER);
//printf("Found [%s] expecting %d args\n", token, commands[i].args);
break;
}
}
if (state == STATE_COMMAND) {
printf("Unknown command [%s]\n", token);
break;
}
} else {
if (state == STATE_NUMBER) {
data[dIndex++] = (jint16)atoi(token);
}
}
}
}
token = strtok(NULL, " ");
}
// Can we execute this?
if (dIndex > 0) {
args = dIndex - 1;
i = 1;
//printf("Command %d with %d args\n", data[0], args);
switch (data[0]) {
case COMMAND_COLOR:
if (args == 1) {
EMIT_COMMAND;
EMIT_BYTE;
jlDrawColorSet((byte)data[i]);
}
break;
case COMMAND_CLEAR:
if (args == 0) {
EMIT_COMMAND;
jlDrawClear();
}
break;
case COMMAND_PLOT:
count = args % 2;
if (count == 0) {
count = args / 2;
EMIT_COMMAND;
EMIT_COUNT;
for (x=0; x<count; x++) {
EMIT_JINT16;
x1 = data[i++];
EMIT_BYTE;
y1 = data[i++];
jlDrawPixelSet(x1, y1);
}
}
break;
case COMMAND_LINE:
count = args % 2;
if ((count == 0) && (args >= 4)) {
count = args / 2;
EMIT_COMMAND;
EMIT_COUNT;
EMIT_JINT16;
x1 = data[i++];
EMIT_BYTE;
y1 = data[i++];
for (x=1; x<count; x++) {
EMIT_JINT16;
x2 = data[i++];
EMIT_BYTE;
y2 = data[i++];
jlDrawLine(x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
}
break;
case COMMAND_FILL:
count = args % 2;
if (count == 0) {
count = args / 2;
EMIT_COMMAND;
EMIT_COUNT;
for (x=0; x<count; x++) {
EMIT_JINT16;
x1 = data[i++];
EMIT_BYTE;
y1 = data[i++];
jlDrawFill(x1, y1);
}
}
break;
case COMMAND_PALETTE:
count = args % 4;
if (count == 0) {
count = args / 4;
EMIT_COMMAND;
EMIT_COUNT;
for (x=0; x<count; x++) {
EMIT_BYTE;
x1 = data[i++];
EMIT_BYTE;
y1 = data[i++];
EMIT_BYTE;
x2 = data[i++];
EMIT_BYTE;
y2 = data[i++];
jlPaletteSet((byte)x1, (byte)y1, (byte)x2, (byte)y2);
}
}
break;
case COMMAND_RESET:
if (args == 0) {
EMIT_COMMAND;
jlPaletteDefault();
}
break;
case COMMAND_HBOX:
count = args % 4;
if (count == 0) {
count = args / 4;
EMIT_COMMAND;
EMIT_COUNT;
for (x=0; x<count; x++) {
EMIT_JINT16;
x1 = data[i++];
EMIT_BYTE;
y1 = data[i++];
EMIT_JINT16;
x2 = data[i++];
EMIT_BYTE;
y2 = data[i++];
jlDrawBox(x1, y1, x2, y2);
}
}
break;
case COMMAND_FBOX:
count = args % 4;
if (count == 0) {
count = args / 4;
EMIT_COMMAND;
EMIT_COUNT;
for (x=0; x<count; x++) {
EMIT_JINT16;
x1 = data[i++];
EMIT_BYTE;
y1 = data[i++];
EMIT_JINT16;
x2 = data[i++];
EMIT_BYTE;
y2 = data[i++];
jlDrawBoxFilled(x1, y1, x2, y2);
}
}
break;
case COMMAND_FILLTO:
count = args % 3;
if (count == 0) {
count = args / 3;
EMIT_COMMAND;
EMIT_COUNT;
for (x=0; x<count; x++) {
EMIT_JINT16;
x1 = data[i++];
EMIT_BYTE;
y1 = data[i++];
EMIT_BYTE;
x2 = data[i++];
jlDrawFillTo(x1, y1, (byte)x2);
}
}
break;
}
jlDisplayPresent();
}
}
fclose(out);
fclose(in);
jlKeyWaitForAny();
} // while not exiting
jlUtilShutdown();
}