aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrodri <rgl@antares-labs.eu>2020-06-14 19:54:18 +0000
committerrodri <rgl@antares-labs.eu>2020-06-14 19:54:18 +0000
commit1024676bc6ad5ef8b073cefd5da22c89dbb59dde (patch)
treec94ca5df7fd2c0f3b22913ef6c9cf9609aa69d33
parentd80ac9e9f103779aa61871c65d9939a3478c19a6 (diff)
downloadpuppeteer-1024676bc6ad5ef8b073cefd5da22c89dbb59dde.tar.gz
puppeteer-1024676bc6ad5ef8b073cefd5da22c89dbb59dde.tar.bz2
puppeteer-1024676bc6ad5ef8b073cefd5da22c89dbb59dde.zip
now it's possible to paint on any given layer. also changed worldrf.
-rw-r--r--canvas.c25
-rw-r--r--dat.h3
-rw-r--r--fns.h9
-rw-r--r--layer.c17
-rw-r--r--main.c99
-rw-r--r--mkfile1
6 files changed, 112 insertions, 42 deletions
diff --git a/canvas.c b/canvas.c
index abd0089..d2632bb 100644
--- a/canvas.c
+++ b/canvas.c
@@ -5,17 +5,8 @@
#include "dat.h"
#include "fns.h"
-static int
-alphachan(ulong chan)
-{
- for(; chan; chan >>= 8)
- if(TYPE(chan) == CAlpha)
- return 1;
- return 0;
-}
-
Canvas*
-newcanvas(Point2 p, Rectangle r, ulong chan)
+newcanvas(char *name, Point2 p, Rectangle r, ulong chan)
{
Canvas *c;
@@ -23,9 +14,23 @@ newcanvas(Point2 p, Rectangle r, ulong chan)
c->p = p;
c->bx = Vec2(1,0);
c->by = Vec2(0,1);
+ c->name = strdup(name);
c->image = eallocimage(display, r, chan, 0, alphachan(chan)? DTransparent: DNofill);
memset(&c->layers, 0, sizeof(Layer));
c->layers.next = &c->layers;
c->layers.prev = &c->layers;
+ c->curlayer = nil;
return c;
}
+
+void
+rmcanvas(Canvas *c)
+{
+ Layer *l;
+
+ for(l = c->layers.next; l != &c->layers; l = l->next)
+ rmlayer(l);
+ freeimage(c->image);
+ free(c->name);
+ free(c);
+}
diff --git a/dat.h b/dat.h
index b913602..ce1cd64 100644
--- a/dat.h
+++ b/dat.h
@@ -4,6 +4,7 @@ typedef struct Canvas Canvas;
struct Layer
{
RFrame;
+ char *name;
Image *image;
Layer *prev, *next;
};
@@ -11,6 +12,8 @@ struct Layer
struct Canvas
{
RFrame;
+ char *name;
Image *image;
Layer layers;
+ Layer *curlayer;
};
diff --git a/fns.h b/fns.h
index 6667415..cd9b91e 100644
--- a/fns.h
+++ b/fns.h
@@ -4,8 +4,13 @@ void *erealloc(void*, ulong);
Image *eallocimage(Display*, Rectangle, ulong, int, ulong);
/* canvas */
-Canvas *newcanvas(Point2, Rectangle, ulong);
+Canvas *newcanvas(char*, Point2, Rectangle, ulong);
+void rmcanvas(Canvas*);
/* layer */
-Layer *newlayer(Canvas*);
+Layer *newlayer(char*, Canvas*);
void rmlayer(Layer*);
+
+/* utils */
+double fclamp(double, double, double);
+int alphachan(ulong);
diff --git a/layer.c b/layer.c
index e3a389d..77584bc 100644
--- a/layer.c
+++ b/layer.c
@@ -5,17 +5,8 @@
#include "dat.h"
#include "fns.h"
-static int
-alphachan(ulong chan)
-{
- for(; chan; chan >>= 8)
- if(TYPE(chan) == CAlpha)
- return 1;
- return 0;
-}
-
Layer*
-newlayer(Canvas *c)
+newlayer(char *name, Canvas *c)
{
Layer *l;
@@ -23,11 +14,14 @@ newlayer(Canvas *c)
l->p = Pt2(0,0,1);
l->bx = c->bx;
l->by = c->by;
- l->image = eallocimage(display, c->image->r, c->image->chan, 0, alphachan(c->image->chan)? DTransparent: DNofill);
+ l->name = strdup(name);
+ l->image = eallocimage(display, c->image->r, c->image->chan, 0, 0);
l->prev = c->layers.prev;
l->next = &c->layers;
c->layers.prev->next = l;
c->layers.prev = l;
+ if(c->curlayer == nil)
+ c->curlayer = l;
return l;
}
@@ -37,5 +31,6 @@ rmlayer(Layer *l)
l->prev->next = l->next;
l->next->prev = l->prev;
freeimage(l->image);
+ free(l->name);
free(l);
}
diff --git a/main.c b/main.c
index dad91f1..720bc56 100644
--- a/main.c
+++ b/main.c
@@ -20,6 +20,8 @@ Image *pal[NCOLOR];
Image *background;
Canvas *curcanvas;
+void resized(void);
+
Point
toscreen(Point2 p)
{
@@ -70,6 +72,8 @@ drawcanvas(Canvas *c)
{
Layer *l;
+ if(c == nil)
+ return;
for(l = c->layers.next; l != &c->layers; l = l->next)
drawlayer(c, l);
draw(screen, rectaddpt(c->image->r, toscreen(c->p)), c->image, nil, ZP);
@@ -81,24 +85,12 @@ redraw(void)
lockdisplay(display);
draw(screen, screen->r, pal[PCBlack], nil, ZP);
draw(screen, curcanvas == nil? screen->r: rectaddpt(curcanvas->image->r, toscreen(curcanvas->p)), background, nil, ZP);
- if(curcanvas != nil)
- drawcanvas(curcanvas);
+ drawcanvas(curcanvas);
flushimage(display, 1);
unlockdisplay(display);
}
void
-resized(void)
-{
- lockdisplay(display);
- if(getwindow(display, Refnone) < 0)
- sysfatal("resize failed");
- unlockdisplay(display);
- worldrf.p = Pt2(screen->r.min.x,screen->r.max.y,1);
- redraw();
-}
-
-void
rmb(Mousectl *mc, Keyboardctl *kc)
{
enum {
@@ -114,6 +106,7 @@ rmb(Mousectl *mc, Keyboardctl *kc)
char buf[256], chanstr[9+1], *s;
ulong w, h, chan;
Point2 cpos;
+ Layer *l;
switch(menuhit(3, mc, &menu, nil)){
case NEW:
@@ -124,20 +117,77 @@ rmb(Mousectl *mc, Keyboardctl *kc)
w = strtoul(buf, &s, 10);
h = strtoul(s, &s, 10);
chan = strtochan(s);
- cpos = Pt2(Dx(screen->r)/2 - w/2,Dy(screen->r)/2 + h/2,1);
- curcanvas = newcanvas(cpos, Rect(0,0,w,h), chan);
+ cpos = Pt2(Dx(screen->r)/2 - w/2,Dy(screen->r)/2 - h/2,1);
+ curcanvas = newcanvas("default", cpos, Rect(0,0,w,h), chan);
+ fprint(2, "created canvas %s\n", curcanvas->name);
break;
case NEWLAYER:
if(curcanvas == nil)
break;
- newlayer(curcanvas);
+ buf[0] = 0;
+ while(strlen(buf) == 0)
+ enter("layer name", buf, sizeof buf, mc, kc, nil);
+ l = newlayer(buf, curcanvas);
+ fprint(2, "created layer %s\n", l->name);
break;
}
}
+static char*
+genlayeritem(int idx)
+{
+ Layer *l;
+
+ l = curcanvas->layers.next;
+ while(l != &curcanvas->layers && idx--)
+ l = l->next;
+ if(l == &curcanvas->layers)
+ return nil;
+ return l->name;
+}
+
+void
+mmb(Mousectl *mc, Keyboardctl *)
+{
+ static Menu menu = { .gen = genlayeritem };
+ int layeridx;
+ Layer *l;
+
+ if(curcanvas == nil)
+ return;
+ layeridx = menuhit(2, mc, &menu, nil);
+ if(layeridx >= 0){
+ l = curcanvas->layers.next;
+ while(l != &curcanvas->layers && layeridx--)
+ l = l->next;
+ curcanvas->curlayer = l;
+ fprint(2, "curlayer %s\n", l->name);
+ }
+}
+
+void
+lmb(Mousectl *mc, Keyboardctl *)
+{
+ Rectangle r;
+ Point2 mpos;
+ Point p;
+
+ if(curcanvas == nil)
+ return;
+ r = Rect(0,0,1,1);
+ mpos = fromscreen(mc->xy);
+ mpos = rframexform(mpos, *curcanvas);
+ p = Pt(mpos.x,mpos.y);
+ draw(curcanvas->curlayer->image, rectaddpt(r, p), pal[PCBlack], nil, ZP);
+}
+
void
mouse(Mousectl *mc, Keyboardctl *kc)
{
+ if((mc->buttons&1) != 0)
+ lmb(mc, kc);
+ if((mc->buttons&2) != 0)
+ mmb(mc, kc);
if((mc->buttons&4) != 0)
rmb(mc, kc);
}
@@ -179,9 +229,9 @@ threadmain(int argc, char *argv[])
if((kc = initkeyboard(nil)) == nil)
sysfatal("initkeyboard: %r");
- worldrf.p = Pt2(screen->r.min.x,screen->r.max.y,1);
- worldrf.bx = Vec2(1, 0);
- worldrf.by = Vec2(0,-1);
+ worldrf.p = Pt2(screen->r.min.x,screen->r.min.y,1);
+ worldrf.bx = Vec2(1,0);
+ worldrf.by = Vec2(0,1);
initpalette();
background = mkcheckerboard(4, 4);
@@ -213,3 +263,14 @@ threadmain(int argc, char *argv[])
redraw();
}
}
+
+void
+resized(void)
+{
+ lockdisplay(display);
+ if(getwindow(display, Refnone) < 0)
+ sysfatal("resize failed");
+ unlockdisplay(display);
+ worldrf.p = Pt2(screen->r.min.x,screen->r.min.y,1);
+ redraw();
+}
diff --git a/mkfile b/mkfile
index e83852c..5fa680c 100644
--- a/mkfile
+++ b/mkfile
@@ -3,6 +3,7 @@
BIN=/$objtype/bin
TARG=puppeteer
OFILES=\
+ utils.$O\
alloc.$O\
layer.$O\
canvas.$O\