diff --git a/bun.c b/bun.c index 8923995..f4b593d 100644 --- a/bun.c +++ b/bun.c @@ -26,7 +26,6 @@ #define BUN_MAX_RANGE (31 + 320) -#define BUN_COUNT (12) #define BUN_SPEED (1) #define BUN_HORIZ_DISTANCE_BETWEEN_BUNS ((BUN_MAX_RANGE / 4) - COOL_BUN_WIDTH) @@ -48,12 +47,6 @@ extern unsigned char chip coolbun[]; extern struct Custom far custom; -void setupBun(void) { -} - -void teardownBun(void) { -} - #define BLITTER_ASCENDING (0) #define BLITTER_DESCENDING (1) @@ -310,13 +303,6 @@ void calculateBunPositions( bunPositions[current][0] = x; bunPositions[current][1] = y; - - // for the blitter video - /* - if (frame == 0) { - printf("%d,%d\n", bunPositions[current][0], bunPositions[current][1]); - } - */ } } @@ -366,12 +352,15 @@ void setupBunRenderer( bunRenderer->screenDefinition = screenDefinition; bunRenderer->activeScreenBufferDetails = activeScreenBufferDetails; - setupBun(); buildBunAngleAdjustments(); calculateAllBunPositions(screenDefinition); precalculateBunRenderInfo(); } +/** + * Is there bun clear information for this frame? This is not true for the + * first frame in the demo. + */ int hasBunClear[2] = {0,0}; struct BunClear bunClearForScreen[2][BUN_COUNT]; @@ -430,6 +419,42 @@ void renderBunFrame( hasBunClear[bunRenderer->activeScreenBufferDetails->currentBuffer] = 1; } -void teardownBunRenderer() { - teardownBun(); +void calculateNeededRedrawRanges( + int frame, + uint16_t redrawRanges[BUN_COUNT][4] +) { + int i, sx, sy, ex, ey, tmp; + + int thisFrame = frame % FRAMES_FOR_SCREEN; + int lastFrame = (frame + FRAMES_FOR_SCREEN - 1) % FRAMES_FOR_SCREEN; + + for (i = 0; i < BUN_COUNT; ++i) { + sx = allBunPositionsByFrame[lastFrame][i][0]; + if ( + allBunPositionsByFrame[lastFrame][i][1] < + allBunPositionsByFrame[thisFrame][i][1] + ) { + sy = allBunPositionsByFrame[lastFrame][i][1]; + ey = allBunPositionsByFrame[thisFrame][i][1] + COOL_BUN_HEIGHT; + } else { + sy = allBunPositionsByFrame[thisFrame][i][1]; + ey = allBunPositionsByFrame[lastFrame][i][1] + COOL_BUN_HEIGHT; + } + + ex = allBunPositionsByFrame[thisFrame][i][0] + COOL_BUN_WIDTH; + + if (sx > ex) { + tmp = sx; + sx = ex; + ex = tmp; + } + + redrawRanges[i][0] = sx; + redrawRanges[i][1] = sy; + redrawRanges[i][2] = ex; + redrawRanges[i][3] = ey; + } +} + +void teardownBunRenderer() { } diff --git a/bun.h b/bun.h index d22fe2d..90db276 100644 --- a/bun.h +++ b/bun.h @@ -4,6 +4,7 @@ #include "screen.h" #define FRAMES_FOR_SCREEN (60) +#define BUN_COUNT (12) struct BunRenderer { struct ScreenDefinition *screenDefinition; @@ -24,4 +25,9 @@ void clearCurrentBuns( struct BunRenderer * ); void teardownBunRenderer(void); + +void calculateNeededRedrawRanges( + int frame, + uint16_t redrawRanges[BUN_COUNT][4] +); #endif diff --git a/main.c b/main.c index 2ee1bbf..1759cea 100644 --- a/main.c +++ b/main.c @@ -172,10 +172,104 @@ void buildCopperlist(void) { endCopperlist(currentCopperlist); } +void renderTopazPartials( + uint16_t redrawRanges[BUN_COUNT][4] +) { + int plane, i, topazX; + + uint16_t bltcon0; + uint16_t bltamod, bltbmod, bltcmod, bltdmod; + uint16_t width, height, bltsize; + uint8_t *bltapt, *bltbpt, *bltcpt, *bltdpt; + + bltcon0 = 0xca + (1 << 8) + (1 << 9) + (1 << 10) + (1 << 11); + bltcmod = screenDefinition.byteWidth; + bltbpt = TopazBitplanes; + + + for (i = 0; i < BUN_COUNT; ++i) { + if (redrawRanges[i][2] - redrawRanges[i][0] < TOPAZ_WIDTH_PIXELS) { + if ( + (redrawRanges[i][2] > 64 && redrawRanges[i][0] < (64 + TOPAZ_WIDTH_PIXELS)) || + (redrawRanges[i][0] < (64 + TOPAZ_WIDTH_PIXELS) && redrawRanges[i][2] > 64) + ) { + width = redrawRanges[i][2] - redrawRanges[i][0]; + height = redrawRanges[i][3] - redrawRanges[i][1]; + topazX = redrawRanges[i][0] - 64; + + if (topazX < 0) { + topazX += 16; + width -= 16; + } + // always round up to the next word + width += 16; + + bltapt = redrawRanges[i][1] * TOPAZ_WIDTH_BYTES + (topazX >> 4) * 2; + bltbpt = bltapt; + bltcpt = redrawRanges[i][1] * screenDefinition.byteWidth + (redrawRanges[i][0] >> 4) * 2; + bltdpt = bltcpt; + + bltamod = TOPAZ_WIDTH_BYTES - (width >> 4) * 2; + bltbmod = bltamod; + bltcmod = screenDefinition.byteWidth - (width >> 4) * 2; + bltdmod = bltcmod; + + bltsize = BLTSIZE((width >> 4), height); + + printf( + "Coords: %d, %d -> %d, %d\n", + redrawRanges[i][0], + redrawRanges[i][1], + redrawRanges[i][2], + redrawRanges[i][3] + ); + + printf("topazX: %d\n", topazX); + printf("width: %d\n", width); + + printf("BLTAPT: %d\n", bltapt); + printf("BLTBPT: %d\n", bltbpt); + printf("BLTCPT: %d\n", bltcpt); + printf("BLTDPT: %d\n", bltdpt); + + printf("BLTAMOD: %d\n", bltamod); + printf("BLTBMOD: %d\n", bltbmod); + printf("BLTCMOD: %d\n", bltcmod); + printf("BLTDMOD: %d\n", bltdmod); + + printf("BLTSIZE: %d, %d\n", (width >> 4), height); + + /* + for (plane = 0; plane < 3; ++plane) { + custom.bltcon0 = bltcon0; + custom.bltcon1 = 0; + custom.bltafwm = 0xffff; + custom.bltalwm = 0xffff; + custom.bltapt = MaskBitplane; + custom.bltbpt = bltbpt; + custom.bltcpt = activeScreenBufferDetails.planes[plane] + 8; + custom.bltdpt = activeScreenBufferDetails.planes[plane] + 8; + custom.bltamod = 0; + custom.bltbmod = 0; + custom.bltcmod = bltcmod; + custom.bltdmod = bltcmod; + custom.bltsize = BLTSIZE(TOPAZ_WIDTH_WORDS, 256); + + bltbpt += TOPAZ_WIDTH_BYTES * 256; + + WaitBlit(); + } + */ + } + } + } +} + int main(void) { int i; struct BunRenderer bunRenderer; + uint16_t redrawRanges[BUN_COUNT][4]; printf("\nCool bun blitter, copper, and sprite demo by John Bintz\n"); printf("\n"); @@ -229,21 +323,30 @@ int main(void) { } */ + calculateNeededRedrawRanges(0, redrawRanges); + renderTopazPartials(redrawRanges); + + /* takeOverSystem(); setCopperlist(copperlist); setUpDisplay((uint32_t)screenDefinition.bitplanes); + renderTopaz(); + swapCurrentScreenBuffer(&screenDefinition, &activeScreenBufferDetails); + renderTopaz(); + swapCurrentScreenBuffer(&screenDefinition, &activeScreenBufferDetails); + i = 0; - while (1) { + + while (0) { swapCurrentScreenBuffer(&screenDefinition, &activeScreenBufferDetails); - clearCurrentBuns(&bunRenderer); + clearCurrentBuns(&bunRenderer); renderBunFrame(i, &bunRenderer); - renderTopaz(); updateDisplayInCopperList( &screenDefinition, @@ -256,10 +359,11 @@ int main(void) { if ((ciaa.ciapra >> 6) != 3) break; i++; - i %= FRAMES_FOR_SCREEN; + //i %= FRAMES_FOR_SCREEN; } giveBackSystem(); + */ teardownScreen(&screenDefinition); diff --git a/system/system.h b/system/system.h index fd66a68..346ae8e 100644 --- a/system/system.h +++ b/system/system.h @@ -12,6 +12,11 @@ // copperlist extern void initializeCopperlist(void *copperlist); extern uint16_t* endCopperlist(uint16_t *copperlist); +/** + * This only adds bitplane pointers to the copperlist + * and sets it up for double buffering. + * You still need to configure the playfield hardware. + */ extern uint16_t* addDisplayToCopperlist( uint16_t *copperlist, struct ScreenDefinition *, diff --git a/system/system.s b/system/system.s index 61e30a3..360f676 100644 --- a/system/system.s +++ b/system/system.s @@ -73,7 +73,6 @@ ActiveScreenBufferDetails_planes EQU SOFFSET SOFFSET SET SOFFSET+(8*4) LABEL ActiveScreenBufferDetails_SIZEOF -BPLCON0_COLOR EQU $200 M68K_LEVEL3_INTERRUPT_AUTOVECTOR EQU $6C _takeOverSystem: @@ -268,7 +267,6 @@ _addDisplayToCopperlist: LEA ActiveScreenBufferDetails_planes(A3),A3 ; a3 contains address to planes - MOVEQ #0,D0 MOVE.W ScreenDefinition_bitplanes(A2),D0 ; d0 is num of bitplanes @@ -289,9 +287,10 @@ _addDisplayToCopperlist: ; get this position for later updating MOVE.L A1,(A4)+ MOVE.W D3,(A1)+ + ADDQ #2,D1 + ; low byte SWAP D3 - ADDQ #2,D1 MOVE.W D1,(A1)+ ; get this position for later updating MOVE.L A1,(A4)+ @@ -340,34 +339,44 @@ _endCopperlist: RTS +BPLCON0_ENABLE_COMPOSITE_COLOR EQU $200 + +; TODO: [ ] Create a stock display structure w/ all the default values in it +; that can be overridden, with guides/help on how to do so, then +; have this accept that structure ; @stack bitplaneCount _setUpDisplay: MOVE.L D2,-(SP) - MOVE.L 8(A7),D2 + MOVE.L 8(A7),D2 ; bitplaneCount LEA _custom,A1 MOVEQ #0,D0 - MOVE.W #BPLCON0_COLOR,D0 + MOVE.W #BPLCON0_ENABLE_COMPOSITE_COLOR,D0 + ; move bitplane count to bits 12-14 MOVEQ #0,D1 MOVE.W D2,D1 - AND.W #$7,D1 ROL.W #8,D1 ROL.W #4,D1 ADD.W D1,D0 + MOVE.W D0,bplcon0(A1) + ; this controls horizontal scroll. I'm not good enough + ; yet to provide opinions on this. MOVE.W #0,bplcon1(A1) - ; sprites always on top + + ; sprites always on top for this demo MOVE.W #$0020,bplcon2(A1) + + ; no modulos needed MOVE.W #0,bpl1mod(A1) MOVE.W #0,bpl2mod(A1) + + ; pal default MOVE.W #$2c81,diwstrt(A1) - ; pal trick - ;MOVE.W #$f4c1,diwstop(A1) - ;MOVE.W #$38c1,diwstop(A1) MOVE.W #$2cc1,diwstop(A1) MOVE.W #$0038,ddfstrt(A1) MOVE.W #$00d0,ddfstop(A1)