From: Michael Georgoulopoulos Date: Sun, 18 Sep 2016 22:58:58 +0000 (+0300) Subject: Function that distributes the streaks in an rle scanline so that non-overlapping... X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=commitdiff_plain;h=30970f9b5b2f3601dbd50d337a960c1b9bc7d842 Function that distributes the streaks in an rle scanline so that non-overlapping streaks from the previous scanline will not be interpolated (total hack) --- diff --git a/src/grise.c b/src/grise.c index f354181..9226cc6 100644 --- a/src/grise.c +++ b/src/grise.c @@ -81,6 +81,7 @@ static float nearScrollAmount = 0.0f; static char miniFXBuffer[1024]; static RLEBitmap *grobj = 0; +static RLEBitmap *rlePropeller = 0; static struct screen scr = { "galaxyrise", @@ -171,7 +172,7 @@ static void draw(void) lastFrameTime = time_msec; /* Update mini-effects here */ - updatePropeller(time_msec / 1000.0f); + updatePropeller(4.0f * time_msec / 1000.0f); /* First, render the horizon */ for (scanline = 0; scanline < HORIZON_HEIGHT; scanline++) { @@ -195,7 +196,7 @@ static void draw(void) } /* Blit reflections first, to be displaced */ - for (i = 0; i < 5; i++) rleBlitScaleInv(backBuffer + PIXEL_PADDING, fb_width, fb_height, BB_SIZE, grobj, 134 + (i-3) * 60, 235, 1.0f, 1.8f); + for (i = 0; i < 5; i++) rleBlitScaleInv(backBuffer + PIXEL_PADDING, fb_width, fb_height, BB_SIZE, rlePropeller, 134 + (i-3) * 60, 200, 1.0f, 1.8f); /* Perform displacement */ dst = backBuffer + HORIZON_HEIGHT * BB_SIZE + PIXEL_PADDING; @@ -212,14 +213,8 @@ 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, grobj, 134 + (i-3) * 60, 100); - - for (scanline = 0; scanline < 32; scanline++) { - for (i = 0; i < 32; i++) { - backBuffer[PIXEL_PADDING + scanline * BB_SIZE + i] = miniFXBuffer[i + 32 * scanline] ? 0xFFFF : 0x0000; - } - } - + 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; @@ -334,13 +329,17 @@ static void updateScrollTables(float dt) { #define RLE_FIXED_BITS 16 +static int rleByteCount(int w, int h) { + return h * RLE_BYTES_PER_SCANLINE + w; +} + static RLEBitmap *rleCreate(unsigned int w, unsigned int h) { RLEBitmap *ret = (RLEBitmap*)malloc(sizeof(RLEBitmap)); ret->w = w; ret->h = h; /* Add some padding at the end of the buffer, with the worst case for a scanline (w/2 streaks) */ - ret->scans = (unsigned char*) calloc(h * RLE_BYTES_PER_SCANLINE + w, 1); + ret->scans = (unsigned char*) calloc(rleByteCount(w, h), 1); return ret; } @@ -361,6 +360,7 @@ static RLEBitmap *rleEncode(RLEBitmap *b, unsigned char *pixels, unsigned int w, /* https://www.youtube.com/watch?v=RKMR02o1I88&feature=youtu.be&t=55 */ if (!b) b = rleCreate(w, h); + else memset(b->scans, 0, rleByteCount(b->w, b->h)); /* The following code assumes cleared array */ for (scanline = 0; scanline < h; scanline++) { output = b->scans + scanline * RLE_BYTES_PER_SCANLINE; @@ -404,6 +404,25 @@ static RLEBitmap *rleEncode(RLEBitmap *b, unsigned char *pixels, unsigned int w, return b; } +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) { + tmp = ptr[0]; + ptr[0] = ptr[6]; + ptr[6] = tmp; + tmp = ptr[1]; + ptr[1] = ptr[7]; + ptr[7] = tmp; + } + + ptr += 8; + } +} + static void rleBlit(unsigned short *dst, int dstW, int dstH, int dstStride, RLEBitmap *bitmap, int blitX, int blitY) { @@ -658,4 +677,10 @@ static void updatePropeller(float t) { *dst++ = count >= 2; } } + + /* Then, encode to rle */ + rlePropeller = rleEncode(rlePropeller, miniFXBuffer, 32, 32); + + /* Distribute the produced streaks so that they don't produce garbage when interpolated */ + rleDistributeStreaks(rlePropeller); }