Palette moved under Color toolbar icon. Added "RND" math function. Objects clip when drawn off the viewport. Project tree rendering.

This commit is contained in:
Scott Duensing 2022-12-16 19:09:42 -06:00
parent 078a02d9f1
commit 5a1aa2ec4e
20 changed files with 592 additions and 156 deletions

View file

@ -29,7 +29,7 @@ project(joeydev LANGUAGES C VERSION 1.0)
# Default to ON for developing the app. buildFlatpak.sh turns this off for us.
option(DEBUG_OUTPUT "Enable debugging output and memory tracing?" ON)
option(DEBUG_MODE "Enable debugging output and memory tracing?" ON)
set(CMAKE_C_STANDARD 99)
@ -47,6 +47,7 @@ set(SOURCE_FILES
src/vecparse.c
src/color.c
src/palette.c
src/project.c
)
configure_file(include/config.h.in config.h)

View file

@ -11,7 +11,7 @@ modules:
buildsystem: simple
build-commands:
- cmake -DDEBUG_OUTPUT=OFF -G Ninja -S . -B .
- cmake -DDEBUG_MODE=OFF -G Ninja -S . -B .
- ninja
- install -D joeydev /app/bin/joeydev
- install -Dm755 com.kangaroopunch.JoeyDev.desktop -t /app/share/applications

View file

@ -27,6 +27,9 @@
#include "common.h"
#define COLOR_RESPONSE_EDIT 1
typedef struct ColorS {
unsigned char red;
unsigned char green;

View file

@ -29,7 +29,7 @@
#include "array.h"
#ifdef DEBUG_OUTPUT
#ifdef DEBUG_MODE
#define debug(...) printf(__VA_ARGS__)
#define MEMWATCH
#else

View file

@ -29,10 +29,11 @@
#define JOEYDEV_VERSION "@joeydev_VERSION_MAJOR@.@joeydev_VERSION_MINOR@"
#define VICTOR_VERSION "1.0" // Used for file format versioning.
#define PROJECT_VERSION "1.0" // Used for file format versioning.
#define VICTOR_VERSION "1.0" // Used for file format versioning.
#cmakedefine DEBUG_OUTPUT
#cmakedefine DEBUG_MODE
#endif // CONFIG_H_IN

View file

@ -70,6 +70,9 @@ void jlDrawPixelSet(jlContextT *c, jint16 x, jint16 y);
void jlPaletteDefault(jlContextT *c);
void jlPaletteGet(jlContextT *c, jbyte index, jbyte *r, jbyte *g, jbyte *b); // This is not a standard JoeyLib API.
void jlPaletteSet(jlContextT *c, jbyte index, jbyte r, jbyte g, jbyte b);
int16_t jlUtilRandom(void);
int jlUtilRandomSeedGet(void);
void jlUtilRandomSeedSet(int seed);
#define jlUtilStackPop(c, stack) _jlUtilStackPop(c, (jlStackT **)&(stack)) // Syntatic Sugar
void *_jlUtilStackPop(jlContextT *c, jlStackT **stack);
#define jlUtilStackPush(c, stack, data) _jlUtilStackPush(c, (jlStackT **)&(stack), data, __LINE__, (char *)__FILE__) // Syntatic Sugar

30
include/project.h Normal file
View file

@ -0,0 +1,30 @@
/*
* JoeyDev
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#ifndef PROJECT_H
#define PROJECT_H
void winProjectCreate(void);
#endif // PROJECT_H

View file

@ -33,7 +33,6 @@ void utilEnsureBufferSize(unsigned char **buffer, int *length, int wante
gboolean utilFileExists(char *filename);
WindowDataT *utilGetWindowData(GtkWidget *window);
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData);
GtkWidget *utilGetWindowFromMemory(char *resource, char *name, gpointer userData);
gboolean utilQuestionDialog(GtkWidget *parent, char *title, char *question);
void utilWindowRegister(gpointer windowData);
int utilWindowsCloseAll(void);

View file

@ -54,6 +54,7 @@ enum ParserMathE {
MATH_SUBTRACT,
MATH_MULTIPLY,
MATH_DIVIDE,
MATH_RND,
MATH_MOD,
MATH_POW,
MATH_SQRT,

View file

@ -121,6 +121,8 @@ GtkWidget *color_dialog_new(GtkWidget *parent, char *title, ColorT colors[]) {
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
"_Cancel",
GTK_RESPONSE_CANCEL,
"_Edit",
COLOR_RESPONSE_EDIT,
"_Select",
GTK_RESPONSE_OK,
NULL

View file

@ -28,6 +28,11 @@
#include "draw.h"
//***TODO*** This entire thing should render to a 4 bit buffer and only
// convert to truecolor when needed. That way we can implement palette
// side effects.
typedef struct {
jint16 StartX;
jint16 EndX;
@ -39,7 +44,9 @@ typedef struct {
} _jlScanDataT;
static void _jlDrawCircleClipped(jlContextT *c, jint16 x0, jint16 y0, jint16 radius);
static int32_t _jlSeed = 0;
static void _jlDrawFill(jlContextT *c, jint16 x, jint16 y, jbool how);
static void _jlDrawFillAddLine(jlContextT *c, jint16 startX, jint16 endX, jint16 y, jint16 ignoreStart, jint16 ignoreEnd, char dir, jbool isNextInDir, jbool how);
static _jlScanDataT *_jlDrawFillNewSegment(jlContextT *c, jint16 startX, jint16 endX, jint16 y, signed char dir, jbool scanLeft, jbool scanRight);
@ -82,40 +89,6 @@ void jlDrawBoxFilled(jlContextT *c, jint16 x1, jint16 y1, jint16 x2, jint16 y2)
}
void _jlDrawCircleClipped(jlContextT *c, jint16 x0, jint16 y0, jint16 radius) {
jint16 x = radius-1;
jint16 y = 0;
jint16 dx = 1;
jint16 dy = 1;
jint16 err = dx - (jint16)(radius << 1);
//***TODO*** This produces negative Y values for large circles.
while (x >= y) {
if ((x0 + x < 320) && (y0 + y < 200)) jlDrawPixelSet(c, x0 + x, y0 + y);
if ((x0 + y < 320) && (y0 + x < 200)) jlDrawPixelSet(c, x0 + y, y0 + x);
if ((x0 - y < 320) && (y0 + x < 200)) jlDrawPixelSet(c, x0 - y, y0 + x);
if ((x0 - x < 320) && (y0 + y < 200)) jlDrawPixelSet(c, x0 - x, y0 + y);
if ((x0 - x < 320) && (y0 - y < 200)) jlDrawPixelSet(c, x0 - x, y0 - y);
if ((x0 - x < 320) && (y0 - x < 200)) jlDrawPixelSet(c, x0 - y, y0 - x);
if ((x0 + y < 320) && (y0 - x < 200)) jlDrawPixelSet(c, x0 + y, y0 - x);
if ((x0 + x < 320) && (y0 - y < 200)) jlDrawPixelSet(c, x0 + x, y0 - y);
if (err <= 0) {
y++;
err += dy;
dy += 2;
}
if (err > 0) {
x--;
dx += 2;
err += dx - (radius << 1);
}
}
}
void jlDrawCircle(jlContextT *c, jint16 x0, jint16 y0, jint16 radius) {
jint16 x = radius-1;
jint16 y = 0;
@ -123,13 +96,6 @@ void jlDrawCircle(jlContextT *c, jint16 x0, jint16 y0, jint16 radius) {
jint16 dy = 1;
jint16 err = dx - (jint16)(radius << 1);
// Is any of this going to be off the screen?
//***TODO*** All our drawing primitives should do this.
if ((x0 + radius > 319) || (x0 - radius < 0) || (y0 + radius > 199) || (y0 - radius < 0)) {
_jlDrawCircleClipped(c, x0, y0, radius);
return;
}
while (x >= y) {
jlDrawPixelSet(c, x0 + x, y0 + y);
jlDrawPixelSet(c, x0 + y, y0 + x);
@ -361,6 +327,12 @@ jbyte jlDrawPixelGet(jlContextT *c, jint16 x, jint16 y) {
int index = 0;
int i;
// Clip at edge. We can do this on modern machines!
if (x < 0) return 0;
if (x > 319) return 0;
if (y < 0) return 0;
if (y > 199) return 0;
// Find the palette index for this color.
for (i=0; i<16; i++) {
if (r == c->_jlPalette[i].r && g == c->_jlPalette[i].g && b == c->_jlPalette[i].b) {
@ -376,6 +348,12 @@ jbyte jlDrawPixelGet(jlContextT *c, jint16 x, jint16 y) {
void jlDrawPixelSet(jlContextT *c, jint16 x, jint16 y) {
unsigned int offset = (x + y * 320) * 4;
// Clip at edge. We can do this on modern machines!
if (x < 0) return;
if (x > 319) return;
if (y < 0) return;
if (y > 199) return;
c->_pixels[offset] = c->_jlPalette[c->_jlDrawColor].b * 16;
c->_pixels[offset + 1] = c->_jlPalette[c->_jlDrawColor].g * 16;
c->_pixels[offset + 2] = c->_jlPalette[c->_jlDrawColor].r * 16;
@ -420,6 +398,22 @@ void jlPaletteSet(jlContextT *c, jbyte index, jbyte r, jbyte g, jbyte b) {
}
int16_t jlUtilRandom(void) {
_jlSeed = _jlSeed * 1103515245 + 12345;
return _jlSeed / 65536;
}
int jlUtilRandomSeedGet(void) {
return _jlSeed;
}
void jlUtilRandomSeedSet(int seed) {
_jlSeed = seed;
}
void *_jlUtilStackPop(jlContextT *c, jlStackT **stack) {
void *d = NULL;
jlStackT *s;

View file

@ -24,25 +24,26 @@
#include "common.h"
#include "utils.h"
#include "project.h"
#include "vector.h"
#include "joeydev.h"
static GtkWidget *_winJoeyDev;
static GtkWidget *_winJoeyDev = NULL;
EVENT void toolJoeyDevAboutClicked(GtkWidget *object, gpointer userData);
EVENT void toolJoeyDevProjectClicked(GtkWidget *object, gpointer userData);
EVENT void toolJoeyDevQuitClicked(GtkWidget *object, gpointer userData);
EVENT void toolJoeyDevVectorClicked(GtkWidget *object, gpointer userData);
EVENT gboolean winJoeyDevClose(GtkWidget *object, gpointer userData);
EVENT void toolJoeyDevAboutClicked(GtkWidget *widget, gpointer userData);
EVENT void toolJoeyDevProjectClicked(GtkWidget *widget, gpointer userData);
EVENT void toolJoeyDevQuitClicked(GtkWidget *widget, gpointer userData);
EVENT void toolJoeyDevVectorClicked(GtkWidget *widget, gpointer userData);
EVENT gboolean winJoeyDevClose(GtkWidget *widget, gpointer userData);
EVENT void toolJoeyDevAboutClicked(GtkWidget *object, gpointer userData) {
EVENT void toolJoeyDevAboutClicked(GtkWidget *widget, gpointer userData) {
GtkWidget *dialog;
GdkPixbuf *pixbuf;
(void)object;
(void)widget;
(void)userData;
pixbuf = gdk_pixbuf_new_from_resource("/com/kangaroopunch/joeydev/Logo.png", NULL);
@ -63,29 +64,28 @@ EVENT void toolJoeyDevAboutClicked(GtkWidget *object, gpointer userData) {
}
EVENT void toolJoeyDevProjectClicked(GtkWidget *object, gpointer userData) {
(void)object;
EVENT void toolJoeyDevProjectClicked(GtkWidget *widget, gpointer userData) {
(void)widget;
(void)userData;
debug("Project Clicked!\n");
winProjectCreate();
}
EVENT void toolJoeyDevQuitClicked(GtkWidget *object, gpointer userData) {
winJoeyDevClose(object, userData);
EVENT void toolJoeyDevQuitClicked(GtkWidget *widget, gpointer userData) {
winJoeyDevClose(widget, userData);
}
EVENT void toolJoeyDevVectorClicked(GtkWidget *object, gpointer userData) {
(void)object;
EVENT void toolJoeyDevVectorClicked(GtkWidget *widget, gpointer userData) {
(void)widget;
(void)userData;
winVectorCreate();
}
EVENT gboolean winJoeyDevClose(GtkWidget *object, gpointer userData) {
(void)object;
EVENT gboolean winJoeyDevClose(GtkWidget *widget, gpointer userData) {
(void)userData;
// Do they want to quit?
@ -101,5 +101,23 @@ EVENT gboolean winJoeyDevClose(GtkWidget *object, gpointer userData) {
void winJoeyDevCreate(void) {
_winJoeyDev = utilGetWindowFromMemory("/com/kangaroopunch/joeydev/JoeyDev.glade", "winJoeyDev", NULL);
GtkWidget *toolJoeyDevProject;
char *widgetNames[] = {
"winJoeyDev",
"toolJoeyDevProject",
NULL
};
GtkWidget **widgets[] = {
&_winJoeyDev,
&toolJoeyDevProject
};
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/JoeyDev.glade", widgetNames, widgets, NULL);
#ifndef DEBUG_MODE
// Don't enable the project tool if we're not debugging.
gtk_widget_set_sensitive(GTK_WIDGET(toolJoeyDevProject), FALSE);
#endif
gtk_widget_show_all(_winJoeyDev);
}

203
src/project.c Normal file
View file

@ -0,0 +1,203 @@
/*
* JoeyDev
* Copyright (C) 2018-2023 Scott Duensing <scott@kangaroopunch.com>
*
* This software is provided 'as-is', without any express or implied
* warranty. In no event will the authors be held liable for any damages
* arising from the use of this software.
*
* Permission is granted to anyone to use this software for any purpose,
* including commercial applications, and to alter it and redistribute it
* freely, subject to the following restrictions:
*
* 1. The origin of this software must not be misrepresented; you must not
* claim that you wrote the original software. If you use this software
* in a product, an acknowledgment in the product documentation would be
* appreciated but is not required.
* 2. Altered source versions must be plainly marked as such, and must not be
* misrepresented as being the original software.
* 3. This notice may not be removed or altered from any source distribution.
*/
#include "common.h"
#include "project.h"
#include "utils.h"
typedef struct ProjectDataS {
WindowDataT windowData;
GtkWidget *treeProject;
GtkTreeStore *storeProject;
GtkTreeIter iterTop;
GtkTreeIter iterHeaders;
GtkTreeIter iterCode;
GtkTreeIter iterBitmaps;
GtkTreeIter iterVectors;
GtkTreeIter iterSounds;
GtkTreeIter iterMusic;
GtkTreeIter iterData;
char *title;
} ProjectDataT;
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData);
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData);
EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData);
EVENT void menuProjectFileSaveAs(GtkWidget *object, gpointer userData);
EVENT void menuProjectFileClose(GtkWidget *object, gpointer userData);
EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData);
EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData);
EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userData);
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData);
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData);
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData);
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData);
static void winProjectDelete(gpointer userData);
EVENT void menuProjectFileNew(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectFileOpen(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectFileSave(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectFileSaveAs(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectFileClose(GtkWidget *object, gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
(void)object;
gtk_window_close(GTK_WINDOW(self->windowData.window));
}
EVENT void menuProjectProjectAdd(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectProjectRemove(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectProjectProperties(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectBuildSettings(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectBuildBuild(GtkWidget *object, gpointer userData) {
}
EVENT void menuProjectHelpProject(GtkWidget *object, gpointer userData) {
(void)object;
(void)userData;
gtk_show_uri_on_window(NULL, "https://skunkworks.kangaroopunch.com/skunkworks/joeydev/-/wikis/Project-Editor", GDK_CURRENT_TIME, NULL);
}
EVENT gboolean winProjectClose(GtkWidget *object, gpointer userData) {
// userData is not reliable due to menuVectorFileClose and util indirectly calling us.
ProjectDataT *self = (ProjectDataT *)utilGetWindowData(object);
(void)userData;
if (self->windowData.isDirty == TRUE) {
if (utilQuestionDialog(self->windowData.window, "Exit", "You have unsaved changes. Exit?")) {
winProjectDelete(self);
return FALSE;
}
return TRUE;
}
winProjectDelete(self);
return FALSE;
}
void winProjectCreate(void) {
ProjectDataT *self;
char *widgetNames[] = {
"winProject",
"treeProject",
NULL
};
GtkWidget **widgets[] = {
NULL,
NULL,
NULL
};
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
// Set up instance data.
self = NEW(ProjectDataT);
self->windowData.closeWindow = winProjectClose;
// Load widgets from XML.
widgets[0] = &self->windowData.window;
widgets[1] = &self->treeProject;
utilGetWidgetsFromMemory("/com/kangaroopunch/joeydev/Project.glade", widgetNames, widgets, self);
// Build tree.
col = gtk_tree_view_column_new();
gtk_tree_view_append_column(GTK_TREE_VIEW(self->treeProject), col);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_add_attribute(col, renderer, "text", 0);
self->storeProject = gtk_tree_store_new(1, G_TYPE_STRING);
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Headers", -1);
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Code", -1);
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Bitmaps", -1);
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Vectors", -1);
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Sounds", -1);
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Music", -1);
gtk_tree_store_append(self->storeProject, &self->iterTop, NULL);
gtk_tree_store_set(self->storeProject, &self->iterTop, 0, "Data", -1);
gtk_tree_view_set_model(GTK_TREE_VIEW(self->treeProject), GTK_TREE_MODEL(self->storeProject));
g_object_unref(self->storeProject);
// Grab title.
self->title = strdup(gtk_window_get_title(GTK_WINDOW(self->windowData.window)));
// Register window & show it.
utilWindowRegister(self);
gtk_widget_show_all(self->windowData.window);
}
static void winProjectDelete(gpointer userData) {
ProjectDataT *self = (ProjectDataT *)userData;
utilWindowUnRegister(userData);
DEL(self);
}

View file

@ -94,26 +94,6 @@ WindowDataT *utilGetWindowData(GtkWidget *window) {
}
GtkWidget *utilGetWindowFromMemory(char *resource, char *name, gpointer userData) {
GtkBuilder *gtkBuilder;
GtkWidget *window;
gtkBuilder = gtk_builder_new();
if (gtk_builder_add_from_resource(gtkBuilder, resource, NULL) == 0) {
printf("Failed to build UI '%s'!\n", name);
exit(1);
}
window = GTK_WIDGET(gtk_builder_get_object(gtkBuilder, name));
gtk_builder_connect_signals(gtkBuilder, userData);
g_object_unref(G_OBJECT(gtkBuilder));
gtk_widget_show(window);
return window;
}
gboolean utilGetWidgetsFromMemory(char *resource, char *name[], GtkWidget **widgets[], gpointer userData) {
GtkBuilder *gtkBuilder;
int x;

View file

@ -157,6 +157,7 @@ static int parserGetWord(char *wordList, char **tokenEnd) {
char *token;
char *word;
char *wordEnd = NULL;
char *mutable;
int index = -1;
// Returns -1 if the word is not found in the wordlist.
@ -166,13 +167,17 @@ static int parserGetWord(char *wordList, char **tokenEnd) {
token = strtok_r(NULL, " ", tokenEnd);
if (token == NULL) return index;
word = strtok_r(wordList, " ", &wordEnd);
mutable = strdup(wordList);
word = strtok_r(mutable, " ", &wordEnd);
while (word != NULL) {
index++;
if (strcasecmp(token, word) == 0) break;
word = strtok_r(NULL, " ", &wordEnd);
}
DEL(mutable);
return index;
}
@ -314,6 +319,7 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
{ "-", MATH_SUBTRACT },
{ "*", MATH_MULTIPLY },
{ "/", MATH_DIVIDE },
{ "RND", MATH_RND },
{ "MOD", MATH_MOD },
{ "POW", MATH_POW },
{ "SQRT", MATH_SQRT },
@ -688,7 +694,7 @@ int vecparser(char *programIn, VecByteCodeT *bytecode) {
// Resolve forward label declarations and patch bytecode.
if (lineOkay) {
#ifdef DEBUG
#ifdef DEBUG_MODE
for (y1 = 0; y1 < shlen(labels); y1++) {
debug("Resolved - %s\n", labels[y1].key);
}

View file

@ -135,7 +135,6 @@ EVENT void toolColorClicked(GtkToolButton *object, gpointer userData);
EVENT void toolEllipseClicked(GtkToolButton *object, gpointer userData);
EVENT void toolFillClicked(GtkToolButton *object, gpointer userData);
EVENT void toolLineClicked(GtkToolButton *object, gpointer userData);
EVENT void toolPaletteClicked(GtkToolButton *object, gpointer userData);
EVENT void toolPlotClicked(GtkToolButton *object, gpointer userData);
EVENT void toolRectangleClicked(GtkToolButton *object, gpointer userData);
static float variable(VectorDataT *self, unsigned char byte);
@ -412,7 +411,7 @@ EVENT void editorVectorNotify(GtkWidget *sciWidget, gint ctrlID, struct SCNotifi
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_ARROW);
SSM(SCI_MARKERADD, lineNumber, MARKER_ERROR_HIGHLIGHT);
} else {
#ifdef DEBUG
#ifdef DEBUG_MODE
FILE *out = fopen("bytecode.bin", "wb");
fwrite(byteCode.bytes, byteCode.length, 1, out);
fclose(out);
@ -878,6 +877,7 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
jlDrawColorSet(self->jlc, 0);
jlDrawClear(self->jlc);
jlDrawColorSet(self->jlc, 15);
jlUtilRandomSeedSet(0);
startTime = time(NULL);
self->variables = NULL;
@ -1075,6 +1075,12 @@ static void renderBytecode(VecByteCodeT *bytecode, VectorDataT *self) {
debug("%f / %f", f1, f2);
break;
case MATH_RND:
f1 = abs(jlUtilRandom());
f1 = (int)f1 % (int)f2;
debug("%f rnd %f", f1, f2);
break;
case MATH_MOD:
f1 = modff(f1, &f2);
debug("%f mod %f", f1, f2);
@ -1261,34 +1267,54 @@ EVENT void toolCircleClicked(GtkToolButton *object, gpointer userData) {
EVENT void toolColorClicked(GtkToolButton *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData;
GtkWidget *dialog;
VectorDataT *self = (VectorDataT *)userData;
GtkWidget *colorDialog;
GtkWidget *paletteDialog;
ColorT colors[16];
char temp[4];
int i;
char temp[32];
int response;
int selected;
(void)object;
// Load the current JoeyLib palette into the dialog.
for (i=0; i<16; i++) {
jlPaletteGet(self->jlc, i, &colors[i].red, &colors[i].green, &colors[i].blue);
for (selected=0; selected<16; selected++) {
jlPaletteGet(self->jlc, selected, &colors[selected].red, &colors[selected].green, &colors[selected].blue);
}
// Build the dialog.
dialog = color_dialog_new(self->windowData.window, "Select Color", colors);
colorDialog = color_dialog_new(self->windowData.window, "Select Color", colors);
// Run the dialog.
if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
i = color_dialog_get_selected(dialog);
if (i >= 0) {
do {
response = gtk_dialog_run(GTK_DIALOG(colorDialog));
selected = color_dialog_get_selected(colorDialog);
} while (selected == -1 && response != GTK_RESPONSE_CANCEL);
// They want to edit a color.
if (response == COLOR_RESPONSE_EDIT) {
paletteDialog = palette_dialog_new(colorDialog, "Edit Palette Entry", colors[selected].red, colors[selected].green, colors[selected].blue);
if (gtk_dialog_run(GTK_DIALOG(paletteDialog)) == GTK_RESPONSE_OK) {
palette_dialog_get_color(paletteDialog, &colors[selected].red, &colors[selected].green, &colors[selected].blue);
// Write our new palette entry into the editor.
snprintf(temp, 32, "%d as %d,%d,%d", selected, colors[selected].red, colors[selected].green, colors[selected].blue);
insertCommand(self, "palette");
insertText(self, temp);
}
gtk_widget_destroy(paletteDialog);
}
// They selected a color.
if (response == GTK_RESPONSE_OK) {
if (selected >= 0) {
// Write our selected color into the editor.
snprintf(temp, 4, " %d", i);
snprintf(temp, 4, " %d", selected);
insertCommand(self, "color");
insertText(self, temp);
}
}
gtk_widget_destroy(dialog);
gtk_widget_destroy(colorDialog);
}
@ -1325,45 +1351,6 @@ EVENT void toolLineClicked(GtkToolButton *object, gpointer userData) {
}
EVENT void toolPaletteClicked(GtkToolButton *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData;
GtkWidget *colorDialog;
GtkWidget *paletteDialog;
ColorT colors[16];
char temp[32];
int i;
(void)object;
// Load the current JoeyLib palette into the dialog.
for (i=0; i<16; i++) {
jlPaletteGet(self->jlc, i, &colors[i].red, &colors[i].green, &colors[i].blue);
}
// Build the dialog.
colorDialog = color_dialog_new(self->windowData.window, "Select Color to Edit", colors);
// Run the dialog.
if (gtk_dialog_run(GTK_DIALOG(colorDialog)) == GTK_RESPONSE_OK) {
i = color_dialog_get_selected(colorDialog);
if (i >= 0) {
// User selected a color, now edit it.
paletteDialog = palette_dialog_new(colorDialog, "Edit Palette Entry", colors[i].red, colors[i].green, colors[i].blue);
if (gtk_dialog_run(GTK_DIALOG(paletteDialog)) == GTK_RESPONSE_OK) {
palette_dialog_get_color(paletteDialog, &colors[i].red, &colors[i].green, &colors[i].blue);
// Write our new palette entry into the editor.
snprintf(temp, 32, "%d as %d,%d,%d", i, colors[i].red, colors[i].green, colors[i].blue);
insertCommand(self, "palette");
insertText(self, temp);
}
gtk_widget_destroy(paletteDialog);
}
}
gtk_widget_destroy(colorDialog);
}
EVENT void toolPlotClicked(GtkToolButton *object, gpointer userData) {
VectorDataT *self = (VectorDataT *)userData;

View file

@ -57,7 +57,6 @@ Author: Scott Duensing <scott@kangaroopunch.com>
<child>
<object class="GtkToolButton" id="toolJoeyDevProject">
<property name="visible">True</property>
<property name="sensitive">False</property>
<property name="can-focus">False</property>
<property name="tooltip-text" translatable="yes">Project</property>
<property name="label" translatable="yes">Project</property>

221
ui/Project.glade Normal file
View file

@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.40.0 -->
<interface>
<requires lib="gtk+" version="3.24"/>
<object class="GtkWindow" id="winProject">
<property name="width-request">300</property>
<property name="height-request">600</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Project</property>
<property name="icon-name">applications-engineering</property>
<signal name="delete-event" handler="winProjectClose" swapped="no"/>
<child>
<object class="GtkBox">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkMenuBar">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">_File</property>
<property name="use-underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkMenuItem" id="menuProjectFileNew">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">New</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectFileNew" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuProjectFileOpen">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Open...</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectFileOpen" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuProjectFileSave">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Save</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectFileSave" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuProjectFileSaveAs">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Save As...</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectFileSaveAs" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuProjectFileClose">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Close</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectFileClose" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">_Project</property>
<property name="use-underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkMenuItem" id="menuProjectProjectAdd">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Add File...</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectProjectAdd" swapped="no"/>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuProjectProjectRemove">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Remove File</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectProjectRemove" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuProjectProjectProperties">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Properties...</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectProjectProperties" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">_Build</property>
<property name="use-underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkMenuItem" id="menuProjectBuildSettings">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Settings...</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectBuildSettings" swapped="no"/>
</object>
</child>
<child>
<object class="GtkSeparatorMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
</object>
</child>
<child>
<object class="GtkMenuItem" id="menuProjectBuildBuild">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Build Project</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectBuildBuild" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
<child>
<object class="GtkMenuItem">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">_Help</property>
<property name="use-underline">True</property>
<child type="submenu">
<object class="GtkMenu">
<property name="visible">True</property>
<property name="can-focus">False</property>
<child>
<object class="GtkMenuItem" id="menuProjectHelpProject">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Project Editor...</property>
<property name="use-underline">True</property>
<signal name="activate" handler="menuProjectHelpProject" swapped="no"/>
</object>
</child>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkTreeView" id="treeProject">
<property name="visible">True</property>
<property name="can-focus">True</property>
<property name="headers-visible">False</property>
<property name="search-column">0</property>
<property name="enable-tree-lines">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection"/>
</child>
</object>
<packing>
<property name="expand">True</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>
</object>
</child>
</object>
</interface>

View file

@ -54,6 +54,7 @@ Author: Scott Duensing <scott@kangaroopunch.com>
<property name="width-request">1250</property>
<property name="can-focus">False</property>
<property name="title" translatable="yes">Vector</property>
<property name="icon-name">image-x-generic</property>
<signal name="delete-event" handler="winVectorClose" swapped="no"/>
<child>
<object class="GtkBox">
@ -345,20 +346,6 @@ Author: Scott Duensing <scott@kangaroopunch.com>
<property name="homogeneous">True</property>
</packing>
</child>
<child>
<object class="GtkToolButton" id="toolPalette">
<property name="visible">True</property>
<property name="can-focus">False</property>
<property name="label" translatable="yes">Palette</property>
<property name="use-underline">True</property>
<property name="icon-name">action-palette</property>
<signal name="clicked" handler="toolPaletteClicked" swapped="no"/>
</object>
<packing>
<property name="expand">False</property>
<property name="homogeneous">True</property>
</packing>
</child>
</object>
<packing>
<property name="expand">False</property>

View file

@ -2,6 +2,7 @@
<gresources>
<gresource prefix="/com/kangaroopunch/joeydev">
<file preprocess="xml-stripblanks">JoeyDev.glade</file>
<file preprocess="xml-stripblanks">Project.glade</file>
<file preprocess="xml-stripblanks">Vector.glade</file>
<file>Logo.png</file>
</gresource>