X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fgreets.c;h=8b128c65eece58618492f8a689dc5c42434f6110;hp=353d29cf9e324a38a12a424c181171c1fd1884da;hb=3b52c25b520e0e1b9143cafaee2670e57c89ef0d;hpb=31878d7f28961f71c3ef708bbbf4095edda0d229 diff --git a/src/greets.c b/src/greets.c index 353d29c..8b128c6 100644 --- a/src/greets.c +++ b/src/greets.c @@ -11,6 +11,7 @@ #include "util.h" #include "gfxutil.h" #include "timer.h" +#include "smoketxt.h" #ifdef MSDOS #include "dos/gfx.h" /* for wait_vsync assembly macro */ @@ -18,66 +19,14 @@ void wait_vsync(void); #endif -/* if defined, use bilinear interpolation for dispersion field vectors */ -#define BILERP_FIELD -/* if defined randomize field vectors by RAND_FIELD_MAX */ -#define RANDOMIZE_FIELD - -#define RAND_FIELD_MAX 0.7 - #define BLUR_RAD 5 -#define PCOUNT 4000 -#define MAX_LIFE 7.0f -#define PALPHA 1.0f -#define ZBIAS 0.25 -#define DRAG 0.95 -#define FORCE 0.07 -#define FREQ 0.085 -static float wind[] = {-0.0, 0.0, 0.01}; - - -struct vec2 { - float x, y; -}; - -struct vec3 { - float x, y, z; -}; - -struct particle { - float x, y, z; - float vx, vy, vz; /* velocity */ - int r, g, b; - float life; -}; - -struct emitter { - struct particle *plist; - int pcount; -}; - -struct vfield { - struct vec2 pos, size; - - int width, height; - int xshift; - struct vec2 *v; -}; - static int init(void); static void destroy(void); static void start(long trans_time); static void draw(void); -int init_emitter(struct emitter *em, int num, unsigned char *map, int xsz, int ysz); -void update_particles(struct emitter *em, float dt); -void draw_particles(struct emitter *em); - -int init_vfield_load(struct vfield *vf, const char *fname); -void vfield_eval(struct vfield *vf, float x, float y, struct vec2 *dir); - static struct screen scr = { "greets", @@ -87,11 +36,10 @@ static struct screen scr = { draw }; -static struct emitter em; -static struct vfield vfield; -static struct g3d_vertex *varr; static long start_time; +static struct smktxt *stx; + static uint16_t *cur_smokebuf, *prev_smokebuf; static int smokebuf_size; #define smokebuf_start (cur_smokebuf < prev_smokebuf ? cur_smokebuf : prev_smokebuf) @@ -113,23 +61,7 @@ struct screen *greets_screen(void) static int init(void) { - int xsz, ysz; - unsigned char *pixels; - - if(!(pixels = img_load_pixels("data/greets1.png", &xsz, &ysz, IMG_FMT_GREY8))) { - fprintf(stderr, "failed to load particle spawn map\n"); - return -1; - } - - init_emitter(&em, PCOUNT, pixels, xsz, ysz); - img_free_pixels(pixels); - - if(!(varr = malloc(PCOUNT * sizeof *varr))) { - perror("failed to allocate particle vertex buffer\n"); - return -1; - } - - if(init_vfield_load(&vfield, "data/vfield1") == -1) { + if(!(stx = create_smktxt("data/greets1.png", "data/vfield1"))) { return -1; } @@ -145,9 +77,8 @@ static int init(void) static void destroy(void) { - free(varr); - free(vfield.v); free(smokebuf_start); + destroy_smktxt(stx); } static void start(long trans_time) @@ -196,7 +127,7 @@ static void update(void) prev_my = mouse_y; prev_bmask = mouse_bmask; - update_particles(&em, dt); + update_smktxt(stx, dt); } static void draw(void) @@ -220,7 +151,7 @@ static void draw(void) memcpy(cur_smokebuf, prev_smokebuf, smokebuf_size); g3d_framebuffer(fb_width, fb_height, cur_smokebuf); - draw_particles(&em); + draw_smktxt(stx); g3d_framebuffer(fb_width, fb_height, fb_pixels); dest = fb_pixels; @@ -251,161 +182,3 @@ static void draw(void) swap_buffers(fb_pixels); last_swap = get_msec(); } - - - -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; ix = (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 = p->g = 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; ipcount; 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->a = cround64(p->life * 255.0 / MAX_LIFE); - v->r = 0; - v->g = (v->a & 0xe0) >> 3; - v->b = (v->a & 0x1f) << 3; - ++v; - - ++p; - } -} - -void draw_particles(struct emitter *em) -{ - g3d_draw(G3D_POINTS, varr, PCOUNT); -} - - -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; - } - - if(!(vf->v = malloc(vf->width * vf->height * sizeof *vf->v))) { - fprintf(stderr, "failed to allocate %dx%d vector field\n", vf->width, vf->height); - fclose(fp); - return -1; - } - if(fread(vf->v, sizeof *vf->v, vf->width * vf->height, fp) < vf->width * vf->height) { - fprintf(stderr, "init_vfield_load: unexpected end of file while reading %dx%d vector field\n", - vf->width, vf->height); - fclose(fp); - return -1; - } - fclose(fp); - - vf->pos.x = vf->pos.y = 0; - vf->size.x = vf->size.y = 1; - return 0; -} - -void vfield_eval(struct vfield *vf, float x, float y, struct vec2 *dir) -{ - int px, py; - float tx, ty; - struct vec2 *p1, *p2; - struct vec2 left, right; - - x = ((x - vf->pos.x) / vf->size.x + 0.5f) * vf->width; - y = ((y - vf->pos.y) / vf->size.y + 0.5f) * vf->height; - x = floor(x); - y = floor(y); - - if(x < 0) x = 0; - if(y < 0) y = 0; - if(x > vf->width - 2) x = vf->width - 2; - if(y > vf->height - 2) y = vf->height - 2; - - px = (int)x; - py = (int)y; - - p1 = vf->v + (py << vf->xshift) + px; -#ifdef BILERP_FIELD - p2 = p1 + vf->width; - - tx = fmod(x, 1.0f); - ty = fmod(y, 1.0f); - - left.x = p1->x + (p2->x - p1->x) * ty; - left.y = p1->y + (p2->y - p1->y) * ty; - ++p1; - ++p2; - right.x = p1->x + (p2->x - p1->x) * ty; - right.y = p1->y + (p2->y - p1->y) * ty; - - dir->x = left.x + (right.x - left.x) * tx; - dir->y = left.y + (right.y - left.y) * ty; -#else - dir->x = p1->x; - dir->y = p1->y; -#endif - -#ifdef RANDOMIZE_FIELD - dir->x += ((float)rand() / RAND_MAX - 0.5) * RAND_FIELD_MAX; - dir->y += ((float)rand() / RAND_MAX - 0.5) * RAND_FIELD_MAX; -#endif -}