-int init_emitter(struct emitter *em, int num, unsigned char *map, int xsz, int ysz)
-{
- int i, x, y;
- float aspect = (float)xsz / (float)ysz;
- struct particle *p;
-
- if(!(em->plist = malloc(num * sizeof *em->plist))) {
- return -1;
- }
- em->pcount = num;
-
- p = em->plist;
- for(i=0; i<num; i++) {
- do {
- x = rand() % xsz;
- y = rand() % ysz;
- } while(map[y * xsz + x] < 128);
-
- p->x = (float)x / (float)xsz - 0.5;
- p->y = -(float)y / (float)xsz + 0.5 / aspect;
- p->z = ((float)i / (float)num * 2.0 - 1.0) * 0.005;
- p->r = 0;
- p->g = 0x1f;
- p->b = 255;
- p->vx = p->vy = p->vz = 0.0f;
- p->life = MAX_LIFE;
- ++p;
- }
- return 0;
-}
-
-void update_particles(struct emitter *em, float dt)
-{
- int i;
- struct vec2 accel;
- struct particle *p = em->plist;
- struct g3d_vertex *v = varr;
-
- for(i=0; i<em->pcount; i++) {
- vfield_eval(&vfield, p->x, p->y, &accel);
- p->x += p->vx * DRAG * dt;
- p->y += p->vy * DRAG * dt;
- p->z += p->vz * DRAG * dt;
- p->vx += (wind[0] + accel.x * FORCE) * dt;
- p->vy += (wind[1] + accel.y * FORCE) * dt;
- p->vz += (wind[2] + p->z * ZBIAS) * dt;
- p->life -= dt;
- if(p->life < 0.0f) p->life = 0.0f;
-
- v->x = p->x;
- v->y = p->y;
- v->z = p->z;
- v->w = 1.0f;
- v->r = p->r;
- v->g = p->g;
- v->b = p->b;
- v->a = cround64(p->life * 255.0 / MAX_LIFE);
- ++v;
-
- ++p;
- }
-}
-
-void draw_particles(struct emitter *em)
-{
- g3d_enable(G3D_BLEND);
- g3d_draw(G3D_POINTS, varr, PCOUNT);
- g3d_disable(G3D_BLEND);
-}
-
-
-int init_vfield_load(struct vfield *vf, const char *fname)
-{
- FILE *fp;
- int tmp;
-
- if(!(fp = fopen(fname, "rb"))) {
- fprintf(stderr, "failed to open vector field: %s\n", fname);
- return -1;
- }
- if(fread(&vf->width, sizeof vf->width, 1, fp) < 1 ||
- fread(&vf->height, sizeof vf->height, 1, fp) < 1) {
- fprintf(stderr, "init_vfield_load: unexpected end of file while reading header\n");
- fclose(fp);
- return -1;
- }
-
- /* assume xsz is pow2 otherwise fuck you */
- tmp = vf->width - 1;
- vf->xshift = 0;
- while(tmp) {
- ++vf->xshift;
- tmp >>= 1;