diff --git a/bun.c b/bun.c index cc0222c..2562cf3 100644 --- a/bun.c +++ b/bun.c @@ -56,6 +56,33 @@ struct BunClear { uint8_t *coolbunPlaneStarts[3][2]; +uint16_t bunRightSide_bltalwmPrecalc[16]; +uint16_t bunLeftSide_bltalwmPrecalc[16]; + +void precalculateBunBLTALWM() { + int shift, j; + uint16_t bltalwm; + + for (shift = 0; shift < 16; ++shift) { + // right + bltalwm = 0x0000; + + for (j = 0; j < 15 - shift; ++j) { + bltalwm += (1 << (15 - j)); + } + + bunRightSide_bltalwmPrecalc[shift] = bltalwm; + + //left + bltalwm = 0x0000; + for (j = 0; j <= 15 - shift; ++j) { + bltalwm += (1 << j); + } + + bunLeftSide_bltalwmPrecalc[shift] = bltalwm; + } +} + void bun_offRightSide( int plusXValue, int y, @@ -75,10 +102,14 @@ void bun_offRightSide( bunClear->widthWords = 2 - wordShift; bunClear->direction = BLITTER_ASCENDING; + bltalwm = bunRightSide_bltalwmPrecalc[shift]; + + /* bltalwm = 0x0000; for (i = 0; i <= 15 - shift; ++i) { bltalwm += (1 << (15 - i)); } + */ bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); bltcon1 = BLTCON1(bunClear->direction, shift); @@ -130,10 +161,14 @@ void bun_offLeftSide( bunClear->widthWords = 2 - wordShift; bunClear->direction = BLITTER_DESCENDING; + bltalwm = bunLeftSide_bltalwmPrecalc[shift]; + + /* bltalwm = 0x0000; for (i = 0; i <= 15 - shift; ++i) { bltalwm += (1 << i); } + */ bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); bltcon1 = BLTCON1(bunClear->direction, shift); @@ -215,6 +250,8 @@ void bun_anywhere( } } +#define ENABLE_RENDER_BUN_CHECKING (0) + void renderBun( int x, int y, @@ -224,14 +261,17 @@ void renderBun( ) { /** * Conditions that will cause the program to crash if met. If your bun - * isn't rendering, it's due to here. + * isn't rendering, it's due to here. Turn off checking once you know + * everything is solid to save some CPU. * * TODO: Handle top/bottom off-screen as well. */ - if (x < -31) return; - if (x > screenDefinition->width + 31) return; - if (y < 1) return; - if (y > screenDefinition->height - COOL_BUN_HEIGHT - 1) return; + if (ENABLE_RENDER_BUN_CHECKING) { + if (x < -31) return; + if (x > screenDefinition->width + 31) return; + if (y < 1) return; + if (y > screenDefinition->height - COOL_BUN_HEIGHT - 1) return; + } if (x < 0) { bun_offLeftSide( @@ -348,6 +388,7 @@ void setupBunRenderer( buildBunAngleAdjustments(); calculateAllBunPositions(screenDefinition); precalculateBunRenderInfo(); + precalculateBunBLTALWM(); } /** diff --git a/main.c b/main.c index 0779113..e36c642 100644 --- a/main.c +++ b/main.c @@ -30,8 +30,11 @@ #include "bun.h" /** - * This barely gets 50fps but I'm leaving it for now. Potential improvements: + * This barely gets 50fps on an A1200 but I'm leaving it for now. Potential improvements: * + * [ ] Precalculate even more of bun.c. This may get 50fps on an A500 if I do this. + * It would require more significant caching of as much stuff as possible. + * The A500 is spending entirely too much time on CPU tasks. * [ ] Topaz re-rendering is limited to squares or rows that changed in the last frame. * I tried this once but I need a more precise way of redrawing those areas. * [ ] Cool bun clears and re-renders happen in the same pass. @@ -368,7 +371,7 @@ int main(void) { if ((ciaa.ciapra >> 6) != 3) break; i++; - i %= FRAMES_FOR_SCREEN; + if (i > FRAMES_FOR_SCREEN) i = 0; } giveBackSystem(); diff --git a/screen.c b/screen.c index 74eabcb..811f769 100644 --- a/screen.c +++ b/screen.c @@ -21,6 +21,7 @@ void allocateDoubleBufferedScreenMemory( uint8_t bitplanes ) { unsigned char *memory; + int buffer, plane; screenDefinition->width = width; screenDefinition->height = height; @@ -38,6 +39,14 @@ void allocateDoubleBufferedScreenMemory( screenDefinition->nextBitplaneAdvance = screenDefinition->byteWidth * height; screenDefinition->nextBufferAdvance = screenDefinition->nextBitplaneAdvance * bitplanes; + for (buffer = 0; buffer < 2; ++buffer) { + for (plane = 0; plane < bitplanes; ++plane) { + screenDefinition->bufferPlanes[buffer][plane] = screenDefinition->memoryStart + + buffer * screenDefinition->nextBufferAdvance + + plane * screenDefinition->nextBitplaneAdvance; + } + } + setActiveScreenBuffer(screenDefinition, activeScreenBufferDetails, 0); } @@ -59,9 +68,7 @@ void setActiveScreenBuffer( currentScreen->currentBuffer = buffer; for (plane = 0; plane < screenDefinition->bitplanes; ++plane) { - currentScreen->planes[plane] = screenDefinition->memoryStart + - buffer * screenDefinition->nextBufferAdvance + - plane * screenDefinition->nextBitplaneAdvance; + currentScreen->planes[plane] = screenDefinition->bufferPlanes[buffer][plane]; } } diff --git a/screen.h b/screen.h index dfb8069..6d26ced 100644 --- a/screen.h +++ b/screen.h @@ -17,6 +17,7 @@ struct ScreenDefinition { uint16_t byteWidth; uint16_t nextBitplaneAdvance; uint16_t nextBufferAdvance; + unsigned char *bufferPlanes[2][8]; }; struct ActiveScreenBufferDetails {