diff --git a/showcase/src/test/blitsmalldest.c b/showcase/src/test/blitsmalldest.c index 4d74b5e6..8e4b978d 100644 --- a/showcase/src/test/blitsmalldest.c +++ b/showcase/src/test/blitsmalldest.c @@ -21,7 +21,24 @@ static tBitMap *s_pRefBitmap; static tBitMap *s_pDstBitmap; UBYTE ubFrameIdx; +static void blitSmallDestDrawFrame(void) { + blitRect( + s_pTestBlitBfr->pBack, 0, 0, + s_pTestBlitBfr->uBfrBounds.uwX, + s_pTestBlitBfr->uBfrBounds.uwY, + 0 + ); + blitCopy( + s_pRefBitmap, ubFrameIdx, ubFrameIdx * 32, + s_pDstBitmap, 0, 0, 32, 32, 0xCA + ); + blitCopyAligned( + s_pDstBitmap, 0, 0, s_pTestBlitBfr->pBack, 16, 16, 32, 32 + ); +} + void prepareRefBitmap(void) { + // s_pRefBitmap = bitmapCreateFromPath("data/blitToSmall.bm"); UBYTE ubBlockWidth = 32; UBYTE ubBlockHeight = 32; UBYTE ubImageCount = 16; @@ -57,6 +74,7 @@ void gsTestBlitSmallDestCreate(void) { s_pDstBitmap = bitmapCreate(32, 32, SHOWCASE_BPP, 0); prepareRefBitmap(); ubFrameIdx = 0; + blitSmallDestDrawFrame(); // Display view with its viewports viewLoad(s_pTestBlitView); @@ -79,14 +97,7 @@ void gsTestBlitSmallDestLoop(void) { if(bUpdate && ubFrameIdx + bUpdate > -1 && ubFrameIdx + bUpdate < 16) { ubFrameIdx += bUpdate; - blitRect( - s_pTestBlitBfr->pBack, 0, 0, - s_pTestBlitBfr->uBfrBounds.uwX, - s_pTestBlitBfr->uBfrBounds.uwY, - 0 - ); - blitCopy(s_pRefBitmap, ubFrameIdx, ubFrameIdx*32, s_pDstBitmap, 0, 0, 32, 32, 0xCA); - blitCopyAligned(s_pDstBitmap, 0, 0, s_pTestBlitBfr->pBack, 16, 16, 32, 32); + blitSmallDestDrawFrame(); } vPortWaitForEnd(s_pTestBlitVPort); diff --git a/showcase/src/test/buffer_reuse.c b/showcase/src/test/buffer_reuse.c index cc25855a..035c4fe5 100644 --- a/showcase/src/test/buffer_reuse.c +++ b/showcase/src/test/buffer_reuse.c @@ -82,10 +82,10 @@ static tSimpleBufferManager *s_pSimpleBfr; static tTileBufferManager *s_pTileBfr; /* - * Shared display memory: - * s_pChip - CHIP pool (you own this) - * s_pSharedBm - tBitMap wrapper recreated when geometry changes - */ +* Shared display memory: +* s_pChip - CHIP pool (you own this) +* s_pSharedBm - tBitMap wrapper recreated when geometry changes +*/ static tBitMap *s_pSharedBm; static void *s_pChip; static ULONG s_ulChipSize; @@ -100,32 +100,11 @@ static tTextBitMap *s_pTextBm; static UWORD s_pFullPalette[1 << SHOWCASE_BPP]; static void bufferReuseDrawSimpleScreen(void); -static void bufferReuseStartTilePhase(void); +static UBYTE bufferReuseRestoreSimplePhase(void); +static UBYTE bufferReuseStartTilePhase(void); static void bufferReuseFadeTransition(void); -static void bufferReuseOnTileDraw( - UWORD uwTileX, UWORD uwTileY, - tBitMap *pBitMap, UWORD uwBitMapX, UWORD uwBitMapY -); static void bufferReuseFillTileMap(void); -/** - * TileBuffer redraw callback: blit one column-strip tile from s_pTileSet into the - * scroll buffer bitmap at the pixel position the manager calculated. - */ -static void bufferReuseOnTileDraw( - UWORD uwTileX, UWORD uwTileY, - tBitMap *pBitMap, UWORD uwBitMapX, UWORD uwBitMapY -) { - tTileBufferTileIndex tile = s_pTileBfr->pTileData[uwTileX][uwTileY]; - UWORD uwSrcY = (UWORD)tile * REUSE_TILE_SIZE; - blitCopy( - s_pTileSet, 0, uwSrcY, - pBitMap, uwBitMapX, uwBitMapY, - REUSE_TILE_SIZE, REUSE_TILE_SIZE, - MINTERM_COOKIE - ); -} - static void bufferReuseFillTileMap(void) { for(UWORD uwX = 0; uwX < REUSE_MAP_TILES_X; ++uwX) { for(UWORD uwY = 0; uwY < REUSE_MAP_TILES_Y; ++uwY) { @@ -185,7 +164,7 @@ static void bufferReuseApplyFade(UBYTE ubLevel) { static void bufferReuseFadeFrame(UBYTE ubLevel, tBufferReusePhase ePhase) { bufferReuseApplyFade(ubLevel); viewProcessManagers(s_pView); - if(ePhase == BUFFER_REUSE_PHASE_TILE) { + if(ePhase == BUFFER_REUSE_PHASE_TILE && s_pTileBfr) { tileBufferQueueProcess(s_pTileBfr); } copProcessBlocks(); @@ -200,7 +179,10 @@ static void bufferReuseFadeTransition(void) { bufferReuseFadeFrame(ubLevel, BUFFER_REUSE_PHASE_SIMPLE); } - bufferReuseStartTilePhase(); + if(!bufferReuseStartTilePhase()) { + logWrite("ERR: tile phase failed; staying on simple buffer\n"); + return; + } for(i = 0; i <= REUSE_FADE_STEPS; ++i) { UBYTE ubLevel = (15 * i) / REUSE_FADE_STEPS; @@ -212,29 +194,72 @@ static void bufferReuseFadeTransition(void) { ); } +/** Recreate phase 1 after a failed transition (simple manager was already removed). */ +static UBYTE bufferReuseRestoreSimplePhase(void) { + UBYTE ubBitmapFlags = BMF_CLEAR; + UWORD uwSimpleW = s_pVPort->uwWidth; + UWORD uwSimpleH = s_pVPort->uwHeight; + + if(!s_pChip) { + logWrite("ERR: no CHIP pool to restore simple phase\n"); + return 0; + } + + s_pSharedBm = bitmapCreateFromMem( + s_pChip, uwSimpleW, uwSimpleH, s_pVPort->ubBpp, ubBitmapFlags + ); + if(!s_pSharedBm) { + logWrite("ERR: bitmapCreateFromMem failed restoring simple phase\n"); + return 0; + } + + s_pSimpleBfr = simpleBufferCreate(0, + TAG_SIMPLEBUFFER_VPORT, s_pVPort, + TAG_SIMPLEBUFFER_FRONT_BITMAP, s_pSharedBm, + TAG_DONE + ); + if(!s_pSimpleBfr) { + logWrite("ERR: simpleBufferCreate failed restoring simple phase\n"); + bitmapDestroy(s_pSharedBm); + s_pSharedBm = 0; + return 0; + } + + s_ePhase = BUFFER_REUSE_PHASE_SIMPLE; + bufferReuseDrawSimpleScreen(); + viewLoad(s_pView); + return 0; +} + /** * Tear down phase 1 managers/wrappers and start phase 2 on the same s_pChip. + * @return 1 on success, 0 on failure (simple phase restored when possible). */ -static void bufferReuseStartTilePhase(void) { +static UBYTE bufferReuseStartTilePhase(void) { UWORD uwScrollW, uwScrollH; UBYTE ubBitmapFlags = BMF_CLEAR; logWrite("Switching to tile buffer, same CHIP @ %p\n", s_pChip); + if(!s_pChip) { + logWrite("ERR: CHIP pool is null\n"); + return 0; + } + /* - * 1) Remove simpleBuffer from the viewport. Its destroy callback runs but - * does NOT free s_pSharedBm (we passed TAG_SIMPLEBUFFER_FRONT_BITMAP). - * Camera manager is left on the vPort; tileBuffer will reuse it. - */ + * 1) Remove simpleBuffer from the viewport. Its destroy callback runs but + * does NOT free s_pSharedBm (we passed TAG_SIMPLEBUFFER_FRONT_BITMAP). + * Camera manager is left on the vPort; tileBuffer will reuse it. + */ vPortRmManager(s_pVPort, (tVpManager*)s_pSimpleBfr); s_pSimpleBfr = 0; /* - * 2) Destroy the tBitMap *header* only (BMF_EXTERNAL). - * s_pChip is unchanged — compare log address before/after this call. - * We must drop the old header because simple and scroll bitmaps use - * different widths/heights (BytesPerRow, Rows, plane layout). - */ + * 2) Destroy the tBitMap *header* only (BMF_EXTERNAL). + * s_pChip is unchanged — compare log address before/after this call. + * We must drop the old header because simple and scroll bitmaps use + * different widths/heights (BytesPerRow, Rows, plane layout). + */ bitmapDestroy(s_pSharedBm); s_pSharedBm = 0; @@ -253,27 +278,26 @@ static void bufferReuseStartTilePhase(void) { ); /* - * 3) Single scroll wrapper in s_pChip (no double-buffer — ACE only copies - * bitplane 0 when syncing front/back, which flashes with 5bpp external pool). - */ + * 3) Single scroll wrapper in s_pChip (no double-buffer — ACE only copies + * bitplane 0 when syncing front/back, which flashes with 5bpp external pool). + */ s_pSharedBm = bitmapCreateFromMem( s_pChip, uwScrollW, uwScrollH, s_pVPort->ubBpp, ubBitmapFlags ); if(!s_pSharedBm) { logWrite("ERR: bitmapCreateFromMem failed for scroll size\n"); - return; + return bufferReuseRestoreSimplePhase(); } /* - * 4) tileBuffer creates scrollBuffer with external bitmap in s_pChip. - */ + * 4) tileBuffer creates scrollBuffer with external bitmap in s_pChip. + */ s_pTileBfr = tileBufferCreate(0, TAG_TILEBUFFER_VPORT, s_pVPort, TAG_TILEBUFFER_TILE_SHIFT, REUSE_TILE_SHIFT, TAG_TILEBUFFER_BOUND_TILE_X, REUSE_MAP_TILES_X, TAG_TILEBUFFER_BOUND_TILE_Y, REUSE_MAP_TILES_Y, TAG_TILEBUFFER_TILESET, s_pTileSet, - TAG_TILEBUFFER_CALLBACK_TILE_DRAW, bufferReuseOnTileDraw, TAG_TILEBUFFER_REDRAW_QUEUE_LENGTH, REUSE_REDRAW_QUEUE, TAG_TILEBUFFER_BITMAP_FLAGS, ubBitmapFlags, TAG_TILEBUFFER_FRONT_BITMAP, s_pSharedBm, @@ -283,7 +307,7 @@ static void bufferReuseStartTilePhase(void) { logWrite("ERR: tileBufferCreate failed\n"); bitmapDestroy(s_pSharedBm); s_pSharedBm = 0; - return; + return bufferReuseRestoreSimplePhase(); } bufferReuseFillTileMap(); @@ -294,6 +318,7 @@ static void bufferReuseStartTilePhase(void) { tileBufferRedrawAll(s_pTileBfr); viewLoad(s_pView); s_ePhase = BUFFER_REUSE_PHASE_TILE; + return 1; } void gsTestBufferReuseCreate(void) { @@ -318,10 +343,10 @@ void gsTestBufferReuseCreate(void) { ); /* - * Phase 1 bitmap size = viewport (simpleBuffer default bounds). - * Phase 2 needs one scrollBuffer bitmap in the same pool. - * Allocate CHIP once for max(phase1 simple, scroll). - */ + * Phase 1 bitmap size = viewport (simpleBuffer default bounds). + * Phase 2 needs one scrollBuffer bitmap in the same pool. + * Allocate CHIP once for max(phase1 simple, scroll). + */ uwSimpleW = s_pVPort->uwWidth; uwSimpleH = s_pVPort->uwHeight; @@ -343,16 +368,28 @@ void gsTestBufferReuseCreate(void) { "CHIP pool %lu bytes (simple %lu, scroll %lu) @ %p\n", s_ulChipSize, ulSimpleSize, ulScrollSize, s_pChip ); + if(!s_pChip) { + logWrite("ERR: memAllocChip failed (%lu bytes)\n", s_ulChipSize); + goto fail; + } /* Wrap CHIP for phase 1 geometry; manager will not allocate or free planes. */ s_pSharedBm = bitmapCreateFromMem( s_pChip, uwSimpleW, uwSimpleH, s_pVPort->ubBpp, ubBitmapFlags ); + if(!s_pSharedBm) { + logWrite("ERR: bitmapCreateFromMem failed for simple size\n"); + goto fail; + } s_pSimpleBfr = simpleBufferCreate(0, TAG_SIMPLEBUFFER_VPORT, s_pVPort, TAG_SIMPLEBUFFER_FRONT_BITMAP, s_pSharedBm, TAG_DONE ); + if(!s_pSimpleBfr) { + logWrite("ERR: simpleBufferCreate failed\n"); + goto fail; + } /* Tileset is independent CHIP (small); not reused as the scroll buffer. */ s_pTileSet = bitmapCreate( @@ -383,9 +420,42 @@ void gsTestBufferReuseCreate(void) { viewLoad(s_pView); logBlockEnd("gsTestBufferReuseCreate"); systemUnuse(); + return; + +fail: + if(s_pSharedBm) { + bitmapDestroy(s_pSharedBm); + s_pSharedBm = 0; + } + if(s_pChip) { + memFree(s_pChip, s_ulChipSize); + s_pChip = 0; + } + if(s_pSimpleBfr) { + vPortRmManager(s_pVPort, (tVpManager*)s_pSimpleBfr); + s_pSimpleBfr = 0; + } + if(s_pTileSet) { + bitmapDestroy(s_pTileSet); + s_pTileSet = 0; + } + fontDestroyTextBitMap(s_pTextBm); + s_pTextBm = 0; + fontDestroy(s_pFont); + s_pFont = 0; + viewDestroy(s_pView); + s_pView = 0; + s_pVPort = 0; + logBlockEnd("gsTestBufferReuseCreate"); + systemUnuse(); + stateChange(g_pGameStateManager, &g_pTestStates[TEST_STATE_MENU]); } void gsTestBufferReuseLoop(void) { + if(!s_pView) { + return; + } + if(keyUse(KEY_ESCAPE)) { stateChange(g_pGameStateManager, &g_pTestStates[TEST_STATE_MENU]); return; @@ -414,6 +484,10 @@ void gsTestBufferReuseLoop(void) { if(joyCheck(JOY1_DOWN) || keyCheck(KEY_S) || keyCheck(KEY_DOWN)) { wDy = REUSE_SCROLL_SPEED; } + if(!s_pTileBfr) { + return; + } + if(wDx || wDy) { cameraMoveBy(s_pTileBfr->pCamera, wDx, wDy); } @@ -429,9 +503,9 @@ void gsTestBufferReuseDestroy(void) { systemUse(); /* - * tileBufferDestroy() does not remove the internal scrollBuffer from the vPort, - * so detach tile then scroll explicitly when leaving phase 2. - */ + * tileBufferDestroy() does not remove the internal scrollBuffer from the vPort, + * so detach tile then scroll explicitly when leaving phase 2. + */ if(s_pTileBfr) { vPortRmManager(s_pVPort, (tVpManager*)s_pTileBfr); s_pTileBfr = 0; diff --git a/showcase/src/test/buffer_scroll.c b/showcase/src/test/buffer_scroll.c index 470a1ca6..f5b396c3 100644 --- a/showcase/src/test/buffer_scroll.c +++ b/showcase/src/test/buffer_scroll.c @@ -80,16 +80,32 @@ static void fillBfr(tBitMap *pBfr, UWORD uwWidth, UWORD uwHeight) { blitRect(pBfr, 0, 0, 1, uwHeight, 6); blitRect(pBfr, uwWidth, 0, 1, uwHeight, 6); - drawModeInfo(pBfr, 50, 50); + /* Keep menu text clear of the y=100 ruler grid line */ + drawModeInfo(pBfr, 50, 30); logBlockEnd("fillBfr()"); } -static void initSimpleBuffer(UBYTE isHires, UWORD uwWidth, UWORD uwHeight) { +static void bufferScrollReloadDisplay(void) { + /* viewLoad while system is still held — OS must not run between setup and DMA */ + viewLoad(s_pView); + viewProcessManagers(s_pView); + /* viewLoad already ran copProcessBlocks once — run again so both cop bfrs match */ + copProcessBlocks(); + systemUnuse(); +} + +static void bufferScrollDestroyVPort(void) { + if(!s_pView->pFirstVPort) { + return; + } viewLoad(0); + vPortDestroy(s_pView->pFirstVPort); + s_pVPort = 0; +} + +static void initSimpleBuffer(UBYTE isHires, UWORD uwWidth, UWORD uwHeight) { systemUse(); - if(s_pView->pFirstVPort) { - vPortDestroy(s_pView->pFirstVPort); - } + bufferScrollDestroyVPort(); s_pVPort = vPortCreate(0, TAG_VPORT_VIEW, s_pView, @@ -107,17 +123,11 @@ static void initSimpleBuffer(UBYTE isHires, UWORD uwWidth, UWORD uwHeight) { s_pCamera = s_pBfr->pCamera; fillBfr(s_pBfr->pBack, uwWidth, uwHeight); - - viewLoad(s_pView); - systemUnuse(); } static void initScrollBuffer(UBYTE isHires) { - viewLoad(0); systemUse(); - if(s_pView->pFirstVPort) { - vPortDestroy(s_pView->pFirstVPort); - } + bufferScrollDestroyVPort(); s_pVPort = vPortCreate(0, TAG_VPORT_VIEW, s_pView, @@ -156,10 +166,7 @@ static void initScrollBuffer(UBYTE isHires) { blitRect(s_pBfr->pBack, 16, 16, 32, 32, 5); - drawModeInfo(s_pBfr->pBack, 50, 50); - - viewLoad(s_pView); - systemUnuse(); + drawModeInfo(s_pBfr->pBack, 50, 30); } static void changeMode(tMode eMode) { @@ -180,20 +187,21 @@ static void changeMode(tMode eMode) { default: break; } + bufferScrollReloadDisplay(); } void gsTestBufferScrollCreate(void) { logBlockBegin("gsTestBufferScrollCreate()"); s_pView = viewCreate(0, + TAG_VIEW_GLOBAL_HRES, 0, TAG_DONE); - s_pFont = fontCreateFromPath("data/silkscreen.fnt"); + s_pFont = fontCreateFromPath("data/fonts/silkscreen.fnt"); s_pTextBitMap = fontCreateTextBitMap(320, s_pFont->uwHeight); s_eCurrentMode = MODE_SIMPLE_LORES; changeMode(s_eCurrentMode); logBlockEnd("gsTestBufferScrollCreate()"); - systemUnuse(); } void gsTestBufferScrollLoop(void) { @@ -238,10 +246,14 @@ void gsTestBufferScrollLoop(void) { void gsTestBufferScrollDestroy(void) { logBlockBegin("gsTestBufferScrollDestroy()"); systemUse(); + viewLoad(0); viewDestroy(s_pView); fontDestroy(s_pFont); fontDestroyTextBitMap(s_pTextBitMap); logBlockEnd("gsTestBufferScrollDestroy()"); + systemUnuse(); } + + \ No newline at end of file diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 78726be3..d51162e9 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -71,7 +71,7 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { pCopList = pVPort->pView->pCopList; if(pCopList->ubMode == COPPER_MODE_BLOCK) { pManager->pStartBlock = copBlockCreate( - pVPort->pView->pCopList, 2 * pVPort->ubBpp + 8, + pVPort->pView->pCopList, 2 * pVPort->ubBpp + 9, // Vertically addition from DiWStrt, horizontally just so that 6bpp can be set up. // First to set are ddf, modulos & shift so they are changed during fetch. s_pCopperWaitXByBitplanes[pVPort->ubBpp], pVPort->uwOffsY + pVPort->pView->ubPosY -1 @@ -153,7 +153,8 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { } static void scrollBufferDestroyOwnedBitmaps(tScrollBufferManager *pManager) { - if(pManager->ubFlags & SCROLLBUFFER_FLAG_OWN_FRONT) { + UBYTE isOwnFront = pManager->ubFlags & SCROLLBUFFER_FLAG_OWN_FRONT; + if(isOwnFront) { if(pManager->pFront) { bitmapDestroy(pManager->pFront); } @@ -161,7 +162,7 @@ static void scrollBufferDestroyOwnedBitmaps(tScrollBufferManager *pManager) { } if( (pManager->ubFlags & SCROLLBUFFER_FLAG_OWN_BACK) && - pManager->pBack && pManager->pBack != pManager->pFront + pManager->pBack && (!isOwnFront || pManager->pBack != pManager->pFront) ) { bitmapDestroy(pManager->pBack); } @@ -187,8 +188,9 @@ void scrollBufferDestroy(tScrollBufferManager *pManager) { UBYTE scrollBufferGetRawCopperlistInstructionCountStart(UBYTE ubBpp) { return ( 1 + // initial WAIT - 1 + 2 * ubBpp + // bitplane ptrs & bplcon commands - 4 // After bitplane ptrs & bplcon + 1 + 2 * ubBpp + // bitplane ptrs & bplcon1 + 1 + // BPLCON0 (BPP + HIRES) + 4 // DDF & modulo ); } @@ -213,7 +215,11 @@ static void resetStartCopperlist(tCopCmd *pCmds, tScrollBufferManager *pManager) copSetMove(&pCmds[i++].sMove, &g_pBplFetch[j].uwHi, 0); copSetMove(&pCmds[i++].sMove, &g_pBplFetch[j].uwLo, 0); } - // After bitplane ptrs & bplcon + copSetMove( + &pCmds[i++].sMove, &g_pCustom->bplcon0, + (pManager->sCommon.pVPort->ubBpp << 12) | BV(9) | + ((pManager->sCommon.pVPort->eFlags & VP_FLAG_HIRES) ? BV(15) : 0) + ); copSetMove(&pCmds[i++].sMove, &g_pCustom->ddfstrt, pManager->uwDDfStrt); // Fetch start copSetMove(&pCmds[i++].sMove, &g_pCustom->bpl1mod, pManager->uwModulo); // Odd planes modulo copSetMove(&pCmds[i++].sMove, &g_pCustom->bpl2mod, pManager->uwModulo); // Even planes modulo @@ -315,7 +321,7 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { } // NOTE trying to set colors before and after copper instructions made vport // move one line lower on 4bpp - there will be problem on 5 & 6bpp - pBlock->uwCurrCount += 4; // Add constant part + pBlock->uwCurrCount += 5; // Add constant part (bplcon0 + DDF + modulo) // Copper block after Y-break pBlock = pManager->pBreakBlock; @@ -448,8 +454,8 @@ void scrollBufferReset( pManager->uwDDfStrt += 4; pManager->uwDDfStop += 4; - // One word more for fetch - pManager->uwModulo -= 2; + // Two words more for fetch (hires 4-part bitplane pattern) + pManager->uwModulo -= 4; } else { fetchModeApplyScrollBufferXScrollCopper( @@ -489,8 +495,13 @@ void scrollBufferReset( pManager->sCommon.pVPort->pView->ubPosY + pManager->sCommon.pVPort->uwOffsY - 1 )); - // After bitplane ptrs & bplcon + // After bitplane ptrs & bplcon1 (filled by scrollBufferProcess) pBlock->uwCurrCount = 2 * pManager->sCommon.pVPort->ubBpp + 1; + copMove( + pCopList, pBlock, &g_pCustom->bplcon0, + (pManager->sCommon.pVPort->ubBpp << 12) | BV(9) | + ((pManager->sCommon.pVPort->eFlags & VP_FLAG_HIRES) ? BV(15) : 0) + ); copMove(pCopList, pBlock, &g_pCustom->ddfstrt, pManager->uwDDfStrt); // Fetch start copMove(pCopList, pBlock, &g_pCustom->bpl1mod, pManager->uwModulo); // Odd planes modulo copMove(pCopList, pBlock, &g_pCustom->bpl2mod, pManager->uwModulo); // Even planes modulo diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index b2b6000e..6ac43ce1 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -69,6 +69,7 @@ static void simpleBufferInitializeCopperList( // Update (rewrite) copperlist // TODO this could be unified with copBlock being set with copSetMove too tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; + UBYTE ubHiresCop = (pVPort->eFlags & VP_FLAG_HIRES) ? 1 : 0; if(pManager->ubFlags & SIMPLEBUFFER_FLAG_COPLIST_RAW) { // Since simpleBufferProcess only updates bitplane ptrs and shift, // copperlist must be shaped here. @@ -103,6 +104,12 @@ static void simpleBufferInitializeCopperList( else { tCopBlock *pBlock = pManager->pCopBlock; pBlock->uwCurrCount = 0; // Rewind to beginning + if(ubHiresCop) { + copMove( + pCopList, pBlock, &g_pCustom->bplcon0, + (pVPort->ubBpp << 12) | BV(9) | BV(15) + ); + } copMove(pCopList, pBlock, &g_pCustom->ddfstop, uwDDfStop); // Data fetch copMove(pCopList, pBlock, &g_pCustom->ddfstrt, uwDDfStrt); copMove(pCopList, pBlock, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo @@ -282,10 +289,12 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { pCopList = pVPort->pView->pCopList; if(pCopList->ubMode == COPPER_MODE_BLOCK) { + UBYTE ubHiresCop = (pVPort->eFlags & VP_FLAG_HIRES) ? 1 : 0; // CopBlock contains: bitplanes + shiftX pManager->pCopBlock = copBlockCreate( // WAIT is already in copBlock so 1 instruction less - pCopList, simpleBufferGetRawCopperlistInstructionCount(pVPort->ubBpp) - 1, + pCopList, + simpleBufferGetRawCopperlistInstructionCount(pVPort->ubBpp) - 1 + ubHiresCop, // Vertically addition from DiWStrt, horizontally just so that 6bpp can be set up. // First to set are ddf, modulos & shift so they are changed during fetch. s_pCopperWaitXByBitplanes[pVPort->ubBpp], @@ -378,7 +387,10 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { // copperlist needs refreshing. ULONG ulBplOffs; UWORD uwShift = simpleBufferCalcBplOffsAndShift(pManager, &ulBplOffs); - pManager->pCopBlock->uwCurrCount = 4; // Rewind to shift cmd pos + pManager->pCopBlock->uwCurrCount = 4; + if(pManager->sCommon.pVPort->eFlags & VP_FLAG_HIRES) { + ++pManager->pCopBlock->uwCurrCount; + } copMove(pCopList, pManager->pCopBlock, &g_pCustom->bplcon1, uwShift); for(UBYTE i = 0; i < pManager->pBack->Depth; ++i) { ULONG ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; diff --git a/src/ace/utils/extview.c b/src/ace/utils/extview.c index c9f433f1..417ba380 100644 --- a/src/ace/utils/extview.c +++ b/src/ace/utils/extview.c @@ -281,6 +281,9 @@ void viewLoad(tView *pView) { g_pCustom->fmode = 0; // AGA fix g_pCustom->bplcon3 = 0; // AGA fix #endif + if(pView->pFirstVPort->eFlags & VP_FLAG_HIRES) { + g_pCustom->bplcon0 |= BV(15); + } g_pCustom->bplcon4 = 0x0011; // AGA fix UWORD uwDiwStartX = pView->ubPosX;