Everything in Vector appears to be working. Not finished, but good enough to start testing.
This commit is contained in:
parent
116d469f5c
commit
0a7dfc1184
7 changed files with 162 additions and 103 deletions
|
@ -24,10 +24,19 @@
|
|||
#define COMMON_H
|
||||
|
||||
|
||||
#define DEBUG // If we're debugging.
|
||||
|
||||
|
||||
#include <gtk/gtk.h>
|
||||
#include "array.h"
|
||||
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debug(...) printf(__VA_ARGS__)
|
||||
#define MEMWATCH
|
||||
#else
|
||||
#define debug(s)
|
||||
#endif
|
||||
#include "memwatch.h"
|
||||
|
||||
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
|
||||
char *utilCreateString(char *format, ...);
|
||||
char *utilCreateStringVArgs(char *format, va_list args);
|
||||
void utilEnsureBufferSize(unsigned char **buffer, int *length, int wanted);
|
||||
gboolean utilFileExists(char *filename);
|
||||
GdkPixbuf *utilGetPixbufFromMemory(char *data, unsigned int len);
|
||||
WindowDataT *utilGetWindowData(GtkWidget *window);
|
||||
|
|
|
@ -70,7 +70,7 @@ EVENT void toolJoeyDevProjectClicked(GtkWidget *object, gpointer userData) {
|
|||
(void)object;
|
||||
(void)userData;
|
||||
|
||||
printf("Project Clicked!\n");
|
||||
debug("Project Clicked!\n");
|
||||
}
|
||||
|
||||
|
||||
|
|
15
src/utils.c
15
src/utils.c
|
@ -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) {
|
||||
FILE *f = fopen(filename, "rb");
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include <errno.h>
|
||||
#include "common.h"
|
||||
#include "vecparse.h"
|
||||
#include "utils.h"
|
||||
|
||||
|
||||
#define IS_NUMBER(n) (n & 0x8000 ? FALSE : TRUE)
|
||||
|
@ -45,7 +46,6 @@ typedef struct LabelS {
|
|||
} LabelT;
|
||||
|
||||
|
||||
static void ensureBufferSize(VecByteCodeT *bytecode, int needed);
|
||||
static int labelGetValue(int lineNumber, VecByteCodeT *bytecode, LabelT *labels, LabelT ***unresolved, char *label);
|
||||
static void outputByte(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 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) {
|
||||
int index;
|
||||
int found = -1;
|
||||
|
@ -105,7 +90,7 @@ static int labelGetValue(int lineNumber, VecByteCodeT *bytecode, LabelT *labels,
|
|||
static void outputByte(VecByteCodeT *bytecode, unsigned short 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 (word & 0x8000) {
|
||||
|
@ -117,7 +102,7 @@ static void outputByte(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 & 0x00FF;
|
||||
}
|
||||
|
@ -356,7 +341,7 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
|
|||
|
||||
} else { // blank line
|
||||
|
||||
printf("[%s]\n", token);
|
||||
debug("[%s]\n", token);
|
||||
|
||||
// Is it math?
|
||||
if (strlen(token) > 1 && token[0] == '%') {
|
||||
|
@ -700,18 +685,19 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
|
|||
} // read program line
|
||||
|
||||
// Resolve forward label declarations and patch bytecode.
|
||||
//***DEBUG***
|
||||
#ifdef DEBUG
|
||||
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++) {
|
||||
printf("Unresolved - %s\n", unresolved[y1]->key);
|
||||
debug("Unresolved - %s\n", unresolved[y1]->key);
|
||||
}
|
||||
#endif
|
||||
for (y1=0; y1<arrlen(unresolved); y1++) {
|
||||
// Find offset of this unresolved label. We search ourselves so it's case-insensitive.
|
||||
x2 = -1;
|
||||
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) {
|
||||
x2 = x1;
|
||||
break;
|
||||
|
|
179
src/vector.c
179
src/vector.c
|
@ -38,6 +38,7 @@
|
|||
|
||||
|
||||
#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 MARGIN_SCRIPT_FOLD_INDEX 1
|
||||
|
@ -66,6 +67,8 @@ typedef struct VectorDataS {
|
|||
char *filename;
|
||||
char *title;
|
||||
char *tracename;
|
||||
char *buffer;
|
||||
int bufferLength;
|
||||
} VectorDataT;
|
||||
|
||||
|
||||
|
@ -187,47 +190,44 @@ EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotifi
|
|||
VectorDataT *self = (VectorDataT *)userData;
|
||||
int lineNumber = (int)SSM(SCI_LINEFROMPOSITION, (uptr_t)notifyData->position, (sptr_t)0);
|
||||
int length = SSM(SCI_GETLENGTH, 0, 0);
|
||||
char *code;
|
||||
VecByteCodeT byteCode;
|
||||
|
||||
(void)sciWidget;
|
||||
(void)ctrlID;
|
||||
|
||||
//printf("Notification %d\n", notifyData->modificationType);
|
||||
//debug("Notification %d\n", notifyData->modificationType);
|
||||
|
||||
switch (notifyData->nmhdr.code) {
|
||||
case SCN_MODIFIED:
|
||||
if (notifyData->modificationType & SC_MOD_INSERTTEXT || notifyData->modificationType & SC_MOD_DELETETEXT) {
|
||||
// Allocate space to fetch code from editor.
|
||||
code = (char *)malloc(length + 1);
|
||||
if (!code) return;
|
||||
utilEnsureBufferSize((unsigned char **)&self->buffer, &self->bufferLength, length);
|
||||
// Clear error markers.
|
||||
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_ARROW, 0);
|
||||
SSM(SCI_MARKERDELETEALL, MARKER_ERROR_HIGHLIGHT, 0);
|
||||
// Fetch code.
|
||||
SSM(SCI_GETTEXT, length, (sptr_t)code);
|
||||
SSM(SCI_GETTEXT, length, (sptr_t)self->buffer);
|
||||
// Parse code.
|
||||
byteCode.bytes = NULL;
|
||||
byteCode.length = 0;
|
||||
byteCode.bytes = NULL;
|
||||
byteCode.length = 0;
|
||||
byteCode.bufferSize = 0;
|
||||
lineNumber = vecparser(code, &byteCode);
|
||||
lineNumber = vecparser(self->buffer, &byteCode);
|
||||
if (lineNumber >= 0) {
|
||||
// Mark lines that fail to parse.
|
||||
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_ARROW);
|
||||
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_HIGHLIGHT);
|
||||
} else {
|
||||
//***DEBUG***
|
||||
#ifdef DEBUG
|
||||
FILE *out = fopen("bytecode.bin", "wb");
|
||||
fwrite(byteCode.bytes, byteCode.length, 1, out);
|
||||
fclose(out);
|
||||
#endif
|
||||
// All good!
|
||||
renderBytecode(&byteCode, self);
|
||||
}
|
||||
|
||||
// Release bytecode.
|
||||
if (byteCode.bytes != NULL) DEL(byteCode.bytes);
|
||||
// Release code.
|
||||
DEL(code);
|
||||
// Mark text dirty. SCN_SAVEPOINTLEFT isn't being reliable.
|
||||
setDirty(self, TRUE);
|
||||
}
|
||||
|
@ -260,7 +260,7 @@ EVENT void fileVectorTraceImageFileSet(GtkWidget *object, gpointer userData) {
|
|||
VectorDataT *self = (VectorDataT *)userData;
|
||||
char *temp = NULL;
|
||||
|
||||
printf("fileVectorTraceImageFileSet fired\n");
|
||||
debug("fileVectorTraceImageFileSet fired\n");
|
||||
temp = (char *)gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(object));
|
||||
loadTraceImage(self, temp);
|
||||
DEL(temp);
|
||||
|
@ -327,22 +327,38 @@ static void loadTraceImage(VectorDataT *self, char *filename) {
|
|||
|
||||
|
||||
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) {
|
||||
VectorDataT *self = (VectorDataT *)userData;
|
||||
|
||||
(void)object;
|
||||
|
||||
SSM(SCI_CUT, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
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) {
|
||||
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");
|
||||
if (in != NULL) {
|
||||
self->buffer[0] = 0;
|
||||
while (getline(&line, &len, in) != -1) {
|
||||
switch (count) {
|
||||
case 0: // Version Number
|
||||
|
@ -440,13 +457,15 @@ EVENT void menuVectorFileOpen(GtkWidget *object, gpointer userData) {
|
|||
break;
|
||||
|
||||
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;
|
||||
}
|
||||
count++;
|
||||
}
|
||||
fclose(in);
|
||||
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.
|
||||
} else {
|
||||
//***TODO*** Something bad happened.
|
||||
|
@ -528,26 +547,31 @@ EVENT void menuVectorFileSaveAs(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) {
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int count;
|
||||
int i;
|
||||
float f1;
|
||||
float f2;
|
||||
int index = 0;
|
||||
int *stack = NULL;
|
||||
int x1;
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int count;
|
||||
int i;
|
||||
float f1;
|
||||
float f2;
|
||||
time_t startTime;
|
||||
int index = 0;
|
||||
int *stack = NULL;
|
||||
GtkWidget *dialog;
|
||||
|
||||
#define GET_BYTE (bytecode->bytes[index++])
|
||||
#define GET_WORD getWord(bytecode, &index)
|
||||
|
||||
printf("-----------------------------------\n");
|
||||
debug("-----------------------------------\n");
|
||||
|
||||
self->variables = NULL;
|
||||
|
||||
|
@ -557,7 +581,9 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
jlDrawClear(self->jlc);
|
||||
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++]) {
|
||||
|
||||
case PARSE_NONE:
|
||||
|
@ -569,7 +595,7 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
y1 = word(self, GET_WORD);
|
||||
x2 = 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);
|
||||
break;
|
||||
|
||||
|
@ -577,25 +603,25 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
x1 = word(self, GET_WORD);
|
||||
arrput(stack, index);
|
||||
index = x1;
|
||||
printf("Call %d\n", index);
|
||||
debug("Call %d\n", index);
|
||||
break;
|
||||
|
||||
case PARSE_CIRCLE:
|
||||
y2 = word(self, GET_WORD);
|
||||
x1 = 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);
|
||||
break;
|
||||
|
||||
case PARSE_CLEAR:
|
||||
printf("Clear\n");
|
||||
debug("Clear\n");
|
||||
jlDrawClear(self->jlc);
|
||||
break;
|
||||
|
||||
case PARSE_COLOR:
|
||||
x1 = byte(self, GET_BYTE);
|
||||
printf("Color %d\n", x1);
|
||||
debug("Color %d\n", x1);
|
||||
jlDrawColorSet(self->jlc, x1);
|
||||
break;
|
||||
|
||||
|
@ -608,7 +634,7 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
y1 = word(self, GET_WORD);
|
||||
x2 = 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);
|
||||
break;
|
||||
|
||||
|
@ -617,66 +643,66 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
y1 = word(self, GET_WORD);
|
||||
x2 = byte(self, GET_BYTE);
|
||||
if (x2 > 15) {
|
||||
printf("Fill %d,%d\n", x1, y1);
|
||||
debug("Fill %d,%d\n", x1, y1);
|
||||
jlDrawFill(self->jlc, x1, y1);
|
||||
} 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);
|
||||
}
|
||||
break;
|
||||
|
||||
case PARSE_GOTO:
|
||||
index = word(self, GET_WORD);
|
||||
printf("Goto %d\n", index);
|
||||
debug("Goto %d\n", index);
|
||||
break;
|
||||
|
||||
case PARSE_IF:
|
||||
x1 = word(self, GET_WORD); // arg1
|
||||
y1 = byte(self, GET_BYTE); // compare
|
||||
x2 = word(self, GET_WORD); // arg2
|
||||
printf("If %d ", x1);
|
||||
debug("If %d ", x1);
|
||||
y2 = -1;
|
||||
switch (y1) {
|
||||
case 0: // ==
|
||||
printf("==");
|
||||
debug("==");
|
||||
if (x1 == x2) y2 = 1;
|
||||
break;
|
||||
|
||||
case 1: // !=
|
||||
printf("!=");
|
||||
debug("!=");
|
||||
if (x1 != x2) y2 = 1;
|
||||
break;
|
||||
|
||||
case 2: // <
|
||||
printf("<");
|
||||
debug("<");
|
||||
if (x1 < x2) y2 = 1;
|
||||
break;
|
||||
|
||||
case 3: // >
|
||||
printf(">");
|
||||
debug(">");
|
||||
if (x1 > x2) y2 = 1;
|
||||
break;
|
||||
|
||||
case 4: // <=
|
||||
printf("<=");
|
||||
debug("<=");
|
||||
if (x1 <= x2) y2 = 1;
|
||||
break;
|
||||
|
||||
case 5: // >=
|
||||
printf(">=");
|
||||
debug(">=");
|
||||
if (x1 >= x2) y2 = 1;
|
||||
break;
|
||||
}
|
||||
printf(" %d ", x2);
|
||||
debug(" %d ", x2);
|
||||
x1 = byte(self, GET_BYTE); // goto/call
|
||||
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 (x1 == 1) arrput(stack, index);
|
||||
index = x2;
|
||||
printf("(true)");
|
||||
debug("(true)");
|
||||
}
|
||||
printf("\n");
|
||||
debug("\n");
|
||||
break;
|
||||
|
||||
case PARSE_LABEL:
|
||||
|
@ -686,16 +712,16 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
count = word(self, GET_WORD);
|
||||
x1 = 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++) {
|
||||
x2 = 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);
|
||||
x1 = x2;
|
||||
y1 = y2;
|
||||
}
|
||||
printf("\n");
|
||||
debug("\n");
|
||||
break;
|
||||
|
||||
case PARSE_MATH:
|
||||
|
@ -709,7 +735,7 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
}
|
||||
x1 &= 0x7f; // Clear variable flag.
|
||||
f1 = variable(self, x1);
|
||||
printf("Math: %d: ", x1);
|
||||
debug("Math: %d: ", x1);
|
||||
switch (y1) {
|
||||
case MATH_NONE:
|
||||
// Well, none!
|
||||
|
@ -717,65 +743,65 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
|
||||
case MATH_ASSIGN:
|
||||
f1 = f2;
|
||||
printf("= %f", f2);
|
||||
debug("= %f", f2);
|
||||
break;
|
||||
|
||||
case MATH_ADD:
|
||||
f1 += f2;
|
||||
printf("%f + %f", f1, f2);
|
||||
debug("%f + %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_SUBTRACT:
|
||||
f1 -= f2;
|
||||
printf("%f - %f", f1, f2);
|
||||
debug("%f - %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_MULTIPLY:
|
||||
f1 *= f2;
|
||||
printf("%f * %f", f1, f2);
|
||||
debug("%f * %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_DIVIDE:
|
||||
f1 /= f2;
|
||||
printf("%f / %f", f1, f2);
|
||||
debug("%f / %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_MOD:
|
||||
f1 = modff(f1, &f2);
|
||||
printf("%f mod %f", f1, f2);
|
||||
debug("%f mod %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_POW:
|
||||
f1 = powf(f1, f2);
|
||||
printf("%f pow %f", f1, f2);
|
||||
debug("%f pow %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_SQRT:
|
||||
f1 = sqrtf(f2);
|
||||
printf("%f sqrt %f", f1, f2);
|
||||
debug("%f sqrt %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_ABS:
|
||||
f1 = fabsf(f2);
|
||||
printf("%f abs %f", f1, f2);
|
||||
debug("%f abs %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_COS:
|
||||
f1 = cosf(f2);
|
||||
printf("%f cos %f", f1, f2);
|
||||
debug("%f cos %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_SIN:
|
||||
f1 = sinf(f2);
|
||||
printf("%f sin %f", f1, f2);
|
||||
debug("%f sin %f", f1, f2);
|
||||
break;
|
||||
|
||||
case MATH_TAN:
|
||||
f1 = tanf(f2);
|
||||
printf("%f tan %f", f1, f2);
|
||||
debug("%f tan %f", f1, f2);
|
||||
break;
|
||||
}
|
||||
printf("\n");
|
||||
debug("\n");
|
||||
// Make sure we have enough slots for this variable.
|
||||
while (arrlen(self->variables) <= x1) {
|
||||
arrput(self->variables, 0.0f);
|
||||
|
@ -788,14 +814,14 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
x2 = byte(self, GET_BYTE);
|
||||
y1 = 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);
|
||||
break;
|
||||
|
||||
case PARSE_PLOT:
|
||||
x1 = 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);
|
||||
break;
|
||||
|
||||
|
@ -804,13 +830,13 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
y1 = word(self, GET_WORD);
|
||||
x2 = 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);
|
||||
break;
|
||||
|
||||
case PARSE_RETURN:
|
||||
index = arrpop(stack);
|
||||
printf("Return %d\n", index);
|
||||
debug("Return %d\n", index);
|
||||
break;
|
||||
|
||||
} // switch
|
||||
|
@ -828,6 +854,19 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
|
|||
|
||||
// Refresh widget.
|
||||
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->windowData.closeWindow = winVectorClose;
|
||||
|
||||
// Set up working buffer.
|
||||
utilEnsureBufferSize((unsigned char **)&self->buffer, &self->bufferLength, 1024);
|
||||
|
||||
// Load widgets from XML.
|
||||
widgets[0] = &self->windowData.window;
|
||||
widgets[1] = &self->boxVectorForEditor;
|
||||
|
@ -968,9 +1010,7 @@ void winVectorCreate(void) {
|
|||
SSM(SCI_SETTABWIDTH, 3, 0);
|
||||
SSM(SCI_SETMARGINWIDTHN, 0, (int)SSM(SCI_TEXTWIDTH, STYLE_LINENUMBER, (sptr_t)"_99999"));
|
||||
SSM(SCI_SETMARGINWIDTHN, 1, 16);
|
||||
SSM(SCI_SETWRAPMODE, SC_WRAP_WORD, 0);
|
||||
SSM(SCI_SETWRAPVISUALFLAGS, SC_WRAPVISUALFLAG_END, 0);
|
||||
SSM(SCI_SETWRAPINDENTMODE, SC_WRAPINDENT_INDENT, 0);
|
||||
SSM(SCI_SETWRAPMODE, SC_WRAP_NONE, 0);
|
||||
SSM(SCI_SETCARETSTYLE, CARETSTYLE_BLOCK | CARETSTYLE_OVERSTRIKE_BLOCK, 0);
|
||||
SSM(SCI_SETCARETFORE, 0x00ffff, 0);
|
||||
SSM(SCI_STYLESETBACK, STYLE_LINENUMBER, 0x222222);
|
||||
|
@ -1053,6 +1093,7 @@ static void winVectorDelete(gpointer userData) {
|
|||
if (self->filename != NULL) DEL(self->filename);
|
||||
if (self->title != NULL) DEL(self->title);
|
||||
if (self->tracename != NULL) DEL(self->tracename);
|
||||
if (self->buffer != NULL) DEL(self->buffer);
|
||||
|
||||
DEL(self);
|
||||
}
|
||||
|
|
|
@ -25,12 +25,10 @@
|
|||
</patterns>
|
||||
</object>
|
||||
<object class="GtkWindow" id="winVector">
|
||||
<property name="width-request">1500</property>
|
||||
<property name="height-request">600</property>
|
||||
<property name="width-request">1000</property>
|
||||
<property name="height-request">500</property>
|
||||
<property name="can-focus">False</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"/>
|
||||
<child>
|
||||
<object class="GtkBox">
|
||||
|
@ -56,36 +54,40 @@
|
|||
<object class="GtkMenuItem" id="menuVectorFileNew">
|
||||
<property name="visible">True</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>
|
||||
<signal name="activate" handler="menuVectorFileNew" swapped="no"/>
|
||||
<accelerator key="n" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuVectorFileOpen">
|
||||
<property name="visible">True</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>
|
||||
<signal name="activate" handler="menuVectorFileOpen" swapped="no"/>
|
||||
<accelerator key="o" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuVectorFileSave">
|
||||
<property name="visible">True</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>
|
||||
<signal name="activate" handler="menuVectorFileSave" swapped="no"/>
|
||||
<accelerator key="s" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuVectorFileSaveAs">
|
||||
<property name="visible">True</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>
|
||||
<signal name="activate" handler="menuVectorFileSaveAs" swapped="no"/>
|
||||
<accelerator key="s" signal="activate" modifiers="GDK_SHIFT_MASK | GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -98,9 +100,10 @@
|
|||
<object class="GtkMenuItem" id="menuVectorFileClose">
|
||||
<property name="visible">True</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>
|
||||
<signal name="activate" handler="menuVectorFileClose" swapped="no"/>
|
||||
<accelerator key="F4" signal="activate" modifiers="GDK_MOD1_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
@ -124,15 +127,17 @@
|
|||
<property name="label" translatable="yes">Cut</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorEditCut" swapped="no"/>
|
||||
<accelerator key="x" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkMenuItem" id="menuVectorEditCopy">
|
||||
<property name="visible">True</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>
|
||||
<signal name="activate" handler="menuVectorEditCopy" swapped="no"/>
|
||||
<accelerator key="c" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -142,6 +147,7 @@
|
|||
<property name="label" translatable="yes">Paste</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorEditPaste" swapped="no"/>
|
||||
<accelerator key="v" signal="activate" modifiers="GDK_CONTROL_MASK"/>
|
||||
</object>
|
||||
</child>
|
||||
<child>
|
||||
|
@ -174,6 +180,7 @@
|
|||
<property name="label" translatable="yes">Vector Editor...</property>
|
||||
<property name="use-underline">True</property>
|
||||
<signal name="activate" handler="menuVectorHelpVector" swapped="no"/>
|
||||
<accelerator key="F1" signal="activate"/>
|
||||
</object>
|
||||
</child>
|
||||
</object>
|
||||
|
|
Loading…
Add table
Reference in a new issue