shithub: slug

Download patch

ref: a5456e6c0abe933600de2de1b290b08e264953f2
author: phil9 <[email protected]>
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 <[email protected]>
+
+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");
+}
+