diff --git a/bun.c b/bun.c index 2562cf3..f1abcea 100644 --- a/bun.c +++ b/bun.c @@ -14,6 +14,7 @@ #include "bun.h" #include "system/system.h" #include "system/blitter.h" +#include "types.h" #define COOL_BUN_WIDTH (32) #define COOL_BUN_WIDTH_BYTES (COOL_BUN_WIDTH / 8) @@ -83,21 +84,34 @@ void precalculateBunBLTALWM() { } } +struct PrecalcBunInfo { + uint32_t memoryStartOffsetBytes; + uint16_t bltcon0; + uint16_t bltcon1; + uint16_t bltdmod; +}; + +struct PrecalcBunInfo precalcBunInfo[FRAMES_FOR_SCREEN][BUN_COUNT]; + void bun_offRightSide( int plusXValue, int y, struct ScreenDefinition *screenDefinition, struct ActiveScreenBufferDetails *activeScreenBufferDetails, - struct BunClear *bunClear + struct BunClear *bunClear, + struct PrecalcBunInfo *precalcBunInfo ) { uint8_t i, plane = 0; uint8_t shift = plusXValue & 15; uint8_t wordShift = (plusXValue >> 4); uint16_t bltalwm, bltcon0, bltcon1, bltdmod, bltsize; + /* bunClear->memoryStartOffsetBytes = (y * screenDefinition->byteWidth) + screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES + wordShift * 2; + */ + bunClear->memoryStartOffsetBytes = precalcBunInfo->memoryStartOffsetBytes; bunClear->heightRows = COOL_BUN_HEIGHT; bunClear->widthWords = 2 - wordShift; bunClear->direction = BLITTER_ASCENDING; @@ -111,11 +125,14 @@ void bun_offRightSide( } */ - bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); - bltcon1 = BLTCON1(bunClear->direction, shift); + //bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); + //bltcon1 = BLTCON1(bunClear->direction, shift); + //bltdmod = screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES + + // wordShift * 2; - bltdmod = screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES + - wordShift * 2; + bltcon0 = precalcBunInfo->bltcon0; + bltcon1 = precalcBunInfo->bltcon1; + bltdmod = precalcBunInfo->bltdmod; bltsize = bunClear->widthWords + (bunClear->heightRows << 6); @@ -144,7 +161,8 @@ void bun_offLeftSide( int y, struct ScreenDefinition *screenDefinition, struct ActiveScreenBufferDetails *activeScreenBufferDetails, - struct BunClear *bunClear + struct BunClear *bunClear, + struct PrecalcBunInfo *precalcBunInfo ) { unsigned char plane; uint8_t shift = minusXValue & 15; @@ -155,8 +173,11 @@ void bun_offLeftSide( // y can't be 0 otherwise we will corrupt memory for now if (y == 0) return; + /* bunClear->memoryStartOffsetBytes = (screenDefinition->byteWidth * (y + COOL_BUN_LAST_ROW)) + 2 - wordShift * 2; + */ + bunClear->memoryStartOffsetBytes = precalcBunInfo->memoryStartOffsetBytes; bunClear->heightRows = COOL_BUN_HEIGHT; bunClear->widthWords = 2 - wordShift; bunClear->direction = BLITTER_DESCENDING; @@ -170,9 +191,12 @@ void bun_offLeftSide( } */ - bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); - bltcon1 = BLTCON1(bunClear->direction, shift); - bltdmod = screenDefinition->byteWidth - 4 + wordShift * 2; + //bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); + //bltcon1 = BLTCON1(bunClear->direction, shift); + //bltdmod = screenDefinition->byteWidth - 4 + wordShift * 2; + bltcon0 = precalcBunInfo->bltcon0; + bltcon1 = precalcBunInfo->bltcon1; + bltdmod = precalcBunInfo->bltdmod; bltsize = bunClear->widthWords + (bunClear->heightRows << 6); @@ -204,22 +228,29 @@ void bun_anywhere( int y, struct ScreenDefinition *screenDefinition, struct ActiveScreenBufferDetails *activeScreenBufferDetails, - struct BunClear *bunClear + struct BunClear *bunClear, + struct PrecalcBunInfo *precalcBunInfo ) { uint8_t plane; uint8_t shift = x & 15; uint8_t needsExtraWord = shift != 0; uint16_t bltcon0, bltcon1, bltalwm, bltamod, bltdmod, bltsize; - bunClear->memoryStartOffsetBytes = WORD_ALIGNED_BYTE_POSITION(screenDefinition->width, x, y); + //bunClear->memoryStartOffsetBytes = WORD_ALIGNED_BYTE_POSITION(screenDefinition->width, x, y); + bunClear->memoryStartOffsetBytes = precalcBunInfo->memoryStartOffsetBytes; bunClear->heightRows = COOL_BUN_HEIGHT; bunClear->widthWords = 2 + needsExtraWord; bunClear->direction = BLITTER_ASCENDING; // buns will never interfere with a background so they don't need a mask - bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); - bltcon1 = BLTCON1(bunClear->direction, shift); + //bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); + //bltcon1 = BLTCON1(bunClear->direction, shift); + //bltdmod = screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2); + + bltcon0 = precalcBunInfo->bltcon0; + bltcon1 = precalcBunInfo->bltcon1; + bltdmod = precalcBunInfo->bltdmod; if (needsExtraWord) { bltalwm = 0x0000; @@ -228,7 +259,6 @@ void bun_anywhere( } bltamod = -(needsExtraWord * 2); - bltdmod = screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2); bltsize = bunClear->widthWords + (bunClear->heightRows << 6); for (plane = 0; plane < 2; ++plane) { @@ -252,12 +282,15 @@ void bun_anywhere( #define ENABLE_RENDER_BUN_CHECKING (0) +uint16_t screenDefCoolBunWidthCheck; + void renderBun( int x, int y, struct ScreenDefinition *screenDefinition, struct ActiveScreenBufferDetails *activeScreenBufferDetails, - struct BunClear *bunClear + struct BunClear *bunClear, + struct PrecalcBunInfo *precalcBunInfo ) { /** * Conditions that will cause the program to crash if met. If your bun @@ -279,15 +312,19 @@ void renderBun( y, screenDefinition, activeScreenBufferDetails, - bunClear + bunClear, + precalcBunInfo ); - } else if (x > screenDefinition->width - COOL_BUN_WIDTH) { + //} else if (x > screenDefinition->width - COOL_BUN_WIDTH) { + } else if (x > screenDefCoolBunWidthCheck) { bun_offRightSide( - x - (screenDefinition->width - COOL_BUN_WIDTH), + //x - (screenDefinition->width - COOL_BUN_WIDTH), + x - screenDefCoolBunWidthCheck, y, screenDefinition, activeScreenBufferDetails, - bunClear + bunClear, + precalcBunInfo ); } else { bun_anywhere( @@ -295,7 +332,8 @@ void renderBun( y, screenDefinition, activeScreenBufferDetails, - bunClear + bunClear, + precalcBunInfo ); } } @@ -341,6 +379,66 @@ void calculateBunPositions( short int allBunPositionsByFrame[FRAMES_FOR_SCREEN][BUN_COUNT][2]; +void precalculateBunInfoForFrames( + struct ScreenDefinition *screenDefinition +) { + int frame, bun; + int x, y; + uint8_t wordShift, shift, needsExtraWord; + + screenDefCoolBunWidthCheck = screenDefinition->width - COOL_BUN_WIDTH; + + for (frame = 0; frame < FRAMES_FOR_SCREEN; ++frame) { + for (bun = 0; bun < BUN_COUNT; ++bun) { + x = allBunPositionsByFrame[frame][bun][0]; + y = allBunPositionsByFrame[frame][bun][1]; + + // off left + if (x < 0) { + x = -x; + shift = x & 15; + wordShift = x >> 4; + + precalcBunInfo[frame][bun].memoryStartOffsetBytes = + (screenDefinition->byteWidth * (y + COOL_BUN_LAST_ROW)) + + 2 - wordShift * 2; + precalcBunInfo[frame][bun].bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); + precalcBunInfo[frame][bun].bltcon1 = BLTCON1(BLITTER_DESCENDING, shift); + precalcBunInfo[frame][bun].bltdmod = + screenDefinition->byteWidth - 4 + + wordShift * 2; + // off right + } else if (x > screenDefinition->width - COOL_BUN_WIDTH) { + x = x - (screenDefinition->width - COOL_BUN_WIDTH), + + wordShift = x >> 4; + shift = x & 15; + + precalcBunInfo[frame][bun].memoryStartOffsetBytes = + (y * screenDefinition->byteWidth) + + screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES + + wordShift * 2; + precalcBunInfo[frame][bun].bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); + precalcBunInfo[frame][bun].bltcon1 = BLTCON1(BLITTER_ASCENDING, shift); + precalcBunInfo[frame][bun].bltdmod = + screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES + + wordShift * 2; + // anywhere + } else { + shift = x & 15; + needsExtraWord = shift != 0; + + precalcBunInfo[frame][bun].memoryStartOffsetBytes = + WORD_ALIGNED_BYTE_POSITION(screenDefinition->width, x, y); + precalcBunInfo[frame][bun].bltcon0 = BLTCON0(0xf0, 1, 0, 0, 1, shift); + precalcBunInfo[frame][bun].bltcon1 = BLTCON1(BLITTER_ASCENDING, shift); + precalcBunInfo[frame][bun].bltdmod = + screenDefinition->byteWidth - COOL_BUN_WIDTH_BYTES - (needsExtraWord * 2); + } + } + } +} + void calculateAllBunPositions( struct ScreenDefinition *screenDefinition ) { @@ -389,6 +487,7 @@ void setupBunRenderer( calculateAllBunPositions(screenDefinition); precalculateBunRenderInfo(); precalculateBunBLTALWM(); + precalculateBunInfoForFrames(screenDefinition); } /** @@ -446,7 +545,8 @@ void renderBunFrame( allBunPositionsByFrame[frame][bun][1], bunRenderer->screenDefinition, bunRenderer->activeScreenBufferDetails, - &bunClearForScreen[bunRenderer->activeScreenBufferDetails->currentBuffer][bun] + &bunClearForScreen[bunRenderer->activeScreenBufferDetails->currentBuffer][bun], + &precalcBunInfo[frame][bun] ); }