diff options
Diffstat (limited to 'src/modules')
| -rw-r--r-- | src/modules/sparkler/bsp.c | 56 | ||||
| -rw-r--r-- | src/modules/sparkler/bsp.h | 2 | ||||
| -rw-r--r-- | src/modules/sparkler/burst.c | 27 | ||||
| -rw-r--r-- | src/modules/sparkler/list.h | 2 | ||||
| -rw-r--r-- | src/modules/sparkler/particle.c | 6 | ||||
| -rw-r--r-- | src/modules/sparkler/particle.h | 31 | ||||
| -rw-r--r-- | src/modules/sparkler/particles.c | 152 | ||||
| -rw-r--r-- | src/modules/sparkler/particles.h | 6 | ||||
| -rw-r--r-- | src/modules/sparkler/rocket.c | 8 | ||||
| -rw-r--r-- | src/modules/sparkler/simple.c | 6 | ||||
| -rw-r--r-- | src/modules/sparkler/spark.c | 6 | ||||
| -rw-r--r-- | src/modules/sparkler/sparkler.c | 78 | ||||
| -rw-r--r-- | src/modules/sparkler/xplode.c | 6 | 
13 files changed, 333 insertions, 53 deletions
diff --git a/src/modules/sparkler/bsp.c b/src/modules/sparkler/bsp.c index ae5a20e..f55501a 100644 --- a/src/modules/sparkler/bsp.c +++ b/src/modules/sparkler/bsp.c @@ -574,3 +574,59 @@ void bsp_search_sphere(bsp_t *bsp, v3f_t *center, float radius_min, float radius  	_bsp_search_sphere(bsp, &bsp->root, &search, &aabb_min, &aabb_max);  } + + +static void _bsp_walk_leaves(const bsp_t *bsp, const bsp_node_t *node, unsigned depth, const v3f_t *aabb_min, const v3f_t *aabb_max, void (*cb)(const bsp_t *bsp, const list_head_t *occupants, unsigned depth, const v3f_t *bv_min, const v3f_t *bv_max, void *cb_data), void *cb_data) +{ +	v3f_t	oaabb_min, oaabb_max; + +	/* if node is a leaf, call cb with the occupants, then return. */ +	if (!node->octrants) +		return cb(bsp, &node->occupants, depth, aabb_min, aabb_max, cb_data); + +	/* node is a parent, recur on each octrant with appropriately adjusted aabb_min:aabb_max values */ +	/* if any of the octrants absolutely overlaps the search sphere, skip the others by returning. */ +#define walk_octrant(_oid, _aabb_min, _aabb_max)					\ +	_bsp_walk_leaves(bsp, &node->octrants[_oid], depth + 1, _aabb_min, _aabb_max, cb, cb_data); + +	/* OCT_XL_YL_ZL and OCT_XR_YR_ZR AABBs don't require tedious composition */ +	walk_octrant(OCT_XL_YL_ZL, aabb_min, &node->center); +	walk_octrant(OCT_XR_YR_ZR, &node->center, aabb_max); + +	/* the rest are stitched together requiring temp storage and tedium */ +	v3f_set(&oaabb_min, node->center.x, aabb_min->y, aabb_min->z); +	v3f_set(&oaabb_max, aabb_max->x, node->center.y, node->center.z); +	walk_octrant(OCT_XR_YL_ZL, &oaabb_min, &oaabb_max); + +	v3f_set(&oaabb_min, aabb_min->x, node->center.y, aabb_min->z); +	v3f_set(&oaabb_max, node->center.x, aabb_max->y, node->center.z); +	walk_octrant(OCT_XL_YR_ZL, &oaabb_min, &oaabb_max); + +	v3f_set(&oaabb_min, node->center.x, node->center.y, aabb_min->z); +	v3f_set(&oaabb_max, aabb_max->x, aabb_max->y, node->center.z); +	walk_octrant(OCT_XR_YR_ZL, &oaabb_min, &oaabb_max); + +	v3f_set(&oaabb_min, aabb_min->x, aabb_min->y, node->center.z); +	v3f_set(&oaabb_max, node->center.x, node->center.y, aabb_max->z); +	walk_octrant(OCT_XL_YL_ZR, &oaabb_min, &oaabb_max); + +	v3f_set(&oaabb_min, node->center.x, aabb_min->y, node->center.z); +	v3f_set(&oaabb_max, aabb_max->x, node->center.y, aabb_max->z); +	walk_octrant(OCT_XR_YL_ZR, &oaabb_min, &oaabb_max); + +	v3f_set(&oaabb_min, aabb_min->x, node->center.y, node->center.z); +	v3f_set(&oaabb_max, node->center.x, aabb_max->y, aabb_max->z); +	walk_octrant(OCT_XL_YR_ZR, &oaabb_min, &oaabb_max); + +#undef walk_octrant +} + + +/* traverse the bsp tree calling cb for every leaf node, no discriminating of positions */ +void bsp_walk_leaves(const bsp_t *bsp, void (*cb)(const bsp_t *bsp, const list_head_t *occupants, unsigned depth, const v3f_t *bv_min, const v3f_t *bv_max, void *cb_data), void *cb_data) +{ +	v3f_t	aabb_min = v3f_init(-1.0f, -1.0f, -1.0f); +	v3f_t	aabb_max = v3f_init(1.0f, 1.0f, 1.0f); + +	_bsp_walk_leaves(bsp, &bsp->root, 0, &aabb_min, &aabb_max, cb, cb_data); +} diff --git a/src/modules/sparkler/bsp.h b/src/modules/sparkler/bsp.h index f5ce303..3ca0c02 100644 --- a/src/modules/sparkler/bsp.h +++ b/src/modules/sparkler/bsp.h @@ -25,4 +25,6 @@ void bsp_delete_occupant(bsp_t *bsp, bsp_occupant_t *occupant);  void bsp_move_occupant(bsp_t *bsp, bsp_occupant_t *occupant, v3f_t *position);  void bsp_search_sphere(bsp_t *bsp, v3f_t *center, float radius_min, float radius_max, void (*cb)(bsp_t *, list_head_t *, void *), void *cb_data); +void bsp_walk_leaves(const bsp_t *bsp, void (*cb)(const bsp_t *bsp, const list_head_t *occupants, unsigned depth, const v3f_t *bv_min, const v3f_t *bv_max, void *cb_data), void *cb_data); +  #endif diff --git a/src/modules/sparkler/burst.c b/src/modules/sparkler/burst.c index 72cde03..b5ad365 100644 --- a/src/modules/sparkler/burst.c +++ b/src/modules/sparkler/burst.c @@ -18,7 +18,7 @@ typedef struct _burst_ctxt_t {  } burst_ctxt_t; -static int burst_init(particles_t *particles, particle_t *p) +static int burst_init(particles_t *particles, const particles_conf_t *conf, particle_t *p)  {  	burst_ctxt_t	*ctxt = p->ctxt; @@ -43,9 +43,13 @@ static inline void thrust_part(particle_t *burst, particle_t *victim, float dist  typedef struct burst_sphere_t { -	particle_t	*center; +	particles_t	*particles; +	particle_t	*center, *last; +	fb_fragment_t	*fragment;  	float		radius_min;  	float		radius_max; +	unsigned	trace_matches:1; +	unsigned	trace_affected:1;  } burst_sphere_t; @@ -64,7 +68,7 @@ static void burst_cb(bsp_t *bsp, list_head_t *occupants, void *_s)  	list_for_each_entry(o, occupants, occupants) {  		particle_t	*p = container_of(o, particle_t, occupant);  		float		d_sq; -		 +  		if (p->props->virtual) {  			/* don't move virtual particles (includes ourself) */  			continue; @@ -75,13 +79,22 @@ static void burst_cb(bsp_t *bsp, list_head_t *occupants, void *_s)  		if (d_sq > rmin_sq && d_sq < rmax_sq) {  			/* displace the part relative to the burst origin */  			thrust_part(s->center, p, d_sq); + +			if (s->trace_affected) { +				particles_draw_line(s->particles, &s->last->props->position, &p->props->position, s->fragment); +				s->last = p; +			}  		} +		if (s->trace_matches) { +			particles_draw_line(s->particles, &s->last->props->position, &p->props->position, s->fragment); +			s->last = p; +		}  	}  } -static particle_status_t burst_sim(particles_t *particles, particle_t *p) +static particle_status_t burst_sim(particles_t *particles, const particles_conf_t *conf, particle_t *p, fb_fragment_t *f)  {  	burst_ctxt_t	*ctxt = p->ctxt;  	bsp_t		*bsp = particles_bsp(particles);	/* XXX see note above about bsp_occupant_t */ @@ -94,7 +107,11 @@ static particle_status_t burst_sim(particles_t *particles, particle_t *p)  	/* affect neighbors for the shock-wave */  	s.radius_min = (1.0f - ((float)ctxt->longevity / ctxt->lifetime)) * 0.075f;  	s.radius_max = s.radius_min + .01f; -	s.center = p; +	s.center = s.last = p; +	s.trace_matches = (conf->show_bsp_matches && !conf->show_bsp_matches_affected_only); +	s.trace_affected = (conf->show_bsp_matches && conf->show_bsp_matches_affected_only); +	s.particles = particles; +	s.fragment = f;  	bsp_search_sphere(bsp, &p->props->position, s.radius_min, s.radius_max, burst_cb, &s);  	return PARTICLE_ALIVE; diff --git a/src/modules/sparkler/list.h b/src/modules/sparkler/list.h index 48bca36..04cafd6 100644 --- a/src/modules/sparkler/list.h +++ b/src/modules/sparkler/list.h @@ -130,7 +130,7 @@ static inline void list_move_tail(struct list_head *list,   * list_empty - tests whether a list is empty   * @head: the list to test.   */ -static inline int list_empty(struct list_head *head) +static inline int list_empty(const struct list_head *head)  {  	return head->next == head;  } diff --git a/src/modules/sparkler/particle.c b/src/modules/sparkler/particle.c index 0e3d2c8..76d0c70 100644 --- a/src/modules/sparkler/particle.c +++ b/src/modules/sparkler/particle.c @@ -1,14 +1,14 @@  #include "particle.h"  /* convert a particle to a new type */ -void particle_convert(particles_t *particles, particle_t *p, particle_props_t *props, particle_ops_t *ops) +void particle_convert(particles_t *particles, const particles_conf_t *conf, particle_t *p, particle_props_t *props, particle_ops_t *ops)  { -	particle_cleanup(particles, p); +	particle_cleanup(particles, conf, p);  	if (props) {  		*p->props = *props;  	}  	if (ops) {  		p->ops = ops;  	} -	particle_init(particles, p); +	particle_init(particles, conf, p);  } diff --git a/src/modules/sparkler/particle.h b/src/modules/sparkler/particle.h index c63024d..a5999ee 100644 --- a/src/modules/sparkler/particle.h +++ b/src/modules/sparkler/particle.h @@ -22,13 +22,14 @@ typedef enum particle_status_t {  typedef struct particle_t particle_t;  typedef struct particles_t particles_t; +typedef struct particles_conf_t particles_conf_t;  typedef struct particle_ops_t {  	unsigned		context_size;								/* size of the particle context (0 for none) */ -	int			(*init)(particles_t *, particle_t *);					/* initialize the particle, called after allocating context (optional) */ -	void			(*cleanup)(particles_t *, particle_t *);				/* cleanup function, called before freeing context (optional) */ -	particle_status_t	(*sim)(particles_t *, particle_t *);					/* simulate the particle for another cycle (required) */ -	void			(*draw)(particles_t *, particle_t *, int, int, fb_fragment_t *);	/* draw the particle, 3d->2d projection has been done already (optional) */ +	int			(*init)(particles_t *, const particles_conf_t *, particle_t *);					/* initialize the particle, called after allocating context (optional) */ +	void			(*cleanup)(particles_t *, const particles_conf_t *, particle_t *);				/* cleanup function, called before freeing context (optional) */ +	particle_status_t	(*sim)(particles_t *, const particles_conf_t *, particle_t *, fb_fragment_t *);			/* simulate the particle for another cycle (required) */ +	void			(*draw)(particles_t *, const particles_conf_t *, particle_t *, int, int, fb_fragment_t *);	/* draw the particle, 3d->2d projection has been done already (optional) */  } particle_ops_t;  struct particle_t { @@ -47,34 +48,38 @@ struct particle_t {  #define INHERIT_PROPS	NULL -static inline int particle_init(particles_t *particles, particle_t *p) { +static inline int particle_init(particles_t *particles, const particles_conf_t *conf, particle_t *p) {  	if (p->ops->init) { -		return p->ops->init(particles, p); +		return p->ops->init(particles, conf, p);  	}  	return 1;  } -static inline void particle_cleanup(particles_t *particles, particle_t *p) { +static inline void particle_cleanup(particles_t *particles, const particles_conf_t *conf, particle_t *p) {  	if (p->ops->cleanup) { -		p->ops->cleanup(particles, p); +		p->ops->cleanup(particles, conf, p);  	}  } -static inline particle_status_t particle_sim(particles_t *particles, particle_t *p) { -	return p->ops->sim(particles, p); +/* XXX: fragment is supplied to ops->sim() only for debugging/overlay purposes, if particles_conf_t.show_bsp_matches for + * example is true, then sim may draw into fragment, and the callers shouldn't zero the fragment between sim and draw but + * instead should zero it before sim.  It's kind of janky, not a fan. + */ +static inline particle_status_t particle_sim(particles_t *particles, const particles_conf_t *conf, particle_t *p, fb_fragment_t *f) { +	return p->ops->sim(particles, conf, p, f);  } -static inline void particle_draw(particles_t *particles, particle_t *p, int x, int y, fb_fragment_t *f) { +static inline void particle_draw(particles_t *particles, const particles_conf_t *conf, particle_t *p, int x, int y, fb_fragment_t *f) {  	if (p->ops->draw) { -		p->ops->draw(particles, p, x, y, f); +		p->ops->draw(particles, conf, p, x, y, f);  	}  } -void particle_convert(particles_t *particles, particle_t *p, particle_props_t *props, particle_ops_t *ops); +void particle_convert(particles_t *particles, const particles_conf_t *conf, particle_t *p, particle_props_t *props, particle_ops_t *ops);  #endif diff --git a/src/modules/sparkler/particles.c b/src/modules/sparkler/particles.c index b43c57b..d4677b7 100644 --- a/src/modules/sparkler/particles.c +++ b/src/modules/sparkler/particles.c @@ -78,7 +78,7 @@ static inline void _particles_free_particle(particles_t *particles, _particle_t  {  	assert(p); -	particle_cleanup(particles, &p->public); +	particle_cleanup(particles, &particles->conf, &p->public);  	chunker_free(p);  } @@ -157,7 +157,7 @@ static inline int _particles_add_particle(particles_t *particles, list_head_t *l  		p->public.ctxt = p->context;  	} -	if (!particle_init(particles, &p->public)) { +	if (!particle_init(particles, &particles->conf, &p->public)) {  		/* XXX FIXME this shouldn't be normal, we don't want to allocate  		 * particles that cannot be initialized.  the rockets today set a cap  		 * by failing initialization, that's silly. */ @@ -237,7 +237,7 @@ static inline void _particles_draw(particles_t *particles, list_head_t *list, fb  		x = (p->props.position.x / (p->props.position.z - ZCONST) * w2) + w2;  		y = (p->props.position.y / (p->props.position.z - ZCONST) * h2) + h2; -		particle_draw(particles, &p->public, x, y, fragment); +		particle_draw(particles, &particles->conf, &p->public, x, y, fragment);  		if (!list_empty(&p->children)) {  			_particles_draw(particles, &p->children, fragment); @@ -246,16 +246,134 @@ static inline void _particles_draw(particles_t *particles, list_head_t *list, fb  } +/* TODO: maybe polish up and move into fb.c? */ +static void draw_line(fb_fragment_t *fragment, int x1, int y1, int x2, int y2) +{ +	int	x_delta = x2 - x1; +	int	y_delta = y2 - y1; +	int	sdx = x_delta < 0 ? -1 : 1; +	int	sdy = y_delta < 0 ? -1 : 1; + +	x_delta = abs(x_delta); +	y_delta = abs(y_delta); + +	if (x_delta >= y_delta) { +		/* X-major */ +		for (int minor = 0, x = 0; x <= x_delta; x++, x1 += sdx, minor += y_delta) { +			if (minor >= x_delta) { +				y1 += sdy; +				minor -= x_delta; +			} + +			fb_fragment_put_pixel_checked(fragment, x1, y1, 0xffffffff); +		} +	} else { +		/* Y-major */ +		for (int minor = 0, y = 0; y <= y_delta; y++, y1 += sdy, minor += x_delta) { +			if (minor >= y_delta) { +				x1 += sdx; +				minor -= y_delta; +			} + +			fb_fragment_put_pixel_checked(fragment, x1, y1, 0xffffffff); +		} +	} +} + + +static void draw_edge(fb_fragment_t *fragment, const v3f_t *a, const v3f_t *b) +{ +	float	w2 = fragment->frame_width * .5f, h2 = fragment->frame_height * .5f; +	int	x1, y1, x2, y2; + +	/* project the 3d coordinates onto the 2d plane */ +	x1 = (a->x / (a->z - ZCONST) * w2) + w2; +	y1 = (a->y / (a->z - ZCONST) * h2) + h2; +	x2 = (b->x / (b->z - ZCONST) * w2) + w2; +	y2 = (b->y / (b->z - ZCONST) * h2) + h2; + +	draw_line(fragment, x1, y1, x2, y2); +} + + +static void draw_bv(fb_fragment_t *fragment, const v3f_t *bv_min, const v3f_t *bv_max) +{ +	draw_edge(fragment, +		&(v3f_t){bv_min->x, bv_max->y, bv_min->z}, +		&(v3f_t){bv_max->x, bv_max->y, bv_min->z}); +	draw_edge(fragment, +		&(v3f_t){bv_min->x, bv_max->y, bv_min->z}, +		&(v3f_t){bv_min->x, bv_max->y, bv_max->z}); +	draw_edge(fragment, +		&(v3f_t){bv_min->x, bv_max->y, bv_min->z}, +		&(v3f_t){bv_min->x, bv_min->y, bv_min->z}); +	draw_edge(fragment, +		&(v3f_t){bv_max->x, bv_min->y, bv_min->z}, +		&(v3f_t){bv_max->x, bv_min->y, bv_max->z}); +	draw_edge(fragment, +		&(v3f_t){bv_max->x, bv_min->y, bv_min->z}, +		&(v3f_t){bv_min->x, bv_min->y, bv_min->z}); +	draw_edge(fragment, +		&(v3f_t){bv_max->x, bv_min->y, bv_min->z}, +		&(v3f_t){bv_max->x, bv_max->y, bv_min->z}); +	draw_edge(fragment, +		&(v3f_t){bv_max->x, bv_max->y, bv_max->z}, +		&(v3f_t){bv_min->x, bv_max->y, bv_max->z}); +	draw_edge(fragment, +		&(v3f_t){bv_max->x, bv_max->y, bv_max->z}, +		&(v3f_t){bv_max->x, bv_max->y, bv_min->z}); +	draw_edge(fragment, +		&(v3f_t){bv_max->x, bv_max->y, bv_max->z}, +		&(v3f_t){bv_max->x, bv_min->y, bv_max->z}); +	draw_edge(fragment, +		&(v3f_t){bv_min->x, bv_min->y, bv_max->z}, +		&(v3f_t){bv_min->x, bv_min->y, bv_min->z}); +	draw_edge(fragment, +		&(v3f_t){bv_min->x, bv_min->y, bv_max->z}, +		&(v3f_t){bv_min->x, bv_max->y, bv_max->z}); +	draw_edge(fragment, +		&(v3f_t){bv_min->x, bv_min->y, bv_max->z}, +		&(v3f_t){bv_max->x, bv_min->y, bv_max->z}); +} + + +/* something to encapsulate these pointers for passing through as one to draw_leaf() */ +typedef struct draw_leafs_t { +	particles_t	*particles; +	fb_fragment_t	*fragment; +} draw_leafs_t; + + +/* callback for bsp_walk_leaves() when show_bsp_leafs is enabled */ +static void draw_leaf(const bsp_t *bsp, const list_head_t *occupants, unsigned depth, const v3f_t *bv_min, const v3f_t *bv_max, void *cb_data) +{ +	draw_leafs_t	*draw = cb_data; + +	if (list_empty(occupants)) +		return; + +	if (depth < draw->particles->conf.show_bsp_leafs_min_depth) +		return; + +	draw_bv(draw->fragment, bv_min, bv_max); +} + +  /* draw all of the particles, currently called in heirarchical order */  void particles_draw(particles_t *particles, fb_fragment_t *fragment)  { +	draw_leafs_t	draw = { .particles = particles, .fragment = fragment }; +  	assert(particles);  	_particles_draw(particles, &particles->active, fragment); + +	if (particles->conf.show_bsp_leafs) +		bsp_walk_leaves(particles->bsp, draw_leaf, &draw);  } -static inline particle_status_t _particles_sim(particles_t *particles, list_head_t *list) +static inline particle_status_t _particles_sim(particles_t *particles, list_head_t *list, fb_fragment_t *fragment)  {  	particle_status_t	ret = PARTICLE_DEAD, s;  	_particle_t		*p, *_p; @@ -264,11 +382,11 @@ static inline particle_status_t _particles_sim(particles_t *particles, list_head  	assert(list);  	list_for_each_entry_safe(p, _p, list, siblings) { -		if ((s = particle_sim(particles, &p->public)) == PARTICLE_ALIVE) { +		if ((s = particle_sim(particles, &particles->conf, &p->public, fragment)) == PARTICLE_ALIVE) {  			ret = PARTICLE_ALIVE;  			if (!list_empty(&p->children) && -			    _particles_sim(particles, &p->children) == PARTICLE_ALIVE) { +			    _particles_sim(particles, &p->children, fragment) == PARTICLE_ALIVE) {  				ret = PARTICLE_ALIVE;  			}  		} else { @@ -282,11 +400,11 @@ static inline particle_status_t _particles_sim(particles_t *particles, list_head  /* simulate the particles, call the sim method of every particle in the heirarchy, this is what makes the particles dynamic */  /* if any paticle is still living, we return PARTICLE_ALIVE, to inform the caller when everything's dead */ -particle_status_t particles_sim(particles_t *particles) +particle_status_t particles_sim(particles_t *particles, fb_fragment_t *fragment)  {  	assert(particles); -	return _particles_sim(particles, &particles->active); +	return _particles_sim(particles, &particles->active, fragment);  } @@ -357,3 +475,21 @@ void particles_age(particles_t *particles)  	_particles_age(particles, &particles->active);  } + + +/* draw a line expressed in world-space positions a to b into fragment, this is intended for + * instrumentation/overlay debugging type purposes... + */ +void particles_draw_line(particles_t *particles, const v3f_t *a, const v3f_t *b, fb_fragment_t *fragment) +{ +	float	w2 = fragment->frame_width * .5f, h2 = fragment->frame_height * .5f; +	int	x1, y1, x2, y2; + +	/* project the 3d coordinates onto the 2d plane */ +	x1 = (a->x / (a->z - ZCONST) * w2) + w2; +	y1 = (a->y / (a->z - ZCONST) * h2) + h2; +	x2 = (b->x / (b->z - ZCONST) * w2) + w2; +	y2 = (b->y / (b->z - ZCONST) * h2) + h2; + +	draw_line(fragment, x1, y1, x2, y2); +} diff --git a/src/modules/sparkler/particles.h b/src/modules/sparkler/particles.h index b191b6e..9d6e3af 100644 --- a/src/modules/sparkler/particles.h +++ b/src/modules/sparkler/particles.h @@ -9,18 +9,22 @@  typedef struct particles_conf_t {  	unsigned	show_bsp_leafs:1;  	unsigned	show_bsp_matches:1; +	unsigned	show_bsp_matches_affected_only:1; +	unsigned	show_bsp_leafs_min_depth;  } particles_conf_t;  typedef struct particles_t particles_t; +typedef struct v3f_t v3f_t;  particles_t * particles_new(const particles_conf_t *conf);  void particles_draw(particles_t *particles, fb_fragment_t *fragment); -particle_status_t particles_sim(particles_t *particles); +particle_status_t particles_sim(particles_t *particles, fb_fragment_t *fragment);  void particles_age(particles_t *particles);  void particles_free(particles_t *particles);  int particles_add_particle(particles_t *particles, particle_props_t *props, particle_ops_t *ops);  void particles_spawn_particle(particles_t *particles, particle_t *parent, particle_props_t *props, particle_ops_t *ops);  void particles_add_particles(particles_t *particles, particle_props_t *props, particle_ops_t *ops, int num);  bsp_t * particles_bsp(particles_t *particles); +void particles_draw_line(particles_t *particles, const v3f_t *a, const v3f_t *b, fb_fragment_t *fragment);  #endif diff --git a/src/modules/sparkler/rocket.c b/src/modules/sparkler/rocket.c index b56c324..50e1ff5 100644 --- a/src/modules/sparkler/rocket.c +++ b/src/modules/sparkler/rocket.c @@ -28,7 +28,7 @@ typedef struct rocket_ctxt_t {  } rocket_ctxt_t; -static int rocket_init(particles_t *particles, particle_t *p) +static int rocket_init(particles_t *particles, const particles_conf_t *conf, particle_t *p)  {  	rocket_ctxt_t	*ctxt = p->ctxt; @@ -54,7 +54,7 @@ static int rocket_init(particles_t *particles, particle_t *p)  } -static particle_status_t rocket_sim(particles_t *particles, particle_t *p) +static particle_status_t rocket_sim(particles_t *particles, const particles_conf_t *conf, particle_t *p, fb_fragment_t *f)  {  	rocket_ctxt_t	*ctxt = p->ctxt;  	int		i, n_sparks; @@ -120,7 +120,7 @@ static particle_status_t rocket_sim(particles_t *particles, particle_t *p)  } -static void rocket_draw(particles_t *particles, particle_t *p, int x, int y, fb_fragment_t *f) +static void rocket_draw(particles_t *particles, const particles_conf_t *conf, particle_t *p, int x, int y, fb_fragment_t *f)  {  	rocket_ctxt_t	*ctxt = p->ctxt; @@ -132,7 +132,7 @@ static void rocket_draw(particles_t *particles, particle_t *p, int x, int y, fb_  } -static void rocket_cleanup(particles_t *particles, particle_t *p) +static void rocket_cleanup(particles_t *particles, const particles_conf_t *conf, particle_t *p)  {  	rockets_cnt--;  } diff --git a/src/modules/sparkler/simple.c b/src/modules/sparkler/simple.c index 7c7d415..8db15b1 100644 --- a/src/modules/sparkler/simple.c +++ b/src/modules/sparkler/simple.c @@ -23,7 +23,7 @@ typedef struct _simple_ctxt_t {  } simple_ctxt_t; -static int simple_init(particles_t *particles, particle_t *p) +static int simple_init(particles_t *particles, const particles_conf_t *conf, particle_t *p)  {  	simple_ctxt_t	*ctxt = p->ctxt; @@ -54,7 +54,7 @@ static int simple_init(particles_t *particles, particle_t *p)  } -static particle_status_t simple_sim(particles_t *particles, particle_t *p) +static particle_status_t simple_sim(particles_t *particles, const particles_conf_t *conf, particle_t *p, fb_fragment_t *f)  {  	simple_ctxt_t	*ctxt = p->ctxt; @@ -95,7 +95,7 @@ static particle_status_t simple_sim(particles_t *particles, particle_t *p)  } -static void simple_draw(particles_t *particles, particle_t *p, int x, int y, fb_fragment_t *f) +static void simple_draw(particles_t *particles, const particles_conf_t *conf, particle_t *p, int x, int y, fb_fragment_t *f)  {  	simple_ctxt_t	*ctxt = p->ctxt; diff --git a/src/modules/sparkler/spark.c b/src/modules/sparkler/spark.c index 16268a9..c432bf5 100644 --- a/src/modules/sparkler/spark.c +++ b/src/modules/sparkler/spark.c @@ -18,7 +18,7 @@ typedef struct _spark_ctxt_t {  } spark_ctxt_t; -static int spark_init(particles_t *particles, particle_t *p) +static int spark_init(particles_t *particles, const particles_conf_t *conf, particle_t *p)  {  	spark_ctxt_t	*ctxt = p->ctxt; @@ -32,7 +32,7 @@ static int spark_init(particles_t *particles, particle_t *p)  } -static particle_status_t spark_sim(particles_t *particles, particle_t *p) +static particle_status_t spark_sim(particles_t *particles, const particles_conf_t *conf, particle_t *p, fb_fragment_t *f)  {  	spark_ctxt_t	*ctxt = p->ctxt; @@ -45,7 +45,7 @@ static particle_status_t spark_sim(particles_t *particles, particle_t *p)  } -static void spark_draw(particles_t *particles, particle_t *p, int x, int y, fb_fragment_t *f) +static void spark_draw(particles_t *particles, const particles_conf_t *conf, particle_t *p, int x, int y, fb_fragment_t *f)  {  	spark_ctxt_t	*ctxt = p->ctxt; diff --git a/src/modules/sparkler/sparkler.c b/src/modules/sparkler/sparkler.c index 20a56c7..b673d0c 100644 --- a/src/modules/sparkler/sparkler.c +++ b/src/modules/sparkler/sparkler.c @@ -74,7 +74,10 @@ static void sparkler_prepare_frame(void *context, unsigned ticks, unsigned ncpus  	*res_fragmenter = sparkler_fragmenter;  	ctxt->n_cpus = ncpus; -	particles_sim(ctxt->particles); +	if (sparkler_conf.show_bsp_matches) +		fb_fragment_zero(fragment); + +	particles_sim(ctxt->particles, fragment);  	particles_add_particles(ctxt->particles, NULL, &simple_ops, INIT_PARTS / 4);  	particles_age(ctxt->particles);  } @@ -85,7 +88,9 @@ static void sparkler_render_fragment(void *context, unsigned ticks, unsigned cpu  {  	sparkler_context_t	*ctxt = context; -	fb_fragment_zero(fragment); +	if (!sparkler_conf.show_bsp_matches) +		fb_fragment_zero(fragment); +  	particles_draw(ctxt->particles, fragment);  } @@ -96,11 +101,13 @@ static int sparkler_setup(const settings_t *settings, setting_desc_t **next_sett  	const char	*show_bsp_leafs;  	const char	*show_bsp_matches;  	const char	*values[] = { -				"on",  				"off", +				"on",  				NULL  			}; +	/* TODO: return -EINVAL on parse errors? */ +  	show_bsp_leafs = settings_get_value(settings, "show_bsp_leafs");  	if (!show_bsp_leafs) {  		int	r; @@ -117,6 +124,40 @@ static int sparkler_setup(const settings_t *settings, setting_desc_t **next_sett  		return 1;  	} +	if (!strcasecmp(show_bsp_leafs, "on")) { +		const char	*show_bsp_leafs_min_depth; + +		sparkler_conf.show_bsp_leafs = 1; + +		show_bsp_leafs_min_depth = settings_get_value(settings, "show_bsp_leafs_min_depth"); +		if (!show_bsp_leafs_min_depth) { +			const char	*depth_values[] = { +						"0", +						"4", +						"6", +						"8", +						"10", +						NULL +					}; +			int	r; + +			r = setting_desc_clone(&(setting_desc_t){ +							.name = "Show BSP Leaf Node Bounding Boxes Minimum Depth", +							.key = "show_bsp_leafs_min_depth", +							.preferred = "8", +							.values = depth_values, +						}, next_setting); +			if (r < 0) +				return r; + +			return 1; +		} + +		sscanf(show_bsp_leafs_min_depth, "%u", &sparkler_conf.show_bsp_leafs_min_depth); +	} else { +		sparkler_conf.show_bsp_leafs = 0; +	} +  	show_bsp_matches = settings_get_value(settings, "show_bsp_matches");  	if (!show_bsp_matches) {  		int	r; @@ -133,17 +174,36 @@ static int sparkler_setup(const settings_t *settings, setting_desc_t **next_sett  		return 1;  	} -	/* TODO: return -EINVAL on parse errors? */ -	if (!strcasecmp(show_bsp_leafs, "on")) -		sparkler_conf.show_bsp_leafs = 1; -	else -		sparkler_conf.show_bsp_leafs = 0; -  	if (!strcasecmp(show_bsp_matches, "on"))  		sparkler_conf.show_bsp_matches = 1;  	else  		sparkler_conf.show_bsp_matches = 0; +	if (!strcasecmp(show_bsp_matches, "on")) { +		const char	*show_bsp_matches_affected_only; + +		show_bsp_matches_affected_only = settings_get_value(settings, "show_bsp_matches_affected_only"); +		if (!show_bsp_matches_affected_only) { +			int	r; + +			r = setting_desc_clone(&(setting_desc_t){ +							.name = "Show Only Affected BSP Search Matches", +							.key = "show_bsp_matches_affected_only", +							.preferred = "off", +							.values = values, +						}, next_setting); +			if (r < 0) +				return r; + +			return 1; +		} + +		if (!strcasecmp(show_bsp_matches_affected_only, "on")) +			sparkler_conf.show_bsp_matches_affected_only = 1; +		else +			sparkler_conf.show_bsp_matches_affected_only = 0; +	} +  	return 0;  } diff --git a/src/modules/sparkler/xplode.c b/src/modules/sparkler/xplode.c index 8b191cd..4d6ee36 100644 --- a/src/modules/sparkler/xplode.c +++ b/src/modules/sparkler/xplode.c @@ -21,7 +21,7 @@ typedef struct _xplode_ctxt_t {  } xplode_ctxt_t; -static int xplode_init(particles_t *particles, particle_t *p) +static int xplode_init(particles_t *particles, const particles_conf_t *conf, particle_t *p)  {  	xplode_ctxt_t	*ctxt = p->ctxt; @@ -36,7 +36,7 @@ static int xplode_init(particles_t *particles, particle_t *p)  } -static particle_status_t xplode_sim(particles_t *particles, particle_t *p) +static particle_status_t xplode_sim(particles_t *particles, const particles_conf_t *conf, particle_t *p, fb_fragment_t *f)  {  	xplode_ctxt_t	*ctxt = p->ctxt; @@ -57,7 +57,7 @@ static particle_status_t xplode_sim(particles_t *particles, particle_t *p)  } -static void xplode_draw(particles_t *particles, particle_t *p, int x, int y, fb_fragment_t *f) +static void xplode_draw(particles_t *particles, const particles_conf_t *conf, particle_t *p, int x, int y, fb_fragment_t *f)  {  	xplode_ctxt_t	*ctxt = p->ctxt;  	uint32_t	color;  | 
