From: Michael Georgoulopoulos Date: Sat, 15 Oct 2016 21:44:43 +0000 (+0300) Subject: Merge branch 'master' of mutantstargoat.com:/home/nuclear/git/dosdemo X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=commitdiff_plain;h=864abe83bf0aef3c7a1b7f9f4ef0d89fc1fe80ef;hp=c98f98b1b91a0d6ac626386484bdc3e3621c452b Merge branch 'master' of mutantstargoat.com:/home/nuclear/git/dosdemo --- diff --git a/src/bump.c b/src/bump.c index 104b127..07ac26c 100644 --- a/src/bump.c +++ b/src/bump.c @@ -7,7 +7,6 @@ #include "demo.h" #include "screen.h" -#include "tinyfps.h" static int init(void); static void destroy(void); @@ -31,6 +30,11 @@ struct point { #define BIG_LIGHT_WIDTH 256 #define BIG_LIGHT_HEIGHT BIG_LIGHT_WIDTH +#define NUM_PARTICLES 64 +#define PARTICLE_LIGHT_WIDTH 32 +#define PARTICLE_LIGHT_HEIGHT 32 + + static unsigned long startingTime; static unsigned char *heightmap; @@ -40,6 +44,9 @@ static int *bumpOffset; static unsigned short *bigLight[NUM_BIG_LIGHTS]; static struct point bigLightPoint[NUM_BIG_LIGHTS]; +static unsigned short *particleLight; +static struct point particlePoint[NUM_PARTICLES]; + struct screen *bump_screen(void) { return &scr; @@ -51,8 +58,10 @@ static int init(void) const int numBlurs = 3; const int lightRadius = BIG_LIGHT_WIDTH / 2; + const int particleRadius = PARTICLE_LIGHT_WIDTH / 2; const int bigLightSize = BIG_LIGHT_WIDTH * BIG_LIGHT_HEIGHT; + const int particleLightSize = PARTICLE_LIGHT_WIDTH * PARTICLE_LIGHT_HEIGHT; const int fb_size = fb_width * fb_height; // Just some parameters to temporary test the colors of 3 lights @@ -60,7 +69,6 @@ static int init(void) const float rgbMul[9] = { 1.0f, 0.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 0.0f, 1.0f}; - initFpsFonts(); heightmap = malloc(sizeof(*heightmap) * fb_size); lightmap = malloc(sizeof(*lightmap) * fb_size); @@ -69,8 +77,11 @@ static int init(void) for (i = 0; i < NUM_BIG_LIGHTS; i++) bigLight[i] = malloc(sizeof(*bigLight[i]) * bigLightSize); + particleLight = malloc(sizeof(*particleLight) * particleLightSize); + memset(lightmap, 0, sizeof(*lightmap) * fb_size); memset(bumpOffset, 0, sizeof(*bumpOffset) * fb_size); + memset(particlePoint, 0, sizeof(*particlePoint) * NUM_PARTICLES); // Create random junk for (i = 0; i < fb_size; i++) @@ -87,7 +98,7 @@ static int init(void) { for (x = 0; x < fb_width; x++) { - const float offsetPower = 2.0f; + const float offsetPower = 0.5f; int dx, dy, xp, yp; dx = i < fb_size - 1 ? (int)((heightmap[i] - heightmap[i + 1]) * offsetPower) : 0; @@ -130,6 +141,22 @@ static int init(void) } } + i = 0; + for (y = 0; y < PARTICLE_LIGHT_HEIGHT; y++) + { + int yc = y - (PARTICLE_LIGHT_HEIGHT / 2); + for (x = 0; x < PARTICLE_LIGHT_WIDTH; x++) + { + int xc = x - (PARTICLE_LIGHT_WIDTH / 2); + + float invDist = ((float)particleRadius - (float)sqrt(xc * xc + yc * yc)) / (float)particleRadius; + if (invDist < 0.0f) invDist = 0.0f; + + c = (int)(invDist * 63); + particleLight[i++] = ((c >> 1) << 11) | (c << 5) | (c >> 1); + } + } + return 0; } @@ -230,6 +257,13 @@ static void renderLights() renderLight(&bigLightPoint[i], BIG_LIGHT_WIDTH, BIG_LIGHT_HEIGHT, bigLight[i]); } +static void renderParticles() +{ + int i; + for (i = 0; i < NUM_PARTICLES; i++) + renderLight(&particlePoint[i], PARTICLE_LIGHT_WIDTH, PARTICLE_LIGHT_HEIGHT, particleLight); +} + static void animateLights() { struct point center; @@ -258,14 +292,34 @@ static void renderBump(unsigned short *vram) } } +static void animateParticles() +{ + int i; + struct point center; + float dt = (float)(time_msec - startingTime) / 1000.0f; + + center.x = (fb_width >> 1) - (PARTICLE_LIGHT_WIDTH / 2); + center.y = (fb_height >> 1) - (PARTICLE_LIGHT_HEIGHT / 2); + + for (i = 0; i < NUM_PARTICLES; i++) + { + particlePoint[i].x = center.x + sin(1.2f * (i*i*i + dt)) * 74.0f + sin(0.6f * (i + dt)) * 144.0f; + particlePoint[i].y = center.y + sin(1.8f * (i + dt)) * 68.0f + sin(0.5f * (i*i + dt)) * 132.0f; + } +} + static void draw(void) { - eraseLights(); + memset(lightmap, 0, fb_width * fb_height * sizeof(*lightmap)); + + //eraseLights(); animateLights(); renderLights(); - renderBump((unsigned short*)vmem_back); - drawFps((unsigned short*)vmem_back); + animateParticles(); + renderParticles(); + + renderBump((unsigned short*)vmem_back); swap_buffers(0); } diff --git a/src/demo.c b/src/demo.c index 472da32..518bb53 100644 --- a/src/demo.c +++ b/src/demo.c @@ -9,6 +9,7 @@ #include "3dgfx.h" #include "music.h" #include "cfgopt.h" +#include "tinyfps.h" int fb_width = 320; int fb_height = 240; @@ -35,6 +36,8 @@ int demo_init(int argc, char **argv) return -1; } + initFpsFonts(); + if(g3d_init() == -1) { return -1; } diff --git a/src/dos/main.c b/src/dos/main.c index 53b8888..051cdb5 100644 --- a/src/dos/main.c +++ b/src/dos/main.c @@ -76,6 +76,9 @@ void swap_buffers(void *pixels) /* TODO implement page flipping */ if(pixels) { /*wait_vsync();*/ + drawFps(pixels); memcpy(vmem_front, pixels, fbsize); + } else { + drawFps(vmem_back); } } diff --git a/src/fract.c b/src/fract.c index 15da79d..a17550b 100644 --- a/src/fract.c +++ b/src/fract.c @@ -12,7 +12,6 @@ static int init(void); static void destroy(void); static void draw(void); static int julia(long x, long y, long cx, long cy, int max_iter); -static int calc_walk(struct vec2x *path, long x, long y, int max_steps); static struct screen scr = { "fract", @@ -49,9 +48,8 @@ static void destroy(void) static void draw(void) { - int i, j, len, x, y; - unsigned short *pixels = fb_pixels; - struct vec2x walkpos[WALK_SIZE]; + int i, j; + unsigned short *pixels = vmem_back; cx = mouse_x; cy = mouse_y; @@ -63,29 +61,9 @@ static void draw(void) } } - pixels = fb_pixels; - - if((len = calc_walk(walkpos, mouse_x, mouse_y, WALK_SIZE))) { - x = walkpos[0].x >> 16; - y = walkpos[0].y >> 16; - - for(i=1; i> 16; - int y1 = walkpos[i].y >> 16; - - if(clip_line(&x0, &y0, &x1, &y1, 0, 0, fb_width - 1, fb_height - 1)) { - draw_line(x0, y0, x1, y1, PACK_RGB16(32, 128, 255)); - } - x = x1; - y = y1; - } - } - + pixels = vmem_back; pixels[mouse_y * fb_width + mouse_x] = 0xffe; - - swap_buffers(fb_pixels); + swap_buffers(vmem_back); } static long normalize_coord(long x, long range) @@ -94,12 +72,6 @@ static long normalize_coord(long x, long range) return (x << 17) / range - 65536; } -static long device_coord(long x, long range) -{ - /* (x + 1) / 2 * (range - 1) */ - return ((x + 65536) >> 1) * (range - 1); -} - static int julia(long x, long y, long cx, long cy, int max_iter) { int i; @@ -124,30 +96,3 @@ static int julia(long x, long y, long cx, long cy, int max_iter) return i < max_iter ? (256 * i / max_iter) : 0; } - -static int calc_walk(struct vec2x *path, long x, long y, int max_steps) -{ - int i; - long cx, cy; - - /* convert to fixed point roughly [-1, 1] */ - x = cx = (normalize_coord(x, fb_width) >> 8) * xscale_24x8; - y = cy = (normalize_coord(y, fb_height) >> 8) * yscale_24x8; - - for(i=0; i> 8; - long py = y >> 8; - - path[i].x = device_coord((x << 8) / xscale_24x8, fb_width); - path[i].y = device_coord((y << 8) / yscale_24x8, fb_height); - - if(px * px + py * py > (4 << 16)) { - break; - } - x = px * px - py * py + cx; - y = (px * py << 1) + cy; - } - - return i; -} diff --git a/src/grise.c b/src/grise.c index 1a1cebf..7179511 100644 --- a/src/grise.c +++ b/src/grise.c @@ -16,7 +16,7 @@ typedef struct { static RLEBitmap *rleCreate(unsigned int w, unsigned int h); static void rleDestroy(RLEBitmap *b); -static void rleBlit(unsigned short *dst, int dstW, int dstH, int dstStride, +static void rleBlit(unsigned short *dst, int dstW, int dstH, int dstStride, RLEBitmap *bitmap, int blitX, int blitY); static void rleBlitScale(unsigned short *dst, int dstW, int dstH, int dstStride, RLEBitmap *bitmap, int blitX, int blitY, float scaleX, float scaleY); @@ -26,8 +26,6 @@ static RLEBitmap *rleEncode(RLEBitmap *b, unsigned char *pixels, unsigned int w, static void updatePropeller(float t); -extern void drawFps(unsigned short *vram); - #define BG_FILENAME "data/grise.png" #define GROBJ_01_FILENAME "data/grobj_01.png" @@ -64,8 +62,8 @@ static void updateScrollTables(float dt); static unsigned short *background = 0; -static unsigned int backgroundW = 0; -static unsigned int backgroundH = 0; +static int backgroundW = 0; +static int backgroundH = 0; static unsigned int lastFrameTime = 0; static float lastFrameDuration = 0.0f; @@ -80,7 +78,7 @@ static int scrollTableRounded[REFLECTION_HEIGHT]; static int scrollModTable[REFLECTION_HEIGHT]; static float nearScrollAmount = 0.0f; -static char miniFXBuffer[1024]; +static unsigned char miniFXBuffer[1024]; static RLEBitmap *grobj = 0; static RLEBitmap *rlePropeller = 0; @@ -90,7 +88,7 @@ static struct screen scr = { init, destroy, start, - stop, + 0, draw }; @@ -130,11 +128,7 @@ static int init(void) processNormal(); -#ifdef MIKE_PC - return 0xCAFE; -#else return 0; -#endif } static void destroy(void) @@ -152,15 +146,9 @@ static void start(long trans_time) lastFrameTime = time_msec; } -static void stop(long trans_time) -{ -} - - - static void draw(void) -{ +{ int scroll = MIN_SCROLL + (MAX_SCROLL - MIN_SCROLL) * mouse_x / fb_width; unsigned short *dst = backBuffer + PIXEL_PADDING; unsigned short *src = background + scroll; @@ -184,11 +172,11 @@ static void draw(void) src += backgroundW; dst += BB_SIZE; } - + /* Create scroll offsets for all scanlines of the normalmap */ updateScrollTables(lastFrameDuration); - /* Render the baked reflection one scanline below its place, so that + /* Render the baked reflection one scanline below its place, so that * the displacement that follows will be done in a cache-friendly way */ src -= PIXEL_PADDING; /* We want to also fill the PADDING pixels here */ @@ -229,18 +217,16 @@ static void draw(void) /* Then after displacement, blit the objects */ for (i = 0; i < 5; i++) rleBlit(backBuffer + PIXEL_PADDING, fb_width, fb_height, BB_SIZE, rlePropeller, 134 + (i-3) * 60, 100); - + /* Blit effect to framebuffer */ src = backBuffer + PIXEL_PADDING; dst = vmem_back; for (scanline = 0; scanline < fb_height; scanline++) { memcpy(dst, src, fb_width * 2); - src += BB_SIZE; + src += BB_SIZE; dst += fb_width; } - drawFps(vmem_back); - swap_buffers(0); } @@ -323,7 +309,7 @@ static void initScrollTables() { static void updateScrollTables(float dt) { int i = 0; - + nearScrollAmount += dt * NEAR_SCROLL_SPEED; nearScrollAmount = (float) fmod(nearScrollAmount, 512.0f); @@ -334,7 +320,7 @@ static void updateScrollTables(float dt) { } /* ------------------------------------------------------------------------------------------------- - * RLE STUFF + * RLE STUFF * ------------------------------------------------------------------------------------------------- */ /* Limit streak count per scanline so we can directly jump to specific scanline */ @@ -424,7 +410,7 @@ static RLEBitmap *rleEncode(RLEBitmap *b, unsigned char *pixels, unsigned int w, static void rleDistributeStreaks(RLEBitmap *bitmap) { int scanline, halfW = bitmap->w >> 1; unsigned char *ptr, tmp; - + ptr = bitmap->scans; for (scanline = 0; scanline < bitmap->h; scanline++) { if (ptr[0] >= halfW) { @@ -441,7 +427,7 @@ static void rleDistributeStreaks(RLEBitmap *bitmap) { } static void rleBlit(unsigned short *dst, int dstW, int dstH, int dstStride, - RLEBitmap *bitmap, int blitX, int blitY) + RLEBitmap *bitmap, int blitX, int blitY) { int scanline = 0; int streakPos = 0; @@ -486,7 +472,7 @@ static void interpolateScan(unsigned char *output, unsigned char *a, unsigned ch t += 1.0f; ti = (*((unsigned int*)&t)) & 0x7FFFFF; - + for (i = 0; i < RLE_BYTES_PER_SCANLINE; i++) { if (*a == 0) { *output++ = *b++; @@ -516,7 +502,7 @@ static void rleBlitScale(unsigned short *dst, int dstW, int dstH, int dstStride, int scaleXFixed; static unsigned char scan[512]; - int blitW = (int)(bitmap->w * scaleX + 0.5f); + /*int blitW = (int)(bitmap->w * scaleX + 0.5f);*/ int blitH = (int)(bitmap->h * scaleY + 0.5f); /* From this point on, scaleY will be inverted */ @@ -577,7 +563,7 @@ static void rleBlitScaleInv(unsigned short *dst, int dstW, int dstH, int dstStri int scaleXFixed; static unsigned char scan[512]; - int blitW = (int)(bitmap->w * scaleX + 0.5f); + /*int blitW = (int)(bitmap->w * scaleX + 0.5f);*/ int blitH = (int)(bitmap->h * scaleY + 0.5f); /* From this point on, scaleY will be inverted */ @@ -638,7 +624,7 @@ static struct { static void updatePropeller(float t) { int i, j; int cx, cy, count = 0; - char *dst; + unsigned char *dst; float x = 0.0f; float y = 18.0f; float nx, ny; diff --git a/src/plasma.c b/src/plasma.c index 132cff3..c20ff63 100644 --- a/src/plasma.c +++ b/src/plasma.c @@ -5,7 +5,6 @@ #include "demo.h" #include "screen.h" -#include "tinyfps.h" static int init(void); static void destroy(void); @@ -41,8 +40,6 @@ static int init(void) { int i; - initFpsFonts(); - psin1 = (unsigned char*)malloc(sizeof(unsigned char) * PSIN_SIZE); psin2 = (unsigned char*)malloc(sizeof(unsigned char) * PSIN_SIZE); psin3 = (unsigned char*)malloc(sizeof(unsigned char) * PSIN_SIZE); @@ -67,7 +64,6 @@ static int init(void) plasmaPal[i] = (r<<11) | (g<<5) | b; } - //return 0xCAFE; return 0; } @@ -111,7 +107,5 @@ static void draw(void) } } - drawFps((unsigned short*)vmem_back); - swap_buffers(0); } diff --git a/src/polyclip.c b/src/polyclip.c new file mode 100644 index 0000000..9ef8e95 --- /dev/null +++ b/src/polyclip.c @@ -0,0 +1,154 @@ +#include +#include +#include "polyclip.h" + +struct ray { + float origin[3]; + float dir[3]; +}; + +static int clip_edge(struct g3d_vertex *poly, int *vnumptr, + const struct g3d_vertex *v0, const struct g3d_vertex *v1, + const struct cplane *plane); +static float distance_signed(float *pos, const struct cplane *plane); +static int intersect(const struct ray *ray, const struct cplane *plane, float *t); + + +int clip_poly(struct g3d_vertex *vout, int *voutnum, + const struct g3d_vertex *vin, int vnum, struct cplane *plane) +{ + int i; + int edges_clipped = 0; + int out_vnum = 0; + + for(i=0; i 0 ? 0 : 1; +} + +#define LERP_VATTR(res, v0, v1, t) \ + do { \ + (res)->nx = (v0)->nx + ((v1)->nx - (v0)->nx) * (t); \ + (res)->ny = (v0)->ny + ((v1)->ny - (v0)->ny) * (t); \ + (res)->nz = (v0)->nz + ((v1)->nz - (v0)->nz) * (t); \ + (res)->u = (v0)->u + ((v1)->u - (v0)->u) * (t); \ + (res)->v = (v0)->v + ((v1)->v - (v0)->v) * (t); \ + (res)->r = (v0)->r + ((v1)->r - (v0)->r) * (t); \ + (res)->g = (v0)->g + ((v1)->g - (v0)->g) * (t); \ + (res)->b = (v0)->b + ((v1)->b - (v0)->b) * (t); \ + } while(0) + + +/* returns: + * 1 -> both inside + * 0 -> straddling and clipped + * -1 -> both outside + * + * also returns the size of the polygon through vnumptr + */ +static int clip_edge(struct g3d_vertex *poly, int *vnumptr, + const struct g3d_vertex *v0, const struct g3d_vertex *v1, + const struct cplane *plane) +{ + float pos0[3], pos1[3]; + float d0, d1, t; + struct ray ray; + int i, vnum = *vnumptr; + + pos0[0] = v0->x; pos0[1] = v0->y; pos0[2] = v0->z; + pos1[0] = v1->x; pos1[1] = v1->y; pos1[2] = v1->z; + + d0 = distance_signed(pos0, plane); + d1 = distance_signed(pos1, plane); + + for(i=0; i<3; i++) { + ray.origin[i] = pos0[i]; + ray.dir[i] = pos1[i] - pos0[i]; + } + + if(d0 >= 0.0) { + /* start inside */ + if(d1 >= 0.0) { + /* all inside */ + poly[vnum++] = *v1; /* append v1 */ + *vnumptr = vnum; + return 1; + } else { + /* going out */ + struct g3d_vertex *vptr = poly + vnum; + + intersect(&ray, plane, &t); + + vptr->x = ray.origin[0] + ray.dir[0] * t; + vptr->y = ray.origin[1] + ray.dir[1] * t; + vptr->z = ray.origin[2] + ray.dir[2] * t; + vptr->w = 1.0f; + + LERP_VATTR(vptr, v0, v1, t); + vnum++; /* append new vertex on the intersection point */ + } + } else { + /* start outside */ + if(d1 >= 0) { + /* going in */ + struct g3d_vertex *vptr = poly + vnum; + + intersect(&ray, plane, &t); + + vptr->x = ray.origin[0] + ray.dir[0] + t; + vptr->y = ray.origin[1] + ray.dir[1] + t; + vptr->z = ray.origin[2] + ray.dir[2] + t; + vptr->w = 1.0f; + + LERP_VATTR(vptr, v0, v1, t); + vnum++; /* append new vertex on the intersection point */ + + /* then append v1 ... */ + poly[vnum++] = *v1; + } else { + /* all outside */ + return -1; + } + } + + *vnumptr = vnum; + return 0; +} + + +static float distance_signed(float *pos, const struct cplane *plane) +{ + float dx = pos[0] - plane->x; + float dy = pos[1] - plane->y; + float dz = pos[2] - plane->z; + return dx * plane->nx + dy * plane->ny + dz * plane->nz; +} + +static int intersect(const struct ray *ray, const struct cplane *plane, float *t) +{ + float orig_pt_dir[3]; + + float ndotdir = plane->nx * ray->dir[0] + plane->ny * ray->dir[1] + plane->nz * ray->dir[2]; + if(fabs(ndotdir) < 1e-4) { + *t = 0.0f; + return 0; + } + + orig_pt_dir[0] = plane->x - ray->origin[0]; + orig_pt_dir[1] = plane->y - ray->origin[1]; + orig_pt_dir[2] = plane->z - ray->origin[2]; + + *t = (plane->nx * orig_pt_dir[0] + plane->ny * orig_pt_dir[1] + plane->nz * orig_pt_dir[2]) / ndotdir; + return 1; +} diff --git a/src/polyclip.h b/src/polyclip.h new file mode 100644 index 0000000..c6745e3 --- /dev/null +++ b/src/polyclip.h @@ -0,0 +1,22 @@ +#ifndef POLYCLIP_H_ +#define POLYCLIP_H_ + +#include "3dgfx.h" + +struct cplane { + float x, y, z; + float nx, ny, nz; +}; + +/* Polygon clipper + * returns: + * 1 -> fully inside, not clipped + * 0 -> straddling the plane and clipped + * -1 -> fully outside, not clipped + * in all cases, vertices are copied to vout, and the vertex count is written + * to wherever voutnum is pointing + */ +int clip_poly(struct g3d_vertex *vout, int *voutnum, + const struct g3d_vertex *vin, int vnum, struct cplane *plane); + +#endif /* POLYCLIP_H_ */ diff --git a/src/sdl/main.c b/src/sdl/main.c index 48852f5..05744e8 100644 --- a/src/sdl/main.c +++ b/src/sdl/main.c @@ -3,6 +3,7 @@ #include #include #include "demo.h" +#include "tinyfps.h" static void handle_event(SDL_Event *ev); static void toggle_fullscreen(void); @@ -61,6 +62,7 @@ int main(int argc, char **argv) time_msec = SDL_GetTicks() - start_time; demo_draw(); + drawFps(fb_pixels); if(SDL_MUSTLOCK(fbsurf)) { SDL_LockSurface(fbsurf);