Everything in Vector appears to be working. Not finished, but good enough to start testing.

This commit is contained in:
Scott Duensing 2022-12-09 18:08:46 -06:00
parent 116d469f5c
commit 0a7dfc1184
7 changed files with 162 additions and 103 deletions

View file

@ -24,10 +24,19 @@
#define COMMON_H #define COMMON_H
#define DEBUG // If we're debugging.
#include <gtk/gtk.h> #include <gtk/gtk.h>
#include "array.h" #include "array.h"
#ifdef DEBUG
#define debug(...) printf(__VA_ARGS__)
#define MEMWATCH #define MEMWATCH
#else
#define debug(s)
#endif
#include "memwatch.h" #include "memwatch.h"

View file

@ -29,6 +29,7 @@
char *utilCreateString(char *format, ...); char *utilCreateString(char *format, ...);
char *utilCreateStringVArgs(char *format, va_list args); char *utilCreateStringVArgs(char *format, va_list args);
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
gboolean utilFileExists(char *filename); gboolean utilFileExists(char *filename);
GdkPixbuf *utilGetPixbufFromMemory(char *data, unsigned int len); GdkPixbuf *utilGetPixbufFromMemory(char *data, unsigned int len);
WindowDataT *utilGetWindowData(GtkWidget *window); WindowDataT *utilGetWindowData(GtkWidget *window);

View file

@ -70,7 +70,7 @@ EVENT void toolJoeyDevProjectClicked(GtkWidget *object, gpointer userData) {
(void)object; (void)object;
(void)userData; (void)userData;
printf("Project Clicked!\n"); debug("Project Clicked!\n");
} }

View file

@ -62,6 +62,21 @@ char *utilCreateStringVArgs(char *format, va_list args) {
} }
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted) {
unsigned char *temp = NULL;
if (*length < wanted) {
*length = *length + 1024;
temp = realloc(*buffer, *length);
if (temp == NULL) {
//***TODO*** Something bad happened.
} else {
*buffer = temp;
}
}
}
gboolean utilFileExists(char *filename) { gboolean utilFileExists(char *filename) {
FILE *f = fopen(filename, "rb"); FILE *f = fopen(filename, "rb");

View file

@ -23,6 +23,7 @@
#include <errno.h> #include <errno.h>
#include "common.h" #include "common.h"
#include "vecparse.h" #include "vecparse.h"
#include "utils.h"
#define IS_NUMBER(n) (n & 0x8000 ? FALSE : TRUE) #define IS_NUMBER(n) (n & 0x8000 ? FALSE : TRUE)
@ -45,7 +46,6 @@ typedef struct LabelS {
} LabelT; } LabelT;
static void ensureBufferSize(VecByteCodeT *bytecode, int needed);
static int labelGetValue(int lineNumber, VecByteCodeT *bytecode, LabelT *labels, LabelT ***unresolved, char *label); static int labelGetValue(int lineNumber, VecByteCodeT *bytecode, LabelT *labels, LabelT ***unresolved, char *label);
static void outputByte(VecByteCodeT *bytecode, unsigned short word); static void outputByte(VecByteCodeT *bytecode, unsigned short word);
static void outputWord(VecByteCodeT *bytecode, unsigned short word); static void outputWord(VecByteCodeT *bytecode, unsigned short word);
@ -58,21 +58,6 @@ static gboolean parserGetXYZ(char **tokenEnd, char ***variables, int *x, int *y
static int variableCollect(char *value, char ***variables); static int variableCollect(char *value, char ***variables);
static void ensureBufferSize(VecByteCodeT *bytecode, int needed) {
unsigned char *temp = NULL;
if (bytecode->bufferSize < bytecode->length + needed) {
bytecode->bufferSize += 1024;
temp = realloc(bytecode->bytes, bytecode->bufferSize);
if (temp == NULL) {
//***TODO*** Something bad happened.
} else {
bytecode->bytes = temp;
}
}
}
static int labelGetValue(int lineNumber, VecByteCodeT *bytecode, LabelT *labels, LabelT ***unresolved, char *label) { static int labelGetValue(int lineNumber, VecByteCodeT *bytecode, LabelT *labels, LabelT ***unresolved, char *label) {
int index; int index;
int found = -1; int found = -1;
@ -105,7 +90,7 @@ static int labelGetValue(int lineNumber, VecByteCodeT *bytecode, LabelT *labels,
static void outputByte(VecByteCodeT *bytecode, unsigned short word) { static void outputByte(VecByteCodeT *bytecode, unsigned short word) {
unsigned char byte = (unsigned char)word; unsigned char byte = (unsigned char)word;
ensureBufferSize(bytecode, 1); utilEnsureBufferSize(&bytecode->bytes, &bytecode->bufferSize, bytecode->length + 1);
// If the word passed in is a variable, set the MSb in the byte as well. // If the word passed in is a variable, set the MSb in the byte as well.
if (word & 0x8000) { if (word & 0x8000) {
@ -117,7 +102,7 @@ static void outputByte(VecByteCodeT *bytecode, unsigned short word) {
static void outputWord(VecByteCodeT *bytecode, unsigned short word) { static void outputWord(VecByteCodeT *bytecode, unsigned short word) {
ensureBufferSize(bytecode, 2); utilEnsureBufferSize(&bytecode->bytes, &bytecode->bufferSize, bytecode->length + 2);
bytecode->bytes[bytecode->length++] = (word & 0xFF00) >> 8; bytecode->bytes[bytecode->length++] = (word & 0xFF00) >> 8;
bytecode->bytes[bytecode->length++] = word & 0x00FF; bytecode->bytes[bytecode->length++] = word & 0x00FF;
} }
@ -356,7 +341,7 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
} else { // blank line } else { // blank line
printf("[%s]\n", token); debug("[%s]\n", token);
// Is it math? // Is it math?
if (strlen(token) > 1 && token[0] == '%') { if (strlen(token) > 1 && token[0] == '%') {
@ -700,18 +685,19 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
} // read program line } // read program line
// Resolve forward label declarations and patch bytecode. // Resolve forward label declarations and patch bytecode.
//***DEBUG*** #ifdef DEBUG
for (y1=0; y1<shlen(labels); y1++) { for (y1=0; y1<shlen(labels); y1++) {
printf("Resolved - %s\n", labels[y1].key); debug("Resolved - %s\n", labels[y1].key);
} }
for (y1=0; y1<arrlen(unresolved); y1++) { for (y1=0; y1<arrlen(unresolved); y1++) {
printf("Unresolved - %s\n", unresolved[y1]->key); debug("Unresolved - %s\n", unresolved[y1]->key);
} }
#endif
for (y1=0; y1<arrlen(unresolved); y1++) { for (y1=0; y1<arrlen(unresolved); y1++) {
// Find offset of this unresolved label. We search ourselves so it's case-insensitive. // Find offset of this unresolved label. We search ourselves so it's case-insensitive.
x2 = -1; x2 = -1;
for (x1 = 0; x1 < shlen(labels); x1++) { for (x1 = 0; x1 < shlen(labels); x1++) {
printf("Checking label %d of %d - %s == %s\n", y1, (int)arrlen(unresolved), unresolved[y1]->key, labels[x1].key); debug("Checking label %d of %d - %s == %s\n", y1, (int)arrlen(unresolved), unresolved[y1]->key, labels[x1].key);
if (strcasecmp(unresolved[y1]->key, labels[x1].key) == 0) { if (strcasecmp(unresolved[y1]->key, labels[x1].key) == 0) {
x2 = x1; x2 = x1;
break; break;

View file

@ -38,6 +38,7 @@
#define VICTOR_VERSION "1.00" #define VICTOR_VERSION "1.00"
#define RENDER_TIMEOUT 5 // In seconds
#define SSM(m, w, l) scintilla_send_message(self->sci, m, w, l) #define SSM(m, w, l) scintilla_send_message(self->sci, m, w, l)
#define MARGIN_SCRIPT_FOLD_INDEX 1 #define MARGIN_SCRIPT_FOLD_INDEX 1
@ -66,6 +67,8 @@ typedef struct VectorDataS {
char *filename; char *filename;
char *title; char *title;
char *tracename; char *tracename;
char *buffer;
int bufferLength;
} VectorDataT; } VectorDataT;
@ -187,47 +190,44 @@ EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotifi
VectorDataT *self = (VectorDataT *)userData; VectorDataT *self = (VectorDataT *)userData;
int lineNumber = (int)SSM(SCI_LINEFROMPOSITION, (uptr_t)notifyData->position, (sptr_t)0); int lineNumber = (int)SSM(SCI_LINEFROMPOSITION, (uptr_t)notifyData->position, (sptr_t)0);
int length = SSM(SCI_GETLENGTH, 0, 0); int length = SSM(SCI_GETLENGTH, 0, 0);
char *code;
VecByteCodeT byteCode; VecByteCodeT byteCode;
(void)sciWidget; (void)sciWidget;
(void)ctrlID; (void)ctrlID;
//printf("Notification %d\n", notifyData->modificationType); //debug("Notification %d\n", notifyData->modificationType);
switch (notifyData->nmhdr.code) { switch (notifyData->nmhdr.code) {
case SCN_MODIFIED: case SCN_MODIFIED:
if (notifyData->modificationType & SC_MOD_INSERTTEXT || notifyData->modificationType & SC_MOD_DELETETEXT) { if (notifyData->modificationType & SC_MOD_INSERTTEXT || notifyData->modificationType & SC_MOD_DELETETEXT) {
// Allocate space to fetch code from editor. // Allocate space to fetch code from editor.
code = (char *)malloc(length + 1); utilEnsureBufferSize((unsigned char **)&self->buffer, &self->bufferLength, length);
if (!code) return;
// Clear error markers. // Clear error markers.
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0); SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0);
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0); SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0);
// Fetch code. // Fetch code.
SSM(SCI_GETTEXT, length, (sptr_t)code); SSM(SCI_GETTEXT, length, (sptr_t)self->buffer);
// Parse code. // Parse code.
byteCode.bytes = NULL; byteCode.bytes = NULL;
byteCode.length = 0; byteCode.length = 0;
byteCode.bufferSize = 0; byteCode.bufferSize = 0;
lineNumber = vecparser(code, &byteCode); lineNumber = vecparser(self->buffer, &byteCode);
if (lineNumber >= 0) { if (lineNumber >= 0) {
// Mark lines that fail to parse. // Mark lines that fail to parse.
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_ARROW); SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_ARROW);
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_HIGHLIGHT); SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_HIGHLIGHT);
} else { } else {
//***DEBUG*** #ifdef DEBUG
FILE *out = fopen("bytecode.bin", "wb"); FILE *out = fopen("bytecode.bin", "wb");
fwrite(byteCode.bytes, byteCode.length, 1, out); fwrite(byteCode.bytes, byteCode.length, 1, out);
fclose(out); fclose(out);
#endif
// All good! // All good!
renderBytecode(&byteCode, self); renderBytecode(&byteCode, self);
} }
// Release bytecode. // Release bytecode.
if (byteCode.bytes != NULL) DEL(byteCode.bytes); if (byteCode.bytes != NULL) DEL(byteCode.bytes);
// Release code.
DEL(code);
// Mark text dirty. SCN_SAVEPOINTLEFT isn't being reliable. // Mark text dirty. SCN_SAVEPOINTLEFT isn't being reliable.
setDirty(self, TRUE); setDirty(self, TRUE);
} }
@ -260,7 +260,7 @@ EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData; VectorDataT *self = (VectorDataT *)userData;
char *temp = NULL; char *temp = NULL;
printf("fileVectorTraceImageFileSet fired\n"); debug("fileVectorTraceImageFileSet fired\n");
temp = (char *)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(object)); temp = (char *)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(object));
loadTraceImage(self, temp); loadTraceImage(self, temp);
DEL(temp); DEL(temp);
@ -327,22 +327,38 @@ static void loadTraceImage(VectorDataT *self, char *filename) {
EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData) { EVENT void menuVectorEditCopy(GtkWidget *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData;
(void)object;
SSM(SCI_COPY, 0, 0);
} }
EVENT void menuVectorEditCut(GtkWidget *object, gpointer userData) { EVENT void menuVectorEditCut(GtkWidget *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData;
(void)object;
SSM(SCI_CUT, 0, 0);
} }
EVENT void menuVectorEditDelete(GtkWidget *object, gpointer userData) { EVENT void menuVectorEditDelete(GtkWidget *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData;
(void)object;
SSM(SCI_CLEAR, 0, 0);
} }
EVENT void menuVectorEditPaste(GtkWidget *object, gpointer userData) { EVENT void menuVectorEditPaste(GtkWidget *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData;
(void)object;
SSM(SCI_PASTE, 0, 0);
} }
@ -424,6 +440,7 @@ EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData) {
in = fopen(self->filename, "rt"); in = fopen(self->filename, "rt");
if (in != NULL) { if (in != NULL) {
self->buffer[0] = 0;
while (getline(&line, &len, in) != -1) { while (getline(&line, &len, in) != -1) {
switch (count) { switch (count) {
case 0: // Version Number case 0: // Version Number
@ -440,13 +457,15 @@ EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData) {
break; break;
default: // Code for editor default: // Code for editor
SSM(SCI_ADDTEXT, strlen(line), (sptr_t)line); utilEnsureBufferSize((unsigned char **)&self->buffer, &self->bufferLength, strlen(self->buffer) + strlen(line));
strcat(self->buffer, line);
break; break;
} }
count++; count++;
} }
fclose(in); fclose(in);
if (line != NULL) DEL(line); if (line != NULL) DEL(line);
SSM(SCI_ADDTEXT, strlen(self->buffer), (sptr_t)self->buffer);
setDirty(self, FALSE); // Do again - loading text marks us dirty. setDirty(self, FALSE); // Do again - loading text marks us dirty.
} else { } else {
//***TODO*** Something bad happened. //***TODO*** Something bad happened.
@ -528,26 +547,31 @@ EVENT void menuVectorFileSaveAs(GtkWidget *object, gpointer userData) {
EVENT void menuVectorHelpVector(GtkWidget *object, gpointer userData) { EVENT void menuVectorHelpVector(GtkWidget *object, gpointer userData) {
(void)object;
(void)userData;
gtk_show_uri_on_window(NULL, "https://skunkworks.kangaroopunch.com/skunkworks/joeydev/-/wikis/Victor-Vector-Editor", GDK_CURRENT_TIME, NULL);
} }
static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) { static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
int x1; int x1;
int y1; int y1;
int x2; int x2;
int y2; int y2;
int count; int count;
int i; int i;
float f1; float f1;
float f2; float f2;
int index = 0; time_t startTime;
int *stack = NULL; int index = 0;
int *stack = NULL;
GtkWidget *dialog;
#define GET_BYTE (bytecode->bytes[index++]) #define GET_BYTE (bytecode->bytes[index++])
#define GET_WORD getWord(bytecode, &index) #define GET_WORD getWord(bytecode, &index)
printf("-----------------------------------\n"); debug("-----------------------------------\n");
self->variables = NULL; self->variables = NULL;
@ -557,7 +581,9 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
jlDrawClear(self->jlc); jlDrawClear(self->jlc);
jlDrawColorSet(self->jlc, 15); jlDrawColorSet(self->jlc, 15);
while (index < bytecode->length) { startTime = time(NULL);
while (index < bytecode->length && difftime(time(NULL), startTime) < RENDER_TIMEOUT) {
switch (bytecode->bytes[index++]) { switch (bytecode->bytes[index++]) {
case PARSE_NONE: case PARSE_NONE:
@ -569,7 +595,7 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
y1 = word(self, GET_WORD); y1 = word(self, GET_WORD);
x2 = word(self, GET_WORD); x2 = word(self, GET_WORD);
y2 = word(self, GET_WORD); y2 = word(self, GET_WORD);
printf("Box %d,%d to %d,%d\n", x1, y1, x2, y2); debug("Box %d,%d to %d,%d\n", x1, y1, x2, y2);
jlDrawBox(self->jlc, x1, y1, x2, y2); jlDrawBox(self->jlc, x1, y1, x2, y2);
break; break;
@ -577,25 +603,25 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
x1 = word(self, GET_WORD); x1 = word(self, GET_WORD);
arrput(stack, index); arrput(stack, index);
index = x1; index = x1;
printf("Call %d\n", index); debug("Call %d\n", index);
break; break;
case PARSE_CIRCLE: case PARSE_CIRCLE:
y2 = word(self, GET_WORD); y2 = word(self, GET_WORD);
x1 = word(self, GET_WORD); x1 = word(self, GET_WORD);
y1 = word(self, GET_WORD); y1 = word(self, GET_WORD);
printf("Circle %d at %d,%d\n", y2, x1, y1); debug("Circle %d at %d,%d\n", y2, x1, y1);
jlDrawCircle(self->jlc, x1, y1, y2); jlDrawCircle(self->jlc, x1, y1, y2);
break; break;
case PARSE_CLEAR: case PARSE_CLEAR:
printf("Clear\n"); debug("Clear\n");
jlDrawClear(self->jlc); jlDrawClear(self->jlc);
break; break;
case PARSE_COLOR: case PARSE_COLOR:
x1 = byte(self, GET_BYTE); x1 = byte(self, GET_BYTE);
printf("Color %d\n", x1); debug("Color %d\n", x1);
jlDrawColorSet(self->jlc, x1); jlDrawColorSet(self->jlc, x1);
break; break;
@ -608,7 +634,7 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
y1 = word(self, GET_WORD); y1 = word(self, GET_WORD);
x2 = word(self, GET_WORD); x2 = word(self, GET_WORD);
y2 = word(self, GET_WORD); y2 = word(self, GET_WORD);
printf("Ellipse %d,%d to %d,%d\n", x1, y1, x2, y2); debug("Ellipse %d,%d to %d,%d\n", x1, y1, x2, y2);
jlDrawEllipse(self->jlc, x1, y1, x2, y2); jlDrawEllipse(self->jlc, x1, y1, x2, y2);
break; break;
@ -617,66 +643,66 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
y1 = word(self, GET_WORD); y1 = word(self, GET_WORD);
x2 = byte(self, GET_BYTE); x2 = byte(self, GET_BYTE);
if (x2 > 15) { if (x2 > 15) {
printf("Fill %d,%d\n", x1, y1); debug("Fill %d,%d\n", x1, y1);
jlDrawFill(self->jlc, x1, y1); jlDrawFill(self->jlc, x1, y1);
} else { } else {
printf("Fill %d,%d to %d\n", x1, y1, x2); debug("Fill %d,%d to %d\n", x1, y1, x2);
jlDrawFillTo(self->jlc, x1, y1, x2); jlDrawFillTo(self->jlc, x1, y1, x2);
} }
break; break;
case PARSE_GOTO: case PARSE_GOTO:
index = word(self, GET_WORD); index = word(self, GET_WORD);
printf("Goto %d\n", index); debug("Goto %d\n", index);
break; break;
case PARSE_IF: case PARSE_IF:
x1 = word(self, GET_WORD); // arg1 x1 = word(self, GET_WORD); // arg1
y1 = byte(self, GET_BYTE); // compare y1 = byte(self, GET_BYTE); // compare
x2 = word(self, GET_WORD); // arg2 x2 = word(self, GET_WORD); // arg2
printf("If %d ", x1); debug("If %d ", x1);
y2 = -1; y2 = -1;
switch (y1) { switch (y1) {
case 0: // == case 0: // ==
printf("=="); debug("==");
if (x1 == x2) y2 = 1; if (x1 == x2) y2 = 1;
break; break;
case 1: // != case 1: // !=
printf("!="); debug("!=");
if (x1 != x2) y2 = 1; if (x1 != x2) y2 = 1;
break; break;
case 2: // < case 2: // <
printf("<"); debug("<");
if (x1 < x2) y2 = 1; if (x1 < x2) y2 = 1;
break; break;
case 3: // > case 3: // >
printf(">"); debug(">");
if (x1 > x2) y2 = 1; if (x1 > x2) y2 = 1;
break; break;
case 4: // <= case 4: // <=
printf("<="); debug("<=");
if (x1 <= x2) y2 = 1; if (x1 <= x2) y2 = 1;
break; break;
case 5: // >= case 5: // >=
printf(">="); debug(">=");
if (x1 >= x2) y2 = 1; if (x1 >= x2) y2 = 1;
break; break;
} }
printf(" %d ", x2); debug(" %d ", x2);
x1 = byte(self, GET_BYTE); // goto/call x1 = byte(self, GET_BYTE); // goto/call
x2 = word(self, GET_WORD); // label x2 = word(self, GET_WORD); // label
printf(" %s %d ", (x1 == 0 ? "Goto" : "Call"), x2); debug(" %s %d ", (x1 == 0 ? "Goto" : "Call"), x2);
if (y2 > 0) { if (y2 > 0) {
if (x1 == 1) arrput(stack, index); if (x1 == 1) arrput(stack, index);
index = x2; index = x2;
printf("(true)"); debug("(true)");
} }
printf("\n"); debug("\n");
break; break;
case PARSE_LABEL: case PARSE_LABEL:
@ -686,16 +712,16 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
count = word(self, GET_WORD); count = word(self, GET_WORD);
x1 = word(self, GET_WORD); x1 = word(self, GET_WORD);
y1 = word(self, GET_WORD); y1 = word(self, GET_WORD);
printf("Line %d,%d", x1, y1); debug("Line %d,%d", x1, y1);
for (i=0; i<count - 1; i++) { for (i=0; i<count - 1; i++) {
x2 = word(self, GET_WORD); x2 = word(self, GET_WORD);
y2 = word(self, GET_WORD); y2 = word(self, GET_WORD);
printf(" to %d,%d", x2, y2); debug(" to %d,%d", x2, y2);
jlDrawLine(self->jlc, x1, y1, x2, y2); jlDrawLine(self->jlc, x1, y1, x2, y2);
x1 = x2; x1 = x2;
y1 = y2; y1 = y2;
} }
printf("\n"); debug("\n");
break; break;
case PARSE_MATH: case PARSE_MATH:
@ -709,7 +735,7 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
} }
x1 &= 0x7f; // Clear variable flag. x1 &= 0x7f; // Clear variable flag.
f1 = variable(self, x1); f1 = variable(self, x1);
printf("Math: %d: ", x1); debug("Math: %d: ", x1);
switch (y1) { switch (y1) {
case MATH_NONE: case MATH_NONE:
// Well, none! // Well, none!
@ -717,65 +743,65 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
case MATH_ASSIGN: case MATH_ASSIGN:
f1 = f2; f1 = f2;
printf("= %f", f2); debug("= %f", f2);
break; break;
case MATH_ADD: case MATH_ADD:
f1 += f2; f1 += f2;
printf("%f + %f", f1, f2); debug("%f + %f", f1, f2);
break; break;
case MATH_SUBTRACT: case MATH_SUBTRACT:
f1 -= f2; f1 -= f2;
printf("%f - %f", f1, f2); debug("%f - %f", f1, f2);
break; break;
case MATH_MULTIPLY: case MATH_MULTIPLY:
f1 *= f2; f1 *= f2;
printf("%f * %f", f1, f2); debug("%f * %f", f1, f2);
break; break;
case MATH_DIVIDE: case MATH_DIVIDE:
f1 /= f2; f1 /= f2;
printf("%f / %f", f1, f2); debug("%f / %f", f1, f2);
break; break;
case MATH_MOD: case MATH_MOD:
f1 = modff(f1, &f2); f1 = modff(f1, &f2);
printf("%f mod %f", f1, f2); debug("%f mod %f", f1, f2);
break; break;
case MATH_POW: case MATH_POW:
f1 = powf(f1, f2); f1 = powf(f1, f2);
printf("%f pow %f", f1, f2); debug("%f pow %f", f1, f2);
break; break;
case MATH_SQRT: case MATH_SQRT:
f1 = sqrtf(f2); f1 = sqrtf(f2);
printf("%f sqrt %f", f1, f2); debug("%f sqrt %f", f1, f2);
break; break;
case MATH_ABS: case MATH_ABS:
f1 = fabsf(f2); f1 = fabsf(f2);
printf("%f abs %f", f1, f2); debug("%f abs %f", f1, f2);
break; break;
case MATH_COS: case MATH_COS:
f1 = cosf(f2); f1 = cosf(f2);
printf("%f cos %f", f1, f2); debug("%f cos %f", f1, f2);
break; break;
case MATH_SIN: case MATH_SIN:
f1 = sinf(f2); f1 = sinf(f2);
printf("%f sin %f", f1, f2); debug("%f sin %f", f1, f2);
break; break;
case MATH_TAN: case MATH_TAN:
f1 = tanf(f2); f1 = tanf(f2);
printf("%f tan %f", f1, f2); debug("%f tan %f", f1, f2);
break; break;
} }
printf("\n"); debug("\n");
// Make sure we have enough slots for this variable. // Make sure we have enough slots for this variable.
while (arrlen(self->variables) <= x1) { while (arrlen(self->variables) <= x1) {
arrput(self->variables, 0.0f); arrput(self->variables, 0.0f);
@ -788,14 +814,14 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
x2 = byte(self, GET_BYTE); x2 = byte(self, GET_BYTE);
y1 = byte(self, GET_BYTE); y1 = byte(self, GET_BYTE);
y2 = byte(self, GET_BYTE); y2 = byte(self, GET_BYTE);
printf("Palette %d as %d,%d,%d\n", x1, x2, y1, y2); debug("Palette %d as %d,%d,%d\n", x1, x2, y1, y2);
jlPaletteSet(self->jlc, x1, x2, y1, y2); jlPaletteSet(self->jlc, x1, x2, y1, y2);
break; break;
case PARSE_PLOT: case PARSE_PLOT:
x1 = word(self, GET_WORD); x1 = word(self, GET_WORD);
y1 = word(self, GET_WORD); y1 = word(self, GET_WORD);
printf("Plot %d,%d\n", x1, y1); debug("Plot %d,%d\n", x1, y1);
jlDrawPixelSet(self->jlc, x1, y1); jlDrawPixelSet(self->jlc, x1, y1);
break; break;
@ -804,13 +830,13 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
y1 = word(self, GET_WORD); y1 = word(self, GET_WORD);
x2 = word(self, GET_WORD); x2 = word(self, GET_WORD);
y2 = word(self, GET_WORD); y2 = word(self, GET_WORD);
printf("Rectangle %d,%d to %d,%d\n", x1, y1, x2, y2); debug("Rectangle %d,%d to %d,%d\n", x1, y1, x2, y2);
jlDrawBoxFilled(self->jlc, x1, y1, x2, y2); jlDrawBoxFilled(self->jlc, x1, y1, x2, y2);
break; break;
case PARSE_RETURN: case PARSE_RETURN:
index = arrpop(stack); index = arrpop(stack);
printf("Return %d\n", index); debug("Return %d\n", index);
break; break;
} // switch } // switch
@ -828,6 +854,19 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
// Refresh widget. // Refresh widget.
gtk_widget_queue_draw(self->drawVectorImage); gtk_widget_queue_draw(self->drawVectorImage);
// Did execution time out?
if (index < bytecode->length) {
dialog = gtk_message_dialog_new(
GTK_WINDOW(self->windowData.window),
GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_MODAL,
GTK_MESSAGE_WARNING,
GTK_BUTTONS_OK,
"Rendering is taking too long! Stopped.\n\n(Did you create an infinite loop?)");
gtk_window_set_title(GTK_WINDOW(dialog), "Notice");
gtk_dialog_run(GTK_DIALOG(dialog));
gtk_widget_destroy(dialog);
}
} }
@ -930,6 +969,9 @@ void winVectorCreate(void) {
self = NEW(VectorDataT); self = NEW(VectorDataT);
self->windowData.closeWindow = winVectorClose; self->windowData.closeWindow = winVectorClose;
// Set up working buffer.
utilEnsureBufferSize((unsigned char **)&self->buffer, &self->bufferLength, 1024);
// Load widgets from XML. // Load widgets from XML.
widgets[0] = &self->windowData.window; widgets[0] = &self->windowData.window;
widgets[1] = &self->boxVectorForEditor; widgets[1] = &self->boxVectorForEditor;
@ -968,9 +1010,7 @@ void winVectorCreate(void) {
SSM(SCI_SETTABWIDTH, 3, 0); SSM(SCI_SETTABWIDTH, 3, 0);
SSM(SCI_SETMARGINWIDTHN, 0, (int)SSM(SCI_TEXTWIDTH, STYLE_LINENUMBER, (sptr_t)"_99999")); SSM(SCI_SETMARGINWIDTHN, 0, (int)SSM(SCI_TEXTWIDTH, STYLE_LINENUMBER, (sptr_t)"_99999"));
SSM(SCI_SETMARGINWIDTHN, 1, 16); SSM(SCI_SETMARGINWIDTHN, 1, 16);
SSM(SCI_SETWRAPMODE, SC_WRAP_WORD, 0); SSM(SCI_SETWRAPMODE, SC_WRAP_NONE, 0);
SSM(SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END, 0);
SSM(SCI_SETWRAPINDENTMODE, SC_WRAPINDENT_INDENT, 0);
SSM(SCI_SETCARETSTYLE, CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK, 0); SSM(SCI_SETCARETSTYLE, CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK, 0);
SSM(SCI_SETCARETFORE, 0x00ffff, 0); SSM(SCI_SETCARETFORE, 0x00ffff, 0);
SSM(SCI_STYLESETBACK, STYLE_LINENUMBER, 0x222222); SSM(SCI_STYLESETBACK, STYLE_LINENUMBER, 0x222222);
@ -1053,6 +1093,7 @@ static void winVectorDelete(gpointer userData) {
if (self->filename != NULL) DEL(self->filename); if (self->filename != NULL) DEL(self->filename);
if (self->title != NULL) DEL(self->title); if (self->title != NULL) DEL(self->title);
if (self->tracename != NULL) DEL(self->tracename); if (self->tracename != NULL) DEL(self->tracename);
if (self->buffer != NULL) DEL(self->buffer);
DEL(self); DEL(self);
} }

View file

@ -25,12 +25,10 @@
</patterns> </patterns>
</object> </object>
<object class="GtkWindow" id="winVector"> <object class="GtkWindow" id="winVector">
<property name="width-request">1500</property> <property name="width-request">1000</property>
<property name="height-request">600</property> <property name="height-request">500</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="title" translatable="yes">Vector</property> <property name="title" translatable="yes">Vector</property>
<property name="default-width">1500</property>
<property name="default-height">600</property>
<signal name="delete-event" handler="winVectorClose" swapped="no"/> <signal name="delete-event" handler="winVectorClose" swapped="no"/>
<child> <child>
<object class="GtkBox"> <object class="GtkBox">
@ -56,36 +54,40 @@
<object class="GtkMenuItem" id="menuVectorFileNew"> <object class="GtkMenuItem" id="menuVectorFileNew">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">_New</property> <property name="label" translatable="yes">New</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorFileNew" swapped="no"/> <signal name="activate" handler="menuVectorFileNew" swapped="no"/>
<accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="menuVectorFileOpen"> <object class="GtkMenuItem" id="menuVectorFileOpen">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">_Open...</property> <property name="label" translatable="yes">Open...</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorFileOpen" swapped="no"/> <signal name="activate" handler="menuVectorFileOpen" swapped="no"/>
<accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="menuVectorFileSave"> <object class="GtkMenuItem" id="menuVectorFileSave">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">_Save</property> <property name="label" translatable="yes">Save</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorFileSave" swapped="no"/> <signal name="activate" handler="menuVectorFileSave" swapped="no"/>
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="menuVectorFileSaveAs"> <object class="GtkMenuItem" id="menuVectorFileSaveAs">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">Save _As...</property> <property name="label" translatable="yes">Save As...</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorFileSaveAs" swapped="no"/> <signal name="activate" handler="menuVectorFileSaveAs" swapped="no"/>
<accelerator key="s" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
@ -98,9 +100,10 @@
<object class="GtkMenuItem" id="menuVectorFileClose"> <object class="GtkMenuItem" id="menuVectorFileClose">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">C_lose</property> <property name="label" translatable="yes">Close</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorFileClose" swapped="no"/> <signal name="activate" handler="menuVectorFileClose" swapped="no"/>
<accelerator key="F4" signal="activate" modifiers="GDK_MOD1_MASK"/>
</object> </object>
</child> </child>
</object> </object>
@ -124,15 +127,17 @@
<property name="label" translatable="yes">Cut</property> <property name="label" translatable="yes">Cut</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorEditCut" swapped="no"/> <signal name="activate" handler="menuVectorEditCut" swapped="no"/>
<accelerator key="x" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
<object class="GtkMenuItem" id="menuVectorEditCopy"> <object class="GtkMenuItem" id="menuVectorEditCopy">
<property name="visible">True</property> <property name="visible">True</property>
<property name="can-focus">False</property> <property name="can-focus">False</property>
<property name="label" translatable="yes">_Copy</property> <property name="label" translatable="yes">Copy</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorEditCopy" swapped="no"/> <signal name="activate" handler="menuVectorEditCopy" swapped="no"/>
<accelerator key="c" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
@ -142,6 +147,7 @@
<property name="label" translatable="yes">Paste</property> <property name="label" translatable="yes">Paste</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorEditPaste" swapped="no"/> <signal name="activate" handler="menuVectorEditPaste" swapped="no"/>
<accelerator key="v" signal="activate" modifiers="GDK_CONTROL_MASK"/>
</object> </object>
</child> </child>
<child> <child>
@ -174,6 +180,7 @@
<property name="label" translatable="yes">Vector Editor...</property> <property name="label" translatable="yes">Vector Editor...</property>
<property name="use-underline">True</property> <property name="use-underline">True</property>
<signal name="activate" handler="menuVectorHelpVector" swapped="no"/> <signal name="activate" handler="menuVectorHelpVector" swapped="no"/>
<accelerator key="F1" signal="activate"/>
</object> </object>
</child> </child>
</object> </object>