X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fgrise.c;h=94e385062fbaa76db774c77c47cc1e064bfa0805;hp=f354181d510962cfa49e4f18b32d2a6d14e42837;hb=7deef4d5a20da09044bf7311c6ee274090cde5e6;hpb=7fc67193bb83e0bf6fc1583d6aa50e5ea987ab5a diff --git a/src/grise.c b/src/grise.c index f354181..94e3850 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); @@ -62,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; @@ -78,16 +78,17 @@ 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; static struct screen scr = { "galaxyrise", init, destroy, start, - stop, + 0, draw }; @@ -96,7 +97,6 @@ struct screen *grise_screen(void) return &scr; } - static int init(void) { unsigned char *tmpBitmap; @@ -128,11 +128,7 @@ static int init(void) processNormal(); -#ifdef MIKE_PC - return 0xCAFE; -#else return 0; -#endif } static void destroy(void) @@ -150,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; @@ -166,12 +156,15 @@ static void draw(void) int i = 0; short *dispScanline; int d; + int accum = 0; + int md, sc; + int scrolledIndex; lastFrameDuration = (time_msec - lastFrameTime) / 1000.0f; 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++) { @@ -179,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 */ @@ -195,15 +188,26 @@ 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; src = dst + BB_SIZE; /* The pixels to be displaced are 1 scanline below */ dispScanline = displacementMap; for (scanline = 0; scanline < REFLECTION_HEIGHT; scanline++) { + + md = scrollModTable[scanline]; + sc = scrollTableRounded[scanline]; + accum = 0; + for (i = 0; i < fb_width; i++) { - d = dispScanline[(i + scrollTableRounded[scanline]) % scrollModTable[scanline]]; + /* Try to immitate modulo without the division */ + if (i == md) accum += md; + scrolledIndex = i - accum + sc; + if (scrolledIndex >= md) scrolledIndex -= md; + + /* Displace */ + d = dispScanline[scrolledIndex]; *dst++ = src[i + d]; } src += backgroundW; @@ -212,20 +216,14 @@ 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; + dst = fb_pixels; for (scanline = 0; scanline < fb_height; scanline++) { memcpy(dst, src, fb_width * 2); - src += BB_SIZE; + src += BB_SIZE; dst += fb_width; } @@ -311,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); @@ -322,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 */ @@ -334,13 +332,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 +363,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,8 +407,27 @@ 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) + RLEBitmap *bitmap, int blitX, int blitY) { int scanline = 0; int streakPos = 0; @@ -450,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++; @@ -477,16 +499,17 @@ static void rleBlitScale(unsigned short *dst, int dstW, int dstH, int dstStride, unsigned int *output32; unsigned char *input; int scanlineCounter = 0; + 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 */ scaleY = 1.0f / scaleY; - int scaleXFixed = (int)(scaleX * (float)(1 << RLE_FIXED_BITS) + 0.5f); - + scaleXFixed = (int)(scaleX * (float)(1 << RLE_FIXED_BITS) + 0.5f); + dst += blitX + blitY * dstStride; for (scanline = blitY; scanline < blitY + blitH; scanline++) { @@ -537,15 +560,16 @@ static void rleBlitScaleInv(unsigned short *dst, int dstW, int dstH, int dstStri unsigned int *output32; unsigned char *input; int scanlineCounter = 0; + 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 */ scaleY = 1.0f / scaleY; - int scaleXFixed = (int)(scaleX * (float)(1 << RLE_FIXED_BITS) + 0.5f); + scaleXFixed = (int)(scaleX * (float)(1 << RLE_FIXED_BITS) + 0.5f); dst += blitX + blitY * dstStride; @@ -600,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; @@ -658,4 +682,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); }