X-Git-Url: http://git.mutantstargoat.com/user/nuclear/?p=dosdemo;a=blobdiff_plain;f=src%2Fgrise.c;h=ed15de011b93930a58087c9a515d173f150f32bf;hp=e6cd7ea257e58186822c7a3032f61cf27e476940;hb=9dda65bd2ac317cf110c080e561f40b2ee221c93;hpb=976c2aca502358c5f407a109c31d67abd519ac1d diff --git a/src/grise.c b/src/grise.c index e6cd7ea..ed15de0 100644 --- a/src/grise.c +++ b/src/grise.c @@ -33,7 +33,7 @@ static RLEBitmap rleEncode(unsigned char *pixels, unsigned int w, unsigned int h #define PIXEL_PADDING 32 /* Make sure this is less than PIXEL_PADDING*/ -#define MAX_DISPLACEMENT 16 +#define MAX_DISPLACEMENT 16 #define MIN_SCROLL PIXEL_PADDING #define MAX_SCROLL (backgroundW - fb_width - MIN_SCROLL) @@ -150,6 +150,73 @@ static void stop(long trans_time) { } + +struct { + int circleX[3]; + int circleY[3]; +} wheelState; + +static void updateWheel(float t) { + float x = 0.0f; + float y = 18.0f; + float nx, ny; + float cost, sint; + static float sin120 = 0.86602540378f; + static float cos120 = -0.5f; + + /* Rotate */ + sint = sin(t); + cost = cos(t); + nx = x * cost - y * sint; + ny = y * cost + x * sint; + x = nx; + y = ny; + wheelState.circleX[0] = (int)(x + 0.5f) + 16; + wheelState.circleY[0] = (int)(y + 0.5f) + 16; + + /* Rotate by 120 degrees, for the second circle */ + nx = x * cos120 - y * sin120; + ny = y * cos120 + x * sin120; + x = nx; + y = ny; + wheelState.circleX[1] = (int)(x + 0.5f) + 16; + wheelState.circleY[1] = (int)(y + 0.5f) + 16; + + /* 3rd circle */ + nx = x * cos120 - y * sin120; + ny = y * cos120 + x * sin120; + x = nx; + y = ny; + wheelState.circleX[2] = (int)(x + 0.5f) + 16; + wheelState.circleY[2] = (int)(y + 0.5f) + 16; +} + +#define WHEEL_CIRCLE_RADIUS 18 +#define WHEEL_CIRCLE_RADIUS_SQ (WHEEL_CIRCLE_RADIUS * WHEEL_CIRCLE_RADIUS) + +static unsigned short wheel(int x, int y) { + int cx, cy, count=0; + + /* First circle */ + cx = wheelState.circleX[0] - x; + cy = wheelState.circleY[0] - y; + if (cx*cx + cy*cy < WHEEL_CIRCLE_RADIUS_SQ) count++; + + /* 2nd circle */ + cx = wheelState.circleX[1] - x; + cy = wheelState.circleY[1] - y; + if (cx*cx + cy*cy < WHEEL_CIRCLE_RADIUS_SQ) count++; + + /* 3rd circle */ + cx = wheelState.circleX[2] - x; + cy = wheelState.circleY[2] - y; + if (cx*cx + cy*cy < WHEEL_CIRCLE_RADIUS_SQ) count++; + + if (count >= 2) return 0xFFFF; + + return 0x000F; +} + static void draw(void) { int scroll = MIN_SCROLL + (MAX_SCROLL - MIN_SCROLL) * mouse_x / fb_width; @@ -163,6 +230,9 @@ static void draw(void) lastFrameDuration = (time_msec - lastFrameTime) / 1000.0f; lastFrameTime = time_msec; + /* Update mini-effects here */ + updateWheel(time_msec / 1000.0f); + /* First, render the horizon */ for (scanline = 0; scanline < HORIZON_HEIGHT; scanline++) { memcpy(dst, src, fb_width * 2); @@ -204,6 +274,12 @@ 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] = wheel(i, scanline); + } + } + /* Blit effect to framebuffer */ src = backBuffer + PIXEL_PADDING; dst = vmem_back; @@ -316,6 +392,8 @@ static void updateScrollTables(float dt) { #define RLE_FILL_COLOR 0 #define RLE_FILL_COLOR_32 ((RLE_FILL_COLOR << 16) | RLE_FILL_COLOR) +#define RLE_FIXED_BITS 16 + static RLEBitmap rleCreate(unsigned int w, unsigned int h) { RLEBitmap ret; ret.w = w; @@ -433,7 +511,17 @@ static void interpolateScan(unsigned char *output, unsigned char *a, unsigned ch ti = (*((unsigned int*)&t)) & 0x7FFFFF; for (i = 0; i < RLE_BYTES_PER_SCANLINE; i++) { - *output++ = ((*b++ * ti) + (*a++ * (div - ti))) >> 23; + if (*a == 0) { + *output++ = *b++; + a++; + } else { + if (*b == 0) { + *output++ = *a++; + b++; + } else { + *output++ = ((*b++ * ti) + (*a++ * (div - ti))) >> 23; + } + } } } @@ -452,11 +540,16 @@ static void rleBlitScale(unsigned short *dst, int dstW, int dstH, int dstStride, 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); dst += blitX + blitY * dstStride; for (scanline = blitY; scanline < blitY + blitH; scanline++) { - float normalScan = scanlineCounter / scaleY; + float normalScan = scanlineCounter * scaleY; /* ScaleY is inverted */ unsigned char *scan0 = bitmap.scans + RLE_BYTES_PER_SCANLINE * (int)normalScan; unsigned char *scan1 = scan0 + RLE_BYTES_PER_SCANLINE; normalScan -= (int)normalScan; @@ -466,8 +559,8 @@ static void rleBlitScale(unsigned short *dst, int dstW, int dstH, int dstStride, if (scanline < 0 || scanline >= dstH) continue; for (streak = 0; streak < RLE_STREAKS_PER_SCANLINE; streak++) { - streakPos = (int) ((*input++) * scaleX + 0.5f); - streakLength = (int)((*input++) * scaleX + 0.5f); + streakPos = (*input++ * scaleXFixed) >> RLE_FIXED_BITS; + streakLength = (*input++ * scaleXFixed) >> RLE_FIXED_BITS; if ((streakPos + blitX) <= 0) continue; @@ -490,6 +583,8 @@ static void rleBlitScale(unsigned short *dst, int dstW, int dstH, int dstStride, } } + + static void rleBlitScaleInv(unsigned short *dst, int dstW, int dstH, int dstStride, RLEBitmap bitmap, int blitX, int blitY, float scaleX, float scaleY) { @@ -506,10 +601,15 @@ static void rleBlitScaleInv(unsigned short *dst, int dstW, int dstH, int dstStri 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); + dst += blitX + blitY * dstStride; for (scanline = blitY; scanline > blitY - blitH; scanline--) { - float normalScan = scanlineCounter / scaleY; + float normalScan = scanlineCounter * scaleY; /* ScaleY is inverted */ unsigned char *scan0 = bitmap.scans + RLE_BYTES_PER_SCANLINE * (int)normalScan; unsigned char *scan1 = scan0 + RLE_BYTES_PER_SCANLINE; normalScan -= (int)normalScan; @@ -519,8 +619,8 @@ static void rleBlitScaleInv(unsigned short *dst, int dstW, int dstH, int dstStri if (scanline < 0 || scanline >= dstH) continue; for (streak = 0; streak < RLE_STREAKS_PER_SCANLINE; streak++) { - streakPos = (int)((*input++) * scaleX + 0.5f); - streakLength = (int)((*input++) * scaleX + 0.5f); + streakPos = (*input++ * scaleXFixed) >> RLE_FIXED_BITS; + streakLength = (*input++ * scaleXFixed) >> RLE_FIXED_BITS; if ((streakPos + blitX) <= 0) continue;