ref: a5456e6c0abe933600de2de1b290b08e264953f2
author: phil9 <telephil9@gmail.com>
date: Tue Nov 29 16:13:10 EST 2022
initial import
--- /dev/null
+++ b/LICENSE
@@ -1,0 +1,21 @@
+MIT License
+
+Copyright (c) 2022 phil9 <telephil9@gmail.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
--- /dev/null
+++ b/README.md
@@ -1,0 +1,46 @@
+slug
+=====
+slug (Simple LUA graphics) is a graphics programming tool inspired by [Processing](https://processing.org).
+
+Installation:
+-------------
+slug uses the [lu9-lua](https://git.sr.ht/~kvik/lu9-lua) native lua port to 9front by kvik.
+1) Clone the slug repository somewhere.
+2) Clone the lu9-lua repository as lua within the slug directory
+3) mk && mk install
+
+Usage:
+------
+A slug program is composed of two functions:
+- setup (not mandatory) which is called before the main draw loop.
+- draw which is called in a loop until program exits.
+
+slug provides the following functions:
+- background(color) paint the background using given color (see colors)
+- stroke(color) change the shapes stroke color
+- strokeWidth(n) change the width of strokes
+- line(x1, y1, x2, y2) draw a line between points (x1,y1) and (x2, y2)
+
+colors:
+slug currently uses a 216 color palette based on web safe color palette.
+color parameter is thus a number in the range [0;216[
+
+Sample:
+-------
+```lua
+function draw()
+ background(0)
+ stroke(255)
+ strokeWidth(5)
+ line(10, 10, 100, 100)
+end
+```
+
+License:
+--------
+MIT
+
+Bugs:
+-----
+This is a really quick proof of concept so bugs most certainly exist.
+
--- /dev/null
+++ b/colors.h
@@ -1,0 +1,219 @@
+Color palette[] = {
+ { 0x000000FF, nil },
+ { 0x000033FF, nil },
+ { 0x000066FF, nil },
+ { 0x000099FF, nil },
+ { 0x0000CCFF, nil },
+ { 0x0000FFFF, nil },
+ { 0x003300FF, nil },
+ { 0x003333FF, nil },
+ { 0x003366FF, nil },
+ { 0x003399FF, nil },
+ { 0x0033CCFF, nil },
+ { 0x0033FFFF, nil },
+ { 0x006600FF, nil },
+ { 0x006633FF, nil },
+ { 0x006666FF, nil },
+ { 0x006699FF, nil },
+ { 0x0066CCFF, nil },
+ { 0x0066FFFF, nil },
+ { 0x009900FF, nil },
+ { 0x009933FF, nil },
+ { 0x009966FF, nil },
+ { 0x009999FF, nil },
+ { 0x0099CCFF, nil },
+ { 0x0099FFFF, nil },
+ { 0x00CC00FF, nil },
+ { 0x00CC33FF, nil },
+ { 0x00CC66FF, nil },
+ { 0x00CC99FF, nil },
+ { 0x00CCCCFF, nil },
+ { 0x00CCFFFF, nil },
+ { 0x00FF00FF, nil },
+ { 0x00FF33FF, nil },
+ { 0x00FF66FF, nil },
+ { 0x00FF99FF, nil },
+ { 0x00FFCCFF, nil },
+ { 0x00FFFFFF, nil },
+ { 0x330000FF, nil },
+ { 0x330033FF, nil },
+ { 0x330066FF, nil },
+ { 0x330099FF, nil },
+ { 0x3300CCFF, nil },
+ { 0x3300FFFF, nil },
+ { 0x333300FF, nil },
+ { 0x333333FF, nil },
+ { 0x333366FF, nil },
+ { 0x333399FF, nil },
+ { 0x3333CCFF, nil },
+ { 0x3333FFFF, nil },
+ { 0x336600FF, nil },
+ { 0x336633FF, nil },
+ { 0x336666FF, nil },
+ { 0x336699FF, nil },
+ { 0x3366CCFF, nil },
+ { 0x3366FFFF, nil },
+ { 0x339900FF, nil },
+ { 0x339933FF, nil },
+ { 0x339966FF, nil },
+ { 0x339999FF, nil },
+ { 0x3399CCFF, nil },
+ { 0x3399FFFF, nil },
+ { 0x33CC00FF, nil },
+ { 0x33CC33FF, nil },
+ { 0x33CC66FF, nil },
+ { 0x33CC99FF, nil },
+ { 0x33CCCCFF, nil },
+ { 0x33CCFFFF, nil },
+ { 0x33FF00FF, nil },
+ { 0x33FF33FF, nil },
+ { 0x33FF66FF, nil },
+ { 0x33FF99FF, nil },
+ { 0x33FFCCFF, nil },
+ { 0x33FFFFFF, nil },
+ { 0x660000FF, nil },
+ { 0x660033FF, nil },
+ { 0x660066FF, nil },
+ { 0x660099FF, nil },
+ { 0x6600CCFF, nil },
+ { 0x6600FFFF, nil },
+ { 0x663300FF, nil },
+ { 0x663333FF, nil },
+ { 0x663366FF, nil },
+ { 0x663399FF, nil },
+ { 0x6633CCFF, nil },
+ { 0x6633FFFF, nil },
+ { 0x666600FF, nil },
+ { 0x666633FF, nil },
+ { 0x666666FF, nil },
+ { 0x666699FF, nil },
+ { 0x6666CCFF, nil },
+ { 0x6666FFFF, nil },
+ { 0x669900FF, nil },
+ { 0x669933FF, nil },
+ { 0x669966FF, nil },
+ { 0x669999FF, nil },
+ { 0x6699CCFF, nil },
+ { 0x6699FFFF, nil },
+ { 0x66CC00FF, nil },
+ { 0x66CC33FF, nil },
+ { 0x66CC66FF, nil },
+ { 0x66CC99FF, nil },
+ { 0x66CCCCFF, nil },
+ { 0x66CCFFFF, nil },
+ { 0x66FF00FF, nil },
+ { 0x66FF33FF, nil },
+ { 0x66FF66FF, nil },
+ { 0x66FF99FF, nil },
+ { 0x66FFCCFF, nil },
+ { 0x66FFFFFF, nil },
+ { 0x990000FF, nil },
+ { 0x990033FF, nil },
+ { 0x990066FF, nil },
+ { 0x990099FF, nil },
+ { 0x9900CCFF, nil },
+ { 0x9900FFFF, nil },
+ { 0x993300FF, nil },
+ { 0x993333FF, nil },
+ { 0x993366FF, nil },
+ { 0x993399FF, nil },
+ { 0x9933CCFF, nil },
+ { 0x9933FFFF, nil },
+ { 0x996600FF, nil },
+ { 0x996633FF, nil },
+ { 0x996666FF, nil },
+ { 0x996699FF, nil },
+ { 0x9966CCFF, nil },
+ { 0x9966FFFF, nil },
+ { 0x999900FF, nil },
+ { 0x999933FF, nil },
+ { 0x999966FF, nil },
+ { 0x999999FF, nil },
+ { 0x9999CCFF, nil },
+ { 0x9999FFFF, nil },
+ { 0x99CC00FF, nil },
+ { 0x99CC33FF, nil },
+ { 0x99CC66FF, nil },
+ { 0x99CC99FF, nil },
+ { 0x99CCCCFF, nil },
+ { 0x99CCFFFF, nil },
+ { 0x99FF00FF, nil },
+ { 0x99FF33FF, nil },
+ { 0x99FF66FF, nil },
+ { 0x99FF99FF, nil },
+ { 0x99FFCCFF, nil },
+ { 0x99FFFFFF, nil },
+ { 0xCC0000FF, nil },
+ { 0xCC0033FF, nil },
+ { 0xCC0066FF, nil },
+ { 0xCC0099FF, nil },
+ { 0xCC00CCFF, nil },
+ { 0xCC00FFFF, nil },
+ { 0xCC3300FF, nil },
+ { 0xCC3333FF, nil },
+ { 0xCC3366FF, nil },
+ { 0xCC3399FF, nil },
+ { 0xCC33CCFF, nil },
+ { 0xCC33FFFF, nil },
+ { 0xCC6600FF, nil },
+ { 0xCC6633FF, nil },
+ { 0xCC6666FF, nil },
+ { 0xCC6699FF, nil },
+ { 0xCC66CCFF, nil },
+ { 0xCC66FFFF, nil },
+ { 0xCC9900FF, nil },
+ { 0xCC9933FF, nil },
+ { 0xCC9966FF, nil },
+ { 0xCC9999FF, nil },
+ { 0xCC99CCFF, nil },
+ { 0xCC99FFFF, nil },
+ { 0xCCCC00FF, nil },
+ { 0xCCCC33FF, nil },
+ { 0xCCCC66FF, nil },
+ { 0xCCCC99FF, nil },
+ { 0xCCCCCCFF, nil },
+ { 0xCCCCFFFF, nil },
+ { 0xCCFF00FF, nil },
+ { 0xCCFF33FF, nil },
+ { 0xCCFF66FF, nil },
+ { 0xCCFF99FF, nil },
+ { 0xCCFFCCFF, nil },
+ { 0xCCFFFFFF, nil },
+ { 0xFF0000FF, nil },
+ { 0xFF0033FF, nil },
+ { 0xFF0066FF, nil },
+ { 0xFF0099FF, nil },
+ { 0xFF00CCFF, nil },
+ { 0xFF00FFFF, nil },
+ { 0xFF3300FF, nil },
+ { 0xFF3333FF, nil },
+ { 0xFF3366FF, nil },
+ { 0xFF3399FF, nil },
+ { 0xFF33CCFF, nil },
+ { 0xFF33FFFF, nil },
+ { 0xFF6600FF, nil },
+ { 0xFF6633FF, nil },
+ { 0xFF6666FF, nil },
+ { 0xFF6699FF, nil },
+ { 0xFF66CCFF, nil },
+ { 0xFF66FFFF, nil },
+ { 0xFF9900FF, nil },
+ { 0xFF9933FF, nil },
+ { 0xFF9966FF, nil },
+ { 0xFF9999FF, nil },
+ { 0xFF99CCFF, nil },
+ { 0xFF99FFFF, nil },
+ { 0xFFCC00FF, nil },
+ { 0xFFCC33FF, nil },
+ { 0xFFCC66FF, nil },
+ { 0xFFCC99FF, nil },
+ { 0xFFCCCCFF, nil },
+ { 0xFFCCFFFF, nil },
+ { 0xFFFF00FF, nil },
+ { 0xFFFF33FF, nil },
+ { 0xFFFF66FF, nil },
+ { 0xFFFF99FF, nil },
+ { 0xFFFFCCFF, nil },
+ { 0xFFFFFFFF, nil },
+};
+
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,18 @@
+</$objtype/mkfile
+
+BIN=/$objtype/bin
+TARG=slug
+LIB=lua/liblua.a.$O
+HFILES=
+OFILES=slug.$O
+
+</sys/src/cmd/mkone
+
+CFLAGS=-FTVw -p -Ilua/shim -Ilua -DLUA_USE_PLAN9
+
+$LIB:V:
+ @{cd lua; mk}
+
+clean nuke:V:
+ @{ cd lua; mk $target }
+ rm -f *.[$OS] [$OS].out $TARG
--- /dev/null
+++ b/slug.c
@@ -1,0 +1,178 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <mouse.h>
+#include <keyboard.h>
+#include <lua.h>
+#include <lauxlib.h>
+#include <lualib.h>
+
+typedef struct Color Color;
+
+struct Color
+{
+ ulong color;
+ Image *i;
+};
+
+#include "colors.h"
+
+lua_State *L;
+Mousectl *mc;
+Keyboardctl *kc;
+Image *fg;
+int strokewidth;
+
+void
+lsetup(void)
+{
+ lua_getglobal(L, "setup");
+ if(!lua_isfunction(L, -1))
+ return;
+ lua_call(L, 0, 0);
+ flushimage(display, 1);
+}
+
+void
+ldraw(void)
+{
+ lua_getglobal(L, "draw");
+ if(!lua_isfunction(L, -1))
+ return;
+ lua_call(L, 0, 0);
+ flushimage(display, 1);
+}
+
+Image*
+getcolor(int n)
+{
+ if(n < 0)
+ n = 0;
+ if(n >= nelem(palette))
+ n = nelem(palette) - 1;
+ if(palette[n].i == nil)
+ palette[n].i = allocimage(display, Rect(0, 0, 1, 1), screen->chan, 1, palette[n].color);
+ return palette[n].i;
+}
+
+int
+cbackground(lua_State *L)
+{
+ Image *i;
+ int n;
+
+ n = luaL_checkinteger(L, 1);
+ i = getcolor(n);
+ draw(screen, screen->r, i, nil, ZP);
+ return 0;
+}
+
+int
+cstroke(lua_State *L)
+{
+ int n;
+
+ n = luaL_checkinteger(L, 1);
+ fg = getcolor(n);
+ return 0;
+}
+
+int
+cstrokewidth(lua_State *L)
+{
+ int n;
+
+ n = luaL_checkinteger(L, 1);
+ strokewidth = n;
+ return 0;
+}
+
+int
+cline(lua_State *L)
+{
+ Point p1, p2;
+ int x1, x2, y1, y2;
+
+ x1 = luaL_checkinteger(L, 1);
+ y1 = luaL_checkinteger(L, 2);
+ x2 = luaL_checkinteger(L, 3);
+ y2 = luaL_checkinteger(L, 4);
+ p1 = addpt(screen->r.min, Pt(x1, y1));
+ p2 = addpt(screen->r.min, Pt(x2, y2));
+ line(screen, p1, p2, 0, 0, strokewidth, fg, ZP);
+ return 0;
+}
+
+void
+initcontext(void)
+{
+ fg = display->black;
+ strokewidth = 1;
+}
+
+void
+registerfunc(const char *name, int(*f)(lua_State*))
+{
+ lua_pushcfunction(L, f);
+ lua_setglobal(L, name);
+}
+
+void
+registerfuncs(void)
+{
+ registerfunc("background", cbackground);
+ registerfunc("stroke", cstroke);
+ registerfunc("strokeWidth", cstrokewidth);
+ registerfunc("line", cline);
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+ Rune k;
+ const char *s;
+ int r;
+ Alt alts[] = {
+ { nil, nil, CHANRCV },
+ { nil, &k, CHANRCV },
+ { nil, nil, CHANNOBLK },
+ };
+
+ if(initdraw(nil, nil, "slug") < 0)
+ sysfatal("initdraw: %r");
+ display->locking = 0;
+ if((mc = initmouse(nil, screen)) == nil)
+ sysfatal("initmouse: %r");
+ if((kc = initkeyboard(nil)) == nil)
+ sysfatal("initkeyboard: %r");
+ alts[0].c = mc->resizec;
+ alts[1].c = kc->c;
+ L = luaL_newstate();
+ luaL_openlibs(L);
+ r = luaL_dofile(L, argc > 1 ? argv[1] : NULL);
+ if(r != LUA_OK){
+ s = luaL_checkstring(L, lua_gettop(L));
+ fprint(2, "error: %s\n", s);
+ }
+ registerfuncs();
+ initcontext();
+ lsetup();
+ for(;;){
+ ldraw();
+ switch(alt(alts)){
+ case 0:
+ if(getwindow(display, Refnone)<0)
+ sysfatal("getwindow: %r");
+ break;
+ case 1:
+ if(k == Kdel)
+ goto Done;
+ break;
+ }
+ }
+Done:
+ lua_close(L);
+ threadexitsall(r == LUA_OK ? nil : "error");
+}
+