summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs.c54
1 files changed, 35 insertions, 19 deletions
diff --git a/fs.c b/fs.c
index ceb69ac..a052fd5 100644
--- a/fs.c
+++ b/fs.c
@@ -21,8 +21,8 @@ struct Dirtab
struct Client
{
+ Ref;
ulong slot;
- int inuse;
Camera *cam;
};
@@ -78,6 +78,8 @@ ulong nclients;
static LightSource light = {{0,100,100,1}, {1,1,1,1}, LIGHT_POINT};
+static Client *getclient(ulong);
+
static Point3
vshader(VSparams *sp)
{
@@ -85,7 +87,7 @@ vshader(VSparams *sp)
Point3 pos, lightdir;
double intens;
- c = &clients[0]; /* TODO figure out a way to address the correct client */
+ c = getclient(0); /* TODO figure out a way to address the correct client */
pos = model2world(sp->su->entity, sp->v->p);
lightdir = normvec3(subpt3(light.p, pos));
@@ -149,6 +151,20 @@ strwidth(char *s)
return cw*nc;
}
+static void
+resetcamera(Camera *c)
+{
+ rmviewport(c->vp);
+ c->vp = mkviewport(Rect(0,0,320,200));
+ c->fov = 40*DEG;
+ c->clip.n = 0.01;
+ c->clip.f = 1000;
+ c->projtype = PERSPECTIVE;
+ c->rctl = renderer;
+ placecamera(c, Pt3(0,0,100,1), Pt3(0,0,0,1), Vec3(0,1,0));
+ reloadcamera(c);
+}
+
static ulong
newclient(void)
{
@@ -156,25 +172,18 @@ newclient(void)
int i;
for(i = 0; i < nclients; i++)
- if(!clients[i].inuse)
+ if(clients[i].ref == 0)
return i;
if(nclients%16 == 0)
clients = erealloc9p(clients, (nclients+16)*sizeof(*clients));
- c = &clients[nclients++];
+ c = getclient(nclients++);
+ memset(c, 0, sizeof *c);
c->slot = c-clients;
- c->inuse = 1;
c->cam = emalloc9p(sizeof *c->cam);
- c->cam->vp = mkviewport(Rect(0,0,320,200));
- c->cam->fov = 40*DEG;
- c->cam->clip.n = 0.01;
- c->cam->clip.f = 1000;
- c->cam->projtype = PERSPECTIVE;
- c->cam->rctl = renderer;
+ resetcamera(c->cam);
c->cam->s = newscene(nil);
- placecamera(c->cam, Pt3(0,0,100,1), Pt3(0,0,0,1), Vec3(0,1,0));
- reloadcamera(c->cam);
return c->slot;
}
@@ -189,7 +198,11 @@ getclient(ulong slot)
static void
closeclient(Client *c)
{
- c->inuse = 0;
+ if(decref(c))
+ return;
+
+ clearscene(c->cam->s);
+ resetcamera(c->cam);
}
static void
@@ -365,6 +378,8 @@ deny:
r->fid->qid.path = path;
r->ofcall.qid.path = path;
}
+ if(QTYPE(path) >= Qn)
+ incref(getclient(SLOT(path)));
respond(r, nil);
}
@@ -382,7 +397,7 @@ fsread(Req *r)
path = r->fid->qid.path;
off = r->ifcall.offset;
cnt = r->ifcall.count;
- c = &clients[SLOT(path)];
+ c = getclient(SLOT(path));
switch(QTYPE(path)){
default:
@@ -393,7 +408,7 @@ fsread(Req *r)
respond(r, nil);
break;
case Qn:
- dirread9p(r, clientgen, &clients[SLOT(path)]);
+ dirread9p(r, clientgen, getclient(SLOT(path)));
respond(r, nil);
break;
case Qctl:
@@ -449,7 +464,8 @@ fsread(Req *r)
n += snprint(buf+n, sizeof(buf)-n, "pos %V\n", c->cam->p);
n += snprint(buf+n, sizeof(buf)-n, "fov %g°\n", c->cam->fov/DEG);
n += snprint(buf+n, sizeof(buf)-n, "clip [%g %g]\n", c->cam->clip.n, c->cam->clip.f);
- snprint(buf+n, sizeof(buf)-n, "proj %s\n", c->cam->projtype == PERSPECTIVE? "persp": "ortho");
+ n += snprint(buf+n, sizeof(buf)-n, "proj %s\n", c->cam->projtype == PERSPECTIVE? "persp": "ortho");
+ snprint(buf+n, sizeof(buf)-n, "ents %lud\n", c->cam->s->nents);
readstr(r, buf);
respond(r, nil);
break;
@@ -474,7 +490,7 @@ fswrite(Req *r)
path = r->fid->qid.path;
cnt = r->ifcall.count;
- c = &clients[SLOT(path)];
+ c = getclient(SLOT(path));
switch(QTYPE(path)){
default:
@@ -595,7 +611,7 @@ fsdestroyfid(Fid *f)
path = f->qid.path;
if(f->omode != -1 && QTYPE(path) >= Qn)
- closeclient(&clients[SLOT(path)]);
+ closeclient(getclient(SLOT(path)));
}
void