diff --git a/bun.c b/bun.c index c64c74a..228f8b2 100644 --- a/bun.c +++ b/bun.c @@ -66,41 +66,63 @@ void teardownBun(void) { } } +#define BLITTER_ASCENDING (0) +#define BLITTER_DESCENDING (1) + +struct BunClear { + uint16_t memoryStartOffsetBytes; + uint16_t widthWords; + uint16_t heightRows; + uint8_t direction; +}; + +#define BUN_OFF_RIGHT_SIDE (0) +#define BUN_OFF_LEFT_SIDE (1) +#define BUN_ANYWHERE (2) + +uint8_t *coolbunPlaneStarts[3][2]; + void bun_offRightSide( int plusXValue, int y, struct ScreenSetup *screenSetup, - struct CurrentScreen *currentScreen + struct CurrentScreen *currentScreen, + struct BunClear *bunClear ) { uint8_t i, plane = 0; uint8_t shift = plusXValue & 15; uint8_t wordShift = (plusXValue >> 4); uint16_t bltalwm; + bunClear->memoryStartOffsetBytes = (y * screenSetup->byteWidth) + + screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES + + wordShift * 2; + bunClear->heightRows = COOL_BUN_HEIGHT; + bunClear->widthWords = 2 - wordShift; + bunClear->direction = BLITTER_ASCENDING; + + bltalwm = 0x0000; + for (i = 0; i <= 15 - shift; ++i) { + bltalwm += (1 << (15 - i)); + } + for (plane = 0; plane < 2; ++plane) { custom.bltcon0 = BLTCON0(0xc0, 0, 1, 0, 1, shift); - custom.bltcon1 = BLTCON1(0, shift); + custom.bltcon1 = BLTCON1(bunClear->direction, shift); custom.bltadat = 0xffff; - custom.bltbpt = coolbunArea + - plane * COOL_BUN_PLANE_SIZE; + custom.bltbpt = coolbunPlaneStarts[BUN_OFF_LEFT_SIDE][plane]; custom.bltdpt = currentScreen->planes[plane] + - (y * screenSetup->byteWidth) + - screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES + - wordShift * 2; + bunClear->memoryStartOffsetBytes; custom.bltafwm = 0xffff; - bltalwm = 0x0000; - for (i = 0; i <= 15 - shift; ++i) { - bltalwm += (1 << (15 - i)); - } custom.bltalwm = bltalwm; custom.bltbmod = wordShift * 2; custom.bltdmod = screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES + wordShift * 2; - custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); + custom.bltsize = bunClear->widthWords + (bunClear->heightRows << 6); WaitBlit(); } @@ -110,7 +132,8 @@ void bun_offLeftSide( int minusXValue, int y, struct ScreenSetup *screenSetup, - struct CurrentScreen *currentScreen + struct CurrentScreen *currentScreen, + struct BunClear *bunClear ) { unsigned char plane; uint8_t shift = minusXValue & 15; @@ -121,35 +144,37 @@ void bun_offLeftSide( // y can't be 0 otherwise we will corrupt memory for now if (y == 0) return; + bunClear->memoryStartOffsetBytes = (screenSetup->byteWidth * (y + COOL_BUN_LAST_ROW)) + + 2 - wordShift * 2; + bunClear->heightRows = COOL_BUN_HEIGHT; + bunClear->widthWords = 2 - wordShift; + bunClear->direction = BLITTER_DESCENDING; + + bltalwm = 0x0000; + for (i = 0; i <= 15 - shift; ++i) { + bltalwm += (1 << i); + } + for (plane = 0; plane < 2; ++plane) { // shift left, so descending custom.bltcon0 = BLTCON0(0xc0, 0, 1, 0, 1, shift); - custom.bltcon1 = BLTCON1(1, shift); + custom.bltcon1 = BLTCON1(bunClear->direction, shift); // a has a mask we're shifting custom.bltadat = 0xffff; // b has bun data - custom.bltbpt = coolbunArea + 2 + - COOL_BUN_LAST_ROW_BYTES + - plane * COOL_BUN_PLANE_SIZE; + custom.bltbpt = coolbunPlaneStarts[BUN_OFF_RIGHT_SIDE][plane]; // d is the part on screen - custom.bltdpt = currentScreen->planes[plane] + - (screenSetup->byteWidth * (y + COOL_BUN_LAST_ROW)) + - 2 - - wordShift * 2; + custom.bltdpt = currentScreen->planes[plane] + bunClear->memoryStartOffsetBytes; custom.bltafwm = 0xffff; - bltalwm = 0x0000; - for (i = 0; i <= 15 - shift; ++i) { - bltalwm += (1 << i); - } custom.bltalwm = bltalwm; custom.bltbmod = wordShift * 2; custom.bltdmod = screenSetup->byteWidth - 4 + wordShift * 2; - custom.bltsize = 2 - wordShift + (COOL_BUN_HEIGHT << 6); + custom.bltsize = bunClear->widthWords + (bunClear->heightRows << 6); WaitBlit(); } @@ -159,24 +184,31 @@ void bun_anywhere( int x, int y, struct ScreenSetup *screenSetup, - struct CurrentScreen *currentScreen + struct CurrentScreen *currentScreen, + struct BunClear *bunClear ) { uint8_t plane; uint8_t shift = x & 15; uint8_t needsExtraWord = shift != 0; + bunClear->memoryStartOffsetBytes = WORD_ALIGNED_BYTE_POSITION(screenSetup->width, x, y); + + bunClear->heightRows = COOL_BUN_HEIGHT; + bunClear->widthWords = 2 + needsExtraWord; + bunClear->direction = BLITTER_ASCENDING; + for (plane = 0; plane < 2; ++plane) { // if we extend the bun area by a word, we only need one write // buns will never interfere with a background so they don't need a mask // they do need the scratch area though custom.bltcon0 = BLTCON0(0xc0, 0, 1, 0, 1, shift); - custom.bltcon1 = BLTCON1(0, shift); + custom.bltcon1 = BLTCON1(bunClear->direction, shift); custom.bltadat = 0xffff; - custom.bltbpt = coolbunArea + plane * COOL_BUN_PLANE_SIZE; + custom.bltbpt = coolbunPlaneStarts[BUN_ANYWHERE][plane]; custom.bltdpt = currentScreen->planes[plane] + - WORD_ALIGNED_BYTE_POSITION(screenSetup->width, x, y); + bunClear->memoryStartOffsetBytes; // custom.bltdpt = screenSetup.memoryStart; custom.bltafwm = 0xffff; @@ -188,7 +220,7 @@ void bun_anywhere( custom.bltbmod = -(needsExtraWord * 2); custom.bltdmod = screenSetup->byteWidth - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2); - custom.bltsize = (2 + needsExtraWord) + (COOL_BUN_HEIGHT << 6); + custom.bltsize = bunClear->widthWords + (bunClear->heightRows << 6); WaitBlit(); } @@ -198,7 +230,8 @@ void renderBun( int x, int y, struct ScreenSetup *screenSetup, - struct CurrentScreen *currentScreen + struct CurrentScreen *currentScreen, + struct BunClear *bunClear ) { /** * Conditions that will cause the program to crash if met. If your bun @@ -212,11 +245,29 @@ void renderBun( if (y > screenSetup->height- COOL_BUN_HEIGHT - 1) return; if (x < 0) { - bun_offLeftSide(-x, y, screenSetup, currentScreen); + bun_offLeftSide( + -x, + y, + screenSetup, + currentScreen, + bunClear + ); } else if (x > screenSetup->width - COOL_BUN_WIDTH) { - bun_offRightSide(x - (screenSetup->width - COOL_BUN_WIDTH), y, screenSetup, currentScreen); + bun_offRightSide( + x - (screenSetup->width - COOL_BUN_WIDTH), + y, + screenSetup, + currentScreen, + bunClear + ); } else { - bun_anywhere(x, y, screenSetup, currentScreen); + bun_anywhere( + x, + y, + screenSetup, + currentScreen, + bunClear + ); } } @@ -286,6 +337,18 @@ void buildBunAngleAdjustments() { } } +void precalculeBunRenderInfo(void) { + int plane; + + for (plane = 0; plane < 2; ++plane) { + coolbunPlaneStarts[BUN_OFF_LEFT_SIDE][plane] = coolbunArea + plane * COOL_BUN_PLANE_SIZE; + coolbunPlaneStarts[BUN_ANYWHERE][plane] = coolbunArea + plane * COOL_BUN_PLANE_SIZE; + coolbunPlaneStarts[BUN_OFF_RIGHT_SIDE][plane] = coolbunArea + 2 + + COOL_BUN_LAST_ROW_BYTES + + plane * COOL_BUN_PLANE_SIZE; + } +} + void setupBunRenderer( struct BunRenderer *bunRenderer, struct ScreenSetup *screenSetup, @@ -296,6 +359,36 @@ void setupBunRenderer( setupBun(); buildBunAngleAdjustments(); calculateAllBunPositions(screenSetup); + precalculeBunRenderInfo(); +} + +int hasBunClear[2] = {0,0}; +struct BunClear bunClearForScreen[2][BUN_COUNT]; + +void clearCurrentBuns( + struct BunRenderer *bunRenderer +) { + int bun, plane; + struct BunClear *currentBunClear; + + if (!hasBunClear[bunRenderer->currentScreen->currentBuffer]) return; + + for (bun = 0; bun < BUN_COUNT; ++bun) { + currentBunClear = &bunClearForScreen[bunRenderer->currentScreen->currentBuffer][bun]; + + for (plane = 0; plane < 2; ++plane) { + custom.bltcon0 = 0xc0 + (1 << 8); + custom.bltcon1 = BLTCON1(currentBunClear->direction, 0); + custom.bltadat = 0x0000; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltdpt = bunRenderer->currentScreen->planes[plane] + + currentBunClear->memoryStartOffsetBytes; + custom.bltdmod = bunRenderer->screenSetup->byteWidth - (currentBunClear->widthWords * 2); + custom.bltsize = currentBunClear->widthWords + (currentBunClear->heightRows << 6); + WaitBlit(); + } + } } void renderBunFrame( @@ -311,9 +404,12 @@ void renderBunFrame( allBunPositionsByFrame[frame][bun][0], allBunPositionsByFrame[frame][bun][1], bunRenderer->screenSetup, - bunRenderer->currentScreen + bunRenderer->currentScreen, + &bunClearForScreen[bunRenderer->currentScreen->currentBuffer][bun] ); } + + hasBunClear[bunRenderer->currentScreen->currentBuffer] = 1; } void teardownBunRenderer() { diff --git a/bun.h b/bun.h index b780f92..f5d5602 100644 --- a/bun.h +++ b/bun.h @@ -20,5 +20,8 @@ void renderBunFrame( int frame, struct BunRenderer * ); +void clearCurrentBuns( + struct BunRenderer * +); void teardownBunRenderer(void); #endif diff --git a/main b/main index 6f276b9..ee124a7 100755 Binary files a/main and b/main differ diff --git a/main.c b/main.c index bfa9ee9..70c3793 100644 --- a/main.c +++ b/main.c @@ -180,6 +180,9 @@ int main(void) { while (1) { swapCurrentScreenBuffer(&screenSetup, ¤tScreen); + clearCurrentBuns(&bunRenderer); + + /* for (plane = 0; plane < 2; ++plane) { custom.bltcon0 = 0xc0 + (1 << 8); custom.bltcon1 = 0; @@ -191,6 +194,7 @@ int main(void) { custom.bltsize = screenSetup.byteWidth / 2 + (screenSetup.height << 6); WaitBlit(); } + */ renderBunFrame(i, &bunRenderer); @@ -228,7 +232,6 @@ int main(void) { WaitTOF(); - //WaitTOF(); if ((ciaa.ciapra >> 6) != 3) break;