From 99b2ba7ea8c57e90e06f36a48307fb8013829f51 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 5 May 2018 14:58:39 +0200 Subject: [PATCH 01/56] Initial work on simple buffer double buffering --- include/ace/managers/viewport/simplebuffer.h | 8 +- src/ace/managers/viewport/simplebuffer.c | 209 ++++++++++++------- 2 files changed, 131 insertions(+), 86 deletions(-) diff --git a/include/ace/managers/viewport/simplebuffer.h b/include/ace/managers/viewport/simplebuffer.h index f2cc628c..17215502 100644 --- a/include/ace/managers/viewport/simplebuffer.h +++ b/include/ace/managers/viewport/simplebuffer.h @@ -26,19 +26,17 @@ #define TAG_SIMPLEBUFFER_BOUND_HEIGHT (TAG_USER|3) // Buffer bitmap creation flags #define TAG_SIMPLEBUFFER_BITMAP_FLAGS (TAG_USER|4) +#define TAG_SIMPLEBUFFER_IS_DBLBUF (TAG_USER|5) // If in raw mode, offset on copperlist for placing required copper // instructions, specified in copper instruction count since beginning. #define TAG_SIMPLEBUFFER_COPLIST_OFFSET (TAG_USER|6) -// Flags for internal usage. -#define SIMPLEBUFFER_FLAG_X_SCROLLABLE 1 -#define SIMPLEBUFFER_FLAG_COPLIST_RAW 2 - typedef struct { tVpManager sCommon; tCameraManager *pCameraManager; // scroll-specific fields - tBitMap *pBuffer; ///< Bitmap buffer + tBitMap *pFront; ///< Currently displayed buffer. + tBitMap *pBack; ///< Buffer for drawing. tCopBlock *pCopBlock; ///< CopBlock containing modulo/shift/bitplane cmds tUwCoordYX uBfrBounds; ///< Buffer bounds in pixels UBYTE ubFlags; ///< Read only. See SIMPLEBUFFER_FLAG_*. diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index fd7149dd..df2b1a7b 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -7,6 +7,96 @@ #ifdef AMIGA +// Flags for internal usage. +#define SIMPLEBUFFER_FLAG_X_SCROLLABLE 1 +#define SIMPLEBUFFER_FLAG_COPLIST_RAW 2 + +static void simpleBufferSetBack(tSimpleBufferManager *pManager, tBitMap *pBack) { +#if defined(ACE_DEBUG) + if(pManager->pBack && pManager->pBack->Depth != pBack->Depth) { + logWrite("ERR: buffer bitmaps differ in BPP!\n"); + return; + } +#endif + pManager->pBack = pBack; +} + +void simpleBufferSetFront(tSimpleBufferManager *pManager, tBitMap *pFront) { + logBlockBegin( + "simpleBufferSetFront(pManager: %p, pFront: %p)", + pManager, pFront + ); +#if defined(ACE_DEBUG) + if(pManager->pFront && pManager->pFront->Depth != pFront->Depth) { + logWrite("ERR: buffer bitmaps differ in BPP!\n"); + return; + } +#endif + + pManager->uBfrBounds.sUwCoord.uwX = bitmapGetByteWidth(pFront) << 3; + pManager->uBfrBounds.sUwCoord.uwY = pFront->Rows; + pManager->pFront = pFront; + UWORD uwModulo = pFront->BytesPerRow - (pManager->sCommon.pVPort->uwWidth >> 3); + UWORD uwDDfStrt; + if(pManager->uBfrBounds.sUwCoord.uwX <= pManager->sCommon.pVPort->uwWidth) { + uwDDfStrt = 0x0038; + pManager->ubFlags &= ~SIMPLEBUFFER_FLAG_X_SCROLLABLE; + } + else { + pManager->ubFlags |= SIMPLEBUFFER_FLAG_X_SCROLLABLE; + uwDDfStrt = 0x0030; + uwModulo -= 1; + } + logWrite("Modulo: %u\n", uwModulo); + + // Update (rewrite) copperlist + // TODO this could be unified with copBlock being set with copSetMove too + tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; + if(pManager->ubFlags & SIMPLEBUFFER_FLAG_COPLIST_RAW) { + // Since simpleBufferProcess only updates bitplane ptrs and shift, + // copperlist must be shaped here. + // WAIT is calc'd in same way as in copBlockCreate in simpleBufferCreate(). + tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; + logWrite("Setting copperlist %p at offs %u: %p\n", pCopList->pBackBfr, pManager->uwCopperOffset, pCmdList); + copSetWait(&pCmdList[0].sWait, 0xE2-7*4, pManager->sCommon.pVPort->uwOffsY + 0x2C-1); + copSetMove(&pCmdList[1].sMove, &g_pCustom->ddfstop, 0x00D0); // Data fetch + copSetMove(&pCmdList[2].sMove, &g_pCustom->ddfstrt, uwDDfStrt); + copSetMove(&pCmdList[3].sMove, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo + copSetMove(&pCmdList[4].sMove, &g_pCustom->bpl2mod, uwModulo); + copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, 0); // Shift: 0 + UBYTE i; + ULONG ulPlaneAddr; + for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { + ulPlaneAddr = (ULONG)pManager->pFront->Planes[i]; + copSetMove(&pCmdList[6 + i*2 + 0].sMove, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); + copSetMove(&pCmdList[6 + i*2 + 1].sMove, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); + } + // Copy to front buffer since it needs initialization there too + CopyMem( + &pCopList->pBackBfr->pList[pManager->uwCopperOffset], + &pCopList->pFrontBfr->pList[pManager->uwCopperOffset], + (6+2*pManager->sCommon.pVPort->ubBPP)*sizeof(tCopCmd) + ); + } + else { + tCopBlock *pBlock = pManager->pCopBlock; + pBlock->uwCurrCount = 0; // Rewind to beginning + copMove(pCopList, pBlock, &g_pCustom->ddfstop, 0x00D0); // Data fetch + copMove(pCopList, pBlock, &g_pCustom->ddfstrt, uwDDfStrt); + copMove(pCopList, pBlock, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo + copMove(pCopList, pBlock, &g_pCustom->bpl2mod, uwModulo); + copMove(pCopList, pBlock, &g_pCustom->bplcon1, 0); // Shift: 0 + UBYTE i; + ULONG ulPlaneAddr; + for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { + ulPlaneAddr = (ULONG)pManager->pFront->Planes[i]; + copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); + copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); + } + } + logBlockEnd("simplebufferSetFront()"); +} + tSimpleBufferManager *simpleBufferCreate( void *pTags, ... ) { @@ -15,6 +105,8 @@ tSimpleBufferManager *simpleBufferCreate( tSimpleBufferManager *pManager; UWORD uwBoundWidth, uwBoundHeight; UBYTE ubBitmapFlags; + tBitMap *pFront = 0, *pBack = 0; + UBYTE isCameraCreated = 0; logBlockBegin("simpleBufferCreate(pTags: %p, ...)", pTags); va_start(vaTags, pTags); @@ -39,18 +131,31 @@ tSimpleBufferManager *simpleBufferCreate( uwBoundHeight = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_BOUND_HEIGHT, pVPort->uwHeight); ubBitmapFlags = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_BITMAP_FLAGS, BMF_CLEAR); logWrite("Bounds: %ux%u\n", uwBoundWidth, uwBoundHeight); - tBitMap *pBuffer = bitmapCreate( + pFront = bitmapCreate( uwBoundWidth, uwBoundHeight, pVPort->ubBPP, ubBitmapFlags ); - if(!pBuffer) { + if(!pFront) { logWrite("ERR: Can't alloc buffer bitmap!\n"); goto fail; } + UBYTE isDblBfr = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_IS_DBLBUF, 0); + if(isDblBfr) { + pBack = bitmapCreate( + uwBoundWidth, uwBoundHeight, + pVPort->ubBPP, ubBitmapFlags + ); + if(!pFront) { + logWrite("ERR: Can't alloc buffer bitmap!\n"); + goto fail; + } + } + // Find camera manager, create if not exists pManager->pCameraManager = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); if(!pManager->pCameraManager) { + isCameraCreated = 1; pManager->pCameraManager = cameraCreate(pVPort, 0, 0, uwBoundWidth, uwBoundHeight); } @@ -81,7 +186,8 @@ tSimpleBufferManager *simpleBufferCreate( logWrite("Copperlist offset: %u\n", pManager->uwCopperOffset); } - simpleBufferSetBitmap(pManager, pBuffer); + simpleBufferSetFront(pManager, pFront); + simpleBufferSetBack(pManager, pBack); // Add manager to VPort vPortAddManager(pVPort, (tVpManager*)pManager); @@ -90,89 +196,30 @@ tSimpleBufferManager *simpleBufferCreate( return pManager; fail: - logBlockEnd("simpleBufferCreate()"); - va_end(vaTags); - return 0; -} - -void simpleBufferSetBitmap(tSimpleBufferManager *pManager, tBitMap *pBitMap) { - logBlockBegin( - "simpleBufferSetBitmap(pManager: %p, pBitMap: %p)", - pManager, pBitMap - ); - if(pManager->pBuffer && pManager->pBuffer->Depth != pBitMap->Depth) { - logWrite("ERR: buffer bitmaps differ in BPP!\n"); - return; + if(pFront) { + bitmapDestroy(pFront); } - - pManager->uBfrBounds.sUwCoord.uwX = bitmapGetByteWidth(pBitMap) << 3; - pManager->uBfrBounds.sUwCoord.uwY = pBitMap->Rows; - pManager->pBuffer = pBitMap; - UWORD uwModulo = pBitMap->BytesPerRow - (pManager->sCommon.pVPort->uwWidth >> 3); - UWORD uwDDfStrt; - if(pManager->uBfrBounds.sUwCoord.uwX <= pManager->sCommon.pVPort->uwWidth) { - uwDDfStrt = 0x0038; - pManager->ubFlags &= ~SIMPLEBUFFER_FLAG_X_SCROLLABLE; + if(pBack) { + bitmapDestroy(pBack); } - else { - pManager->ubFlags |= SIMPLEBUFFER_FLAG_X_SCROLLABLE; - uwDDfStrt = 0x0030; - uwModulo -= 1; - } - logWrite("Modulo: %u\n", uwModulo); - - // Update (rewrite) copperlist - // TODO this could be unified with copBlock being set with copSetMove too - tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; - if(pManager->ubFlags & SIMPLEBUFFER_FLAG_COPLIST_RAW) { - // Since simpleBufferProcess only updates bitplane ptrs and shift, - // copperlist must be shaped here. - // WAIT is calc'd in same way as in copBlockCreate in simpleBufferCreate(). - tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; - logWrite("Setting copperlist %p at offs %u: %p\n", pCopList->pBackBfr, pManager->uwCopperOffset, pCmdList); - copSetWait(&pCmdList[0].sWait, 0xE2-7*4, pManager->sCommon.pVPort->uwOffsY + 0x2C-1); - copSetMove(&pCmdList[1].sMove, &g_pCustom->ddfstop, 0x00D0); // Data fetch - copSetMove(&pCmdList[2].sMove, &g_pCustom->ddfstrt, uwDDfStrt); - copSetMove(&pCmdList[3].sMove, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo - copSetMove(&pCmdList[4].sMove, &g_pCustom->bpl2mod, uwModulo); - copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, 0); // Shift: 0 - UBYTE i; - ULONG ulPlaneAddr; - for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { - ulPlaneAddr = (ULONG)pManager->pBuffer->Planes[i]; - copSetMove(&pCmdList[6 + i*2 + 0].sMove, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); - copSetMove(&pCmdList[6 + i*2 + 1].sMove, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); - } - // Copy to front buffer since it needs initialization there too - CopyMem( - &pCopList->pBackBfr->pList[pManager->uwCopperOffset], - &pCopList->pFrontBfr->pList[pManager->uwCopperOffset], - (6+2*pManager->sCommon.pVPort->ubBPP)*sizeof(tCopCmd) - ); + if(pManager) { + memFree(pManager, sizeof(tSimpleBufferManager)); } - else { - tCopBlock *pBlock = pManager->pCopBlock; - pBlock->uwCurrCount = 0; // Rewind to beginning - copMove(pCopList, pBlock, &g_pCustom->ddfstop, 0x00D0); // Data fetch - copMove(pCopList, pBlock, &g_pCustom->ddfstrt, uwDDfStrt); - copMove(pCopList, pBlock, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo - copMove(pCopList, pBlock, &g_pCustom->bpl2mod, uwModulo); - copMove(pCopList, pBlock, &g_pCustom->bplcon1, 0); // Shift: 0 - UBYTE i; - ULONG ulPlaneAddr; - for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { - ulPlaneAddr = (ULONG)pManager->pBuffer->Planes[i]; - copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); - copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); - } + if(pManager->pCameraManager && isCameraCreated) { + cameraDestroy(pManager->pCameraManager); } - logBlockEnd("simplebufferSetBitmap()"); + logBlockEnd("simpleBufferCreate()"); + va_end(vaTags); + return 0; } void simpleBufferDestroy(tSimpleBufferManager *pManager) { logBlockBegin("simpleBufferDestroy()"); logWrite("Destroying bitmap...\n"); - bitmapDestroy(pManager->pBuffer); + bitmapDestroy(pManager->pFront); + if(pManager->pBack) { + bitmapDestroy(pManager->pBack); + } logWrite("Freeing mem...\n"); memFree(pManager, sizeof(tSimpleBufferManager)); logBlockEnd("simpleBufferDestroy()"); @@ -202,7 +249,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { ulBplOffs = (pCameraManager->uPos.sUwCoord.uwX >> 4) << 1; // Calculate Y movement - ulBplOffs += pManager->pBuffer->BytesPerRow*pCameraManager->uPos.sUwCoord.uwY; + ulBplOffs += pManager->pFront->BytesPerRow*pCameraManager->uPos.sUwCoord.uwY; // Copperlist - regen bitplane ptrs, update shift // TODO could be unified by using copSetMove in copBlock @@ -210,7 +257,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, uwShift); for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { - ulPlaneAddr = ((ULONG)pManager->pBuffer->Planes[i]) + ulBplOffs; + ulPlaneAddr = ((ULONG)pManager->pFront->Planes[i]) + ulBplOffs; copSetMove(&pCmdList[6 + i*2 + 0].sMove, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copSetMove(&pCmdList[6 + i*2 + 1].sMove, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } @@ -218,8 +265,8 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { else { pManager->pCopBlock->uwCurrCount = 4; // Rewind to shift cmd pos copMove(pCopList, pManager->pCopBlock, &g_pCustom->bplcon1, uwShift); - for(i = 0; i != pManager->pBuffer->Depth; ++i) { - ulPlaneAddr = ((ULONG)pManager->pBuffer->Planes[i]) + ulBplOffs; + for(i = 0; i != pManager->pFront->Depth; ++i) { + ulPlaneAddr = ((ULONG)pManager->pFront->Planes[i]) + ulBplOffs; copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } From f6ea5b684c0bb754cc3cd87da407363b47215fd2 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 6 May 2018 13:30:04 +0200 Subject: [PATCH 02/56] Manager operates on back bfr and it's valid even on single buffering --- src/ace/managers/viewport/simplebuffer.c | 27 +++++++++++++++--------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index df2b1a7b..39dc1d7f 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -187,7 +187,7 @@ tSimpleBufferManager *simpleBufferCreate( } simpleBufferSetFront(pManager, pFront); - simpleBufferSetBack(pManager, pBack); + simpleBufferSetBack(pManager, pBack == 0 ? pFront : pBack); // Add manager to VPort vPortAddManager(pVPort, (tVpManager*)pManager); @@ -196,12 +196,12 @@ tSimpleBufferManager *simpleBufferCreate( return pManager; fail: + if(pBack && pBack != pFront) { + bitmapDestroy(pBack); + } if(pFront) { bitmapDestroy(pFront); } - if(pBack) { - bitmapDestroy(pBack); - } if(pManager) { memFree(pManager, sizeof(tSimpleBufferManager)); } @@ -216,10 +216,10 @@ tSimpleBufferManager *simpleBufferCreate( void simpleBufferDestroy(tSimpleBufferManager *pManager) { logBlockBegin("simpleBufferDestroy()"); logWrite("Destroying bitmap...\n"); - bitmapDestroy(pManager->pFront); - if(pManager->pBack) { + if(pManager->pBack != pManager->pFront) { bitmapDestroy(pManager->pBack); } + bitmapDestroy(pManager->pFront); logWrite("Freeing mem...\n"); memFree(pManager, sizeof(tSimpleBufferManager)); logBlockEnd("simpleBufferDestroy()"); @@ -249,7 +249,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { ulBplOffs = (pCameraManager->uPos.sUwCoord.uwX >> 4) << 1; // Calculate Y movement - ulBplOffs += pManager->pFront->BytesPerRow*pCameraManager->uPos.sUwCoord.uwY; + ulBplOffs += pManager->pBack->BytesPerRow*pCameraManager->uPos.sUwCoord.uwY; // Copperlist - regen bitplane ptrs, update shift // TODO could be unified by using copSetMove in copBlock @@ -257,7 +257,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, uwShift); for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { - ulPlaneAddr = ((ULONG)pManager->pFront->Planes[i]) + ulBplOffs; + ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; copSetMove(&pCmdList[6 + i*2 + 0].sMove, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copSetMove(&pCmdList[6 + i*2 + 1].sMove, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } @@ -265,12 +265,19 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { else { pManager->pCopBlock->uwCurrCount = 4; // Rewind to shift cmd pos copMove(pCopList, pManager->pCopBlock, &g_pCustom->bplcon1, uwShift); - for(i = 0; i != pManager->pFront->Depth; ++i) { - ulPlaneAddr = ((ULONG)pManager->pFront->Planes[i]) + ulBplOffs; + for(i = 0; i != pManager->pBack->Depth; ++i) { + ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } } + + // Swap buffers if needed + if(pManager->pBack != pManager->pFront) { + tBitMap *pTmp = pManager->pBack; + pManager->pBack = pManager->pFront; + pManager->pFront = pTmp; + } } UBYTE simpleBufferIsRectVisible( From 18639c67f8d3e579b149fe9a4386ce3854e6eb5b Mon Sep 17 00:00:00 2001 From: KaiN Date: Mon, 7 May 2018 13:01:36 +0200 Subject: [PATCH 03/56] fixed reviewed stuff --- src/ace/managers/viewport/simplebuffer.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 39dc1d7f..47f623db 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -146,7 +146,7 @@ tSimpleBufferManager *simpleBufferCreate( uwBoundWidth, uwBoundHeight, pVPort->ubBPP, ubBitmapFlags ); - if(!pFront) { + if(!pBack) { logWrite("ERR: Can't alloc buffer bitmap!\n"); goto fail; } @@ -187,7 +187,7 @@ tSimpleBufferManager *simpleBufferCreate( } simpleBufferSetFront(pManager, pFront); - simpleBufferSetBack(pManager, pBack == 0 ? pFront : pBack); + simpleBufferSetBack(pManager, pBack ? pFront : pBack); // Add manager to VPort vPortAddManager(pVPort, (tVpManager*)pManager); @@ -202,12 +202,12 @@ tSimpleBufferManager *simpleBufferCreate( if(pFront) { bitmapDestroy(pFront); } + if(pManager && pManager->pCameraManager && isCameraCreated) { + cameraDestroy(pManager->pCameraManager); + } if(pManager) { memFree(pManager, sizeof(tSimpleBufferManager)); } - if(pManager->pCameraManager && isCameraCreated) { - cameraDestroy(pManager->pCameraManager); - } logBlockEnd("simpleBufferCreate()"); va_end(vaTags); return 0; From 0609870c2535dc9f002349623173e25934d462f9 Mon Sep 17 00:00:00 2001 From: KaiN Date: Mon, 7 May 2018 13:41:56 +0200 Subject: [PATCH 04/56] Fixed wrong logic with '== 0' ommited --- src/ace/managers/viewport/simplebuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 47f623db..c08652ed 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -187,7 +187,7 @@ tSimpleBufferManager *simpleBufferCreate( } simpleBufferSetFront(pManager, pFront); - simpleBufferSetBack(pManager, pBack ? pFront : pBack); + simpleBufferSetBack(pManager, pBack ? pBack : pFront); // Add manager to VPort vPortAddManager(pVPort, (tVpManager*)pManager); From 2dee8bf99788894711ca2dc2584a3a05ba889ad1 Mon Sep 17 00:00:00 2001 From: KaiN Date: Mon, 7 May 2018 17:45:08 +0200 Subject: [PATCH 05/56] Reduced ifs on simplebuffer fail --- src/ace/managers/viewport/simplebuffer.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index c08652ed..e7e9eecf 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -202,10 +202,10 @@ tSimpleBufferManager *simpleBufferCreate( if(pFront) { bitmapDestroy(pFront); } - if(pManager && pManager->pCameraManager && isCameraCreated) { - cameraDestroy(pManager->pCameraManager); - } if(pManager) { + if(pManager->pCameraManager && isCameraCreated) { + cameraDestroy(pManager->pCameraManager); + } memFree(pManager, sizeof(tSimpleBufferManager)); } logBlockEnd("simpleBufferCreate()"); From 4aa836b1bc0ed61ac8688df6f4600760cd3e4fed Mon Sep 17 00:00:00 2001 From: KaiN Date: Thu, 17 May 2018 17:35:09 +0200 Subject: [PATCH 06/56] Added support for OS takeover on VBCC --- include/ace/types.h | 5 +++-- makefile | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/ace/types.h b/include/ace/types.h index 5b147f2b..b7c4997a 100644 --- a/include/ace/types.h +++ b/include/ace/types.h @@ -29,10 +29,11 @@ typedef int32_t LONG; #define INTERRUPT __amigainterrupt __saveds #define INTERRUPT_END do {} while(0) #elif defined(CONFIG_SYSTEM_OS_TAKEOVER) -#error "Unimplemented OS takeover for VBCC!" +#define INTERRUPT +#define INTERRUPT_END do {} while(0) #endif -#define HWINTERRUPT __interrupt +#define HWINTERRUPT __interrupt __saveds #define UNUSED_ARG #define REGARG(arg, reg) __reg(reg) arg #define CHIP __chip diff --git a/makefile b/makefile index 85826da5..e30e3490 100644 --- a/makefile +++ b/makefile @@ -35,7 +35,7 @@ endif CC_FLAGS_COMMON = -I$(ACE_INC_DIR) -DAMIGA $(TARGET_DEFINES) ifeq ($(ACE_CC), vc) - CC_FLAGS = $(CC_FLAGS_COMMON) +kick13 -c99 + CC_FLAGS = +kick13 -c99 $(CC_FLAGS_COMMON) ACE_AS = vc AS_FLAGS = +kick13 -c OBJDUMP = From e42ad37b1aa4eaac0b67623d9215035b2e341003 Mon Sep 17 00:00:00 2001 From: KaiN Date: Thu, 17 May 2018 17:37:21 +0200 Subject: [PATCH 07/56] reordered compiler ifdefs, cleanup --- include/ace/types.h | 26 +++++++++++++------------- include/ace/utils/custom.h | 6 +----- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/include/ace/types.h b/include/ace/types.h index b7c4997a..790d1f35 100644 --- a/include/ace/types.h +++ b/include/ace/types.h @@ -24,7 +24,19 @@ typedef int16_t WORD; typedef int32_t LONG; #endif // AMIGA -#if defined(__VBCC__) +#if defined(__CODE_CHECKER__) +// My realtime source checker has problems with GCC asm() expanded from REGARG() +// being in fn arg list, so I just use blank defines for it +#define INTERRUPT +#define INTERRUPT_END do {} while(0) +#define HWINTERRUPT +#define UNUSED_ARG __attribute__((unused)) +#define REGARG(arg, x) arg +#define CHIP +#define FAR +#define FN_HOTSPOT +#define FN_COLDSPOT +#elif defined(__VBCC__) #if defined(CONFIG_SYSTEM_OS_FRIENDLY) #define INTERRUPT __amigainterrupt __saveds #define INTERRUPT_END do {} while(0) @@ -59,18 +71,6 @@ typedef int32_t LONG; #define FAR __far #define FN_HOTSPOT __attribute__((hot)) #define FN_COLDSPOT __attribute__((cold)) -#elif defined(__CODE_CHECKER__) -// My realtime source checker has problems with GCC asm() expanded from REGARG() -// being in fn arg list, so I just use blank defines for it -#define INTERRUPT -#define INTERRUPT_END do {} while(0) -#define HWINTERRUPT -#define UNUSED_ARG __attribute__((unused)) -#define REGARG(arg, x) arg -#define CHIP -#define FAR -#define FN_HOTSPOT -#define FN_COLDSPOT #else #error "Compiler not supported!" #endif diff --git a/include/ace/utils/custom.h b/include/ace/utils/custom.h index 614d2549..660b20be 100644 --- a/include/ace/utils/custom.h +++ b/include/ace/utils/custom.h @@ -9,13 +9,9 @@ #ifdef AMIGA -/** - * Quick custom chipset struct include - * Moved to separate file cuz multiple pasting of extern custom is messy - */ +#include // Custom chip register addresses #define REGPTR volatile * const -#include // Custom chip register addresses typedef struct Custom tCustom; From fd79bf115f5290e34bd63430d688023b457f725c Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 23 May 2018 18:59:06 +0200 Subject: [PATCH 08/56] Showcase support for dbl buffering --- showcase/src/menu/menu.c | 18 +++++++++--------- showcase/src/test/blit.c | 4 ++-- showcase/src/test/blitsmalldest.c | 4 ++-- showcase/src/test/copper.c | 10 +++++----- showcase/src/test/font.c | 14 +++++++------- showcase/src/test/interleaved.c | 2 +- showcase/src/test/lines.c | 16 ++++++++-------- 7 files changed, 34 insertions(+), 34 deletions(-) diff --git a/showcase/src/menu/menu.c b/showcase/src/menu/menu.c index ac251fbe..12545224 100644 --- a/showcase/src/menu/menu.c +++ b/showcase/src/menu/menu.c @@ -64,7 +64,7 @@ void gsMenuCreate(void) { 160, 100, 10, 2, s_pMenuFont, FONT_HCENTER|FONT_COOKIE|FONT_SHADOW, 1, 2, 3, - s_pMenuBfr->pBuffer + s_pMenuBfr->pBack ); menuShowMain(); @@ -145,7 +145,7 @@ void menuDrawBg(void) { for(uwY = 0; uwY <= s_pMenuBfr->uBfrBounds.sUwCoord.uwY - 16; uwY += 16) { for(uwX = 0; uwX <= s_pMenuBfr->uBfrBounds.sUwCoord.uwX - 16; uwX += 16) { UBYTE ubColor = isOdd ? 0 : 4; - blitRect(s_pMenuBfr->pBuffer, uwX, uwY, 16, 16, ubColor); + blitRect(s_pMenuBfr->pBack, uwX, uwY, 16, 16, ubColor); isOdd = !isOdd; } isOdd = !isOdd; @@ -154,10 +154,10 @@ void menuDrawBg(void) { // Draw border UWORD uwMaxX = s_pMenuBfr->uBfrBounds.sUwCoord.uwX-1; UWORD uwMaxY = s_pMenuBfr->uBfrBounds.sUwCoord.uwY-1; - blitLine(s_pMenuBfr->pBuffer, 0, 0, uwMaxX, 0, 1, 0xFFFF, 0); - blitLine(s_pMenuBfr->pBuffer, 0, uwMaxY, uwMaxX, uwMaxY, 1, 0xFFFF, 0); - blitLine(s_pMenuBfr->pBuffer, 0, 0, 0, uwMaxY, 1, 0xFFFF, 0); - blitLine(s_pMenuBfr->pBuffer, uwMaxX, 0, uwMaxX, uwMaxY, 1, 0xFFFF, 0); + blitLine(s_pMenuBfr->pBack, 0, 0, uwMaxX, 0, 1, 0xFFFF, 0); + blitLine(s_pMenuBfr->pBack, 0, uwMaxY, uwMaxX, uwMaxY, 1, 0xFFFF, 0); + blitLine(s_pMenuBfr->pBack, 0, 0, 0, uwMaxY, 1, 0xFFFF, 0); + blitLine(s_pMenuBfr->pBack, uwMaxX, 0, uwMaxX, uwMaxY, 1, 0xFFFF, 0); logBlockEnd("menuDrawBg()"); } @@ -169,7 +169,7 @@ void menuShowMain(void) { // Draw BG menuDrawBg(); fontDrawStr( - s_pMenuBfr->pBuffer, s_pMenuFont, + s_pMenuBfr->pBack, s_pMenuFont, s_pMenuBfr->uBfrBounds.sUwCoord.uwX >> 1, 80, "ACE Showcase", 1, FONT_COOKIE|FONT_CENTER|FONT_SHADOW ); @@ -209,7 +209,7 @@ void menuShowTests(void) { // Draw BG menuDrawBg(); fontDrawStr( - s_pMenuBfr->pBuffer, s_pMenuFont, + s_pMenuBfr->pBack, s_pMenuFont, s_pMenuBfr->uBfrBounds.sUwCoord.uwX >> 1, 80, "Tests", 1, FONT_COOKIE|FONT_CENTER|FONT_SHADOW ); @@ -270,7 +270,7 @@ void menuShowExamples(void) { // Draw BG menuDrawBg(); fontDrawStr( - s_pMenuBfr->pBuffer, s_pMenuFont, + s_pMenuBfr->pBack, s_pMenuFont, s_pMenuBfr->uBfrBounds.sUwCoord.uwX >> 1, 80, "Examples", 1, FONT_COOKIE|FONT_CENTER|FONT_SHADOW ); diff --git a/showcase/src/test/blit.c b/showcase/src/test/blit.c index 12ce7393..9f14c197 100644 --- a/showcase/src/test/blit.c +++ b/showcase/src/test/blit.c @@ -68,7 +68,7 @@ void gsTestBlitLoop(void) { //TODO: Restore BG } else { - blitRect(s_pTestBlitBfr->pBuffer, s_uwX, s_uwY, 16, 16, 0); + blitRect(s_pTestBlitBfr->pBack, s_uwX, s_uwY, 16, 16, 0); } // Update type @@ -161,7 +161,7 @@ void gsTestBlitLoop(void) { //TODO: Save BG beneath new bob } // if(s_ubType & TYPE_RECT) { - blitRect(s_pTestBlitBfr->pBuffer, s_uwX, s_uwY, 16, 16, 3); + blitRect(s_pTestBlitBfr->pBack, s_uwX, s_uwY, 16, 16, 3); // } vPortWaitForEnd(s_pTestBlitVPort); } diff --git a/showcase/src/test/blitsmalldest.c b/showcase/src/test/blitsmalldest.c index bb1c4414..afe3d3a4 100644 --- a/showcase/src/test/blitsmalldest.c +++ b/showcase/src/test/blitsmalldest.c @@ -87,13 +87,13 @@ void gsTestBlitSmallDestLoop(void) { if(bUpdate && ubFrameIdx + bUpdate > -1 && ubFrameIdx + bUpdate < 16) { ubFrameIdx += bUpdate; blitRect( - s_pTestBlitBfr->pBuffer, 0, 0, + s_pTestBlitBfr->pBack, 0, 0, s_pTestBlitBfr->uBfrBounds.sUwCoord.uwX, s_pTestBlitBfr->uBfrBounds.sUwCoord.uwY, 0 ); blitCopy(s_pRefBitmap, ubFrameIdx, ubFrameIdx*32, s_pDstBitmap, 0, 0, 32, 32, 0xCA, 0xFF); - blitCopyAligned(s_pDstBitmap, 0, 0, s_pTestBlitBfr->pBuffer, 16, 16, 32, 32); + blitCopyAligned(s_pDstBitmap, 0, 0, s_pTestBlitBfr->pBack, 16, 16, 32, 32); } vPortWaitForEnd(s_pTestBlitVPort); diff --git a/showcase/src/test/copper.c b/showcase/src/test/copper.c index 580553de..90f30c13 100644 --- a/showcase/src/test/copper.c +++ b/showcase/src/test/copper.c @@ -87,25 +87,25 @@ void gsTestCopperCreate(void) { UWORD uwMaxX = s_pTestCopperBfr->uBfrBounds.sUwCoord.uwX-1; UWORD uwMaxY = s_pTestCopperBfr->uBfrBounds.sUwCoord.uwY-1; blitRect( - s_pTestCopperBfr->pBuffer, 0,0, + s_pTestCopperBfr->pBack, 0,0, s_pTestCopperBfr->uBfrBounds.sUwCoord.uwX, s_pTestCopperBfr->uBfrBounds.sUwCoord.uwY, TEST_COPPER_COLOR_INSIDE ); blitLine( - s_pTestCopperBfr->pBuffer, 0, 0, uwMaxX, 0, + s_pTestCopperBfr->pBack, 0, 0, uwMaxX, 0, TEST_COPPER_COLOR_BORDER, 0xFFFF, 0 ); blitLine( - s_pTestCopperBfr->pBuffer, 0, uwMaxY, uwMaxX, uwMaxY, + s_pTestCopperBfr->pBack, 0, uwMaxY, uwMaxX, uwMaxY, TEST_COPPER_COLOR_BORDER, 0xFFFF, 0 ); blitLine( - s_pTestCopperBfr->pBuffer, 0, 0, 0, uwMaxY, + s_pTestCopperBfr->pBack, 0, 0, 0, uwMaxY, TEST_COPPER_COLOR_BORDER, 0xFFFF, 0 ); blitLine( - s_pTestCopperBfr->pBuffer, uwMaxX, 0, uwMaxX, uwMaxY, + s_pTestCopperBfr->pBack, uwMaxX, 0, uwMaxX, uwMaxY, TEST_COPPER_COLOR_BORDER, 0xFFFF, 0 ); diff --git a/showcase/src/test/font.c b/showcase/src/test/font.c index 73c4b601..cf94c6ea 100644 --- a/showcase/src/test/font.c +++ b/showcase/src/test/font.c @@ -156,7 +156,7 @@ void testFontDrawTable(void) { // Background blitRect( - s_pTestFontBfr->pBuffer, 0,0, + s_pTestFontBfr->pBack, 0,0, s_pTestFontBfr->uBfrBounds.sUwCoord.uwX, s_pTestFontBfr->uBfrBounds.sUwCoord.uwY, 2 ); @@ -164,14 +164,14 @@ void testFontDrawTable(void) { UWORD uwMaxY = s_pTestFontBfr->uBfrBounds.sUwCoord.uwY-1; for(i = 0; i < 8; ++i) { // Vertical lines - blitLine(s_pTestFontBfr->pBuffer, 40*i, 0, 40*i, uwMaxY, 0, 0xFFFF, 0); + blitLine(s_pTestFontBfr->pBack, 40*i, 0, 40*i, uwMaxY, 0, 0xFFFF, 0); // Horizontal lines - blitLine(s_pTestFontBfr->pBuffer, 0, 32*i, uwMaxX, 32*i, 0, 0xFFFF, 0); + blitLine(s_pTestFontBfr->pBack, 0, 32*i, uwMaxX, 32*i, 0, 0xFFFF, 0); } // Last V line - blitLine(s_pTestFontBfr->pBuffer, uwMaxX, 0, uwMaxX, uwMaxY, 0, 0xFFFF, 0); + blitLine(s_pTestFontBfr->pBack, uwMaxX, 0, uwMaxX, uwMaxY, 0, 0xFFFF, 0); // Last H line - blitLine(s_pTestFontBfr->pBuffer, 0, uwMaxY, uwMaxX, uwMaxY, 0, 0xFFFF, 0); + blitLine(s_pTestFontBfr->pBack, 0, uwMaxY, uwMaxX, uwMaxY, 0, 0xFFFF, 0); for(i = 0; i < 64; ++i) { UBYTE ubCharIdx = s_ubPage*64+i; @@ -184,7 +184,7 @@ void testFontDrawTable(void) { sprintf(szCodeBfr, "%c", ubCharIdx); fontFillTextBitMap(pFont, s_pGlyph, szCodeBfr); fontDrawTextBitMap( - s_pTestFontBfr->pBuffer, s_pGlyph, + s_pTestFontBfr->pBack, s_pGlyph, (i/8)*40+40/2, (i%8)*32+(32/2), 3, FONT_CENTER|FONT_COOKIE ); @@ -194,7 +194,7 @@ void testFontDrawTable(void) { sprintf(szCodeBfr, "%02X", ubCharIdx); fontFillTextBitMap(s_pFontUI, s_pGlyphCode, szCodeBfr); fontDrawTextBitMap( - s_pTestFontBfr->pBuffer, s_pGlyphCode, + s_pTestFontBfr->pBack, s_pGlyphCode, (i/8)*40+40/2, (i%8)*32+32-2, 0, FONT_HCENTER|FONT_BOTTOM|FONT_COOKIE ); diff --git a/showcase/src/test/interleaved.c b/showcase/src/test/interleaved.c index 96565d03..90373f30 100644 --- a/showcase/src/test/interleaved.c +++ b/showcase/src/test/interleaved.c @@ -35,7 +35,7 @@ void gsTestInterleavedCreate(void) { "data/amidb32.plt", s_pTestInterleavedVPort->pPalette, 1 << SHOWCASE_BPP ); bitmapLoadFromFile( - s_pTestInterleavedBfr->pBuffer, "data/32c_pal_interleaved.bm", 0, 0 + s_pTestInterleavedBfr->pBack, "data/32c_pal_interleaved.bm", 0, 0 ); systemUnuse(); diff --git a/showcase/src/test/lines.c b/showcase/src/test/lines.c index ec340dce..41cae27e 100644 --- a/showcase/src/test/lines.c +++ b/showcase/src/test/lines.c @@ -43,13 +43,13 @@ void gsTestLinesCreate(void) { UWORD uwPattern = 0xFFFF; - blitLine(s_pBfrManager->pBuffer, uwMinX, uwMinY, uwMinX, uwMaxY, 1, uwPattern, 0); - blitLine(s_pBfrManager->pBuffer, uwMaxX, uwMinY, uwMaxX, uwMaxY, 1, uwPattern, 0); - blitLine(s_pBfrManager->pBuffer, uwMinX, uwMinY, uwMaxX, uwMinY, 1, uwPattern, 0); - blitLine(s_pBfrManager->pBuffer, uwMinX, uwMaxY, uwMaxX, uwMaxY, 1, uwPattern, 0); + blitLine(s_pBfrManager->pBack, uwMinX, uwMinY, uwMinX, uwMaxY, 1, uwPattern, 0); + blitLine(s_pBfrManager->pBack, uwMaxX, uwMinY, uwMaxX, uwMaxY, 1, uwPattern, 0); + blitLine(s_pBfrManager->pBack, uwMinX, uwMinY, uwMaxX, uwMinY, 1, uwPattern, 0); + blitLine(s_pBfrManager->pBack, uwMinX, uwMaxY, uwMaxX, uwMaxY, 1, uwPattern, 0); - blitRect(s_pBfrManager->pBuffer, 32, 32, 32, 32, 2); - blitLine(s_pBfrManager->pBuffer, 16, 16, 80, 80, 1, uwPattern, 0); + blitRect(s_pBfrManager->pBack, 32, 32, 32, 32, 2); + blitLine(s_pBfrManager->pBack, 16, 16, 80, 80, 1, uwPattern, 0); // Prepare circle vertex positions const uint8_t uwVertCount = 12; @@ -68,7 +68,7 @@ void gsTestLinesCreate(void) { UBYTE v; for(v = 0; v < uwVertCount-1; ++v) { blitLine( - s_pBfrManager->pBuffer, + s_pBfrManager->pBack, pVerts[v].sUwCoord.uwX, pVerts[v].sUwCoord.uwY, pVerts[v+1].sUwCoord.uwX, pVerts[v+1].sUwCoord.uwY, 2, uwPattern, 0 @@ -76,7 +76,7 @@ void gsTestLinesCreate(void) { } // Close the circle blitLine( - s_pBfrManager->pBuffer, + s_pBfrManager->pBack, pVerts[v].sUwCoord.uwX, pVerts[v].sUwCoord.uwY, pVerts[0].sUwCoord.uwX, pVerts[0].sUwCoord.uwY, 2, uwPattern, 0 From f9ccc5bef92b9b5afea4113ab3d3ae8deab6e226 Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 23 May 2018 18:59:58 +0200 Subject: [PATCH 09/56] reformat, fixed system usage in bitmap fns --- src/ace/managers/viewport/simplebuffer.c | 10 +++------ src/ace/utils/bitmap.c | 27 +++++++++++------------- 2 files changed, 15 insertions(+), 22 deletions(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index e7e9eecf..5f772c81 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -97,9 +97,7 @@ void simpleBufferSetFront(tSimpleBufferManager *pManager, tBitMap *pFront) { logBlockEnd("simplebufferSetFront()"); } -tSimpleBufferManager *simpleBufferCreate( - void *pTags, ... -) { +tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { va_list vaTags; tCopList *pCopList; tSimpleBufferManager *pManager; @@ -132,8 +130,7 @@ tSimpleBufferManager *simpleBufferCreate( ubBitmapFlags = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_BITMAP_FLAGS, BMF_CLEAR); logWrite("Bounds: %ux%u\n", uwBoundWidth, uwBoundHeight); pFront = bitmapCreate( - uwBoundWidth, uwBoundHeight, - pVPort->ubBPP, ubBitmapFlags + uwBoundWidth, uwBoundHeight, pVPort->ubBPP, ubBitmapFlags ); if(!pFront) { logWrite("ERR: Can't alloc buffer bitmap!\n"); @@ -143,8 +140,7 @@ tSimpleBufferManager *simpleBufferCreate( UBYTE isDblBfr = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_IS_DBLBUF, 0); if(isDblBfr) { pBack = bitmapCreate( - uwBoundWidth, uwBoundHeight, - pVPort->ubBPP, ubBitmapFlags + uwBoundWidth, uwBoundHeight, pVPort->ubBPP, ubBitmapFlags ); if(!pBack) { logWrite("ERR: Can't alloc buffer bitmap!\n"); diff --git a/src/ace/utils/bitmap.c b/src/ace/utils/bitmap.c index b38d80a9..b160913c 100644 --- a/src/ace/utils/bitmap.c +++ b/src/ace/utils/bitmap.c @@ -331,28 +331,22 @@ void bitmapSave(const tBitMap *pBitMap, const char *szPath) { fileClose(pFile); logBlockEnd("bitmapSave()"); + systemUnuse(); } void bitmapSaveBmp( const tBitMap *pBitMap, const UWORD *pPalette, const char *szFilePath ) { - UWORD uwOut; - UBYTE ubOut; - ULONG ulOut; - UWORD c; - FILE *pOut; - UWORD uwX, uwY; - UBYTE pIndicesChunk[16]; - UWORD uwWidth; // TODO: EHB support - uwWidth = bitmapGetByteWidth(pBitMap) << 3; - pOut = fileOpen(szFilePath, "w"); + systemUse(); + UWORD uwWidth = bitmapGetByteWidth(pBitMap) << 3; + FILE *pOut = fileOpen(szFilePath, "w"); // BMP header fileWrite(pOut, "BM", 2); - ulOut = endianIntel32((pBitMap->BytesPerRow<<3) * pBitMap->Rows + 14+40+256*4); + ULONG ulOut = endianIntel32((pBitMap->BytesPerRow<<3) * pBitMap->Rows + 14+40+256*4); fileWrite(pOut, &ulOut, sizeof(ULONG)); // BMP file size ulOut = 0; @@ -372,7 +366,7 @@ void bitmapSaveBmp( ulOut = endianIntel32(pBitMap->Rows); fileWrite(pOut, &ulOut, sizeof(ULONG)); // Image height - uwOut = endianIntel16(1); + UWORD uwOut = endianIntel16(1); fileWrite(pOut, &uwOut, sizeof(UWORD)); // Color plane count uwOut = endianIntel16(8); @@ -397,8 +391,9 @@ void bitmapSaveBmp( fileWrite(pOut, &ulOut, sizeof(ULONG)); // Number of important colors - all // Global palette + UWORD c; for(c = 0; c != (1 << pBitMap->Depth); ++c) { - ubOut = pPalette[c] & 0xF; + UBYTE ubOut = pPalette[c] & 0xF; ubOut |= ubOut << 4; fileWrite(pOut, &ubOut, sizeof(UBYTE)); // B @@ -421,12 +416,14 @@ void bitmapSaveBmp( } // Image data - for(uwY = pBitMap->Rows; uwY--;) { + UBYTE pIndicesChunk[16]; + for(UWORD uwY = pBitMap->Rows; uwY--;) { + UWORD uwX; for(uwX = 0; uwX < uwWidth; uwX += 16) { chunkyFromPlanar16(pBitMap, uwX, uwY, pIndicesChunk); fileWrite(pOut, pIndicesChunk, 16*sizeof(UBYTE)); } - ubOut = 0; + UBYTE ubOut = 0; while(uwX & 0x3) {// 4-byte row padding fileWrite(pOut, &ubOut, sizeof(UBYTE)); ++uwX; From ed6dec2dbea6056a376e3ad63ebdbb3d8446d307 Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 23 May 2018 19:00:29 +0200 Subject: [PATCH 10/56] commented out -fverbose-asm, left so it can become if-enabled later --- makefile | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index e30e3490..fcce2b9c 100644 --- a/makefile +++ b/makefile @@ -42,7 +42,8 @@ ifeq ($(ACE_CC), vc) else ifeq ($(ACE_CC), m68k-amigaos-gcc) CC_FLAGS_NO_O = $(CC_FLAGS_COMMON) -std=gnu11 -DAMIGA \ -noixemul -Wall -Wextra -fomit-frame-pointer - CC_FLAGS = $(CC_FLAGS_NO_O) $(TARGET_DEFINES) -O3 -fverbose-asm + CC_FLAGS = $(CC_FLAGS_NO_O) $(TARGET_DEFINES) -O3 + #-fverbose-asm ACE_AS = vasmm68k_mot AS_FLAGS = -quiet -x -m68010 -Faout -ID:\prg\kompilatory\bebbo\m68k-amigaos\sys-include OBJDUMP = m68k-amigaos-objdump -S -l -D $@ > $@.dasm From b248461a3472ee7a5bb0f2b19d5eaef457e3ef8d Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 30 May 2018 20:58:04 +0200 Subject: [PATCH 11/56] Remove excessive logging & whitespace, better forloop conditions --- src/ace/managers/viewport/simplebuffer.c | 17 +++++++++-------- src/ace/utils/dir.c | 3 --- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 5f772c81..2ed7fbdd 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -57,7 +57,10 @@ void simpleBufferSetFront(tSimpleBufferManager *pManager, tBitMap *pFront) { // copperlist must be shaped here. // WAIT is calc'd in same way as in copBlockCreate in simpleBufferCreate(). tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; - logWrite("Setting copperlist %p at offs %u: %p\n", pCopList->pBackBfr, pManager->uwCopperOffset, pCmdList); + logWrite( + "Setting copperlist %p at offs %u\n", + pCopList->pBackBfr, pManager->uwCopperOffset + ); copSetWait(&pCmdList[0].sWait, 0xE2-7*4, pManager->sCommon.pVPort->uwOffsY + 0x2C-1); copSetMove(&pCmdList[1].sMove, &g_pCustom->ddfstop, 0x00D0); // Data fetch copSetMove(&pCmdList[2].sMove, &g_pCustom->ddfstrt, uwDDfStrt); @@ -66,7 +69,7 @@ void simpleBufferSetFront(tSimpleBufferManager *pManager, tBitMap *pFront) { copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, 0); // Shift: 0 UBYTE i; ULONG ulPlaneAddr; - for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { + for (i = 0; i < pManager->sCommon.pVPort->ubBPP; ++i) { ulPlaneAddr = (ULONG)pManager->pFront->Planes[i]; copSetMove(&pCmdList[6 + i*2 + 0].sMove, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copSetMove(&pCmdList[6 + i*2 + 1].sMove, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); @@ -86,10 +89,8 @@ void simpleBufferSetFront(tSimpleBufferManager *pManager, tBitMap *pFront) { copMove(pCopList, pBlock, &g_pCustom->bpl1mod, uwModulo); // Bitplane modulo copMove(pCopList, pBlock, &g_pCustom->bpl2mod, uwModulo); copMove(pCopList, pBlock, &g_pCustom->bplcon1, 0); // Shift: 0 - UBYTE i; - ULONG ulPlaneAddr; - for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { - ulPlaneAddr = (ULONG)pManager->pFront->Planes[i]; + for (UBYTE i = 0; i < pManager->sCommon.pVPort->ubBPP; ++i) { + ULONG ulPlaneAddr = (ULONG)pManager->pFront->Planes[i]; copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } @@ -252,7 +253,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { if(pManager->ubFlags & SIMPLEBUFFER_FLAG_COPLIST_RAW) { tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, uwShift); - for (i = 0; i != pManager->sCommon.pVPort->ubBPP; ++i) { + for (i = 0; i < pManager->sCommon.pVPort->ubBPP; ++i) { ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; copSetMove(&pCmdList[6 + i*2 + 0].sMove, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copSetMove(&pCmdList[6 + i*2 + 1].sMove, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); @@ -261,7 +262,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { else { pManager->pCopBlock->uwCurrCount = 4; // Rewind to shift cmd pos copMove(pCopList, pManager->pCopBlock, &g_pCustom->bplcon1, uwShift); - for(i = 0; i != pManager->pBack->Depth; ++i) { + for(i = 0; i < pManager->pBack->Depth; ++i) { ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); diff --git a/src/ace/utils/dir.c b/src/ace/utils/dir.c index 4070a602..35b90148 100644 --- a/src/ace/utils/dir.c +++ b/src/ace/utils/dir.c @@ -19,7 +19,6 @@ tDir *dirOpen(const char *szPath) { systemUnuse(); return 0; } - logWrite("dirOpenOk\n"); systemUnuse(); return pDir; } @@ -34,7 +33,6 @@ UBYTE dirRead(tDir *pDir, char *szFileName, UWORD uwFileNameMax) { strncpy(szFileName, pDir->sFileBlock.fib_FileName, uwFileNameMax-1); szFileName[uwFileNameMax-1] = '\0'; - logWrite("dirReadOk %s\n", szFileName); systemUnuse(); return 1; } @@ -43,7 +41,6 @@ void dirClose(tDir *pDir) { systemUse(); UnLock(pDir->pLock); memFree(pDir, sizeof(tDir)); - logWrite("dirCloseOk\n"); systemUnuse(); } From 8d5ad78b4e8bc8e1aa6afee1f4fd0fb55fe4c43b Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 30 May 2018 20:58:18 +0200 Subject: [PATCH 12/56] Added stack trashing detection in generic main --- include/ace/generic/main.h | 18 ++++++++++++++++++ makefile | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/include/ace/generic/main.h b/include/ace/generic/main.h index 033f4d9a..c2e0d916 100644 --- a/include/ace/generic/main.h +++ b/include/ace/generic/main.h @@ -19,6 +19,24 @@ void genericCreate(void); void genericProcess(void); void genericDestroy(void); +#if defined(__GNUC__) +#include + +#if UINT32_MAX == UINTPTR_MAX +#define STACK_CHK_GUARD 0xe2dee396 +#else +#define STACK_CHK_GUARD 0x595e9fbd94fda766 +#endif + +uintptr_t __stack_chk_guard = STACK_CHK_GUARD; + +__attribute__((noreturn)) +void __stack_chk_fail(void) { + logWrite("ERR: STACK SMASHED\n"); + while(1) {} +} +#endif + int main(void) { systemCreate(); memCreate(); diff --git a/makefile b/makefile index fcce2b9c..e152e961 100644 --- a/makefile +++ b/makefile @@ -40,9 +40,9 @@ ifeq ($(ACE_CC), vc) AS_FLAGS = +kick13 -c OBJDUMP = else ifeq ($(ACE_CC), m68k-amigaos-gcc) - CC_FLAGS_NO_O = $(CC_FLAGS_COMMON) -std=gnu11 -DAMIGA \ - -noixemul -Wall -Wextra -fomit-frame-pointer CC_FLAGS = $(CC_FLAGS_NO_O) $(TARGET_DEFINES) -O3 + CC_FLAGS_NO_O = $(CC_FLAGS_COMMON) -std=gnu11 -noixemul -Wall -Wextra \ + -fomit-frame-pointer -fstack-protector-all #-fverbose-asm ACE_AS = vasmm68k_mot AS_FLAGS = -quiet -x -m68010 -Faout -ID:\prg\kompilatory\bebbo\m68k-amigaos\sys-include From b31e394568d5c18b827aa93bef7aeaafed7d3a4f Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 17 Jun 2018 11:41:35 +0200 Subject: [PATCH 13/56] This is redundant --- src/ace/managers/memory.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/ace/managers/memory.c b/src/ace/managers/memory.c index bf030d99..565ab630 100644 --- a/src/ace/managers/memory.c +++ b/src/ace/managers/memory.c @@ -163,12 +163,10 @@ void *_memAllocDbg(ULONG ulSize, ULONG ulFlags, UWORD uwLine, char *szFile) { s_ulChipPeakUsage, s_ulFastPeakUsage ); #ifdef AMIGA - systemUse(); filePrintf( s_pMemLog, "Largest available chunk of given type: %lu\n", AvailMem(ulFlags | MEMF_LARGEST) ); - systemUnuse(); #endif // AMIGA return 0; } From d7564fdc8ad971bbd40c58f0fc65d7417e0fc0eb Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 17 Jun 2018 11:41:57 +0200 Subject: [PATCH 14/56] Added chunky <-> bitmap conversion --- include/ace/utils/chunky.h | 32 ++++++++++++++++++++++++++++++++ src/ace/utils/chunky.c | 27 +++++++++++++++++++++++++++ 2 files changed, 59 insertions(+) diff --git a/include/ace/utils/chunky.h b/include/ace/utils/chunky.h index bfcddcf9..0c68bd72 100644 --- a/include/ace/utils/chunky.h +++ b/include/ace/utils/chunky.h @@ -92,4 +92,36 @@ void chunkyToPlanar16(const UBYTE *pIn, UWORD uwX, UWORD uwY, tBitMap *pOut); */ void chunkyToPlanar(const UBYTE ubIn, UWORD uwX, UWORD uwY, tBitMap *pOut); +/** + * @brief Reads given portion of bitmap to chunky buffer. + * + * @param pBitmap Source bitmap image. + * @param pChunky Desitination chunky buffer. + * @param uwSrcOffsX X offset of conversion area, in pixels. + * @param uwSrcOffsY Y offset of conversion area, in pixels. + * @param uwWidth Width of conversion area, in pixels. + * @param uwHeight Height of conversion area, in pixels. + * + * @see chunkyToBitmap + */ +void chunkyFromBitmap( + const tBitMap *pBitmap, UBYTE *pChunky, + UWORD uwSrcOffsX, UWORD uwSrcOffsY, UWORD uwWidth, UWORD uwHeight +); + +/** + * @brief Writes given chunky buffer into specified portion of bitmap + * + * @param pChunky Source chunky data buffer. + * @param pBitmap Destination bitmap. + * @param uwDstOffsX X offset of conversion area, in pixels. + * @param uwDstOffsY Y offset of conversion area, in pixels. + * @param uwWidth Width of conversion area, in pixels. + * @param uwHeight Height of conversion area, in pixels. + */ +void chunkyToBitmap( + const UBYTE *pChunky, tBitMap *pBitmap, + UWORD uwDstOffsX, UWORD uwDstOffsY, UWORD uwWidth, UWORD uwHeight +); + #endif // _ACE_UTILS_CHUNKY_H_ diff --git a/src/ace/utils/chunky.c b/src/ace/utils/chunky.c index db8801e6..e8c4d938 100644 --- a/src/ace/utils/chunky.c +++ b/src/ace/utils/chunky.c @@ -90,3 +90,30 @@ void chunkyRotate( } } } + +void chunkyFromBitmap( + const tBitMap *pBitmap, UBYTE *pChunky, + UWORD uwSrcOffsX, UWORD uwSrcOffsY, UWORD uwWidth, UWORD uwHeight +) { + for(UWORD y = 0; y < uwHeight; ++y) { + for(UWORD x = 0; x < uwWidth; x += 16) { + chunkyFromPlanar16( + pBitmap, uwSrcOffsX + x, uwSrcOffsY + y, &pChunky[y*uwWidth + x] + ); + } + } +} + +void chunkyToBitmap( + const UBYTE *pChunky, tBitMap *pBitmap, + UWORD uwDstOffsX, UWORD uwDstOffsY, UWORD uwWidth, UWORD uwHeight +) { + for(UWORD y = 0; y < uwHeight; ++y) { + for(UWORD x = 0; x < uwWidth; x += 16) + chunkyToPlanar16( + &pChunky[(y*uwWidth) + x], + uwDstOffsX + x, uwDstOffsY + y, + pBitmap + ); + } +} From 1f8f29505842ac1b8cdc864ed1d8d54bb3fbc5a8 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 8 Sep 2018 13:34:13 +0200 Subject: [PATCH 15/56] reformat, removed redundant includes --- include/ace/managers/viewport/simplebuffer.h | 4 +--- src/ace/managers/viewport/simplebuffer.c | 13 ++++++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/include/ace/managers/viewport/simplebuffer.h b/include/ace/managers/viewport/simplebuffer.h index 17215502..9ef8cf21 100644 --- a/include/ace/managers/viewport/simplebuffer.h +++ b/include/ace/managers/viewport/simplebuffer.h @@ -13,10 +13,8 @@ */ #include -#include -#include -#include #include +#include #include // vPort ptr diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 2ed7fbdd..af801eca 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -4,6 +4,7 @@ #include #include +#include #ifdef AMIGA @@ -126,9 +127,15 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { logWrite("Parent VPort: %p\n", pVPort); // Buffer bitmap - uwBoundWidth = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_BOUND_WIDTH, pVPort->uwWidth); - uwBoundHeight = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_BOUND_HEIGHT, pVPort->uwHeight); - ubBitmapFlags = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_BITMAP_FLAGS, BMF_CLEAR); + uwBoundWidth = tagGet( + pTags, vaTags, TAG_SIMPLEBUFFER_BOUND_WIDTH, pVPort->uwWidth + ); + uwBoundHeight = tagGet( + pTags, vaTags, TAG_SIMPLEBUFFER_BOUND_HEIGHT, pVPort->uwHeight + ); + ubBitmapFlags = tagGet( + pTags, vaTags, TAG_SIMPLEBUFFER_BITMAP_FLAGS, BMF_CLEAR + ); logWrite("Bounds: %ux%u\n", uwBoundWidth, uwBoundHeight); pFront = bitmapCreate( uwBoundWidth, uwBoundHeight, pVPort->ubBPP, ubBitmapFlags From dc109229ad70339a1d826a69b2375ae43bf64b4a Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 8 Sep 2018 13:34:47 +0200 Subject: [PATCH 16/56] ScrollBuffer works now, has dbl buffer, todos here and there Tilebuffer is non-functional atm --- include/ace/managers/viewport/scrollbuffer.h | 38 +++- include/ace/managers/viewport/tilebuffer.h | 43 ++-- src/ace/managers/viewport/scrollbuffer.c | 210 +++++++++++++------ src/ace/managers/viewport/tilebuffer.c | 84 +++----- 4 files changed, 228 insertions(+), 147 deletions(-) diff --git a/include/ace/managers/viewport/scrollbuffer.h b/include/ace/managers/viewport/scrollbuffer.h index d7082ec8..0245a341 100644 --- a/include/ace/managers/viewport/scrollbuffer.h +++ b/include/ace/managers/viewport/scrollbuffer.h @@ -11,7 +11,6 @@ * Scrollable buffer manager * Uses scrolling-trick from aminet to achieve memory-efficient scroll * Must be processed as last, because it calls WaitTOF - * Author: KaiN * Requires viewport managers: * - camera * TODO: make it work without tileBuffer manager @@ -28,40 +27,63 @@ #include #include +// vPort ptr +#define TAG_SCROLLBUFFER_VPORT (TAG_USER|1) +// Scrollable area bounds, in pixels +#define TAG_SCROLLBUFFER_BOUND_WIDTH (TAG_USER|2) +#define TAG_SCROLLBUFFER_BOUND_HEIGHT (TAG_USER|3) +// Buffer bitmap creation flags +#define TAG_SCROLLBUFFER_BITMAP_FLAGS (TAG_USER|4) +#define TAG_SCROLLBUFFER_IS_DBLBUF (TAG_USER|5) +// If in raw mode, offset on copperlist for placing required copper +// instructions, specified in copper instruction count since beginning. +#define TAG_SCROLLBUFFER_COPLIST_OFFSET_START (TAG_USER|6) +#define TAG_SCROLLBUFFER_COPLIST_OFFSET_BREAK (TAG_USER|7) +#define TAG_SCROLLBUFFER_MARGIN_WIDTH (TAG_USER|8) + +#define SCROLLBUFFER_FLAG_COPLIST_RAW 1 + /* Types */ typedef struct { tVpManager sCommon; tCameraManager *pCameraManager; /// Quick ref to camera - tBitMap *pBuffer; /// Ptr to buffer bitmap + tBitMap *pFront; + tBitMap *pBack; tCopBlock *pStartBlock; /// Initial data fetch tCopBlock *pBreakBlock; /// Bitplane ptr reset tUwCoordYX uBfrBounds; /// Real bounds of buffer (includes height reserved for x-scroll) UWORD uwBmAvailHeight; /// Avail height of buffer to blit (excludes height reserved for x-scroll) UWORD uwVpHeightPrev; /// Prev height of related VPort, used to force refresh on change UWORD uwModulo; /// Bitplane modulo - tAvg *pAvg; + UBYTE ubFlags; } tScrollBufferManager; /* Globals */ /* Functions */ -tScrollBufferManager *scrollBufferCreate( - tVPort *pVPort, UBYTE ubMarginWidth, - UWORD uwBoundWidth, UWORD uwBoundHeight -); +/** + * Creates scroll manager + */ +tScrollBufferManager *scrollBufferCreate(void *pTags, ...); void scrollBufferDestroy(tScrollBufferManager *pManager); +/** + * Scroll buffer process function + */ void scrollBufferProcess(tScrollBufferManager *pManager); void scrollBufferReset( tScrollBufferManager *pManager, UBYTE ubMarginWidth, - UWORD uwBoundWidth, UWORD uwBoundHeight + UWORD uwBoundWidth, UWORD uwBoundHeight, UBYTE ubBitmapFlags, UBYTE isDblBfr ); +/** + * Uses unsafe blit copy for using out-of-bound X ccord + */ void scrollBufferBlitMask( tBitMap *pSrc, WORD wSrcX, WORD wSrcY, tScrollBufferManager *pDstManager, diff --git a/include/ace/managers/viewport/tilebuffer.h b/include/ace/managers/viewport/tilebuffer.h index ed407154..95fc29f1 100644 --- a/include/ace/managers/viewport/tilebuffer.h +++ b/include/ace/managers/viewport/tilebuffer.h @@ -9,22 +9,15 @@ /** * Tilemap buffer manager - * Provides memory-efficient tilemap buffer + * Provides speed- and memory-efficient tilemap buffer * Redraws only 1-tile margin beyond viewport in all dirs - * Author: KaiN * Requires viewport managers: * - camera * - scroll */ #include -#include -#include - #include -#include - -#include #include #include @@ -73,32 +66,56 @@ typedef struct { /* functions */ +/** + * Tilemap buffer manager create fn + * Be sure to set camera pos, load tile data & then call tileBufferRedraw()! + */ tTileBufferManager *tileBufferCreate( - tVPort *pVPort, - UWORD uwTileX, UWORD uwTileY, UBYTE ubTileShift, - char *szTileSetFileName, tCbTileDraw cbTileDraw + tVPort *pVPort, UWORD uwTileX, UWORD uwTileY, UBYTE ubTileShift, + tBitMap *pTileset, tCbTileDraw cbTileDraw ); void tileBufferDestroy(tTileBufferManager *pManager); +/** + * Redraws one tile for each margin - X and Y + * Redraws all remaining margin's tiles when margin is about to be displayed + */ void tileBufferProcess(tTileBufferManager *pManager); void tileBufferReset( - tTileBufferManager *pManager, - UWORD uwTileX, UWORD uwTileY, char *szTileSetFileName + tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY, tBitMap *pTileset ); +/** + * Redraws tiles on whole screen + * Use for init or something like that, as it's slooooooooow + */ void tileBufferRedraw(tTileBufferManager *pManager); +/** + * Redraws selected tile, calls custom redraw callback + * Calculates destination on buffer + * Use for single redraws + */ void tileBufferDrawTile( tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY ); +/** + * Redraws selected tile, calls custom redraw callback + * Destination coord on buffer must be calculated externally - avoids recalc + * Use for batch redraws with smart uwBfrXY update + */ void tileBufferDrawTileQuick( tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY, UWORD uwBfrX, UWORD uwBfrY ); +/** + * Redraws all tiles intersecting with given rectangle + * Only tiles currently on buffer are redrawn + */ void tileBufferInvalidateRect( tTileBufferManager *pManager, UWORD uwX, UWORD uwY, UWORD uwWidth, UWORD uwHeight diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 50035564..da5b690a 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -3,33 +3,66 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include +#include + #ifdef AMIGA -/** - * Creates scroll manager - */ -tScrollBufferManager *scrollBufferCreate(tVPort *pVPort, UBYTE ubMarginWidth, UWORD uwBoundWidth, UWORD uwBoundHeight) { - logBlockBegin("scrollBufferCreate(pVPort: %p, ubMarginWidth: %hu, uwBoundWidth: %u, uwBoundHeight: %u)", pVPort, ubMarginWidth, uwBoundWidth, uwBoundHeight); +tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { + va_list vaTags; + tCopList *pCopList; tScrollBufferManager *pManager; - - // Wype�nienie struktury mened�era - pManager = memAllocFast(sizeof(tScrollBufferManager)); - logWrite("Addr: %p\n", pManager); - pManager->sCommon.pNext = 0; + UBYTE ubMarginWidth; + UWORD uwBoundWidth, uwBoundHeight; + UBYTE ubBitmapFlags; + UBYTE isCameraCreated = 0; + UBYTE isDblBfr; + + logBlockBegin("scrollBufferCreate(pTags: %p, ...)", pTags); + va_start(vaTags, pTags); + + // Init manager + pManager = memAllocFastClear( + sizeof(tScrollBufferManager) + ); pManager->sCommon.process = (tVpManagerFn)scrollBufferProcess; pManager->sCommon.destroy = (tVpManagerFn)scrollBufferDestroy; pManager->sCommon.ubId = VPM_SCROLL; - pManager->sCommon.pVPort = pVPort; - pManager->pBuffer = 0; - pManager->uwModulo = 0; - pManager->pAvg = logAvgCreate("scrollBufferProcess()", 100); + logWrite("Addr: %p\n", pManager); - scrollBufferReset(pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight); + tVPort *pVPort = (tVPort*)tagGet(pTags, vaTags, TAG_SCROLLBUFFER_VPORT, 0); + if(!pVPort) { + logWrite("ERR: No parent viewport (TAG_SCROLLBUFFER_VPORT) specified!\n"); + goto fail; + } + pManager->sCommon.pVPort = pVPort; + logWrite("Parent VPort: %p\n", pVPort); + + ubMarginWidth = tagGet( + pTags, vaTags, TAG_SCROLLBUFFER_MARGIN_WIDTH, UCHAR_MAX + ); + if(ubMarginWidth == UCHAR_MAX) { + logWrite( + "ERR: No margin width (TAG_SCROLLBUFFER_MARGIN_WIDTH) specified!\n" + ); + goto fail; + } - // Create copperlist - pManager->pStartBlock = copBlockCreate(pVPort->pView->pCopList, 2*pVPort->ubBPP + 8, 0, 0); - pManager->pBreakBlock = copBlockCreate(pVPort->pView->pCopList, 2*pVPort->ubBPP + 2, 0x7F, 0xFF); + // Buffer bitmap + uwBoundWidth = tagGet( + pTags, vaTags, TAG_SCROLLBUFFER_BOUND_WIDTH, pVPort->uwWidth + ); + uwBoundHeight = tagGet( + pTags, vaTags, TAG_SCROLLBUFFER_BOUND_HEIGHT, pVPort->uwHeight + ); + ubBitmapFlags = tagGet( + pTags, vaTags, TAG_SCROLLBUFFER_BITMAP_FLAGS, BMF_CLEAR + ); + logWrite("Bounds: %ux%u\n", uwBoundWidth, uwBoundHeight); + + isDblBfr = tagGet(pTags, vaTags, TAG_SCROLLBUFFER_IS_DBLBUF, 0); + scrollBufferReset(pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight, ubBitmapFlags, isDblBfr); // Must be before camera? Shouldn't be as there are priorities on manager list vPortAddManager(pVPort, (tVpManager*)pManager); @@ -45,60 +78,84 @@ tScrollBufferManager *scrollBufferCreate(tVPort *pVPort, UBYTE ubMarginWidth, UW cameraReset(pManager->pCameraManager, 0,0, uwBoundWidth, uwBoundHeight); } - // TODO: Set copperlist to current camera pos? + // Create copperlist entries + pCopList = pVPort->pView->pCopList; + if(pCopList->ubMode == COPPER_MODE_BLOCK) { + pManager->pStartBlock = copBlockCreate( + pVPort->pView->pCopList, 2 * pVPort->ubBPP + 8, + // Vertically addition from DiWStrt, horizontally a bit before last fetch. + // First to set are ddf, modulos & shift so they are changed during fetch. + 0xE2-7*4, pVPort->uwOffsY + 0x2C-1 + ); + pManager->pBreakBlock = copBlockCreate( + pVPort->pView->pCopList, 2 * pVPort->ubBPP + 2, + // Dummy position - will be updated + 0x7F, 0xFF + ); + } + else { + // TODO Raw mode + goto fail; + } + + // TODO: Update copperlist with current camera pos? + va_end(vaTags); logBlockEnd("scrollBufferCreate"); return pManager; +fail: + va_end(vaTags); + logBlockEnd("scrollBufferCreate"); + return 0; } void scrollBufferDestroy(tScrollBufferManager *pManager) { logBlockBegin("scrollBufferDestroy(pManager: %p)", pManager); - logAvgDestroy(pManager->pAvg); copBlockDestroy(pManager->sCommon.pVPort->pView->pCopList, pManager->pStartBlock); copBlockDestroy(pManager->sCommon.pVPort->pView->pCopList, pManager->pBreakBlock); - bitmapDestroy(pManager->pBuffer); + bitmapDestroy(pManager->pBack); memFree(pManager, sizeof(tScrollBufferManager)); logBlockEnd("scrollBufferDestroy()"); } -/** - * Scroll buffer process function - */ void scrollBufferProcess(tScrollBufferManager *pManager) { UWORD uwVpHeight; uwVpHeight = pManager->sCommon.pVPort->uwHeight; - logAvgBegin(pManager->pAvg); - if (cameraIsMoved(pManager->pCameraManager) || pManager->uwVpHeightPrev != uwVpHeight) { - UBYTE i; - UWORD uwScrollX, uwScrollY; - ULONG ulPlaneOffs; - ULONG ulPlaneAddr; - UWORD uwOffsX; - - // convert camera pos to scroll pos - uwScrollX = pManager->pCameraManager->uPos.sUwCoord.uwX; - uwScrollY = pManager->pCameraManager->uPos.sUwCoord.uwY % pManager->uwBmAvailHeight; - - // preparations for new copperlist - uwOffsX = 15 - (uwScrollX & 0xF); // Bitplane shift - single - uwOffsX = (uwOffsX << 4) | uwOffsX; // Bitplane shift - PF1 | PF2 - - uwScrollX >>= 3; - - // Initial copper block - tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; + UBYTE i; + UWORD uwScrollX, uwScrollY; + ULONG ulPlaneOffs; + ULONG ulPlaneAddr; + UWORD uwOffsX; + + // convert camera pos to scroll pos + uwScrollX = pManager->pCameraManager->uPos.sUwCoord.uwX; + uwScrollY = pManager->pCameraManager->uPos.sUwCoord.uwY % pManager->uwBmAvailHeight; + + // preparations for new copperlist + uwOffsX = 15 - (uwScrollX & 0xF); // Bitplane shift - single + uwOffsX = (uwOffsX << 4) | uwOffsX; // Bitplane shift - PF1 | PF2 + + uwScrollX >>= 3; + + // Initial copper block + tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; + + if(pManager->ubFlags & SCROLLBUFFER_FLAG_COPLIST_RAW) { + // TODO: Raw mode + } + else { tCopBlock *pBlock = pManager->pStartBlock; pBlock->uwCurrCount = 0; // Rewind copBlock copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY); copMove(pCopList, pBlock, &g_pCustom->color[0], 0x0F0); copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwOffsX); // Bitplane shift - ulPlaneOffs = uwScrollX + (pManager->pBuffer->BytesPerRow*uwScrollY); + ulPlaneOffs = uwScrollX + (pManager->pBack->BytesPerRow*uwScrollY); for (i = pManager->sCommon.pVPort->ubBPP; i--;) { - ulPlaneAddr = (ULONG)(pManager->pBuffer->Planes[i]) + ulPlaneOffs; + ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + ulPlaneOffs; copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); } @@ -118,7 +175,7 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { // copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwOffsX); // potrzebne? copMove(pCopList, pBlock, &g_pCustom->color[0], 0x0F00); for (i = pManager->sCommon.pVPort->ubBPP; i--;) { - ulPlaneAddr = (ULONG)(pManager->pBuffer->Planes[i]) + uwScrollX; + ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + uwScrollX; copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } @@ -127,19 +184,28 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { else { copBlockWait(pCopList, pBlock, 0x7F, 0xFF); } - - pManager->uwVpHeightPrev = uwVpHeight; - copProcessBlocks(); } - logAvgEnd(pManager->pAvg); - WaitTOF(); + pManager->uwVpHeightPrev = uwVpHeight; + + // Swap buffers if needed + if(pManager->pBack != pManager->pFront) { + tBitMap *pTmp = pManager->pBack; + pManager->pBack = pManager->pFront; + pManager->pFront = pTmp; + } } -void scrollBufferReset(tScrollBufferManager *pManager, UBYTE ubMarginWidth, UWORD uwBoundWidth, UWORD uwBoundHeight) { +void scrollBufferReset( + tScrollBufferManager *pManager, UBYTE ubMarginWidth, + UWORD uwBoundWidth, UWORD uwBoundHeight, UBYTE ubBitmapFlags, UBYTE isDblBfr +) { UWORD uwVpWidth, uwVpHeight; UWORD uwCalcWidth, uwCalcHeight; - logBlockBegin("scrollBufferReset(pManager: %p, ubMarginWidth: %hu, uwBoundWidth: %u, uwBoundHeight: %u)", pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight); + logBlockBegin( + "scrollBufferReset(pManager: %p, ubMarginWidth: %hu, uwBoundWidth: %u, uwBoundHeight: %u)", + pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight + ); // Helper vars uwVpWidth = pManager->sCommon.pVPort->uwWidth; uwVpHeight = pManager->sCommon.pVPort->uwHeight; @@ -148,25 +214,36 @@ void scrollBufferReset(tScrollBufferManager *pManager, UBYTE ubMarginWidth, UWOR pManager->uwVpHeightPrev = 0; pManager->uBfrBounds.sUwCoord.uwX = uwBoundWidth; pManager->uBfrBounds.sUwCoord.uwY = uwBoundHeight; - pManager->uwBmAvailHeight = ubMarginWidth * blockCountCeil(uwVpHeight, ubMarginWidth) + ubMarginWidth*4; + // TODO optimize avail height to power of two so that modulo can be an AND + pManager->uwBmAvailHeight = ubMarginWidth * (blockCountCeil(uwVpHeight, ubMarginWidth) + 4); // Destroy old buffer bitmap - if(pManager->pBuffer) { - bitmapDestroy(pManager->pBuffer); + if(pManager->pFront != pManager->pBack) { + bitmapDestroy(pManager->pFront); + } + if(pManager->pBack) { + bitmapDestroy(pManager->pBack); } // Create new buffer bitmap uwCalcWidth = uwVpWidth + ubMarginWidth*4; uwCalcHeight = pManager->uwBmAvailHeight + blockCountCeil(uwBoundWidth, uwVpWidth) - 1; - pManager->pBuffer = bitmapCreate(uwCalcWidth, uwCalcHeight, pManager->sCommon.pVPort->ubBPP, BMF_CLEAR); - pManager->uwModulo = pManager->pBuffer->BytesPerRow - (uwVpWidth >> 3) - 2; + pManager->pBack = bitmapCreate( + uwCalcWidth, uwCalcHeight, pManager->sCommon.pVPort->ubBPP, ubBitmapFlags + ); + if(isDblBfr) { + pManager->pFront = bitmapCreate( + uwCalcWidth, uwCalcHeight, pManager->sCommon.pVPort->ubBPP, ubBitmapFlags + ); + } + else { + pManager->pFront = pManager->pBack; + } + pManager->uwModulo = pManager->pBack->BytesPerRow - (uwVpWidth >> 3) - 2; logBlockEnd("scrollBufferReset()"); } -/** - * Uses unsafe blit copy for using out-of-bound X ccord - */ void scrollBufferBlitMask( tBitMap *pSrc, WORD wSrcX, WORD wSrcY, tScrollBufferManager *pDstManager, WORD wDstX, WORD wDstY, @@ -174,14 +251,13 @@ void scrollBufferBlitMask( ) { // TODO: if area is visible wDstY %= pDstManager->uwBmAvailHeight; - // UBYTE ubAddY = wDstX/(pDstManager->pBuffer->BytesPerRow<<3); - wDstY %= (pDstManager->pBuffer->BytesPerRow<<3); + wDstY %= (pDstManager->pBack->BytesPerRow<<3); if(wDstY + wHeight <= pDstManager->uwBmAvailHeight) { // single blit blitUnsafeCopyMask( pSrc, wSrcX, wSrcY, - pDstManager->pBuffer, wDstX, wDstY, + pDstManager->pBack, wDstX, wDstY, wWidth, wHeight, pMsk ); } @@ -191,12 +267,12 @@ void scrollBufferBlitMask( wPartHeight = pDstManager->uwBmAvailHeight - wDstY; blitUnsafeCopyMask( pSrc, wSrcX, wSrcY, - pDstManager->pBuffer, wDstX, wDstY, + pDstManager->pBack, wDstX, wDstY, wWidth, wPartHeight, pMsk ); blitUnsafeCopyMask( pSrc, wSrcX, wSrcY + wPartHeight, - pDstManager->pBuffer, wDstX, 0, + pDstManager->pBack, wDstX, 0, wWidth, wHeight - wPartHeight, pMsk ); } diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index b7521092..df3afa2a 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -3,32 +3,19 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include +#include +#include #ifdef AMIGA -/** - * Tilemap buffer manager - * Provides speed- and memory-efficient tilemap buffer - * Redraws only 1-tile margin beyond viewport in all dirs - * Author: KaiN - * Requires viewport managers: - * - camera - * - scroll - */ - -/** - * Tilemap buffer manager create fn - * Be sure to set camera pos, load tile data & then call tileBufferRedraw()! - */ tTileBufferManager *tileBufferCreate( - tVPort *pVPort, - UWORD uwTileX, UWORD uwTileY, UBYTE ubTileShift, - char *szTileSetFileName, tCbTileDraw cbTileDraw + tVPort *pVPort, UWORD uwTileX, UWORD uwTileY, UBYTE ubTileShift, + tBitMap *pTileset, tCbTileDraw cbTileDraw ) { logBlockBegin( "tileBufferCreate(pVPort: %p, uwTileX: %u, uwTileY: %u, ubTileShift: %hu, " - "szTilesetFileName: %s, cbTileDraw: %p)", - pVPort, uwTileX, uwTileY, ubTileShift, szTileSetFileName, cbTileDraw + "pTileset: %p, cbTileDraw: %p)", + pVPort, uwTileX, uwTileY, ubTileShift, pTileset, cbTileDraw ); tTileBufferManager *pManager; @@ -46,7 +33,7 @@ tTileBufferManager *tileBufferCreate( pManager->pTileData = 0; pManager->pTileSet = 0; - tileBufferReset(pManager, uwTileX, uwTileY, szTileSetFileName); + tileBufferReset(pManager, uwTileX, uwTileY, pTileset); vPortAddManager(pVPort, (tVpManager*)pManager); @@ -85,19 +72,19 @@ void tileBufferDestroy(tTileBufferManager *pManager) { logBlockEnd("tileBufferDestroy"); } -void tileBufferReset(tTileBufferManager *pManager, - UWORD uwTileX, UWORD uwTileY, - // UWORD uwCameraX, UWORD uwCameraY, - char *szTileSetFileName - ) { +void tileBufferReset( + tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY, + tBitMap *pTileset +) { UWORD uwCol; UBYTE ubTileShift; logBlockBegin("tileBufferReset()"); // Free old tile data if(pManager->pTileData) { - for (uwCol = pManager->uTileBounds.sUwCoord.uwX; uwCol--;) + for (uwCol = pManager->uTileBounds.sUwCoord.uwX; uwCol--;) { memFree(pManager->pTileData[uwCol], pManager->uTileBounds.sUwCoord.uwY * sizeof(UBYTE)); + } memFree(pManager->pTileData, pManager->uTileBounds.sUwCoord.uwX * sizeof(UBYTE *)); pManager->pTileData = 0; } @@ -113,12 +100,7 @@ void tileBufferReset(tTileBufferManager *pManager, } // Load new tileset - if(szTileSetFileName) { - if(pManager->pTileSet) { - bitmapDestroy(pManager->pTileSet); - } - pManager->pTileSet = bitmapCreateFromFile(szTileSetFileName, 0); - } + pManager->pTileSet = pTileset; // Reset margin redraw structs ubTileShift = pManager->ubTileShift; @@ -134,13 +116,19 @@ void tileBufferReset(tTileBufferManager *pManager, pManager->pMarginOppositeY = &pManager->sMarginU; // Reset scrollManager, create if not exists - if(!(pManager->pScrollManager = (tScrollBufferManager*)vPortGetManager(pManager->sCommon.pVPort, VPM_SCROLL))) { - pManager->pScrollManager = scrollBufferCreate(pManager->sCommon.pVPort, pManager->ubTileSize, uwTileX << ubTileShift, uwTileY << ubTileShift); + pManager->pScrollManager = (tScrollBufferManager*)vPortGetManager( + pManager->sCommon.pVPort, VPM_SCROLL + ); + if(!(pManager->pScrollManager)) { + pManager->pScrollManager = scrollBufferCreate( + pManager->sCommon.pVPort, pManager->ubTileSize, + uwTileX << ubTileShift, uwTileY << ubTileShift + ); } else { scrollBufferReset( pManager->pScrollManager, pManager->ubTileSize, - uwTileX << ubTileShift, uwTileY << ubTileShift + uwTileX << ubTileShift, uwTileY << ubTileShift, BMF_CLEAR, 0 ); } @@ -150,10 +138,6 @@ void tileBufferReset(tTileBufferManager *pManager, logBlockEnd("tileBufferReset()"); } -/** - * Redraws one tile for each margin - X and Y - * Redraws all remaining margin's tiles when margin is about to be displayed - */ void tileBufferProcess(tTileBufferManager *pManager) { WORD wDeltaX, wDeltaY; WORD wTileIdxX, wTileIdxY; @@ -318,10 +302,6 @@ void tileBufferProcess(tTileBufferManager *pManager) { } } -/** - * Redraws tiles on whole screen - * Use for init or something like that, as it's slooooooooow - */ void tileBufferRedraw(tTileBufferManager *pManager) { UWORD i,j; UWORD uwTileOffsX, uwTileOffsY; @@ -364,11 +344,6 @@ void tileBufferRedraw(tTileBufferManager *pManager) { logBlockEnd("tileBufferRedraw()"); } -/** - * Redraws selected tile, calls custom redraw callback - * Calculates destination on buffer - * Use for single redraws - */ void tileBufferDrawTile(tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY) { UWORD uwBfrX, uwBfrY; UBYTE ubAddY; @@ -380,27 +355,18 @@ void tileBufferDrawTile(tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uw tileBufferDrawTileQuick(pManager, uwTileIdxX, uwTileIdxY, uwBfrX, uwBfrY+ubAddY); } -/** - * Redraws selected tile, calls custom redraw callback - * Destination coord on buffer must be calculated externally - avoids recalc - * Use for batch redraws with smart uwBfrXY update - */ void tileBufferDrawTileQuick(tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY, UWORD uwBfrX, UWORD uwBfrY) { blitCopyAligned( pManager->pTileSet, 0, pManager->pTileData[uwTileIdxX][uwTileIdxY] << pManager->ubTileShift, - pManager->pScrollManager->pBuffer, uwBfrX, uwBfrY, + pManager->pScrollManager->pBack, uwBfrX, uwBfrY, pManager->ubTileSize, pManager->ubTileSize ); if(pManager->cbTileDraw) { - pManager->cbTileDraw(uwTileIdxX, uwTileIdxY, pManager->pScrollManager->pBuffer, uwBfrX, uwBfrY); + pManager->cbTileDraw(uwTileIdxX, uwTileIdxY, pManager->pScrollManager->pBack, uwBfrX, uwBfrY); } } -/** - * Redraws all tiles intersecting with given rectangle - * Only tiles currently on buffer are redrawn - */ void tileBufferInvalidateRect(tTileBufferManager *pManager, UWORD uwX, UWORD uwY, UWORD uwWidth, UWORD uwHeight) { UWORD uwStartX, uwEndX, uwStartY, uwEndY; /// Invalidate tile rect UWORD uwVisStartX, uwVisEndX, uwVisStartY, uwVisEndY; /// Visible tile rect (excluding invisible margins) From fcfbc8413c3c4d1217693a5f099c4f2555e8d413 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 15 Sep 2018 11:12:46 +0200 Subject: [PATCH 17/56] Better names, improved fail on scrollBufferManagerCreate() --- include/ace/managers/viewport/scrollbuffer.h | 20 ++++---- include/ace/managers/viewport/simplebuffer.h | 2 +- src/ace/managers/viewport/scrollbuffer.c | 50 +++++++++++++------- src/ace/managers/viewport/simplebuffer.c | 28 +++++------ 4 files changed, 59 insertions(+), 41 deletions(-) diff --git a/include/ace/managers/viewport/scrollbuffer.h b/include/ace/managers/viewport/scrollbuffer.h index 0245a341..963258a8 100644 --- a/include/ace/managers/viewport/scrollbuffer.h +++ b/include/ace/managers/viewport/scrollbuffer.h @@ -47,16 +47,16 @@ typedef struct { tVpManager sCommon; - tCameraManager *pCameraManager; /// Quick ref to camera - - tBitMap *pFront; - tBitMap *pBack; - tCopBlock *pStartBlock; /// Initial data fetch - tCopBlock *pBreakBlock; /// Bitplane ptr reset - tUwCoordYX uBfrBounds; /// Real bounds of buffer (includes height reserved for x-scroll) - UWORD uwBmAvailHeight; /// Avail height of buffer to blit (excludes height reserved for x-scroll) - UWORD uwVpHeightPrev; /// Prev height of related VPort, used to force refresh on change - UWORD uwModulo; /// Bitplane modulo + tCameraManager *pCamera; ///< Quick ref to camera + + tBitMap *pFront; ///< Front buffer in double buffering + tBitMap *pBack; ///< Back buffer in double buffering + tCopBlock *pStartBlock; ///< Initial data fetch + tCopBlock *pBreakBlock; ///< Bitplane ptr reset + tUwCoordYX uBfrBounds; ///< Real bounds of buffer (includes height reserved for x-scroll) + UWORD uwBmAvailHeight; ///< Avail height of buffer to blit (excludes height reserved for x-scroll) + UWORD uwVpHeightPrev; ///< Prev height of related VPort, used to force refresh on change + UWORD uwModulo; ///< Bitplane modulo UBYTE ubFlags; } tScrollBufferManager; diff --git a/include/ace/managers/viewport/simplebuffer.h b/include/ace/managers/viewport/simplebuffer.h index 9ef8cf21..89cd827b 100644 --- a/include/ace/managers/viewport/simplebuffer.h +++ b/include/ace/managers/viewport/simplebuffer.h @@ -31,7 +31,7 @@ typedef struct { tVpManager sCommon; - tCameraManager *pCameraManager; + tCameraManager *pCamera; // scroll-specific fields tBitMap *pFront; ///< Currently displayed buffer. tBitMap *pBack; ///< Buffer for drawing. diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index da5b690a..3d1b9e5e 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -11,21 +11,19 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { va_list vaTags; - tCopList *pCopList; + tCopList *pCopList = 0; tScrollBufferManager *pManager; UBYTE ubMarginWidth; UWORD uwBoundWidth, uwBoundHeight; UBYTE ubBitmapFlags; UBYTE isCameraCreated = 0; - UBYTE isDblBfr; + UBYTE isDblBuf; logBlockBegin("scrollBufferCreate(pTags: %p, ...)", pTags); va_start(vaTags, pTags); // Init manager - pManager = memAllocFastClear( - sizeof(tScrollBufferManager) - ); + pManager = memAllocFastClear(sizeof(tScrollBufferManager)); pManager->sCommon.process = (tVpManagerFn)scrollBufferProcess; pManager->sCommon.destroy = (tVpManagerFn)scrollBufferDestroy; pManager->sCommon.ubId = VPM_SCROLL; @@ -61,21 +59,25 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { ); logWrite("Bounds: %ux%u\n", uwBoundWidth, uwBoundHeight); - isDblBfr = tagGet(pTags, vaTags, TAG_SCROLLBUFFER_IS_DBLBUF, 0); - scrollBufferReset(pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight, ubBitmapFlags, isDblBfr); + isDblBuf = tagGet(pTags, vaTags, TAG_SCROLLBUFFER_IS_DBLBUF, 0); + scrollBufferReset( + pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight, + ubBitmapFlags, isDblBuf + ); // Must be before camera? Shouldn't be as there are priorities on manager list vPortAddManager(pVPort, (tVpManager*)pManager); // Find camera manager, create if not exists - pManager->pCameraManager = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); - if(!pManager->pCameraManager) { - pManager->pCameraManager = cameraCreate( + pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); + if(!pManager->pCamera) { + pManager->pCamera = cameraCreate( pVPort, 0, 0, uwBoundWidth, uwBoundHeight ); + isCameraCreated = 1; } else { - cameraReset(pManager->pCameraManager, 0,0, uwBoundWidth, uwBoundHeight); + cameraReset(pManager->pCamera, 0,0, uwBoundWidth, uwBoundHeight); } // Create copperlist entries @@ -104,6 +106,17 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { logBlockEnd("scrollBufferCreate"); return pManager; fail: + if(isCameraCreated) { + cameraDestroy(pManager->pCamera); + } + if(pCopList && pManager->pStartBlock) { + copBlockDestroy(pCopList, pManager->pStartBlock); + if(pManager->pBreakBlock) { + copBlockDestroy(pCopList, pManager->pBreakBlock); + } + } + + memFree(pManager, sizeof(tScrollBufferManager)); va_end(vaTags); logBlockEnd("scrollBufferCreate"); return 0; @@ -115,7 +128,12 @@ void scrollBufferDestroy(tScrollBufferManager *pManager) { copBlockDestroy(pManager->sCommon.pVPort->pView->pCopList, pManager->pStartBlock); copBlockDestroy(pManager->sCommon.pVPort->pView->pCopList, pManager->pBreakBlock); - bitmapDestroy(pManager->pBack); + if(pManager->pFront && pManager->pFront != pManager->pBack) { + bitmapDestroy(pManager->pFront); + } + if(pManager->pBack) { + bitmapDestroy(pManager->pBack); + } memFree(pManager, sizeof(tScrollBufferManager)); logBlockEnd("scrollBufferDestroy()"); @@ -132,8 +150,8 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { UWORD uwOffsX; // convert camera pos to scroll pos - uwScrollX = pManager->pCameraManager->uPos.sUwCoord.uwX; - uwScrollY = pManager->pCameraManager->uPos.sUwCoord.uwY % pManager->uwBmAvailHeight; + uwScrollX = pManager->pCamera->uPos.sUwCoord.uwX; + uwScrollY = pManager->pCamera->uPos.sUwCoord.uwY % pManager->uwBmAvailHeight; // preparations for new copperlist uwOffsX = 15 - (uwScrollX & 0xF); // Bitplane shift - single @@ -198,7 +216,7 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { void scrollBufferReset( tScrollBufferManager *pManager, UBYTE ubMarginWidth, - UWORD uwBoundWidth, UWORD uwBoundHeight, UBYTE ubBitmapFlags, UBYTE isDblBfr + UWORD uwBoundWidth, UWORD uwBoundHeight, UBYTE ubBitmapFlags, UBYTE isDblBuf ) { UWORD uwVpWidth, uwVpHeight; UWORD uwCalcWidth, uwCalcHeight; @@ -231,7 +249,7 @@ void scrollBufferReset( pManager->pBack = bitmapCreate( uwCalcWidth, uwCalcHeight, pManager->sCommon.pVPort->ubBPP, ubBitmapFlags ); - if(isDblBfr) { + if(isDblBuf) { pManager->pFront = bitmapCreate( uwCalcWidth, uwCalcHeight, pManager->sCommon.pVPort->ubBPP, ubBitmapFlags ); diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index af801eca..015d7fd3 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -157,10 +157,10 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { } // Find camera manager, create if not exists - pManager->pCameraManager = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); - if(!pManager->pCameraManager) { + pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); + if(!pManager->pCamera) { isCameraCreated = 1; - pManager->pCameraManager = cameraCreate(pVPort, 0, 0, uwBoundWidth, uwBoundHeight); + pManager->pCamera = cameraCreate(pVPort, 0, 0, uwBoundWidth, uwBoundHeight); } pCopList = pVPort->pView->pCopList; @@ -207,8 +207,8 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { bitmapDestroy(pFront); } if(pManager) { - if(pManager->pCameraManager && isCameraCreated) { - cameraDestroy(pManager->pCameraManager); + if(pManager->pCamera && isCameraCreated) { + cameraDestroy(pManager->pCamera); } memFree(pManager, sizeof(tSimpleBufferManager)); } @@ -234,15 +234,15 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { UWORD uwShift; ULONG ulBplOffs; ULONG ulPlaneAddr; - tCameraManager *pCameraManager; + tCameraManager *pCamera; tCopList *pCopList; - pCameraManager = pManager->pCameraManager; + pCamera = pManager->pCamera; pCopList = pManager->sCommon.pVPort->pView->pCopList; // Calculate X movement if(pManager->ubFlags & SIMPLEBUFFER_FLAG_X_SCROLLABLE) { - uwShift = 15-(pCameraManager->uPos.sUwCoord.uwX & 0xF); + uwShift = 15-(pCamera->uPos.sUwCoord.uwX & 0xF); uwShift = (uwShift << 4) | uwShift; } else { @@ -250,10 +250,10 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { } // X offset on bitplane - ulBplOffs = (pCameraManager->uPos.sUwCoord.uwX >> 4) << 1; + ulBplOffs = (pCamera->uPos.sUwCoord.uwX >> 4) << 1; // Calculate Y movement - ulBplOffs += pManager->pBack->BytesPerRow*pCameraManager->uPos.sUwCoord.uwY; + ulBplOffs += pManager->pBack->BytesPerRow*pCamera->uPos.sUwCoord.uwY; // Copperlist - regen bitplane ptrs, update shift // TODO could be unified by using copSetMove in copBlock @@ -289,10 +289,10 @@ UBYTE simpleBufferIsRectVisible( UWORD uwX, UWORD uwY, UWORD uwWidth, UWORD uwHeight ) { return ( - uwX >= pManager->pCameraManager->uPos.sUwCoord.uwX - uwWidth && - uwX <= pManager->pCameraManager->uPos.sUwCoord.uwX + pManager->sCommon.pVPort->uwWidth && - uwY >= pManager->pCameraManager->uPos.sUwCoord.uwY - uwHeight && - uwY <= pManager->pCameraManager->uPos.sUwCoord.uwY + pManager->sCommon.pVPort->uwHeight + uwX >= pManager->pCamera->uPos.sUwCoord.uwX - uwWidth && + uwX <= pManager->pCamera->uPos.sUwCoord.uwX + pManager->sCommon.pVPort->uwWidth && + uwY >= pManager->pCamera->uPos.sUwCoord.uwY - uwHeight && + uwY <= pManager->pCamera->uPos.sUwCoord.uwY + pManager->sCommon.pVPort->uwHeight ); } From af9a916996a7b2c37f10c43c43613cfc3f3b278d Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 15 Sep 2018 11:13:44 +0200 Subject: [PATCH 18/56] fixed return before call --- src/ace/managers/system.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ace/managers/system.c b/src/ace/managers/system.c index 0bcee200..7ff1448c 100644 --- a/src/ace/managers/system.c +++ b/src/ace/managers/system.c @@ -185,8 +185,8 @@ void systemCreate(void) { // Save the system copperlists and flush the view GfxBase = (struct GfxBase *)OpenLibrary((CONST_STRPTR)"graphics.library", 0L); if (!GfxBase) { - return; systemKill("Can't open Gfx Library!\n"); + return; } s_pOsView = GfxBase->ActiView; WaitTOF(); From de9fc6f0a2d4ef61194670f4f769f26265be0c9a Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 15 Sep 2018 14:17:07 +0200 Subject: [PATCH 19/56] fixed ctrl+clickability of file names in log --- src/ace/managers/blit.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ace/managers/blit.c b/src/ace/managers/blit.c index ceffc3c8..41afab7c 100644 --- a/src/ace/managers/blit.c +++ b/src/ace/managers/blit.c @@ -81,7 +81,7 @@ UBYTE _blitCheck( if(pSrc && (wSrcX < 0 || wSrcWidth < wSrcX+wWidth || pSrc->Rows < wSrcY+wHeight)) { logWrite( "ERR: ILLEGAL BLIT Source out of range: " - "source %p %dx%d, dest: %p %dx%d, blit: %d,%d -> %d,%d %dx%d %s@%u\n", + "source %p %dx%d, dest: %p %dx%d, blit: %d,%d -> %d,%d %dx%d %s @ %u\n", pSrc, wSrcWidth, wSrcHeight, pDst, wDstWidth, wDstHeight, wSrcX, wSrcY, wDstX, wDstY, wWidth, wHeight, szFile, uwLine ); @@ -90,7 +90,7 @@ UBYTE _blitCheck( if(pDst && (wDstY < 0 || wDstWidth < wDstX+wWidth || pDst->Rows < wDstY+wHeight)) { logWrite( "ERR: ILLEGAL BLIT Dest out of range: " - "source %p %dx%d, dest: %p %dx%d, blit: %d,%d -> %d,%d %dx%d %s@%u\n", + "source %p %dx%d, dest: %p %dx%d, blit: %d,%d -> %d,%d %dx%d %s @ %u\n", pSrc, wSrcWidth, wSrcHeight, pDst, wDstWidth, wDstHeight, wSrcX, wSrcY, wDstX, wDstY, wWidth, wHeight, szFile, uwLine ); From 5ed7b843191de3b2054ecdde66158a9d33131ec6 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 15 Sep 2018 14:17:30 +0200 Subject: [PATCH 20/56] Tilebuffer is halfway uncrapped --- include/ace/managers/viewport/tilebuffer.h | 109 +++-- src/ace/managers/viewport/tilebuffer.c | 521 +++++++++++++-------- 2 files changed, 398 insertions(+), 232 deletions(-) diff --git a/include/ace/managers/viewport/tilebuffer.h b/include/ace/managers/viewport/tilebuffer.h index 95fc29f1..6f113f50 100644 --- a/include/ace/managers/viewport/tilebuffer.h +++ b/include/ace/managers/viewport/tilebuffer.h @@ -21,45 +21,74 @@ #include #include +// vPort ptr +#define TAG_TILEBUFFER_VPORT (TAG_USER|1) +// Scrollable area bounds, in pixels +#define TAG_TILEBUFFER_BOUND_TILE_X (TAG_USER|2) +#define TAG_TILEBUFFER_BOUND_TILE_Y (TAG_USER|3) +#define TAG_TILEBUFFER_TILE_SHIFT (TAG_USER|4) +// Buffer bitmap creation flags +#define TAG_TILEBUFFER_BITMAP_FLAGS (TAG_USER|5) +#define TAG_TILEBUFFER_IS_DBLBUF (TAG_USER|6) +// If in raw mode, offset on copperlist for placing required copper +// instructions, specified in copper instruction count since beginning. +#define TAG_TILEBUFFER_COPLIST_OFFSET_START (TAG_USER|7) +#define TAG_TILEBUFFER_COPLIST_OFFSET_BREAK (TAG_USER|8) +// Callbacks, tileset +#define TAG_TILEBUFFER_TILESET (TAG_USER|9) +#define TAG_TILEBUFFER_CALLBACK_TILE_DRAW (TAG_USER|10) +#define TAG_TILEBUFFER_REDRAW_QUEUE_LENGTH (TAG_USER|11) + /* types */ -typedef void (*tCbTileDraw)( +typedef void (*tTileDrawCallback)( UWORD uwTileX, UWORD uwTileY, tBitMap *pBitMap, UWORD uwBitMapX, UWORD uwBitMapY ); typedef struct { - WORD wTileOffs; /// Index of row/col to update - WORD wTileCurr; /// Index of current tile to update in row/col - WORD wTileEnd; /// Index of last+1 tile to update in row/col -} tTileMarginData; + WORD wTilePos; ///< Index of row/col to update + WORD wTileCurr; ///< Index of current tile to update in row/col + WORD wTileEnd; ///< Index of last+1 tile to update in row/col +} tMarginState; + +typedef struct _tRedrawState { + tMarginState sMarginL; ///< Data for left margin + tMarginState sMarginR; ///< Ditto, right + tMarginState sMarginU; ///< Ditto, up + tMarginState sMarginD; ///< Ditto, down + // Vars needed in Process, reset in Create + tMarginState *pMarginX; ///< Idx of X margin to be redrawn + tMarginState *pMarginOppositeX; ///< Opposite margin of pMarginX + tMarginState *pMarginY; ///< Idx of Y margin to be redrawn + tMarginState *pMarginOppositeY; ///< Opposite margin of pMarginY + // Tile redraw queue + tUwCoordYX *pPendingQueue; + UBYTE ubPendingCount; +} tRedrawState; typedef struct { tVpManager sCommon; - tCameraManager *pCameraManager; /// Quick ref to Camera - tScrollBufferManager *pScrollManager; /// Quick ref to Scroll - // Manager vars - tUwCoordYX uTileBounds; /// Tile count in x,y - UBYTE ubTileSize; /// Tile size in pixels - UBYTE ubTileShift; /// Tile size in shift, e.g. 4 for 16: 1 << 4 == 16 - UWORD uwMarginedWidth; /// Width of visible area + margins - UWORD uwMarginedHeight; /// Height of visible area + margins - /// TODO: refresh when scrollbuffer changes - tCbTileDraw cbTileDraw; /// Called when tile is redrawn - UBYTE **pTileData; /// 2D array of tile indices - tBitMap *pTileSet; /// Tileset - // Margin vars - UBYTE ubMarginXLength; /// Tile number in margins: left & right - UBYTE ubMarginYLength; /// Ditto, up & down - tTileMarginData sMarginL; /// Data for left margin - tTileMarginData sMarginR; /// Ditto, right - tTileMarginData sMarginU; /// Ditto, up - tTileMarginData sMarginD; /// Ditto, down - // Vars needed in Process, reset in Create - tTileMarginData *pMarginX; /// Idx of X margin to be redrawn - tTileMarginData *pMarginOppositeX; /// Opposite margin of pMarginX - tTileMarginData *pMarginY; /// Idx of Y margin to be redrawn - tTileMarginData *pMarginOppositeY; /// Opposite margin of pMarginY + tCameraManager *pCamera; ///< Quick ref to Camera + tScrollBufferManager *pScroll; ///< Quick ref to Scroll + // Manager vars + tUwCoordYX uTileBounds; ///< Tile count in x,y + UBYTE ubTileSize; ///< Tile size in pixels + UBYTE ubTileShift; ///< Tile size in shift, e.g. 4 for 16: 1 << 4 == 16 + UWORD uwMarginedWidth; ///< Width of visible area + margins + UWORD uwMarginedHeight; ///< Height of visible area + margins + /// TODO: refresh when scrollbuffer changes + tTileDrawCallback cbTileDraw; ///< Called when tile is redrawn + UBYTE **pTileData; ///< 2D array of tile indices + tBitMap *pTileSet; ///< Tileset - one tile beneath another + // Margin & queue geometry + UBYTE ubMarginXLength; ///< Tile number in margins: left & right + UBYTE ubMarginYLength; ///< Ditto, up & down + UBYTE ubQueueSize; + // Redraw state and double buffering + tRedrawState pRedrawStates[2]; + UBYTE ubStateIdx; + } tTileBufferManager; /* globals */ @@ -70,10 +99,7 @@ typedef struct { * Tilemap buffer manager create fn * Be sure to set camera pos, load tile data & then call tileBufferRedraw()! */ -tTileBufferManager *tileBufferCreate( - tVPort *pVPort, UWORD uwTileX, UWORD uwTileY, UBYTE ubTileShift, - tBitMap *pTileset, tCbTileDraw cbTileDraw -); +tTileBufferManager *tileBufferCreate(void *pTags, ...); void tileBufferDestroy(tTileBufferManager *pManager); @@ -84,14 +110,15 @@ void tileBufferDestroy(tTileBufferManager *pManager); void tileBufferProcess(tTileBufferManager *pManager); void tileBufferReset( - tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY, tBitMap *pTileset + tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY, + UBYTE ubBitmapFlags, UBYTE isDblBuf ); /** * Redraws tiles on whole screen * Use for init or something like that, as it's slooooooooow */ -void tileBufferRedraw(tTileBufferManager *pManager); +void tileBufferInitialDraw(const tTileBufferManager *pManager); /** * Redraws selected tile, calls custom redraw callback @@ -99,7 +126,7 @@ void tileBufferRedraw(tTileBufferManager *pManager); * Use for single redraws */ void tileBufferDrawTile( - tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY + const tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY ); /** @@ -108,7 +135,7 @@ void tileBufferDrawTile( * Use for batch redraws with smart uwBfrXY update */ void tileBufferDrawTileQuick( - tTileBufferManager *pManager, + const tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY, UWORD uwBfrX, UWORD uwBfrY ); @@ -121,5 +148,13 @@ void tileBufferInvalidateRect( UWORD uwWidth, UWORD uwHeight ); +void tileBufferInvalidateTile( + tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY +); + +UBYTE tileBufferIsTileOnBuffer( + const tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY +); + #endif // AMIGA #endif // _ACE_MANAGERS_VIEWPORT_TILEBUFFER_H_ diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index df3afa2a..c95ab84e 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -5,67 +5,149 @@ #include #include #include +#include #ifdef AMIGA -tTileBufferManager *tileBufferCreate( - tVPort *pVPort, UWORD uwTileX, UWORD uwTileY, UBYTE ubTileShift, - tBitMap *pTileset, tCbTileDraw cbTileDraw +static void tileBufferQueueAdd( + tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY ) { - logBlockBegin( - "tileBufferCreate(pVPort: %p, uwTileX: %u, uwTileY: %u, ubTileShift: %hu, " - "pTileset: %p, cbTileDraw: %p)", - pVPort, uwTileX, uwTileY, ubTileShift, pTileset, cbTileDraw - ); + tRedrawState *pState = &pManager->pRedrawStates[0]; + pState->pPendingQueue[pState->ubPendingCount].sUwCoord.uwX = uwTileX; + pState->pPendingQueue[pState->ubPendingCount].sUwCoord.uwY = uwTileY; + ++pState->ubPendingCount; + pState = &pManager->pRedrawStates[1]; + pState->pPendingQueue[pState->ubPendingCount].sUwCoord.uwX = uwTileX; + pState->pPendingQueue[pState->ubPendingCount].sUwCoord.uwY = uwTileY; + ++pState->ubPendingCount; +} + +static void tileBufferQueueProcess(tTileBufferManager *pManager) { + tRedrawState *pState = &pManager->pRedrawStates[pManager->ubStateIdx]; + UBYTE ubPendingCount = pState->ubPendingCount; + if(ubPendingCount) { + const tUwCoordYX *pTile = &pState->pPendingQueue[ubPendingCount]; + tileBufferDrawTile(pManager, pTile->sUwCoord.uwX, pTile->sUwCoord.uwY); + --pState->ubPendingCount; + } +} + +tTileBufferManager *tileBufferCreate(void *pTags, ...) { + va_list vaTags; tTileBufferManager *pManager; + UWORD uwTileX, uwTileY; + UBYTE ubBitmapFlags, isDblBuf; + + logBlockBegin("tileBufferCreate(pTags: %p, ...)", pTags); + va_start(vaTags, pTags); // Feed struct with args - pManager = memAllocFast(sizeof(tTileBufferManager)); - pManager->sCommon.pNext = 0; + pManager = memAllocFastClear(sizeof(tTileBufferManager)); pManager->sCommon.process = (tVpManagerFn)tileBufferProcess; pManager->sCommon.destroy = (tVpManagerFn)tileBufferDestroy; pManager->sCommon.ubId = VPM_TILEBUFFER; + + tVPort *pVPort = (tVPort*)tagGet(pTags, vaTags, TAG_TILEBUFFER_VPORT, 0); + if(!pVPort) { + logWrite("ERR: No parent viewport (TAG_TILEBUFFER_VPORT) specified!\n"); + goto fail; + } pManager->sCommon.pVPort = pVPort; + logWrite("Parent VPort: %p\n", pVPort); + UBYTE ubTileShift = tagGet(pTags, vaTags, TAG_TILEBUFFER_TILE_SHIFT, 0); + if(!ubTileShift) { + logWrite("ERR: No tile shift (TAG_TILEBUFFER_TILE_SHIFT) specified!\n"); + goto fail; + } pManager->ubTileShift = ubTileShift; pManager->ubTileSize = 1 << ubTileShift; - pManager->cbTileDraw = cbTileDraw; + + pManager->cbTileDraw = (tTileDrawCallback)tagGet( + pTags, vaTags, TAG_TILEBUFFER_CALLBACK_TILE_DRAW, 0 + ); + + pManager->pTileSet = (tBitMap*)tagGet(pTags, vaTags, TAG_TILEBUFFER_TILESET, 0); + if(!pManager->pTileSet) { + logWrite("ERR: No tileset (TAG_TILEBUFFER_TILESET) specified!\n"); + goto fail; + } + uwTileX = tagGet(pTags, vaTags, TAG_TILEBUFFER_BOUND_TILE_X, 0); + uwTileY = tagGet(pTags, vaTags, TAG_TILEBUFFER_BOUND_TILE_Y, 0); + if(!uwTileX || !uwTileY) { + logWrite( + "ERR: No tile boundaries (TAG_TILEBUFFER_BOUND_TILE_X or _Y) specified!\n" + ); + } pManager->pTileData = 0; - pManager->pTileSet = 0; - tileBufferReset(pManager, uwTileX, uwTileY, pTileset); + ubBitmapFlags = tagGet(pTags, vaTags, TAG_TILEBUFFER_BITMAP_FLAGS, BMF_CLEAR); + isDblBuf = tagGet(pTags, vaTags, TAG_TILEBUFFER_IS_DBLBUF, 0); + tileBufferReset(pManager, uwTileX, uwTileY, ubBitmapFlags, isDblBuf); + + pManager->ubQueueSize = tagGet( + pTags, vaTags, TAG_TILEBUFFER_REDRAW_QUEUE_LENGTH, 0 + ); + if(!pManager->ubQueueSize) { + logWrite( + "ERR: No queue size (TAG_TILEBUFFER_REDRAW_QUEUE_LENGTH) specified!\n" + ); + goto fail; + } + // This alloc could be checked in regard of double buffering + // but I want process to be as quick as possible (one 'if' less) + // and redraw queue has no mem footprint at all (256 bytes max?) + pManager->pRedrawStates[0].pPendingQueue = memAllocFast(pManager->ubQueueSize); + pManager->pRedrawStates[1].pPendingQueue = memAllocFast(pManager->ubQueueSize); + if( + !pManager->pRedrawStates[0].pPendingQueue || + !pManager->pRedrawStates[1].pPendingQueue + ) { + goto fail; + } vPortAddManager(pVPort, (tVpManager*)pManager); // find camera manager, create if not exists // camera created in scroll bfr - pManager->pCameraManager = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); - // if(!(pManager->pCameraManager = (tCameraManager*)extVPortGetManager(pVPort, VPM_CAMERA))) { - // pManager->pCameraManager = cameraCreate(pVPort, 0, 0, uwTileX << ubTileShift, uwTileY << ubTileShift); - // } - // TODO: reset camera bounds? + pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); - // nie tutaj bo kamera jeszcze musi zosta� ustawiona - // i pTileData ustawione - // a bez sensu dwa razy odrysowywa� ca�y ekran - // tileBufferRedraw(pManager); + // Redraw shouldn't take place here because camera is not in proper pos yet, + // also pTileData is empty + va_end(vaTags); logBlockEnd("tileBufferCreate"); return pManager; +fail: + // TODO: proper fail + if(pManager->pRedrawStates[0].pPendingQueue) { + memFree(pManager->pRedrawStates[0].pPendingQueue, pManager->ubQueueSize); + } + if(pManager->pRedrawStates[1].pPendingQueue) { + memFree(pManager->pRedrawStates[1].pPendingQueue, pManager->ubQueueSize); + } + va_end(vaTags); + logBlockEnd("tileBufferCreate"); + return 0; } void tileBufferDestroy(tTileBufferManager *pManager) { UWORD uwCol; logBlockBegin("tileBufferDestroy(pManager: %p)", pManager); - // Free tileset - bitmapDestroy(pManager->pTileSet); - // Free tile data - for (uwCol = pManager->uTileBounds.sUwCoord.uwX; uwCol--;) + for(uwCol = pManager->uTileBounds.sUwCoord.uwX; uwCol--;) { memFree(pManager->pTileData[uwCol], pManager->uTileBounds.sUwCoord.uwY * sizeof(UBYTE)); + } memFree(pManager->pTileData, pManager->uTileBounds.sUwCoord.uwX * sizeof(UBYTE *)); + if(pManager->pRedrawStates[0].pPendingQueue) { + memFree(pManager->pRedrawStates[0].pPendingQueue, pManager->ubQueueSize); + } + if(pManager->pRedrawStates[1].pPendingQueue) { + memFree(pManager->pRedrawStates[1].pPendingQueue, pManager->ubQueueSize); + } + // Free manager memFree(pManager, sizeof(tTileBufferManager)); @@ -74,15 +156,16 @@ void tileBufferDestroy(tTileBufferManager *pManager) { void tileBufferReset( tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY, - tBitMap *pTileset + UBYTE ubBitmapFlags, UBYTE isDblBuf ) { - UWORD uwCol; - UBYTE ubTileShift; - logBlockBegin("tileBufferReset()"); + logBlockBegin( + "tileBufferReset(pManager: %p, uwTileX: %hu, uwTileY: %hu, ubBitmapFlags: %hhu, isDblBuf: %hhu)", + pManager, uwTileX, uwTileY, ubBitmapFlags, isDblBuf + ); // Free old tile data if(pManager->pTileData) { - for (uwCol = pManager->uTileBounds.sUwCoord.uwX; uwCol--;) { + for(UWORD uwCol = pManager->uTileBounds.sUwCoord.uwX; uwCol--;) { memFree(pManager->pTileData[uwCol], pManager->uTileBounds.sUwCoord.uwY * sizeof(UBYTE)); } memFree(pManager->pTileData, pManager->uTileBounds.sUwCoord.uwX * sizeof(UBYTE *)); @@ -93,90 +176,94 @@ void tileBufferReset( pManager->uTileBounds.sUwCoord.uwX = uwTileX; pManager->uTileBounds.sUwCoord.uwY = uwTileY; if(uwTileX && uwTileY) { - pManager->pTileData = memAllocFast(uwTileX * sizeof(BYTE*)); - for(uwCol = uwTileX; uwCol--;) { + pManager->pTileData = memAllocFast(uwTileX * sizeof(UBYTE*)); + for(UWORD uwCol = uwTileX; uwCol--;) { pManager->pTileData[uwCol] = memAllocFastClear(uwTileY * sizeof(UBYTE)); } } - // Load new tileset - pManager->pTileSet = pTileset; - // Reset margin redraw structs - ubTileShift = pManager->ubTileShift; - memset(&pManager->sMarginL, 0, sizeof(tTileMarginData)); - memset(&pManager->sMarginR, 0, sizeof(tTileMarginData)); - memset(&pManager->sMarginU, 0, sizeof(tTileMarginData)); - memset(&pManager->sMarginD, 0, sizeof(tTileMarginData)); + UBYTE ubTileShift = pManager->ubTileShift; + memset(&pManager->pRedrawStates[0], 0, sizeof(tRedrawState)); + memset(&pManager->pRedrawStates[1], 0, sizeof(tRedrawState)); pManager->ubMarginXLength = (pManager->sCommon.pVPort->uwHeight >> ubTileShift) + 4; pManager->ubMarginYLength = (pManager->sCommon.pVPort->uwWidth >> ubTileShift) + 4; - pManager->pMarginX = &pManager->sMarginR; - pManager->pMarginOppositeX = &pManager->sMarginL; - pManager->pMarginY = &pManager->sMarginD; - pManager->pMarginOppositeY = &pManager->sMarginU; + pManager->pRedrawStates[0].pMarginX = &pManager->pRedrawStates[0].sMarginR; + pManager->pRedrawStates[0].pMarginOppositeX = &pManager->pRedrawStates[0].sMarginL; + pManager->pRedrawStates[0].pMarginY = &pManager->pRedrawStates[0].sMarginD; + pManager->pRedrawStates[0].pMarginOppositeY = &pManager->pRedrawStates[0].sMarginU; + pManager->pRedrawStates[1].pMarginX = &pManager->pRedrawStates[1].sMarginR; + pManager->pRedrawStates[1].pMarginOppositeX = &pManager->pRedrawStates[1].sMarginL; + pManager->pRedrawStates[1].pMarginY = &pManager->pRedrawStates[1].sMarginD; + pManager->pRedrawStates[1].pMarginOppositeY = &pManager->pRedrawStates[1].sMarginU; // Reset scrollManager, create if not exists - pManager->pScrollManager = (tScrollBufferManager*)vPortGetManager( + pManager->pScroll = (tScrollBufferManager*)vPortGetManager( pManager->sCommon.pVPort, VPM_SCROLL ); - if(!(pManager->pScrollManager)) { - pManager->pScrollManager = scrollBufferCreate( - pManager->sCommon.pVPort, pManager->ubTileSize, - uwTileX << ubTileShift, uwTileY << ubTileShift - ); + if(!(pManager->pScroll)) { + pManager->pScroll = scrollBufferCreate(0, + TAG_SCROLLBUFFER_VPORT, pManager->sCommon.pVPort, + TAG_SCROLLBUFFER_MARGIN_WIDTH, pManager->ubTileSize, + TAG_SCROLLBUFFER_BOUND_WIDTH, uwTileX << ubTileShift, + TAG_SCROLLBUFFER_BOUND_HEIGHT, uwTileY << ubTileShift, + TAG_SCROLLBUFFER_IS_DBLBUF, isDblBuf, + TAG_SCROLLBUFFER_BITMAP_FLAGS, ubBitmapFlags, + TAG_DONE); } else { scrollBufferReset( - pManager->pScrollManager, pManager->ubTileSize, - uwTileX << ubTileShift, uwTileY << ubTileShift, BMF_CLEAR, 0 + pManager->pScroll, pManager->ubTileSize, + uwTileX << ubTileShift, uwTileY << ubTileShift, ubBitmapFlags, isDblBuf ); } pManager->uwMarginedWidth = pManager->sCommon.pVPort->uwWidth + (4 << ubTileShift); - pManager->uwMarginedHeight = pManager->pScrollManager->uwBmAvailHeight; + pManager->uwMarginedHeight = pManager->pScroll->uwBmAvailHeight; logBlockEnd("tileBufferReset()"); } void tileBufferProcess(tTileBufferManager *pManager) { - WORD wDeltaX, wDeltaY; WORD wTileIdxX, wTileIdxY; UWORD uwTileOffsX, uwTileOffsY; - UBYTE ubTileSize, ubTileShift; UBYTE ubAddY; + tRedrawState *pState = &pManager->pRedrawStates[pManager->ubStateIdx]; - ubTileSize = pManager->ubTileSize; - ubTileShift = pManager->ubTileShift; - wDeltaX = cameraGetDeltaX(pManager->pCameraManager); - wDeltaY = cameraGetDeltaY(pManager->pCameraManager); + UBYTE ubTileSize = pManager->ubTileSize; + UBYTE ubTileShift = pManager->ubTileShift; + WORD wDeltaX = cameraGetDeltaX(pManager->pCamera); + WORD wDeltaY = cameraGetDeltaY(pManager->pCamera); // X movement if (wDeltaX) { // determine movement direction - right or left if (wDeltaX > 0) { - wTileIdxX = ((pManager->pCameraManager->uPos.sUwCoord.uwX + pManager->sCommon.pVPort->uwWidth) >> ubTileShift) +1; // delete +1 to see redraw - pManager->pMarginX = &pManager->sMarginR; - pManager->pMarginOppositeX = &pManager->sMarginL; + wTileIdxX = (( + pManager->pCamera->uPos.sUwCoord.uwX + pManager->sCommon.pVPort->uwWidth + ) >> ubTileShift) +1; // delete +1 to see redraw + pState->pMarginX = &pState->sMarginR; + pState->pMarginOppositeX = &pState->sMarginL; } else { - wTileIdxX = (pManager->pCameraManager->uPos.sUwCoord.uwX >> ubTileShift) -1; - pManager->pMarginX = &pManager->sMarginL; - pManager->pMarginOppositeX = &pManager->sMarginR; + wTileIdxX = (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1; + pState->pMarginX = &pState->sMarginL; + pState->pMarginOppositeX = &pState->sMarginR; } // Not redrawing same column on movement side? - if (wTileIdxX != pManager->pMarginX->wTileOffs) { + if (wTileIdxX != pState->pMarginX->wTilePos) { // Not finished redrawing all column tiles? - if(pManager->pMarginX->wTileCurr < pManager->pMarginX->wTileEnd) { - uwTileOffsY = (pManager->pMarginX->wTileCurr << ubTileShift) % pManager->uwMarginedHeight; - ubAddY = (pManager->pMarginX->wTileOffs << ubTileShift) / pManager->uwMarginedWidth; - uwTileOffsX = (pManager->pMarginX->wTileOffs << ubTileShift) % pManager->uwMarginedWidth; + if(pState->pMarginX->wTileCurr < pState->pMarginX->wTileEnd) { + uwTileOffsY = (pState->pMarginX->wTileCurr << ubTileShift) % pManager->uwMarginedHeight; + ubAddY = (pState->pMarginX->wTilePos << ubTileShift) / pManager->uwMarginedWidth; + uwTileOffsX = (pState->pMarginX->wTilePos << ubTileShift) % pManager->uwMarginedWidth; // Redraw remaining tiles - while (pManager->pMarginX->wTileCurr < pManager->pMarginX->wTileEnd) { + while (pState->pMarginX->wTileCurr < pState->pMarginX->wTileEnd) { tileBufferDrawTileQuick( pManager, - pManager->pMarginX->wTileOffs, pManager->pMarginX->wTileCurr, - uwTileOffsX, uwTileOffsY+ubAddY + pState->pMarginX->wTilePos, pState->pMarginX->wTileCurr, + 0, 0//uwTileOffsX, uwTileOffsY+ubAddY ); - ++pManager->pMarginX->wTileCurr; + ++pState->pMarginX->wTileCurr; uwTileOffsY = (uwTileOffsY + ubTileSize); if(uwTileOffsY >= pManager->uwMarginedHeight) { uwTileOffsY -= pManager->uwMarginedHeight; @@ -184,73 +271,75 @@ void tileBufferProcess(tTileBufferManager *pManager) { } } // Prepare new column redraw data - pManager->pMarginX->wTileOffs = wTileIdxX; + pState->pMarginX->wTilePos = wTileIdxX; if (wTileIdxX < 0 || wTileIdxX >= pManager->uTileBounds.sUwCoord.uwX) { // Don't redraw if new column is out of map bounds - pManager->pMarginX->wTileCurr = 0; - pManager->pMarginX->wTileEnd = 0; + pState->pMarginX->wTileCurr = 0; + pState->pMarginX->wTileEnd = 0; } else { // Prepare new column for redraw - pManager->pMarginX->wTileCurr = (pManager->pCameraManager->uPos.sUwCoord.uwY >> ubTileShift) - 2; - pManager->pMarginX->wTileEnd = pManager->pMarginX->wTileCurr + pManager->ubMarginXLength; - if(pManager->pMarginX->wTileCurr < 0) { - pManager->pMarginX->wTileCurr = 0; + pState->pMarginX->wTileCurr = (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) - 2; + pState->pMarginX->wTileEnd = pState->pMarginX->wTileCurr + pManager->ubMarginXLength; + if(pState->pMarginX->wTileCurr < 0) { + pState->pMarginX->wTileCurr = 0; } } // Modify margin data on opposite side if(wDeltaX < 0) { - --pManager->pMarginOppositeX->wTileCurr; + --pState->pMarginOppositeX->wTileCurr; } else { - ++pManager->pMarginOppositeX->wTileCurr; + ++pState->pMarginOppositeX->wTileCurr; } - pManager->pMarginOppositeX->wTileCurr = 0; - pManager->pMarginOppositeX->wTileEnd = 0; + pState->pMarginOppositeX->wTileCurr = 0; + pState->pMarginOppositeX->wTileEnd = 0; } } // Redraw another X tile - regardless of movement in that direction - if (pManager->pMarginX->wTileCurr < pManager->pMarginX->wTileEnd) { - uwTileOffsX = (pManager->pMarginX->wTileOffs << ubTileShift) % pManager->uwMarginedWidth; - uwTileOffsY = (pManager->pMarginX->wTileCurr << ubTileShift) % pManager->uwMarginedHeight; - ubAddY = (pManager->pMarginX->wTileOffs << ubTileShift) / pManager->uwMarginedWidth; + if (pState->pMarginX->wTileCurr < pState->pMarginX->wTileEnd) { + uwTileOffsX = (pState->pMarginX->wTilePos << ubTileShift) % pManager->uwMarginedWidth; + uwTileOffsY = (pState->pMarginX->wTileCurr << ubTileShift) % pManager->uwMarginedHeight; + ubAddY = (pState->pMarginX->wTilePos << ubTileShift) / pManager->uwMarginedWidth; tileBufferDrawTileQuick( pManager, - pManager->pMarginX->wTileOffs, pManager->pMarginX->wTileCurr, + pState->pMarginX->wTilePos, pState->pMarginX->wTileCurr, uwTileOffsX, uwTileOffsY+ubAddY ); - ++pManager->pMarginX->wTileCurr; + ++pState->pMarginX->wTileCurr; } // Y movement if (wDeltaY) { // determine redraw row - down or up if (wDeltaY > 0) { - wTileIdxY = ((pManager->pCameraManager->uPos.sUwCoord.uwY + pManager->sCommon.pVPort->uwHeight) >> ubTileShift) +1; // Delete +1 to see redraw - pManager->pMarginY = &pManager->sMarginD; - pManager->pMarginOppositeY = &pManager->sMarginU; + wTileIdxY = (( + pManager->pCamera->uPos.sUwCoord.uwY + pManager->sCommon.pVPort->uwHeight + ) >> ubTileShift) +1; // Delete +1 to see redraw + pState->pMarginY = &pState->sMarginD; + pState->pMarginOppositeY = &pState->sMarginU; } else { - wTileIdxY = (pManager->pCameraManager->uPos.sUwCoord.uwY >> ubTileShift) -1; - pManager->pMarginY = &pManager->sMarginU; - pManager->pMarginOppositeY = &pManager->sMarginD; + wTileIdxY = (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1; + pState->pMarginY = &pState->sMarginU; + pState->pMarginOppositeY = &pState->sMarginD; } // Not drawing same row? - if (wTileIdxY != pManager->pMarginY->wTileOffs) { + if (wTileIdxY != pState->pMarginY->wTilePos) { // Not finished redrawing all row tiles? - if(pManager->pMarginY->wTileCurr < pManager->pMarginY->wTileEnd) { - uwTileOffsY = (pManager->pMarginY->wTileOffs << ubTileShift) % pManager->uwMarginedHeight; - ubAddY = (pManager->pMarginY->wTileCurr << ubTileShift) / pManager->uwMarginedWidth; - uwTileOffsX = (pManager->pMarginY->wTileCurr << ubTileShift) % pManager->uwMarginedWidth; + if(pState->pMarginY->wTileCurr < pState->pMarginY->wTileEnd) { + uwTileOffsY = (pState->pMarginY->wTilePos << ubTileShift) % pManager->uwMarginedHeight; + ubAddY = (pState->pMarginY->wTileCurr << ubTileShift) / pManager->uwMarginedWidth; + uwTileOffsX = (pState->pMarginY->wTileCurr << ubTileShift) % pManager->uwMarginedWidth; // Redraw remaining tiles - while(pManager->pMarginY->wTileCurr < pManager->pMarginY->wTileEnd) { + while(pState->pMarginY->wTileCurr < pState->pMarginY->wTileEnd) { tileBufferDrawTileQuick( pManager, - pManager->pMarginY->wTileCurr, pManager->pMarginY->wTileOffs, + pState->pMarginY->wTileCurr, pState->pMarginY->wTilePos, uwTileOffsX, uwTileOffsY+ubAddY ); - ++pManager->pMarginY->wTileCurr; + ++pState->pMarginY->wTileCurr; uwTileOffsX += ubTileSize; if(uwTileOffsX >= pManager->uwMarginedWidth) { uwTileOffsX -= pManager->uwMarginedWidth; @@ -259,77 +348,83 @@ void tileBufferProcess(tTileBufferManager *pManager) { } } // Prepare new row redraw data - pManager->pMarginY->wTileOffs = wTileIdxY; + pState->pMarginY->wTilePos = wTileIdxY; if (wTileIdxY < 0 || wTileIdxY >= pManager->uTileBounds.sUwCoord.uwY) { // Don't redraw if new row is out of map bounds - pManager->pMarginY->wTileCurr = 0; - pManager->pMarginY->wTileEnd = 0; + pState->pMarginY->wTileCurr = 0; + pState->pMarginY->wTileEnd = 0; } else { // Prepare new row for redraw - pManager->pMarginY->wTileCurr = (pManager->pCameraManager->uPos.sUwCoord.uwX >> ubTileShift) - 2; - pManager->pMarginY->wTileEnd = pManager->pMarginY->wTileCurr + pManager->ubMarginYLength; - if(pManager->pMarginY->wTileCurr < 0) { - pManager->pMarginY->wTileCurr = 0; + pState->pMarginY->wTileCurr = (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) - 2; + pState->pMarginY->wTileEnd = pState->pMarginY->wTileCurr + pManager->ubMarginYLength; + if(pState->pMarginY->wTileCurr < 0) { + pState->pMarginY->wTileCurr = 0; } - if(pManager->pMarginY->wTileEnd >= pManager->uTileBounds.sUwCoord.uwX) { - pManager->pMarginY->wTileEnd = pManager->uTileBounds.sUwCoord.uwX-1; + if(pState->pMarginY->wTileEnd >= pManager->uTileBounds.sUwCoord.uwX) { + pState->pMarginY->wTileEnd = pManager->uTileBounds.sUwCoord.uwX-1; } } // Modify opposite margin data if(wDeltaY > 0) { - ++pManager->pMarginOppositeY->wTileOffs; + ++pState->pMarginOppositeY->wTilePos; } else { - --pManager->pMarginOppositeY->wTileOffs; + --pState->pMarginOppositeY->wTilePos; } - pManager->pMarginOppositeY->wTileCurr = 0; - pManager->pMarginOppositeY->wTileEnd = 0; + pState->pMarginOppositeY->wTileCurr = 0; + pState->pMarginOppositeY->wTileEnd = 0; } } // Redraw another Y tile - regardless of movement in that direction - if (pManager->pMarginY->wTileCurr < pManager->pMarginY->wTileEnd) { - ubAddY = (pManager->pMarginY->wTileCurr << ubTileShift) / pManager->uwMarginedWidth; - uwTileOffsX = (pManager->pMarginY->wTileCurr << ubTileShift) % pManager->uwMarginedWidth; - uwTileOffsY = (pManager->pMarginY->wTileOffs << ubTileShift) % pManager->uwMarginedHeight; + if (pState->pMarginY->wTileCurr < pState->pMarginY->wTileEnd) { + ubAddY = (pState->pMarginY->wTileCurr << ubTileShift) / pManager->uwMarginedWidth; + uwTileOffsX = (pState->pMarginY->wTileCurr << ubTileShift) % pManager->uwMarginedWidth; + uwTileOffsY = (pState->pMarginY->wTilePos << ubTileShift) % pManager->uwMarginedHeight; tileBufferDrawTileQuick( pManager, - pManager->pMarginY->wTileCurr, pManager->pMarginY->wTileOffs, + pState->pMarginY->wTileCurr, pState->pMarginY->wTilePos, uwTileOffsX, uwTileOffsY+ubAddY ); - ++pManager->pMarginY->wTileCurr; + ++pState->pMarginY->wTileCurr; } + tileBufferQueueProcess(pManager); + pManager->ubStateIdx = !pManager->ubStateIdx; } -void tileBufferRedraw(tTileBufferManager *pManager) { - UWORD i,j; - UWORD uwTileOffsX, uwTileOffsY; - WORD wTileIdxX, wTileIdxY; - UBYTE ubAddY; - UBYTE ubTileSize, ubTileShift; - - logBlockBegin("tileBufferRedraw(pManager: %p)", pManager); - ubTileSize = pManager->ubTileSize; - ubTileShift = pManager->ubTileShift; - pManager->uwMarginedWidth = pManager->sCommon.pVPort->uwWidth + (4 << ubTileShift); - pManager->uwMarginedHeight = pManager->pScrollManager->uwBmAvailHeight; +void tileBufferInitialDraw(const tTileBufferManager *pManager) { + logBlockBegin("tileBufferInitialDraw(pManager: %p)", pManager); + UBYTE ubTileSize = pManager->ubTileSize; + UBYTE ubTileShift = pManager->ubTileShift; - wTileIdxY = (pManager->pCameraManager->uPos.sUwCoord.uwY >> ubTileShift) -1; - if (wTileIdxY < 0) + WORD wTileIdxY = (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1; + if (wTileIdxY < 0) { wTileIdxY = 0; - uwTileOffsY = (wTileIdxY << ubTileShift) % pManager->uwMarginedHeight; - - for (j = 0; j < pManager->uwMarginedHeight; j += ubTileSize) { + } + UWORD uwTileOffsY = (wTileIdxY << ubTileShift) % pManager->uwMarginedHeight; + // One of bounds may be smaller than viewport + margin size + UBYTE ubEndX = MIN( + pManager->uTileBounds.sUwCoord.uwX, + pManager->uwMarginedWidth >> ubTileShift + ); + UBYTE ubEndY = MIN( + pManager->uTileBounds.sUwCoord.uwY, + pManager->uwMarginedHeight >> ubTileShift + ); - wTileIdxX = (pManager->pCameraManager->uPos.sUwCoord.uwX >> ubTileShift) -1; - if (wTileIdxX < 0) + for (UBYTE x = 0; x < ubEndX; ++x) { + WORD wTileIdxX = (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1; + if (wTileIdxX < 0) { wTileIdxX = 0; - ubAddY = (wTileIdxX << ubTileShift) / pManager->uwMarginedWidth; - uwTileOffsX = (wTileIdxX << ubTileShift) % pManager->uwMarginedWidth; + } + UBYTE ubAddY = (wTileIdxX << ubTileShift) / pManager->uwMarginedWidth; + UWORD uwTileOffsX = (wTileIdxX << ubTileShift) % pManager->uwMarginedWidth; - for (i = 0; i < pManager->uwMarginedWidth; i+= ubTileSize) { - tileBufferDrawTileQuick(pManager, wTileIdxX, wTileIdxY, uwTileOffsX, uwTileOffsY+ubAddY); + for (UBYTE y = 0; y < ubEndY; ++y) { + tileBufferDrawTileQuick( + pManager, wTileIdxX, wTileIdxY, uwTileOffsX, uwTileOffsY+ubAddY + ); ++wTileIdxX; uwTileOffsX += ubTileSize; if(uwTileOffsX >= pManager->uwMarginedWidth) { @@ -341,10 +436,19 @@ void tileBufferRedraw(tTileBufferManager *pManager) { ++wTileIdxY; uwTileOffsY = (uwTileOffsY + ubTileSize) % pManager->uwMarginedHeight; } - logBlockEnd("tileBufferRedraw()"); + + // Copy from back buffer to front buffer + CopyMemQuick( + pManager->pScroll->pFront->Planes[0], pManager->pScroll->pBack->Planes[0], + pManager->pScroll->pFront->BytesPerRow * pManager->pScroll->pFront->Rows + ); + + logBlockEnd("tileBufferInitialDraw()"); } -void tileBufferDrawTile(tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY) { +void tileBufferDrawTile( + const tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY +) { UWORD uwBfrX, uwBfrY; UBYTE ubAddY; @@ -352,67 +456,94 @@ void tileBufferDrawTile(tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uw ubAddY = (uwTileIdxX << pManager->ubTileShift) / pManager->uwMarginedWidth; uwBfrX = (uwTileIdxX << pManager->ubTileShift) % pManager->uwMarginedWidth; - tileBufferDrawTileQuick(pManager, uwTileIdxX, uwTileIdxY, uwBfrX, uwBfrY+ubAddY); + tileBufferDrawTileQuick( + pManager, uwTileIdxX, uwTileIdxY, uwBfrX, uwBfrY+ubAddY + ); } -void tileBufferDrawTileQuick(tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY, UWORD uwBfrX, UWORD uwBfrY) { +void tileBufferDrawTileQuick( + const tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY, + UWORD uwBfrX, UWORD uwBfrY +) { + if((pManager->pTileData[uwTileIdxX][uwTileIdxY] << pManager->ubTileShift) >= 320) { + logWrite("ERR %hu,%hu\n", uwTileIdxX, uwTileIdxY); + } blitCopyAligned( pManager->pTileSet, 0, pManager->pTileData[uwTileIdxX][uwTileIdxY] << pManager->ubTileShift, - pManager->pScrollManager->pBack, uwBfrX, uwBfrY, + pManager->pScroll->pBack, uwBfrX, uwBfrY, pManager->ubTileSize, pManager->ubTileSize ); if(pManager->cbTileDraw) { - pManager->cbTileDraw(uwTileIdxX, uwTileIdxY, pManager->pScrollManager->pBack, uwBfrX, uwBfrY); + pManager->cbTileDraw( + uwTileIdxX, uwTileIdxY, pManager->pScroll->pBack, uwBfrX, uwBfrY + ); } } -void tileBufferInvalidateRect(tTileBufferManager *pManager, UWORD uwX, UWORD uwY, UWORD uwWidth, UWORD uwHeight) { - UWORD uwStartX, uwEndX, uwStartY, uwEndY; /// Invalidate tile rect - UWORD uwVisStartX, uwVisEndX, uwVisStartY, uwVisEndY; /// Visible tile rect (excluding invisible margins) - UWORD uwVisX, uwVisY; - UBYTE ubAddY; - - // graniczne indeksy kafli - uwStartX = uwX >> pManager->ubTileShift; - uwEndX = (uwX+uwWidth) >> pManager->ubTileShift; - uwStartY = uwY >> pManager->ubTileShift; - uwEndY = (uwY+uwHeight) >> pManager->ubTileShift; - - uwVisStartX = pManager->pCameraManager->uPos.sUwCoord.uwX >> pManager->ubTileShift; - uwVisStartY = pManager->pCameraManager->uPos.sUwCoord.uwY >> pManager->ubTileShift; - uwVisEndX = uwVisStartX + (pManager->sCommon.pVPort->uwWidth >> pManager->ubTileShift); - uwVisEndY = uwVisStartY + (pManager->sCommon.pVPort->uwHeight >> pManager->ubTileShift); +void tileBufferInvalidateRect( + tTileBufferManager *pManager, UWORD uwX, UWORD uwY, + UWORD uwWidth, UWORD uwHeight +) { + // Tile x/y ranges in given coord + UWORD uwStartX = uwX >> pManager->ubTileShift; + UWORD uwEndX = (uwX+uwWidth) >> pManager->ubTileShift; + UWORD uwStartY = uwY >> pManager->ubTileShift; + UWORD uwEndY = (uwY+uwHeight) >> pManager->ubTileShift; for(uwX = uwStartX; uwX <= uwEndX; ++uwX) { - if(uwX < uwVisStartX) { - continue; - } - if(uwX > uwVisEndX) { - break; - } - ubAddY = (uwX << pManager->ubTileShift) / pManager->uwMarginedWidth; - uwVisX = (uwX << pManager->ubTileShift) % pManager->uwMarginedWidth; - uwVisY = (uwStartY << pManager->ubTileShift) % pManager->uwMarginedHeight; for(uwY = uwStartY; uwY <= uwEndY; ++uwY) { - if(uwY < uwVisStartY) { - continue; - } - if(uwY > uwVisEndY) { - logWrite("\n"); - logWrite("camera Y: %u, uwMarginedHeight: %u\n", pManager->pCameraManager->uPos.sUwCoord.uwY, pManager->uwMarginedHeight); - logWrite("uwStartY: %u, uwY: %u, uwEndY: %u\n", uwStartY, uwY, uwEndY); - logWrite("uwVisStartY: %u, uwVisY: %u, uwVisEndY: %u\n", uwVisStartY, uwVisY, uwVisEndY); - logWrite("uwY > uwVisEndY (%u > %u)\n", uwY, uwVisEndY); - break; - } - tileBufferDrawTileQuick(pManager, uwX, uwY, uwVisX, uwVisY + ubAddY); - uwVisY += pManager->ubTileSize; - if(uwVisY >= pManager->uwMarginedHeight) { - uwVisY -= pManager->uwMarginedHeight; - } + tileBufferInvalidateTile(pManager, uwX, uwY); } } } +void tileBufferInvalidateTile( + tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY +) { + if(!tileBufferIsTileOnBuffer(pManager, uwTileX, uwTileY)) { + return; + } + + // Previous state will have one more tile to draw, so only check smaller range + const tRedrawState *pState = &pManager->pRedrawStates[pManager->ubStateIdx]; + // omit if not yet drawn on redraw margin - let manager draw it when it + // will be that tile's turn + if( + pState->pMarginX->wTilePos == uwTileX && + uwTileY >= pState->pMarginX->wTileCurr && + uwTileY <= pState->pMarginX->wTileEnd + ) { + return; + } + if( + pState->pMarginY->wTilePos == uwTileY && + uwTileX >= pState->pMarginX->wTileCurr && + uwTileX <= pState->pMarginX->wTileEnd + ) { + return; + } + + // Add to queue + tileBufferQueueAdd(pManager, uwTileX, uwTileY); +} + +UBYTE tileBufferIsTileOnBuffer( + const tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY +) { + UBYTE ubTileShift = pManager->ubTileShift; + UWORD uwStartX = (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1; + UWORD uwEndX = uwStartX + (pManager->uwMarginedWidth >> ubTileShift); + UWORD uwStartY = (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1; + UWORD uwEndY = uwStartY + (pManager->uwMarginedHeight >> ubTileShift); + + if( + uwStartX <= uwTileX && uwTileX <= uwEndX && uwTileX && + uwStartY <= uwTileY && uwTileY <= uwEndY && uwTileY + ) { + return 1; + } + return 0; +} + #endif // AMIGA From fee604289347bea375b677480f17225cd02a19ef Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 15 Sep 2018 15:20:26 +0200 Subject: [PATCH 21/56] Fixed tilebuffer's initial draw --- src/ace/managers/viewport/tilebuffer.c | 45 ++++++++++++-------------- 1 file changed, 20 insertions(+), 25 deletions(-) diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index c95ab84e..c6ccbc31 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -398,48 +398,43 @@ void tileBufferInitialDraw(const tTileBufferManager *pManager) { UBYTE ubTileSize = pManager->ubTileSize; UBYTE ubTileShift = pManager->ubTileShift; - WORD wTileIdxY = (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1; - if (wTileIdxY < 0) { - wTileIdxY = 0; - } - UWORD uwTileOffsY = (wTileIdxY << ubTileShift) % pManager->uwMarginedHeight; + WORD wStartY = MAX( + 0, (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1 + ); + WORD wStartX = MAX( + 0, (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1 + ); // One of bounds may be smaller than viewport + margin size - UBYTE ubEndX = MIN( + UWORD uwEndX = MIN( pManager->uTileBounds.sUwCoord.uwX, pManager->uwMarginedWidth >> ubTileShift ); - UBYTE ubEndY = MIN( + UWORD uwEndY = MIN( pManager->uTileBounds.sUwCoord.uwY, pManager->uwMarginedHeight >> ubTileShift ); - for (UBYTE x = 0; x < ubEndX; ++x) { - WORD wTileIdxX = (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1; - if (wTileIdxX < 0) { - wTileIdxX = 0; - } - UBYTE ubAddY = (wTileIdxX << ubTileShift) / pManager->uwMarginedWidth; - UWORD uwTileOffsX = (wTileIdxX << ubTileShift) % pManager->uwMarginedWidth; + UWORD uwTileOffsY = (wStartY << ubTileShift) % pManager->uwMarginedHeight; + for (UWORD uwTileY = wStartY; uwTileY < uwEndY; ++uwTileY) { + UBYTE ubAddY = (wStartX << ubTileShift) / pManager->uwMarginedWidth; + UWORD uwTileOffsX = (wStartX << ubTileShift) % pManager->uwMarginedWidth; - for (UBYTE y = 0; y < ubEndY; ++y) { + for (UWORD uwTileX = wStartX; uwTileX < uwEndX; ++uwTileX) { tileBufferDrawTileQuick( - pManager, wTileIdxX, wTileIdxY, uwTileOffsX, uwTileOffsY+ubAddY + pManager, uwTileX, uwTileY, uwTileOffsX, uwTileOffsY+ubAddY ); - ++wTileIdxX; uwTileOffsX += ubTileSize; if(uwTileOffsX >= pManager->uwMarginedWidth) { ++ubAddY; uwTileOffsX -= pManager->uwMarginedWidth; } } - - ++wTileIdxY; uwTileOffsY = (uwTileOffsY + ubTileSize) % pManager->uwMarginedHeight; } // Copy from back buffer to front buffer CopyMemQuick( - pManager->pScroll->pFront->Planes[0], pManager->pScroll->pBack->Planes[0], + pManager->pScroll->pBack->Planes[0], pManager->pScroll->pFront->Planes[0], pManager->pScroll->pFront->BytesPerRow * pManager->pScroll->pFront->Rows ); @@ -462,21 +457,21 @@ void tileBufferDrawTile( } void tileBufferDrawTileQuick( - const tTileBufferManager *pManager, UWORD uwTileIdxX, UWORD uwTileIdxY, + const tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY, UWORD uwBfrX, UWORD uwBfrY ) { - if((pManager->pTileData[uwTileIdxX][uwTileIdxY] << pManager->ubTileShift) >= 320) { - logWrite("ERR %hu,%hu\n", uwTileIdxX, uwTileIdxY); + if((pManager->pTileData[uwTileX][uwTileY] << pManager->ubTileShift) >= 320) { + logWrite("ERR %hu,%hu\n", uwTileX, uwTileY); } blitCopyAligned( pManager->pTileSet, - 0, pManager->pTileData[uwTileIdxX][uwTileIdxY] << pManager->ubTileShift, + 0, pManager->pTileData[uwTileX][uwTileY] << pManager->ubTileShift, pManager->pScroll->pBack, uwBfrX, uwBfrY, pManager->ubTileSize, pManager->ubTileSize ); if(pManager->cbTileDraw) { pManager->cbTileDraw( - uwTileIdxX, uwTileIdxY, pManager->pScroll->pBack, uwBfrX, uwBfrY + uwTileX, uwTileY, pManager->pScroll->pBack, uwBfrX, uwBfrY ); } } From 557b8e984404b2d95f970e638bb454a625435721 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 15 Sep 2018 17:17:59 +0200 Subject: [PATCH 22/56] Fixed incomplete redraws on top/bottom margin --- src/ace/managers/viewport/tilebuffer.c | 64 +++++++++++++------------- 1 file changed, 33 insertions(+), 31 deletions(-) diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index c6ccbc31..6ba92bdd 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -186,8 +186,6 @@ void tileBufferReset( UBYTE ubTileShift = pManager->ubTileShift; memset(&pManager->pRedrawStates[0], 0, sizeof(tRedrawState)); memset(&pManager->pRedrawStates[1], 0, sizeof(tRedrawState)); - pManager->ubMarginXLength = (pManager->sCommon.pVPort->uwHeight >> ubTileShift) + 4; - pManager->ubMarginYLength = (pManager->sCommon.pVPort->uwWidth >> ubTileShift) + 4; pManager->pRedrawStates[0].pMarginX = &pManager->pRedrawStates[0].sMarginR; pManager->pRedrawStates[0].pMarginOppositeX = &pManager->pRedrawStates[0].sMarginL; pManager->pRedrawStates[0].pMarginY = &pManager->pRedrawStates[0].sMarginD; @@ -218,8 +216,21 @@ void tileBufferReset( ); } + // Scrollin on one of dirs may be disabled - less redraw on other axis margin pManager->uwMarginedWidth = pManager->sCommon.pVPort->uwWidth + (4 << ubTileShift); pManager->uwMarginedHeight = pManager->pScroll->uwBmAvailHeight; + pManager->ubMarginXLength = MIN( + pManager->uTileBounds.sUwCoord.uwY, + (pManager->sCommon.pVPort->uwHeight >> ubTileShift) + 4 + ); + pManager->ubMarginYLength = MIN( + pManager->uTileBounds.sUwCoord.uwX, + (pManager->sCommon.pVPort->uwWidth >> ubTileShift) + 4 + ); + logWrite( + "Margin sizes: %hhu,%hhu\n", + pManager->ubMarginXLength, pManager->ubMarginYLength + ); logBlockEnd("tileBufferReset()"); } @@ -261,7 +272,7 @@ void tileBufferProcess(tTileBufferManager *pManager) { tileBufferDrawTileQuick( pManager, pState->pMarginX->wTilePos, pState->pMarginX->wTileCurr, - 0, 0//uwTileOffsX, uwTileOffsY+ubAddY + uwTileOffsX, uwTileOffsY+ubAddY ); ++pState->pMarginX->wTileCurr; uwTileOffsY = (uwTileOffsY + ubTileSize); @@ -279,11 +290,13 @@ void tileBufferProcess(tTileBufferManager *pManager) { } else { // Prepare new column for redraw - pState->pMarginX->wTileCurr = (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) - 2; - pState->pMarginX->wTileEnd = pState->pMarginX->wTileCurr + pManager->ubMarginXLength; - if(pState->pMarginX->wTileCurr < 0) { - pState->pMarginX->wTileCurr = 0; - } + pState->pMarginX->wTileCurr = MAX( + 0, (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) - 2 + ); + pState->pMarginX->wTileEnd = MIN( + pState->pMarginX->wTileCurr + pManager->ubMarginXLength, + pManager->uTileBounds.sUwCoord.uwY + ); } // Modify margin data on opposite side if(wDeltaX < 0) { @@ -299,13 +312,8 @@ void tileBufferProcess(tTileBufferManager *pManager) { // Redraw another X tile - regardless of movement in that direction if (pState->pMarginX->wTileCurr < pState->pMarginX->wTileEnd) { - uwTileOffsX = (pState->pMarginX->wTilePos << ubTileShift) % pManager->uwMarginedWidth; - uwTileOffsY = (pState->pMarginX->wTileCurr << ubTileShift) % pManager->uwMarginedHeight; - ubAddY = (pState->pMarginX->wTilePos << ubTileShift) / pManager->uwMarginedWidth; - tileBufferDrawTileQuick( - pManager, - pState->pMarginX->wTilePos, pState->pMarginX->wTileCurr, - uwTileOffsX, uwTileOffsY+ubAddY + tileBufferDrawTile( + pManager, pState->pMarginX->wTilePos, pState->pMarginX->wTileCurr ); ++pState->pMarginX->wTileCurr; } @@ -316,7 +324,7 @@ void tileBufferProcess(tTileBufferManager *pManager) { if (wDeltaY > 0) { wTileIdxY = (( pManager->pCamera->uPos.sUwCoord.uwY + pManager->sCommon.pVPort->uwHeight - ) >> ubTileShift) +1; // Delete +1 to see redraw + ) >> ubTileShift) + 1; // Delete +1 to see redraw pState->pMarginY = &pState->sMarginD; pState->pMarginOppositeY = &pState->sMarginU; } @@ -356,14 +364,13 @@ void tileBufferProcess(tTileBufferManager *pManager) { } else { // Prepare new row for redraw - pState->pMarginY->wTileCurr = (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) - 2; - pState->pMarginY->wTileEnd = pState->pMarginY->wTileCurr + pManager->ubMarginYLength; - if(pState->pMarginY->wTileCurr < 0) { - pState->pMarginY->wTileCurr = 0; - } - if(pState->pMarginY->wTileEnd >= pManager->uTileBounds.sUwCoord.uwX) { - pState->pMarginY->wTileEnd = pManager->uTileBounds.sUwCoord.uwX-1; - } + pState->pMarginY->wTileCurr = MAX( + 0, (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) - 2 + ); + pState->pMarginY->wTileEnd = MIN( + pState->pMarginY->wTileCurr + pManager->ubMarginYLength, + pManager->uTileBounds.sUwCoord.uwX + ); } // Modify opposite margin data if(wDeltaY > 0) { @@ -379,13 +386,8 @@ void tileBufferProcess(tTileBufferManager *pManager) { // Redraw another Y tile - regardless of movement in that direction if (pState->pMarginY->wTileCurr < pState->pMarginY->wTileEnd) { - ubAddY = (pState->pMarginY->wTileCurr << ubTileShift) / pManager->uwMarginedWidth; - uwTileOffsX = (pState->pMarginY->wTileCurr << ubTileShift) % pManager->uwMarginedWidth; - uwTileOffsY = (pState->pMarginY->wTilePos << ubTileShift) % pManager->uwMarginedHeight; - tileBufferDrawTileQuick( - pManager, - pState->pMarginY->wTileCurr, pState->pMarginY->wTilePos, - uwTileOffsX, uwTileOffsY+ubAddY + tileBufferDrawTile( + pManager, pState->pMarginY->wTileCurr, pState->pMarginY->wTilePos ); ++pState->pMarginY->wTileCurr; } From 868af51aab5c23e0e0185f871f096dfd90af642c Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 16 Sep 2018 10:21:57 +0200 Subject: [PATCH 23/56] fixed viewport starting one line lower than it should've start copblock was too long because of color MOVEs --- src/ace/managers/viewport/scrollbuffer.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 3d1b9e5e..06fe3e55 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -169,7 +169,6 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { tCopBlock *pBlock = pManager->pStartBlock; pBlock->uwCurrCount = 0; // Rewind copBlock copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY); - copMove(pCopList, pBlock, &g_pCustom->color[0], 0x0F0); copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwOffsX); // Bitplane shift ulPlaneOffs = uwScrollX + (pManager->pBack->BytesPerRow*uwScrollY); for (i = pManager->sCommon.pVPort->ubBPP; i--;) { @@ -181,7 +180,8 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { copMove(pCopList, pBlock, &g_pCustom->bpl1mod, pManager->uwModulo); // Odd planes modulo copMove(pCopList, pBlock, &g_pCustom->bpl2mod, pManager->uwModulo); // Even planes modulo copMove(pCopList, pBlock, &g_pCustom->ddfstop, 0x00D0); // Fetch stop - copMove(pCopList, pBlock, &g_pCustom->color[0], 0x000); + // TODO setting colors before and after copper instructions moved viewport + // one line lower on 4bpp - there will be problem on 5 & 6bpp // Copper block after Y-break pBlock = pManager->pBreakBlock; From 26b258077c7e30fa77d666481969c0914b7b5f6b Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 16 Sep 2018 15:07:47 +0200 Subject: [PATCH 24/56] cosmetic changes --- src/ace/managers/viewport/scrollbuffer.c | 6 +----- src/ace/managers/viewport/simplebuffer.c | 5 ++--- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 06fe3e55..cee67732 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -159,13 +159,13 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { uwScrollX >>= 3; - // Initial copper block tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; if(pManager->ubFlags & SCROLLBUFFER_FLAG_COPLIST_RAW) { // TODO: Raw mode } else { + // Initial copper block tCopBlock *pBlock = pManager->pStartBlock; pBlock->uwCurrCount = 0; // Rewind copBlock copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY); @@ -188,16 +188,12 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { pBlock->uwCurrCount = 0; // Rewind copBlock if (pManager->uwBmAvailHeight - uwScrollY <= uwVpHeight) { - // logWrite("Break calc: %u - %u == %u, vpHeight: %u\n", pManager->uwBmAvailHeight, uwScrollY, pManager->uwBmAvailHeight - uwScrollY, uwVpHeight); copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY + pManager->uwBmAvailHeight - uwScrollY); - // copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwOffsX); // potrzebne? - copMove(pCopList, pBlock, &g_pCustom->color[0], 0x0F00); for (i = pManager->sCommon.pVPort->ubBPP; i--;) { ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + uwScrollX; copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } - copMove(pCopList, pBlock, &g_pCustom->color[0], 0x0000); } else { copBlockWait(pCopList, pBlock, 0x7F, 0xFF); diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 015d7fd3..7548284d 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -230,7 +230,6 @@ void simpleBufferDestroy(tSimpleBufferManager *pManager) { } void simpleBufferProcess(tSimpleBufferManager *pManager) { - UBYTE i; UWORD uwShift; ULONG ulBplOffs; ULONG ulPlaneAddr; @@ -260,7 +259,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { if(pManager->ubFlags & SIMPLEBUFFER_FLAG_COPLIST_RAW) { tCopCmd *pCmdList = &pCopList->pBackBfr->pList[pManager->uwCopperOffset]; copSetMove(&pCmdList[5].sMove, &g_pCustom->bplcon1, uwShift); - for (i = 0; i < pManager->sCommon.pVPort->ubBPP; ++i) { + for(UBYTE i = 0; i < pManager->sCommon.pVPort->ubBPP; ++i) { ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; copSetMove(&pCmdList[6 + i*2 + 0].sMove, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copSetMove(&pCmdList[6 + i*2 + 1].sMove, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); @@ -269,7 +268,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { else { pManager->pCopBlock->uwCurrCount = 4; // Rewind to shift cmd pos copMove(pCopList, pManager->pCopBlock, &g_pCustom->bplcon1, uwShift); - for(i = 0; i < pManager->pBack->Depth; ++i) { + for(UBYTE i = 0; i < pManager->pBack->Depth; ++i) { ulPlaneAddr = ((ULONG)pManager->pBack->Planes[i]) + ulBplOffs; copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pManager->pCopBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); From 9aa47e0a510ad470bb097bac3b39dc6cf18a4e72 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 16 Sep 2018 15:24:59 +0200 Subject: [PATCH 25/56] moved some of scrollbuffer's copper operations from process fn --- src/ace/managers/viewport/scrollbuffer.c | 62 +++++++++++++++--------- src/ace/managers/viewport/tilebuffer.c | 1 + 2 files changed, 39 insertions(+), 24 deletions(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index cee67732..daa19e17 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -60,25 +60,6 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { logWrite("Bounds: %ux%u\n", uwBoundWidth, uwBoundHeight); isDblBuf = tagGet(pTags, vaTags, TAG_SCROLLBUFFER_IS_DBLBUF, 0); - scrollBufferReset( - pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight, - ubBitmapFlags, isDblBuf - ); - - // Must be before camera? Shouldn't be as there are priorities on manager list - vPortAddManager(pVPort, (tVpManager*)pManager); - - // Find camera manager, create if not exists - pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); - if(!pManager->pCamera) { - pManager->pCamera = cameraCreate( - pVPort, 0, 0, uwBoundWidth, uwBoundHeight - ); - isCameraCreated = 1; - } - else { - cameraReset(pManager->pCamera, 0,0, uwBoundWidth, uwBoundHeight); - } // Create copperlist entries pCopList = pVPort->pView->pCopList; @@ -100,6 +81,26 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { goto fail; } + scrollBufferReset( + pManager, ubMarginWidth, uwBoundWidth, uwBoundHeight, + ubBitmapFlags, isDblBuf + ); + + // Must be before camera? Shouldn't be as there are priorities on manager list + vPortAddManager(pVPort, (tVpManager*)pManager); + + // Find camera manager, create if not exists + pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); + if(!pManager->pCamera) { + pManager->pCamera = cameraCreate( + pVPort, 0, 0, uwBoundWidth, uwBoundHeight + ); + isCameraCreated = 1; + } + else { + cameraReset(pManager->pCamera, 0,0, uwBoundWidth, uwBoundHeight); + } + // TODO: Update copperlist with current camera pos? va_end(vaTags); @@ -139,6 +140,7 @@ void scrollBufferDestroy(tScrollBufferManager *pManager) { logBlockEnd("scrollBufferDestroy()"); } +FN_HOTSPOT void scrollBufferProcess(tScrollBufferManager *pManager) { UWORD uwVpHeight; @@ -168,7 +170,6 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { // Initial copper block tCopBlock *pBlock = pManager->pStartBlock; pBlock->uwCurrCount = 0; // Rewind copBlock - copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY); copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwOffsX); // Bitplane shift ulPlaneOffs = uwScrollX + (pManager->pBack->BytesPerRow*uwScrollY); for (i = pManager->sCommon.pVPort->ubBPP; i--;) { @@ -176,12 +177,9 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); } - copMove(pCopList, pBlock, &g_pCustom->ddfstrt, 0x30); // Fetch start - copMove(pCopList, pBlock, &g_pCustom->bpl1mod, pManager->uwModulo); // Odd planes modulo - copMove(pCopList, pBlock, &g_pCustom->bpl2mod, pManager->uwModulo); // Even planes modulo - copMove(pCopList, pBlock, &g_pCustom->ddfstop, 0x00D0); // Fetch stop // TODO setting colors before and after copper instructions moved viewport // one line lower on 4bpp - there will be problem on 5 & 6bpp + pBlock->uwCurrCount += 4; // Add constant part // Copper block after Y-break pBlock = pManager->pBreakBlock; @@ -255,6 +253,22 @@ void scrollBufferReset( } pManager->uwModulo = pManager->pBack->BytesPerRow - (uwVpWidth >> 3) - 2; + // Constant stuff in copperlist + tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; + if(pManager->ubFlags & SCROLLBUFFER_FLAG_COPLIST_RAW) { + } + else { + tCopBlock *pBlock = pManager->pStartBlock; + // Set initial WAIT + copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY); + // After bitplane ptrs & bplcon + pBlock->uwCurrCount = 2 * pManager->sCommon.pVPort->ubBPP + 1; + copMove(pCopList, pBlock, &g_pCustom->ddfstrt, 0x30); // Fetch start + copMove(pCopList, pBlock, &g_pCustom->bpl1mod, pManager->uwModulo); // Odd planes modulo + copMove(pCopList, pBlock, &g_pCustom->bpl2mod, pManager->uwModulo); // Even planes modulo + copMove(pCopList, pBlock, &g_pCustom->ddfstop, 0x00D0); // Fetch stop + } + logBlockEnd("scrollBufferReset()"); } diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index 6ba92bdd..2253d7aa 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -235,6 +235,7 @@ void tileBufferReset( logBlockEnd("tileBufferReset()"); } +FN_HOTSPOT void tileBufferProcess(tTileBufferManager *pManager) { WORD wTileIdxX, wTileIdxY; UWORD uwTileOffsX, uwTileOffsY; From 7babcdd7b570f4d76df8203fd83b08a123671a95 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 16 Sep 2018 17:31:11 +0200 Subject: [PATCH 26/56] Power of two optimizations --- include/ace/managers/viewport/tilebuffer.h | 2 +- src/ace/managers/viewport/scrollbuffer.c | 19 +++++++++--- src/ace/managers/viewport/tilebuffer.c | 36 ++++++++++++++-------- 3 files changed, 39 insertions(+), 18 deletions(-) diff --git a/include/ace/managers/viewport/tilebuffer.h b/include/ace/managers/viewport/tilebuffer.h index 6f113f50..964590f3 100644 --- a/include/ace/managers/viewport/tilebuffer.h +++ b/include/ace/managers/viewport/tilebuffer.h @@ -88,7 +88,7 @@ typedef struct { // Redraw state and double buffering tRedrawState pRedrawStates[2]; UBYTE ubStateIdx; - + UBYTE ubWidthShift; } tTileBufferManager; /* globals */ diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index daa19e17..7c2b87ca 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -6,9 +6,20 @@ #include #include - #ifdef AMIGA +static UWORD nearestPowerOf2(UWORD uwVal) { + // https://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2 + // Decrease by one and fill result with ones, then increase by one + --uwVal; + uwVal |= uwVal >> 1; + uwVal |= uwVal >> 2; + uwVal |= uwVal >> 4; + uwVal |= uwVal >> 8; + ++uwVal; + return uwVal; +} + tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { va_list vaTags; tCopList *pCopList = 0; @@ -153,7 +164,7 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { // convert camera pos to scroll pos uwScrollX = pManager->pCamera->uPos.sUwCoord.uwX; - uwScrollY = pManager->pCamera->uPos.sUwCoord.uwY % pManager->uwBmAvailHeight; + uwScrollY = pManager->pCamera->uPos.sUwCoord.uwY & (pManager->uwBmAvailHeight-1); // preparations for new copperlist uwOffsX = 15 - (uwScrollX & 0xF); // Bitplane shift - single @@ -227,7 +238,7 @@ void scrollBufferReset( pManager->uBfrBounds.sUwCoord.uwX = uwBoundWidth; pManager->uBfrBounds.sUwCoord.uwY = uwBoundHeight; // TODO optimize avail height to power of two so that modulo can be an AND - pManager->uwBmAvailHeight = ubMarginWidth * (blockCountCeil(uwVpHeight, ubMarginWidth) + 4); + pManager->uwBmAvailHeight = nearestPowerOf2(ubMarginWidth * (blockCountCeil(uwVpHeight, ubMarginWidth) + 4)); // Destroy old buffer bitmap if(pManager->pFront != pManager->pBack) { @@ -238,7 +249,7 @@ void scrollBufferReset( } // Create new buffer bitmap - uwCalcWidth = uwVpWidth + ubMarginWidth*4; + uwCalcWidth = nearestPowerOf2(uwVpWidth + ubMarginWidth*4); uwCalcHeight = pManager->uwBmAvailHeight + blockCountCeil(uwBoundWidth, uwVpWidth) - 1; pManager->pBack = bitmapCreate( uwCalcWidth, uwCalcHeight, pManager->sCommon.pVPort->ubBPP, ubBitmapFlags diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index 2253d7aa..d9891f99 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -7,6 +7,15 @@ #include #include +static UBYTE shiftFromPowerOfTwo(UWORD uwPot) { + UBYTE ubPower = 0; + while(uwPot > 1) { + uwPot >>= 1; + ++ubPower; + } + return ubPower; +} + #ifdef AMIGA static void tileBufferQueueAdd( @@ -217,8 +226,9 @@ void tileBufferReset( } // Scrollin on one of dirs may be disabled - less redraw on other axis margin - pManager->uwMarginedWidth = pManager->sCommon.pVPort->uwWidth + (4 << ubTileShift); + pManager->uwMarginedWidth = bitmapGetByteWidth(pManager->pScroll->pFront)*8; pManager->uwMarginedHeight = pManager->pScroll->uwBmAvailHeight; + pManager->ubWidthShift = shiftFromPowerOfTwo(pManager->uwMarginedWidth); pManager->ubMarginXLength = MIN( pManager->uTileBounds.sUwCoord.uwY, (pManager->sCommon.pVPort->uwHeight >> ubTileShift) + 4 @@ -265,9 +275,9 @@ void tileBufferProcess(tTileBufferManager *pManager) { if (wTileIdxX != pState->pMarginX->wTilePos) { // Not finished redrawing all column tiles? if(pState->pMarginX->wTileCurr < pState->pMarginX->wTileEnd) { - uwTileOffsY = (pState->pMarginX->wTileCurr << ubTileShift) % pManager->uwMarginedHeight; + uwTileOffsY = (pState->pMarginX->wTileCurr << ubTileShift) & (pManager->uwMarginedHeight-1); ubAddY = (pState->pMarginX->wTilePos << ubTileShift) / pManager->uwMarginedWidth; - uwTileOffsX = (pState->pMarginX->wTilePos << ubTileShift) % pManager->uwMarginedWidth; + uwTileOffsX = (pState->pMarginX->wTilePos << ubTileShift) & (pManager->uwMarginedWidth-1); // Redraw remaining tiles while (pState->pMarginX->wTileCurr < pState->pMarginX->wTileEnd) { tileBufferDrawTileQuick( @@ -338,9 +348,9 @@ void tileBufferProcess(tTileBufferManager *pManager) { if (wTileIdxY != pState->pMarginY->wTilePos) { // Not finished redrawing all row tiles? if(pState->pMarginY->wTileCurr < pState->pMarginY->wTileEnd) { - uwTileOffsY = (pState->pMarginY->wTilePos << ubTileShift) % pManager->uwMarginedHeight; - ubAddY = (pState->pMarginY->wTileCurr << ubTileShift) / pManager->uwMarginedWidth; - uwTileOffsX = (pState->pMarginY->wTileCurr << ubTileShift) % pManager->uwMarginedWidth; + uwTileOffsY = (pState->pMarginY->wTilePos << ubTileShift) & (pManager->uwMarginedHeight-1); + ubAddY = (pState->pMarginY->wTileCurr << ubTileShift) >> pManager->ubWidthShift; + uwTileOffsX = (pState->pMarginY->wTileCurr << ubTileShift) & (pManager->uwMarginedWidth-1); // Redraw remaining tiles while(pState->pMarginY->wTileCurr < pState->pMarginY->wTileEnd) { tileBufferDrawTileQuick( @@ -417,10 +427,10 @@ void tileBufferInitialDraw(const tTileBufferManager *pManager) { pManager->uwMarginedHeight >> ubTileShift ); - UWORD uwTileOffsY = (wStartY << ubTileShift) % pManager->uwMarginedHeight; + UWORD uwTileOffsY = (wStartY << ubTileShift) & (pManager->uwMarginedHeight - 1); for (UWORD uwTileY = wStartY; uwTileY < uwEndY; ++uwTileY) { - UBYTE ubAddY = (wStartX << ubTileShift) / pManager->uwMarginedWidth; - UWORD uwTileOffsX = (wStartX << ubTileShift) % pManager->uwMarginedWidth; + UBYTE ubAddY = (wStartX << ubTileShift) >> pManager->ubWidthShift; + UWORD uwTileOffsX = (wStartX << ubTileShift) & (pManager->uwMarginedWidth-1); for (UWORD uwTileX = wStartX; uwTileX < uwEndX; ++uwTileX) { tileBufferDrawTileQuick( @@ -432,7 +442,7 @@ void tileBufferInitialDraw(const tTileBufferManager *pManager) { uwTileOffsX -= pManager->uwMarginedWidth; } } - uwTileOffsY = (uwTileOffsY + ubTileSize) % pManager->uwMarginedHeight; + uwTileOffsY = (uwTileOffsY + ubTileSize) & (pManager->uwMarginedHeight - 1); } // Copy from back buffer to front buffer @@ -450,9 +460,9 @@ void tileBufferDrawTile( UWORD uwBfrX, uwBfrY; UBYTE ubAddY; - uwBfrY = (uwTileIdxY << pManager->ubTileShift) % pManager->uwMarginedHeight; - ubAddY = (uwTileIdxX << pManager->ubTileShift) / pManager->uwMarginedWidth; - uwBfrX = (uwTileIdxX << pManager->ubTileShift) % pManager->uwMarginedWidth; + uwBfrY = (uwTileIdxY << pManager->ubTileShift) & (pManager->uwMarginedHeight - 1); + ubAddY = (uwTileIdxX << pManager->ubTileShift) >> pManager->ubWidthShift; + uwBfrX = (uwTileIdxX << pManager->ubTileShift) & (pManager->uwMarginedWidth-1); tileBufferDrawTileQuick( pManager, uwTileIdxX, uwTileIdxY, uwBfrX, uwBfrY+ubAddY From 62074acbc42fb104233974fd904a2f70d11ae46e Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 16 Sep 2018 17:43:56 +0200 Subject: [PATCH 27/56] review fixes: safety --- src/ace/managers/viewport/scrollbuffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 7c2b87ca..173e6520 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -241,7 +241,7 @@ void scrollBufferReset( pManager->uwBmAvailHeight = nearestPowerOf2(ubMarginWidth * (blockCountCeil(uwVpHeight, ubMarginWidth) + 4)); // Destroy old buffer bitmap - if(pManager->pFront != pManager->pBack) { + if(pManager->pFront && pManager->pFront != pManager->pBack) { bitmapDestroy(pManager->pFront); } if(pManager->pBack) { From d7223879049694eb320f4391b6cb7d7ce6afc5ed Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 19 Sep 2018 09:47:41 +0200 Subject: [PATCH 28/56] fixed tile redraw, QueueProcess must be in game loop, not in process --- include/ace/managers/viewport/tilebuffer.h | 2 ++ src/ace/managers/viewport/tilebuffer.c | 9 ++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/ace/managers/viewport/tilebuffer.h b/include/ace/managers/viewport/tilebuffer.h index 964590f3..3ea97941 100644 --- a/include/ace/managers/viewport/tilebuffer.h +++ b/include/ace/managers/viewport/tilebuffer.h @@ -95,6 +95,8 @@ typedef struct { /* functions */ +void tileBufferQueueProcess(tTileBufferManager *pManager); + /** * Tilemap buffer manager create fn * Be sure to set camera pos, load tile data & then call tileBufferRedraw()! diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index d9891f99..194a1aea 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -31,13 +31,13 @@ static void tileBufferQueueAdd( ++pState->ubPendingCount; } -static void tileBufferQueueProcess(tTileBufferManager *pManager) { +void tileBufferQueueProcess(tTileBufferManager *pManager) { tRedrawState *pState = &pManager->pRedrawStates[pManager->ubStateIdx]; - UBYTE ubPendingCount = pState->ubPendingCount; - if(ubPendingCount) { + if(pState->ubPendingCount) { + --pState->ubPendingCount; + UBYTE ubPendingCount = pState->ubPendingCount; const tUwCoordYX *pTile = &pState->pPendingQueue[ubPendingCount]; tileBufferDrawTile(pManager, pTile->sUwCoord.uwX, pTile->sUwCoord.uwY); - --pState->ubPendingCount; } } @@ -402,7 +402,6 @@ void tileBufferProcess(tTileBufferManager *pManager) { ); ++pState->pMarginY->wTileCurr; } - tileBufferQueueProcess(pManager); pManager->ubStateIdx = !pManager->ubStateIdx; } From 366fc76c6ce0c877923d5c14f1aa0f5a568708e0 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 22 Sep 2018 13:22:52 +0200 Subject: [PATCH 29/56] added tileBufferSetTile, removed dbg --- include/ace/managers/viewport/tilebuffer.h | 4 ++++ src/ace/managers/viewport/tilebuffer.c | 10 +++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/include/ace/managers/viewport/tilebuffer.h b/include/ace/managers/viewport/tilebuffer.h index 3ea97941..299ae4f7 100644 --- a/include/ace/managers/viewport/tilebuffer.h +++ b/include/ace/managers/viewport/tilebuffer.h @@ -158,5 +158,9 @@ UBYTE tileBufferIsTileOnBuffer( const tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY ); +void tileBufferSetTile( + tTileBufferManager *pManager, UWORD uwX, UWORD uwY, UWORD uwIdx +); + #endif // AMIGA #endif // _ACE_MANAGERS_VIEWPORT_TILEBUFFER_H_ diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index 194a1aea..b3d81150 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -472,9 +472,6 @@ void tileBufferDrawTileQuick( const tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY, UWORD uwBfrX, UWORD uwBfrY ) { - if((pManager->pTileData[uwTileX][uwTileY] << pManager->ubTileShift) >= 320) { - logWrite("ERR %hu,%hu\n", uwTileX, uwTileY); - } blitCopyAligned( pManager->pTileSet, 0, pManager->pTileData[uwTileX][uwTileY] << pManager->ubTileShift, @@ -553,4 +550,11 @@ UBYTE tileBufferIsTileOnBuffer( return 0; } +void tileBufferSetTile( + tTileBufferManager *pManager, UWORD uwX, UWORD uwY, UWORD uwIdx +) { + pManager->pTileData[uwX][uwY] = uwIdx; + tileBufferInvalidateTile(pManager, uwX, uwY); +} + #endif // AMIGA From 3b3c69a5f3c4fb9eae3d1189d084cb1f854b3468 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 23 Sep 2018 13:58:50 +0200 Subject: [PATCH 30/56] this shouldn't be here --- src/ace/managers/game.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/ace/managers/game.c b/src/ace/managers/game.c index fe366a39..d25c6835 100644 --- a/src/ace/managers/game.c +++ b/src/ace/managers/game.c @@ -57,7 +57,6 @@ void gamePopState(void) { g_sGameManager.pStateFirst = pGameState->pPrev; memFree(pGameState, sizeof(tGameState)); - viewLoad(0); } void gameChangeState(tGameCb cbCreate, tGameCb cbLoop, tGameCb cbDestroy) { From 8fd86d554bc8750cf01559fe710d0f83f6e257ef Mon Sep 17 00:00:00 2001 From: KaiN Date: Tue, 2 Oct 2018 16:17:11 +0200 Subject: [PATCH 31/56] Fixed bitmapLoadFromFile ignoring Y offset --- src/ace/utils/bitmap.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ace/utils/bitmap.c b/src/ace/utils/bitmap.c index b160913c..6eaf9208 100644 --- a/src/ace/utils/bitmap.c +++ b/src/ace/utils/bitmap.c @@ -165,7 +165,7 @@ void bitmapLoadFromFile( for(ubPlane = 0; ubPlane != pBitMap->Depth; ++ubPlane) { fileRead( pFile, - &pBitMap->Planes[0][uwWidth*((y*pBitMap->Depth)+ubPlane)+(uwStartX>>3)], + &pBitMap->Planes[0][uwWidth*(((uwStartY + y)*pBitMap->Depth)+ubPlane)+(uwStartX>>3)], ((uwSrcWidth+7)>>3) ); } From 83ba03551879d0a9869d781d29d80dd68c526ee5 Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 3 Oct 2018 15:27:36 +0200 Subject: [PATCH 32/56] minor refactor --- src/ace/managers/viewport/scrollbuffer.c | 29 +++++++++--------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 173e6520..9ee12faf 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -153,22 +153,15 @@ void scrollBufferDestroy(tScrollBufferManager *pManager) { FN_HOTSPOT void scrollBufferProcess(tScrollBufferManager *pManager) { - UWORD uwVpHeight; - - uwVpHeight = pManager->sCommon.pVPort->uwHeight; - UBYTE i; - UWORD uwScrollX, uwScrollY; - ULONG ulPlaneOffs; - ULONG ulPlaneAddr; - UWORD uwOffsX; + UWORD uwVpHeight = pManager->sCommon.pVPort->uwHeight; // convert camera pos to scroll pos - uwScrollX = pManager->pCamera->uPos.sUwCoord.uwX; - uwScrollY = pManager->pCamera->uPos.sUwCoord.uwY & (pManager->uwBmAvailHeight-1); + UWORD uwScrollX = pManager->pCamera->uPos.sUwCoord.uwX; + UWORD uwScrollY = pManager->pCamera->uPos.sUwCoord.uwY & (pManager->uwBmAvailHeight - 1); // preparations for new copperlist - uwOffsX = 15 - (uwScrollX & 0xF); // Bitplane shift - single - uwOffsX = (uwOffsX << 4) | uwOffsX; // Bitplane shift - PF1 | PF2 + UWORD uwOffsX = 15 - (uwScrollX & 0xF); // Bitplane shift - single + uwOffsX = (uwOffsX << 4) | uwOffsX; // Bitplane shift - PF1 | PF2 uwScrollX >>= 3; @@ -182,9 +175,9 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { tCopBlock *pBlock = pManager->pStartBlock; pBlock->uwCurrCount = 0; // Rewind copBlock copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwOffsX); // Bitplane shift - ulPlaneOffs = uwScrollX + (pManager->pBack->BytesPerRow*uwScrollY); - for (i = pManager->sCommon.pVPort->ubBPP; i--;) { - ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + ulPlaneOffs; + ULONG ulPlaneOffs = uwScrollX + (pManager->pBack->BytesPerRow*uwScrollY); + for(UBYTE i = pManager->sCommon.pVPort->ubBPP; i--;) { + ULONG ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + ulPlaneOffs; copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); } @@ -196,10 +189,10 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { pBlock = pManager->pBreakBlock; pBlock->uwCurrCount = 0; // Rewind copBlock - if (pManager->uwBmAvailHeight - uwScrollY <= uwVpHeight) { + if(pManager->uwBmAvailHeight - uwScrollY <= uwVpHeight) { copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY + pManager->uwBmAvailHeight - uwScrollY); - for (i = pManager->sCommon.pVPort->ubBPP; i--;) { - ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + uwScrollX; + for(UBYTE i = pManager->sCommon.pVPort->ubBPP; i--;) { + ULONG ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + uwScrollX; copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } From 548019ea8bfa609a9d20e8788f66a874aa98af44 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 7 Oct 2018 17:22:24 +0200 Subject: [PATCH 33/56] tileBufferIsTileOnBuffer ain't working right yet --- src/ace/managers/viewport/tilebuffer.c | 41 +++++++++++++------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index b3d81150..32a61fb2 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -505,28 +505,29 @@ void tileBufferInvalidateRect( void tileBufferInvalidateTile( tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY ) { - if(!tileBufferIsTileOnBuffer(pManager, uwTileX, uwTileY)) { - return; - } + // FIXME it ain't working right yet + // if(!tileBufferIsTileOnBuffer(pManager, uwTileX, uwTileY)) { + // return; + // } // Previous state will have one more tile to draw, so only check smaller range - const tRedrawState *pState = &pManager->pRedrawStates[pManager->ubStateIdx]; // omit if not yet drawn on redraw margin - let manager draw it when it // will be that tile's turn - if( - pState->pMarginX->wTilePos == uwTileX && - uwTileY >= pState->pMarginX->wTileCurr && - uwTileY <= pState->pMarginX->wTileEnd - ) { - return; - } - if( - pState->pMarginY->wTilePos == uwTileY && - uwTileX >= pState->pMarginX->wTileCurr && - uwTileX <= pState->pMarginX->wTileEnd - ) { - return; - } + // const tRedrawState *pState = &pManager->pRedrawStates[pManager->ubStateIdx]; + // if( + // pState->pMarginX->wTilePos == uwTileX && + // pState->pMarginX->wTileCurr <= uwTileY && + // uwTileY <= pState->pMarginX->wTileEnd + // ) { + // return; + // } + // if( + // pState->pMarginY->wTilePos == uwTileY && + // pState->pMarginY->wTileCurr <= uwTileX && + // uwTileX <= pState->pMarginY->wTileEnd + // ) { + // return; + // } // Add to queue tileBufferQueueAdd(pManager, uwTileX, uwTileY); @@ -536,9 +537,9 @@ UBYTE tileBufferIsTileOnBuffer( const tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY ) { UBYTE ubTileShift = pManager->ubTileShift; - UWORD uwStartX = (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1; + UWORD uwStartX = MAX(0, (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1); UWORD uwEndX = uwStartX + (pManager->uwMarginedWidth >> ubTileShift); - UWORD uwStartY = (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1; + UWORD uwStartY = MAX(0, (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1); UWORD uwEndY = uwStartY + (pManager->uwMarginedHeight >> ubTileShift); if( From fbdd3c4077af3449a5407a262511cf6783eb368e Mon Sep 17 00:00:00 2001 From: KaiN Date: Mon, 8 Oct 2018 21:06:20 +0200 Subject: [PATCH 34/56] Unified fn names in joy and key managers, made 4joy polling optional --- include/ace/managers/joy.h | 4 +- src/ace/managers/joy.c | 128 ++++++++++++++++++++----------------- 2 files changed, 72 insertions(+), 60 deletions(-) diff --git a/include/ace/managers/joy.h b/include/ace/managers/joy.h index 78cd6b12..80bd9337 100644 --- a/include/ace/managers/joy.h +++ b/include/ace/managers/joy.h @@ -59,11 +59,11 @@ typedef struct { extern tJoyManager g_sJoyManager; /* Functions */ -void joyOpen(void); +void joyOpen(UBYTE is4joy); void joySetState(UBYTE ubJoyCode, UBYTE ubJoyState); -UBYTE joyPeek(UBYTE ubJoyCode); +UBYTE joyCheck(UBYTE ubJoyCode); UBYTE joyUse(UBYTE ubJoyCode); diff --git a/src/ace/managers/joy.c b/src/ace/managers/joy.c index f8624914..de5727f4 100644 --- a/src/ace/managers/joy.c +++ b/src/ace/managers/joy.c @@ -10,6 +10,7 @@ /* Globals */ tJoyManager g_sJoyManager; +static UBYTE s_is4joy = 0; #if defined(CONFIG_SYSTEM_OS_FRIENDLY) struct Library *MiscBase = 0; @@ -20,58 +21,63 @@ static UBYTE s_ubOldStatusVal; #endif /* Functions */ -void joyOpen(void) { +void joyOpen(UBYTE is4joy) { + s_is4joy = is4joy; #if defined(CONFIG_SYSTEM_OS_FRIENDLY) - // Open misc.resource for 3rd and 4th joy connected to parallel port - static const char *szOwner = "ACE joy manager"; - MiscBase = (struct Library*)OpenResource(MISCNAME); - if(!MiscBase) { - logWrite("ERR: Couldn't open %s\n", MISCNAME); - return; - } + if(s_is4joy) { + // Open misc.resource for 3rd and 4th joy connected to parallel port + static const char *szOwner = "ACE joy manager"; + MiscBase = (struct Library*)OpenResource(MISCNAME); + if(!MiscBase) { + logWrite("ERR: Couldn't open %s\n", MISCNAME); + return; + } - // Are data/status line currently used? - char *szCurrentOwner; - szCurrentOwner = AllocMiscResource(MR_PARALLELPORT, szOwner); - if(szCurrentOwner) { - logWrite("ERR: Parallel data lines access blocked by: %s\n", szCurrentOwner); - return; - } - szCurrentOwner = AllocMiscResource(MR_PARALLELBITS, szOwner); - if(szCurrentOwner) { - logWrite("ERR: Parallel status lines access blocked by: %s\n", szCurrentOwner); - // Free what was already allocated - FreeMiscResource(MR_PARALLELPORT); - } + // Are data/status line currently used? + char *szCurrentOwner; + szCurrentOwner = AllocMiscResource(MR_PARALLELPORT, szOwner); + if(szCurrentOwner) { + logWrite("ERR: Parallel data lines access blocked by: %s\n", szCurrentOwner); + return; + } + szCurrentOwner = AllocMiscResource(MR_PARALLELBITS, szOwner); + if(szCurrentOwner) { + logWrite("ERR: Parallel status lines access blocked by: %s\n", szCurrentOwner); + // Free what was already allocated + FreeMiscResource(MR_PARALLELPORT); + } - // Save old DDR & value regs - s_ubOldDataDdr = g_pCiaA->ddrb; - s_ubOldStatusDdr = g_pCiaB->ddra; - s_ubOldDataVal = g_pCiaA->prb; - s_ubOldStatusVal = g_pCiaB->pra; + // Save old DDR & value regs + s_ubOldDataDdr = g_pCiaA->ddrb; + s_ubOldStatusDdr = g_pCiaB->ddra; + s_ubOldDataVal = g_pCiaA->prb; + s_ubOldStatusVal = g_pCiaB->pra; - // Set data direction register to input. Status lines are as follows: - // bit 0: BUSY - // bit 2: SEL - g_pCiaB->ddra |= BV(0) | BV(2); // Status lines DDR - g_pCiaA->ddrb = 0xFF; // Data lines DDR + // Set data direction register to input. Status lines are as follows: + // bit 0: BUSY + // bit 2: SEL + g_pCiaB->ddra |= BV(0) | BV(2); // Status lines DDR + g_pCiaA->ddrb = 0xFF; // Data lines DDR - g_pCiaB->pra &= 0xFF^(BV(0) | BV(2)); // Status lines values - g_pCiaA->prb = 0; // Data lines values + g_pCiaB->pra &= 0xFF^(BV(0) | BV(2)); // Status lines values + g_pCiaA->prb = 0; // Data lines values + } #endif } void joyClose(void) { #if defined(CONFIG_SYSTEM_OS_FRIENDLY) - // Restore old status/data DDR/val regs - g_pCiaA->prb = s_ubOldDataVal; - g_pCiaB->pra = s_ubOldStatusVal; - g_pCiaA->ddrb= s_ubOldDataDdr; - g_pCiaB->ddra = s_ubOldStatusDdr; - - // Close misc.resource - FreeMiscResource(MR_PARALLELPORT); - FreeMiscResource(MR_PARALLELBITS); + if(s_is4joy) { + // Restore old status/data DDR/val regs + g_pCiaA->prb = s_ubOldDataVal; + g_pCiaB->pra = s_ubOldStatusVal; + g_pCiaA->ddrb= s_ubOldDataDdr; + g_pCiaB->ddra = s_ubOldStatusDdr; + + // Close misc.resource + FreeMiscResource(MR_PARALLELPORT); + FreeMiscResource(MR_PARALLELBITS); + } #endif } @@ -79,7 +85,7 @@ void joySetState(UBYTE ubJoyCode, UBYTE ubJoyState) { g_sJoyManager.pStates[ubJoyCode] = ubJoyState; } -UBYTE joyPeek(UBYTE ubJoyCode) { +UBYTE joyCheck(UBYTE ubJoyCode) { return g_sJoyManager.pStates[ubJoyCode] != JOY_NACTIVE; } @@ -95,8 +101,6 @@ void joyProcess(void) { UBYTE ubCiaAPra = g_pCiaA->pra; UWORD uwJoyDataPort1 = g_pCustom->joy0dat; UWORD uwJoyDataPort2 = g_pCustom->joy1dat; - UBYTE ubParData = g_pCiaA->prb; - UBYTE ubParStatus = g_pCiaB->pra; UWORD pJoyLookup[] = { !BTST(ubCiaAPra, 7), // Joy 1 fire (PORT 2) @@ -110,21 +114,29 @@ void joyProcess(void) { BTST(uwJoyDataPort1 >> 1 ^ uwJoyDataPort1, 0), // Joy 2 down (PORT 1) BTST(uwJoyDataPort1, 9), // Joy 2 left (PORT 1) BTST(uwJoyDataPort1, 1), // Joy 2 right (PORT 1) - - !BTST(ubParStatus, 2), // Joy 3 fire - !BTST(ubParData, 0), // Joy 3 up - !BTST(ubParData, 1), // Joy 3 down - !BTST(ubParData, 2), // Joy 3 left - !BTST(ubParData, 3), // Joy 3 right - - !BTST(ubParStatus , 0), // Joy 4 fire - !BTST(ubParData , 4), // Joy 4 up - !BTST(ubParData , 5), // Joy 4 down - !BTST(ubParData , 6), // Joy 4 left - !BTST(ubParData , 7) // Joy 4 right }; - UBYTE ubJoyCode = 20; + UBYTE ubJoyCode; + if(s_is4joy) { + ubJoyCode = 20; + UBYTE ubParData = g_pCiaA->prb; + UBYTE ubParStatus = g_pCiaB->pra; + + pJoyLookup[10] = !BTST(ubParStatus, 2); // Joy 3 fire + pJoyLookup[11] = !BTST(ubParData, 0); // Joy 3 up + pJoyLookup[12] = !BTST(ubParData, 1); // Joy 3 down + pJoyLookup[13] = !BTST(ubParData, 2); // Joy 3 left + pJoyLookup[14] = !BTST(ubParData, 3); // Joy 3 right + + pJoyLookup[15] = !BTST(ubParStatus , 0); // Joy 4 fire + pJoyLookup[16] = !BTST(ubParData , 4); // Joy 4 up + pJoyLookup[17] = !BTST(ubParData , 5); // Joy 4 down + pJoyLookup[18] = !BTST(ubParData , 6); // Joy 4 left + pJoyLookup[19] = !BTST(ubParData , 7); // Joy 4 right + } + else { + ubJoyCode = 10; + } while (ubJoyCode--) { if (pJoyLookup[ubJoyCode]) { if (g_sJoyManager.pStates[ubJoyCode] == JOY_NACTIVE) { From efad3135e47ec3a9c409771819992afcd158625b Mon Sep 17 00:00:00 2001 From: KaiN Date: Tue, 9 Oct 2018 18:52:56 +0200 Subject: [PATCH 35/56] Added double buffering for camera --- include/ace/managers/viewport/camera.h | 13 +++++--- src/ace/managers/viewport/camera.c | 41 +++++++++++++++++------- src/ace/managers/viewport/scrollbuffer.c | 4 +-- src/ace/managers/viewport/simplebuffer.c | 4 ++- 4 files changed, 43 insertions(+), 19 deletions(-) diff --git a/include/ace/managers/viewport/camera.h b/include/ace/managers/viewport/camera.h index b6586f33..d3a15b0b 100644 --- a/include/ace/managers/viewport/camera.h +++ b/include/ace/managers/viewport/camera.h @@ -17,13 +17,16 @@ typedef struct { tVpManager sCommon; - tUwCoordYX uPos; /// Current camera pos - tUwCoordYX uLastPos; /// Previous camera pos - tUwCoordYX uMaxPos; /// Max camera pos: world W&H - camera W&H + tUwCoordYX uPos; ///< Current camera pos + tUwCoordYX uLastPos[2]; ///< Previous camera pos + tUwCoordYX uMaxPos; ///< Max camera pos: world W&H - camera W&H + UBYTE ubBfr; + UBYTE isDblBfr; } tCameraManager; tCameraManager *cameraCreate( - tVPort *pVPort, UWORD uwPosX, UWORD uwPosY, UWORD uwMaxX, UWORD uwMaxY + tVPort *pVPort, UWORD uwPosX, UWORD uwPosY, UWORD uwMaxX, UWORD uwMaxY, + UBYTE isDblBfr ); void cameraDestroy(tCameraManager *pManager); @@ -31,7 +34,7 @@ void cameraProcess(tCameraManager *pManager); void cameraReset( tCameraManager *pManager, - UWORD uwPosX, UWORD uwPosY, UWORD uwMaxX, UWORD uwMaxY + UWORD uwPosX, UWORD uwPosY, UWORD uwMaxX, UWORD uwMaxY, UBYTE isDblBfr ); void cameraSetCoord(tCameraManager *pManager, UWORD uwX, UWORD uwY); diff --git a/src/ace/managers/viewport/camera.c b/src/ace/managers/viewport/camera.c index d0a53bd7..c1b0c97f 100644 --- a/src/ace/managers/viewport/camera.c +++ b/src/ace/managers/viewport/camera.c @@ -5,8 +5,14 @@ #include #include -tCameraManager *cameraCreate(tVPort *pVPort, UWORD uwPosX, UWORD uwPosY, UWORD uwMaxX, UWORD uwMaxY) { - logBlockBegin("cameraCreate(pVPort: %p, uwPosX: %u, uwPosY: %u, uwMaxX: %u, uwMaxY: %u)", pVPort, uwPosX, uwPosY, uwMaxX, uwMaxY); +tCameraManager *cameraCreate( + tVPort *pVPort, UWORD uwPosX, UWORD uwPosY, UWORD uwMaxX, UWORD uwMaxY, + UBYTE isDblBfr +) { + logBlockBegin( + "cameraCreate(pVPort: %p, uwPosX: %u, uwPosY: %u, uwMaxX: %u, uwMaxY: %u, isDblBfr: %hhu)", + pVPort, uwPosX, uwPosY, uwMaxX, uwMaxY, isDblBfr + ); tCameraManager *pManager; pManager = memAllocFastClear(sizeof(tCameraManager)); @@ -17,7 +23,7 @@ tCameraManager *cameraCreate(tVPort *pVPort, UWORD uwPosX, UWORD uwPosY, UWORD u pManager->sCommon.ubId = VPM_CAMERA; logWrite("Resetting camera bounds...\n"); - cameraReset(pManager, uwPosX, uwPosY, uwMaxX, uwMaxY); + cameraReset(pManager, uwPosX, uwPosY, uwMaxX, uwMaxY, isDblBfr); logWrite("Attaching camera to VPort...\n"); vPortAddManager(pVPort, (tVpManager*)pManager); @@ -32,16 +38,29 @@ void cameraDestroy(tCameraManager *pManager) { } void cameraProcess(tCameraManager *pManager) { - pManager->uLastPos.ulYX = pManager->uPos.ulYX; + pManager->uLastPos[pManager->ubBfr].ulYX = pManager->uPos.ulYX; + if(pManager->isDblBfr) { + pManager->ubBfr = !pManager->ubBfr; + } } -void cameraReset(tCameraManager *pManager, UWORD uwStartX, UWORD uwStartY, UWORD uwWidth, UWORD uwHeight) { - logBlockBegin("cameraReset(pManager: %p, uwStartX: %u, uwStartY: %u, uwWidth: %u, uwHeight: %u)", pManager, uwStartX, uwStartY, uwWidth, uwHeight); +void cameraReset( + tCameraManager *pManager, + UWORD uwStartX, UWORD uwStartY, UWORD uwWidth, UWORD uwHeight, UBYTE isDblBfr +) { + logBlockBegin( + "cameraReset(pManager: %p, uwStartX: %u, uwStartY: %u, uwWidth: %u, uwHeight: %u, isDblBfr: %hhu)", + pManager, uwStartX, uwStartY, uwWidth, uwHeight, isDblBfr + ); pManager->uPos.sUwCoord.uwX = uwStartX; pManager->uPos.sUwCoord.uwY = uwStartY; - pManager->uLastPos.sUwCoord.uwX = uwStartX; - pManager->uLastPos.sUwCoord.uwY = uwStartY; + pManager->uLastPos[0].sUwCoord.uwX = uwStartX; + pManager->uLastPos[0].sUwCoord.uwY = uwStartY; + pManager->uLastPos[1].sUwCoord.uwX = uwStartX; + pManager->uLastPos[1].sUwCoord.uwY = uwStartY; + pManager->isDblBfr = isDblBfr; + pManager->ubBfr = 0; // Max camera coords based on viewport size pManager->uMaxPos.sUwCoord.uwX = uwWidth - pManager->sCommon.pVPort->uwWidth; @@ -71,7 +90,7 @@ void cameraCenterAt(tCameraManager *pManager, UWORD uwAvgX, UWORD uwAvgY) { } UBYTE cameraIsMoved(tCameraManager *pManager) { - return pManager->uPos.ulYX != pManager->uLastPos.ulYX; + return pManager->uPos.ulYX != pManager->uLastPos[pManager->ubBfr].ulYX; } UWORD cameraGetXDiff(tCameraManager *pManager) { @@ -83,9 +102,9 @@ UWORD cameraGetYDiff(tCameraManager *pManager) { } WORD cameraGetDeltaX(tCameraManager *pManager) { - return (pManager->uPos.sUwCoord.uwX - pManager->uLastPos.sUwCoord.uwX); + return (pManager->uPos.sUwCoord.uwX - pManager->uLastPos[pManager->ubBfr].sUwCoord.uwX); } WORD cameraGetDeltaY(tCameraManager *pManager) { - return (pManager->uPos.sUwCoord.uwY - pManager->uLastPos.sUwCoord.uwY); + return (pManager->uPos.sUwCoord.uwY - pManager->uLastPos[pManager->ubBfr].sUwCoord.uwY); } diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 9ee12faf..fc19d96b 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -104,12 +104,12 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); if(!pManager->pCamera) { pManager->pCamera = cameraCreate( - pVPort, 0, 0, uwBoundWidth, uwBoundHeight + pVPort, 0, 0, uwBoundWidth, uwBoundHeight, isDblBuf ); isCameraCreated = 1; } else { - cameraReset(pManager->pCamera, 0,0, uwBoundWidth, uwBoundHeight); + cameraReset(pManager->pCamera, 0,0, uwBoundWidth, uwBoundHeight, isDblBuf); } // TODO: Update copperlist with current camera pos? diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 7548284d..8fcb4532 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -160,7 +160,9 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); if(!pManager->pCamera) { isCameraCreated = 1; - pManager->pCamera = cameraCreate(pVPort, 0, 0, uwBoundWidth, uwBoundHeight); + pManager->pCamera = cameraCreate( + pVPort, 0, 0, uwBoundWidth, uwBoundHeight, isDblBfr + ); } pCopList = pVPort->pView->pCopList; From 75fda79313a10978ce0fd135b48676c3c369e6ec Mon Sep 17 00:00:00 2001 From: KaiN Date: Tue, 27 Nov 2018 15:48:16 +0100 Subject: [PATCH 36/56] Some stuff that asman pointed out --- src/ace/managers/key.c | 9 +++----- src/ace/managers/system.c | 47 +++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/src/ace/managers/key.c b/src/ace/managers/key.c index 77b15026..6dfef210 100644 --- a/src/ace/managers/key.c +++ b/src/ace/managers/key.c @@ -52,12 +52,9 @@ void INTERRUPT keyIntServer( UBYTE ubKeyReleased = ubKeyCode & KEY_RELEASED_BIT; ubKeyCode >>= 1; - if(ubKeyReleased) { - keyIntSetState(pKeyManager, ubKeyCode, KEY_NACTIVE); - } - else { - keyIntSetState(pKeyManager, ubKeyCode, KEY_ACTIVE); - } + keyIntSetState( + pKeyManager, ubKeyCode, ubKeyReleased ? KEY_NACTIVE : KEY_ACTIVE + ); // End handshake UWORD uwDelta; diff --git a/src/ace/managers/system.c b/src/ace/managers/system.c index 7ff1448c..3badb4ca 100644 --- a/src/ace/managers/system.c +++ b/src/ace/managers/system.c @@ -66,6 +66,9 @@ const UWORD s_uwOsMinDma = DMAF_DISK | DMAF_BLITTER; //----------------------------------------------------------- INTERRUPT HANDLERS +// All interrupt handlers should clear their flags twice +// http://eab.abime.net/showthread.php?p=834185#post834185 + FN_HOTSPOT void HWINTERRUPT int1Handler(void) { // Soft / diskBlk / TBE (RS232 TX end) @@ -74,31 +77,35 @@ void HWINTERRUPT int1Handler(void) { FN_HOTSPOT void HWINTERRUPT int2Handler(void) { // Parallel, keyboard, mouse, "some of disk functions" - // ACE only uses it for keyboard so no decision taking here atm - // TODO: this could be re-enabled with vblank since we don't need it - // to retrigger during same frame. - UBYTE ubIcrA = g_pCiaA->icr; // Read clears interrupt flags - if(ubIcrA & CIAICR_SERIAL) { - // Keyboard - if(s_pAceInterrupts[INTB_PORTS].pHandler) { - s_pAceInterrupts[INTB_PORTS].pHandler( - g_pCustom, s_pAceInterrupts[INTB_PORTS].pData - ); + UWORD uwIntReq = g_pCustom->intreqr; + if(uwIntReq & INTF_PORTS) { + UBYTE ubIcrA = g_pCiaA->icr; // Read clears interrupt flags + if(ubIcrA & CIAICR_SERIAL) { + // Keyboard + if(s_pAceInterrupts[INTB_PORTS].pHandler) { + s_pAceInterrupts[INTB_PORTS].pHandler( + g_pCustom, s_pAceInterrupts[INTB_PORTS].pData + ); + } } - } - if(ubIcrA & CIAICR_FLAG) { + if(ubIcrA & CIAICR_FLAG) { - } - if(ubIcrA & CIAICR_TIMER_A) { + } + if(ubIcrA & CIAICR_TIMER_A) { - } - if(ubIcrA & CIAICR_TIMER_B) { + } + if(ubIcrA & CIAICR_TIMER_B) { - } - if(ubIcrA & CIAICR_TOD) { + } + if(ubIcrA & CIAICR_TOD) { + } + // TODO: this could be re-enabled in vblank since we don't need it + // to retrigger during same frame. Or perhaps it's needed so that kbd + // controller won't overflow its queue + g_pCustom->intreq = INTF_PORTS; + g_pCustom->intreq = INTF_PORTS; } - g_pCustom->intreq = INTF_PORTS; } FN_HOTSPOT @@ -142,6 +149,7 @@ void HWINTERRUPT int3Handler(void) { uwReqClr |= INTF_BLIT; } g_pCustom->intreq = uwReqClr; + g_pCustom->intreq = uwReqClr; } FN_HOTSPOT @@ -192,6 +200,7 @@ void systemCreate(void) { WaitTOF(); LoadView(0); WaitTOF(); + WaitTOF(); // Wait for interlaced screen to finish // get VBR location on 68010+ machine // TODO VBR From 007d0612397d92598453b1f103c27e1fc5b9f8c6 Mon Sep 17 00:00:00 2001 From: KaiN Date: Thu, 7 Feb 2019 21:15:34 +0100 Subject: [PATCH 37/56] fixed disabling CopBlocks, scrollBuffer tweak scrollBuffer now disables second copBlock if not needed --- src/ace/managers/copper.c | 13 +++++-------- src/ace/managers/viewport/scrollbuffer.c | 5 ++++- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ace/managers/copper.c b/src/ace/managers/copper.c index 820175c6..bc703bd7 100644 --- a/src/ace/managers/copper.c +++ b/src/ace/managers/copper.c @@ -285,7 +285,7 @@ void copBlockEnable(tCopList *pCopList, tCopBlock *pBlock) { } void copBlockDisable(tCopList *pCopList, tCopBlock *pBlock) { - pBlock->ubDisabled = 0; + pBlock->ubDisabled = 1; pBlock->pNext->ubUpdated = 2; pCopList->ubStatus |= STATUS_UPDATE; } @@ -328,15 +328,12 @@ UBYTE copBfrRealloc(void) { } void copReorderBlocks(void) { + tCopList *pCopList = g_sCopManager.pCopList; UBYTE ubDone; - tCopList *pCopList; - tCopBlock *pBlock, *pPrev; - - pCopList = g_sCopManager.pCopList; do { ubDone = 1; - pBlock = pCopList->pFirstBlock; - pPrev = 0; + tCopBlock *pBlock = pCopList->pFirstBlock; + tCopBlock *pPrev = 0; while(pBlock->pNext) { if(pBlock->uWaitPos.ulYX > pBlock->pNext->uWaitPos.ulYX) { if(!pPrev) { @@ -498,7 +495,7 @@ void copBlockWait(tCopList *pCopList, tCopBlock *pBlock, UWORD uwX, UWORD uwY) { pBlock->uWaitPos.sUwCoord.uwX = uwX; pBlock->ubUpdated = 2; - pCopList->ubStatus |= STATUS_UPDATE; + pCopList->ubStatus |= STATUS_UPDATE | STATUS_REORDER; } void copMove(tCopList *pCopList, tCopBlock *pBlock, volatile void *pAddr, UWORD uwValue) { diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index fc19d96b..14eaaca6 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -190,6 +190,9 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { pBlock->uwCurrCount = 0; // Rewind copBlock if(pManager->uwBmAvailHeight - uwScrollY <= uwVpHeight) { + if(pBlock->ubDisabled) { + copBlockEnable(pCopList, pBlock); + } copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY + pManager->uwBmAvailHeight - uwScrollY); for(UBYTE i = pManager->sCommon.pVPort->ubBPP; i--;) { ULONG ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + uwScrollX; @@ -198,7 +201,7 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { } } else { - copBlockWait(pCopList, pBlock, 0x7F, 0xFF); + copBlockDisable(pCopList, pBlock); } } From 5f974dec3da01050aa97a5aa4f5515f1d0d694a7 Mon Sep 17 00:00:00 2001 From: KaiN Date: Tue, 26 Feb 2019 15:52:02 +0100 Subject: [PATCH 38/56] perhaps it'll fix #88 --- src/ace/utils/extview.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/ace/utils/extview.c b/src/ace/utils/extview.c index 2b86de85..464a1a30 100644 --- a/src/ace/utils/extview.c +++ b/src/ace/utils/extview.c @@ -109,6 +109,7 @@ void viewLoad(tView *pView) { if(!pView) { g_sCopManager.pCopList = g_sCopManager.pBlankList; g_pCustom->bplcon0 = 0; // No output + g_pCustom->bplcon3 = 0; // AGA fix g_pCustom->fmode = 0; // AGA fix for(UBYTE i = 0; i < 6; ++i) { g_pCustom->bplpt[i] = 0; @@ -120,6 +121,7 @@ void viewLoad(tView *pView) { g_sCopManager.pCopList = pView->pCopList; g_pCustom->bplcon0 = (pView->pFirstVPort->ubBPP << 12) | BV(9); // BPP + composite output g_pCustom->fmode = 0; // AGA fix + g_pCustom->bplcon3 = 0; // AGA fix g_pCustom->diwstrt = 0x2C81; // VSTART: 0x2C, HSTART: 0x81 g_pCustom->diwstop = 0x2CC1; // VSTOP: 0x2C, HSTOP: 0xC1 viewUpdateCLUT(pView); From 5ba6a43182c5f184239cafb835e6528697210f90 Mon Sep 17 00:00:00 2001 From: KaiN Date: Mon, 4 Mar 2019 22:56:44 +0100 Subject: [PATCH 39/56] fixed tileBufferIsTileOnBuffer() region check previous version allowed drawing on outermost margins, which resulted in drawing stuff when it shouldn't be drawn --- src/ace/managers/viewport/scrollbuffer.c | 2 +- src/ace/managers/viewport/tilebuffer.c | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 14eaaca6..044e099a 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -233,7 +233,7 @@ void scrollBufferReset( pManager->uwVpHeightPrev = 0; pManager->uBfrBounds.sUwCoord.uwX = uwBoundWidth; pManager->uBfrBounds.sUwCoord.uwY = uwBoundHeight; - // TODO optimize avail height to power of two so that modulo can be an AND + // Optimize avail height to power of two so that modulo can be an AND pManager->uwBmAvailHeight = nearestPowerOf2(ubMarginWidth * (blockCountCeil(uwVpHeight, ubMarginWidth) + 4)); // Destroy old buffer bitmap diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index 32a61fb2..96237ac0 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -87,6 +87,7 @@ tTileBufferManager *tileBufferCreate(void *pTags, ...) { logWrite( "ERR: No tile boundaries (TAG_TILEBUFFER_BOUND_TILE_X or _Y) specified!\n" ); + goto fail; } pManager->pTileData = 0; @@ -538,9 +539,9 @@ UBYTE tileBufferIsTileOnBuffer( ) { UBYTE ubTileShift = pManager->ubTileShift; UWORD uwStartX = MAX(0, (pManager->pCamera->uPos.sUwCoord.uwX >> ubTileShift) -1); - UWORD uwEndX = uwStartX + (pManager->uwMarginedWidth >> ubTileShift); + UWORD uwEndX = uwStartX + ((pManager->uwMarginedWidth >> ubTileShift) - 2); UWORD uwStartY = MAX(0, (pManager->pCamera->uPos.sUwCoord.uwY >> ubTileShift) -1); - UWORD uwEndY = uwStartY + (pManager->uwMarginedHeight >> ubTileShift); + UWORD uwEndY = uwStartY + ((pManager->uwMarginedHeight >> ubTileShift) - 2); if( uwStartX <= uwTileX && uwTileX <= uwEndX && uwTileX && From 38e0d77cbc53fa4e4164767a4df0fb15bc2fc62b Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 24 Apr 2019 19:13:17 +0200 Subject: [PATCH 40/56] minor formatting --- src/ace/managers/joy.c | 6 +++--- src/ace/managers/memory.c | 2 +- src/ace/managers/system.c | 4 ++-- src/ace/utils/bitmap.c | 10 +++++----- src/ace/utils/font.c | 2 +- src/ace/utils/palette.c | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/ace/managers/joy.c b/src/ace/managers/joy.c index de5727f4..11f2ec01 100644 --- a/src/ace/managers/joy.c +++ b/src/ace/managers/joy.c @@ -29,7 +29,7 @@ void joyOpen(UBYTE is4joy) { static const char *szOwner = "ACE joy manager"; MiscBase = (struct Library*)OpenResource(MISCNAME); if(!MiscBase) { - logWrite("ERR: Couldn't open %s\n", MISCNAME); + logWrite("ERR: Couldn't open '%s'\n", MISCNAME); return; } @@ -37,12 +37,12 @@ void joyOpen(UBYTE is4joy) { char *szCurrentOwner; szCurrentOwner = AllocMiscResource(MR_PARALLELPORT, szOwner); if(szCurrentOwner) { - logWrite("ERR: Parallel data lines access blocked by: %s\n", szCurrentOwner); + logWrite("ERR: Parallel data lines access blocked by: '%s'\n", szCurrentOwner); return; } szCurrentOwner = AllocMiscResource(MR_PARALLELBITS, szOwner); if(szCurrentOwner) { - logWrite("ERR: Parallel status lines access blocked by: %s\n", szCurrentOwner); + logWrite("ERR: Parallel status lines access blocked by: '%s'\n", szCurrentOwner); // Free what was already allocated FreeMiscResource(MR_PARALLELPORT); } diff --git a/src/ace/managers/memory.c b/src/ace/managers/memory.c index 565ab630..853b9528 100644 --- a/src/ace/managers/memory.c +++ b/src/ace/managers/memory.c @@ -233,7 +233,7 @@ void _memCheckTrash(void *pMem, UWORD uwLine, char *szFile) { } if(pDead[0] != 0xDE || pDead[1] != 0xAD || pDead[2] != 0xBE || pDead[3] != 0xEF) { filePrintf( - s_pMemLog, "ERR: Right mem trashed: %hu%p (%s:%u)\n", + s_pMemLog, "ERR: Right mem trashed: %hu@%p (%s:%u)\n", pEntry->uwId, pMem, uwLine, szFile ); fileFlush(s_pMemLog); diff --git a/src/ace/managers/system.c b/src/ace/managers/system.c index 3badb4ca..5ab12c0a 100644 --- a/src/ace/managers/system.c +++ b/src/ace/managers/system.c @@ -175,8 +175,8 @@ void HWINTERRUPT int7Handler(void) { //-------------------------------------------------------------------- FUNCTIONS void systemKill(const char *szMsg) { - printf("ERR: SYSKILL: %s", szMsg); - logWrite("ERR: SYSKILL: %s", szMsg); + printf("ERR: SYSKILL: '%s'", szMsg); + logWrite("ERR: SYSKILL: '%s'", szMsg); if(GfxBase) { CloseLibrary((struct Library *) GfxBase); diff --git a/src/ace/utils/bitmap.c b/src/ace/utils/bitmap.c index 6eaf9208..5190bd53 100644 --- a/src/ace/utils/bitmap.c +++ b/src/ace/utils/bitmap.c @@ -94,13 +94,13 @@ void bitmapLoadFromFile( systemUse(); logBlockBegin( - "bitmapLoadFromFile(pBitMap: %p, szFilePath: %s, uwStartX: %u, uwStartY: %u)", + "bitmapLoadFromFile(pBitMap: %p, szFilePath: '%s', uwStartX: %u, uwStartY: %u)", pBitMap, szFilePath, uwStartX, uwStartY ); // Open source bitmap tFile *pFile = fileOpen(szFilePath, "r"); if(!pFile) { - logWrite("ERR: File does not exist: %s\n", szFilePath); + logWrite("ERR: File does not exist\n", szFilePath); logBlockEnd("bitmapLoadFromFile()"); systemUnuse(); return; @@ -195,11 +195,11 @@ tBitMap *bitmapCreateFromFile(const char *szFilePath, UBYTE isFast) { UBYTE ubPlaneCount; // Bitplane count UBYTE i; - logBlockBegin("bitmapCreateFromFile(szFilePath: %s)", szFilePath); + logBlockBegin("bitmapCreateFromFile(szFilePath: '%s')", szFilePath); pFile = fileOpen(szFilePath, "r"); if(!pFile) { fileClose(pFile); - logWrite("ERR: File does not exist: %s\n", szFilePath); + logWrite("ERR: File does not exist\n"); logBlockEnd("bitmapCreateFromFile()"); return 0; } @@ -294,7 +294,7 @@ void bitmapDump(const tBitMap *pBitMap) { void bitmapSave(const tBitMap *pBitMap, const char *szPath) { systemUse(); - logBlockBegin("bitmapSave(pBitMap: %p, szPath: %s)", pBitMap, szPath); + logBlockBegin("bitmapSave(pBitMap: %p, szPath: '%s')", pBitMap, szPath); tFile *pFile = fileOpen(szPath, "wb"); if(!pFile) { diff --git a/src/ace/utils/font.c b/src/ace/utils/font.c index 26a55617..61e8aa43 100644 --- a/src/ace/utils/font.c +++ b/src/ace/utils/font.c @@ -17,7 +17,7 @@ static inline UBYTE fontGlyphWidth(const tFont *pFont, char c) { tFont *fontCreate(const char *szFontName) { tFile *pFontFile; tFont *pFont; - logBlockBegin("fontCreate(szFontName: %s)", szFontName); + logBlockBegin("fontCreate(szFontName: '%s')", szFontName); pFontFile = fileOpen(szFontName, "r"); if (!pFontFile) { diff --git a/src/ace/utils/palette.c b/src/ace/utils/palette.c index a2bf356d..8a1882b5 100644 --- a/src/ace/utils/palette.c +++ b/src/ace/utils/palette.c @@ -11,7 +11,7 @@ void paletteLoad(char *szFileName, UWORD *pPalette, UBYTE ubMaxLength) { tFile *pFile; UBYTE ubPaletteLength; - logBlockBegin("paletteLoad(szFileName: %s, pPalette: %p, ubMaxLength: %hu)", szFileName, pPalette, ubMaxLength); + logBlockBegin("paletteLoad(szFileName: '%s', pPalette: %p, ubMaxLength: %hu)", szFileName, pPalette, ubMaxLength); pFile = fileOpen(szFileName, "r"); fileRead(pFile, &ubPaletteLength, sizeof(UBYTE)); From b1c37fc30da1e1e16275e81627d951e699b0c892 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sun, 24 Mar 2019 16:20:49 +0100 Subject: [PATCH 41/56] parse tRGB form hex code string, tileset_conv has settable bg color --- tools/src/common/bitmap.cpp | 4 ++-- tools/src/common/bitmap.h | 2 +- tools/src/common/rgb.cpp | 25 +++++++++++++++++++++++++ tools/src/common/rgb.h | 5 ++++- tools/src/tileset_conv.cpp | 9 +++++++-- 5 files changed, 39 insertions(+), 6 deletions(-) create mode 100644 tools/src/common/rgb.cpp diff --git a/tools/src/common/bitmap.cpp b/tools/src/common/bitmap.cpp index 982081ad..2175d024 100644 --- a/tools/src/common/bitmap.cpp +++ b/tools/src/common/bitmap.cpp @@ -8,8 +8,8 @@ #include "../common/lodepng.h" #include "../common/endian.h" -tChunkyBitmap::tChunkyBitmap(uint16_t uwWidth, uint16_t uwHeight): - m_uwWidth(uwWidth), m_uwHeight(uwHeight), m_vData(m_uwWidth * m_uwHeight) +tChunkyBitmap::tChunkyBitmap(uint16_t uwWidth, uint16_t uwHeight, tRgb Bg): + m_uwWidth(uwWidth), m_uwHeight(uwHeight), m_vData(m_uwWidth * m_uwHeight, Bg) { } diff --git a/tools/src/common/bitmap.h b/tools/src/common/bitmap.h index 0e6837da..078fb980 100644 --- a/tools/src/common/bitmap.h +++ b/tools/src/common/bitmap.h @@ -23,7 +23,7 @@ class tChunkyBitmap { const tPlanarBitmap &Planar, const tPalette &vPalette ); - tChunkyBitmap(uint16_t uwWidth, uint16_t uwHeight); + tChunkyBitmap(uint16_t uwWidth, uint16_t uwHeight, tRgb Bg = tRgb(0)); tChunkyBitmap(uint16_t uwWidth, uint16_t uwHeight, const uint8_t *pData); diff --git a/tools/src/common/rgb.cpp b/tools/src/common/rgb.cpp new file mode 100644 index 00000000..2eed38e1 --- /dev/null +++ b/tools/src/common/rgb.cpp @@ -0,0 +1,25 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "rgb.h" +#include + +tRgb::tRgb(const std::string &szCode) +{ + if(szCode[0] == '#') { + if(szCode.length() == 3 + 1) { + this->ubR = std::stoul(szCode.substr(1, 1), nullptr, 16); + this->ubG = std::stoul(szCode.substr(2, 1), nullptr, 16); + this->ubB = std::stoul(szCode.substr(3, 1), nullptr, 16); + } + else if(szCode.length() == 6 + 1) { + this->ubR = std::stoul(szCode.substr(1, 2), nullptr, 16); + this->ubG = std::stoul(szCode.substr(3, 2), nullptr, 16); + this->ubB = std::stoul(szCode.substr(5, 2), nullptr, 16); + } + else { + throw std::runtime_error("Can't convert color code"); + } + } +} diff --git a/tools/src/common/rgb.h b/tools/src/common/rgb.h index 2623f78d..5fbaba2a 100644 --- a/tools/src/common/rgb.h +++ b/tools/src/common/rgb.h @@ -5,7 +5,8 @@ #ifndef _ACE_TOOLS_COMMON_RGB_H_ #define _ACE_TOOLS_COMMON_RGB_H_ -#include +#include +#include struct tRgb { uint8_t ubR, ubG, ubB; @@ -19,6 +20,8 @@ struct tRgb { tRgb(): ubR(0), ubG(0), ubB(0) { } + tRgb(const std::string &szCode); + bool operator == (const tRgb &Rhs) const { return ubB == Rhs.ubB && ubG == Rhs.ubG && ubR == Rhs.ubR; } diff --git a/tools/src/tileset_conv.cpp b/tools/src/tileset_conv.cpp index ecc6a183..cf73f65c 100644 --- a/tools/src/tileset_conv.cpp +++ b/tools/src/tileset_conv.cpp @@ -79,8 +79,8 @@ int main(int lArgCount, const char *pArgs[]) int16_t wLastFull = -1; for(uint16_t i = 0; i < 256; ++i) { auto Tile = tChunkyBitmap::fromPng(fmt::format("{}/{}.png", szInPath, i)); + vTiles.push_back(std::move(Tile)); if(Tile.m_uwHeight != 0) { - vTiles.push_back(std::move(Tile)); wLastFull = i; } } @@ -96,7 +96,12 @@ int main(int lArgCount, const char *pArgs[]) fmt::print("Read {} tiles from '{}'\n", uwTileCount, szInPath); std::string szOutExt = nFs::getExt(szOutPath); if(szOutExt == "png" || szOutExt == "bm") { - tChunkyBitmap Out(lTileSize, uwTileCount * lTileSize); + tRgb Bg; + if(Palette.m_vColors.size()) { + Bg = Palette.m_vColors.at(0); + } + fmt::print("Using color for bg: {} {} {}\n", Bg.ubR, Bg.ubG, Bg.ubB); + tChunkyBitmap Out(lTileSize, uwTileCount * lTileSize, Bg); for(uint16_t i = 0; i < uwTileCount; ++i) { auto &Tile = vTiles.at(i); if(Tile.m_uwHeight != 0) { From c197d238d11dda4d1423ed30c21554e215c9eccf Mon Sep 17 00:00:00 2001 From: KaiN Date: Fri, 19 Apr 2019 19:48:54 +0200 Subject: [PATCH 42/56] reorder to prevent std::move crashes --- tools/src/tileset_conv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/src/tileset_conv.cpp b/tools/src/tileset_conv.cpp index cf73f65c..38e5deb4 100644 --- a/tools/src/tileset_conv.cpp +++ b/tools/src/tileset_conv.cpp @@ -79,10 +79,10 @@ int main(int lArgCount, const char *pArgs[]) int16_t wLastFull = -1; for(uint16_t i = 0; i < 256; ++i) { auto Tile = tChunkyBitmap::fromPng(fmt::format("{}/{}.png", szInPath, i)); - vTiles.push_back(std::move(Tile)); if(Tile.m_uwHeight != 0) { wLastFull = i; } + vTiles.push_back(std::move(Tile)); } vTiles.resize(wLastFull + 1); } From 1fec27604efecb042c6eaacf5a9638b048033917 Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 24 Apr 2019 19:12:37 +0200 Subject: [PATCH 43/56] added helpers to main cmakelists --- CMakeLists.txt | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 2da7c78d..ab6df020 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,6 +46,8 @@ set(TARGET_NAME ${PROJECT_NAME_LOWER}) add_library(${TARGET_NAME} ${SOURCES} ${HEADERS}) target_link_libraries(${TARGET_NAME}) +#----------------------------------------------------------------------- INSTALL + install(TARGETS ${TARGET_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) install(FILES ${HEADERS_ACE} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ace) install(FILES ${HEADERS_ACE_GENERIC} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ace/generic) @@ -53,3 +55,74 @@ install(FILES ${HEADERS_ACE_UTILS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ace/u install(FILES ${HEADERS_ACE_MANAGERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ace/managers) install(FILES ${HEADERS_ACE_MANAGERS_VP} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ace/managers/viewport) install(FILES ${HEADERS_FIXMATH} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/fixmath) + +#--------------------------------------------------------------------- FUNCTIONS + +function(toAbsolute PATH_IN) + if(NOT IS_ABSOLUTE ${PATH_IN}) + set(${PATH_IN} "${CMAKE_CURRENT_SOURCE_DIR}/${${PATH_IN}}" PARENT_SCOPE) + endif() +endfunction() + +function(convertPalette TARGET PALETTE_IN PALETTE_OUT) + add_custom_command( + OUTPUT ${PALETTE_OUT} + COMMAND tools/bin/palette_conv ${PALETTE_IN} ${PALETTE_OUT} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${PALETTE_IN} + ) + target_sources(${TARGET} PUBLIC ${PALETTE_OUT}) +endfunction() + +function(convertBitmaps) + set(options INTERLEAVED) + set(oneValArgs TARGET PALETTE MASK_COLOR) + set(multiValArgs SOURCES DESTINATIONS MASKS) + cmake_parse_arguments( + convertBitmaps "${options}" "${oneValArgs}" "${multiValArgs}" ${ARGN} + ) + + if(${convertBitmaps_INTERLEAVED}) + set(extraFlags -i) + endif() + + list(LENGTH convertBitmaps_SOURCES srcCount) + list(LENGTH convertBitmaps_DESTINATIONS dstCount) + list(LENGTH convertBitmaps_MASKS maskCount) + if(NOT ${srcCount} EQUAL ${dstCount}) + message(FATAL_ERROR "SOURCES count doesn't match DESTINATIONS count") + endif() + if(${maskCount} AND NOT ${maskCount} EQUAL ${srcCount}) + message(FATAL_ERROR "MASKS count doesn't match SOURCES count") + endif() + if("${convertBitmaps_MASK_COLOR} " STREQUAL " ") + if(${maskCount} GREATER 0) + message(FATAL_ERROR "MASK_COLOR unspecified") + endif() + else() + string(REPLACE "#" "\\#" convertBitmaps_MASK_COLOR "${convertBitmaps_MASK_COLOR}") + endif() + + MATH(EXPR srcCount "${srcCount}-1") + foreach(bitmap_idx RANGE ${srcCount}) # /path/file.png + list(GET convertBitmaps_SOURCES ${bitmap_idx} bitmapPath) + toAbsolute(bitmapPath) + list(GET convertBitmaps_DESTINATIONS ${bitmap_idx} outPath) + toAbsolute(outPath) + if(${maskCount} GREATER 0) + list(GET convertBitmaps_MASKS ${bitmap_idx} maskPath) + toAbsolute(maskPath) + endif() + + if(NOT "${convertBitmaps_MASK_COLOR} " STREQUAL " ") + set(extraFlags ${extraFlags} -mc ${convertBitmaps_MASK_COLOR} -mo ${maskPath}) + endif() + add_custom_command( + OUTPUT ${outPath} ${maskPath} + COMMAND tools/bitmap_conv/bitmap_conv ${convertBitmaps_PALETTE} ${bitmapPath} -o ${outPath} ${extraFlags} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${convertBitmaps_PALETTE} ${bitmapPath} + ) + target_sources(${convertBitmaps_TARGET} PUBLIC ${outPath} ${maskPath}) + endforeach() +endfunction() From 4ce920f8cdf27b28caf7d03a677932ec298db2f4 Mon Sep 17 00:00:00 2001 From: KaiN Date: Wed, 24 Apr 2019 19:59:11 +0200 Subject: [PATCH 44/56] this is needed for helpers --- CMakeLists.txt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab6df020..1a043206 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ cmake_minimum_required(VERSION 2.8.5) project(ACE) +set(ACE_DIR ${CMAKE_CURRENT_LIST_DIR} PARENT_SCOPE) # needed for helper fns # Adhere to GNU filesystem layout conventions include(GNUInstallDirs) @@ -67,7 +68,7 @@ endfunction() function(convertPalette TARGET PALETTE_IN PALETTE_OUT) add_custom_command( OUTPUT ${PALETTE_OUT} - COMMAND tools/bin/palette_conv ${PALETTE_IN} ${PALETTE_OUT} + COMMAND ${ACE_DIR}/tools/bin/palette_conv ${PALETTE_IN} ${PALETTE_OUT} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${PALETTE_IN} ) @@ -119,7 +120,7 @@ function(convertBitmaps) endif() add_custom_command( OUTPUT ${outPath} ${maskPath} - COMMAND tools/bitmap_conv/bitmap_conv ${convertBitmaps_PALETTE} ${bitmapPath} -o ${outPath} ${extraFlags} + COMMAND ${ACE_DIR}/tools/bitmap_conv/bitmap_conv ${convertBitmaps_PALETTE} ${bitmapPath} -o ${outPath} ${extraFlags} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DEPENDS ${convertBitmaps_PALETTE} ${bitmapPath} ) From fdf4891c2b056fa6a9fa652bb98b0c1e21a70ec9 Mon Sep 17 00:00:00 2001 From: KaiN Date: Fri, 26 Apr 2019 17:33:24 +0200 Subject: [PATCH 45/56] promoted fontGlyphWidth from static since it can be useful --- include/ace/utils/font.h | 9 +++++++++ src/ace/utils/font.c | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/include/ace/utils/font.h b/include/ace/utils/font.h index 54501aa6..5df6beae 100644 --- a/include/ace/utils/font.h +++ b/include/ace/utils/font.h @@ -119,6 +119,15 @@ void fontDestroyTextBitMap(tTextBitMap *pTextBitMap); */ tUwCoordYX fontMeasureText(const tFont *pFont, const char *szText); +/** + * @brief Gets width of specified glyph on given font. + * + * @param pFont Font to be used for measurement. + * @param c Glyph to be checked + * @return Width of glyph, in pixels. + */ +UBYTE fontGlyphWidth(const tFont *pFont, char c); + /** * @brief Checks if given text fits inside specified text buffer. * diff --git a/src/ace/utils/font.c b/src/ace/utils/font.c index 61e8aa43..48de79a4 100644 --- a/src/ace/utils/font.c +++ b/src/ace/utils/font.c @@ -9,7 +9,7 @@ /* Functions */ -static inline UBYTE fontGlyphWidth(const tFont *pFont, char c) { +UBYTE fontGlyphWidth(const tFont *pFont, char c) { UBYTE ubIdx = (UBYTE)c; return pFont->pCharOffsets[ubIdx + 1] - pFont->pCharOffsets[ubIdx]; } From 1ff81a0c66e4e767c7d92047661f14e16b2f9a56 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 27 Apr 2019 14:55:58 +0200 Subject: [PATCH 46/56] added cmake util for font conversion, minor tool fix --- CMakeLists.txt | 14 ++++++++++++++ tools/src/font_conv.cpp | 3 ++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1a043206..404dc974 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -127,3 +127,17 @@ function(convertBitmaps) target_sources(${convertBitmaps_TARGET} PUBLIC ${outPath} ${maskPath}) endforeach() endfunction() + +function(convertFont TARGET FONT_IN FONT_OUT) +toAbsolute(FONT_IN) +toAbsolute(FONT_OUT) +get_filename_component(ext ${FONT_OUT} EXT) +string(SUBSTRING ${ext} 1 -1 ext) +add_custom_command( + OUTPUT ${FONT_OUT} + COMMAND ${ACE_DIR}/tools/bin/font_conv ${FONT_IN} ${ext} -out ${FONT_OUT} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS ${FONT_IN} +) +target_sources(${TARGET} PUBLIC ${FONT_OUT}) +endfunction() diff --git a/tools/src/font_conv.cpp b/tools/src/font_conv.cpp index d007fdc7..7d743495 100644 --- a/tools/src/font_conv.cpp +++ b/tools/src/font_conv.cpp @@ -36,7 +36,7 @@ void printUsage(const std::string &szAppName) { print("\tfnt\tACE font file\n"); print("extraOpts:\n"); // -chars - print("\t-chars \"AB D\"\tInclude only 'A', 'B', ' ' and 'D' chars in font.\n"); + print("\t-chars \"AB D\"\tInclude only 'A', 'B', ' ' and 'D' chars in font. Only for TTF input.\n"); print("\t\t\tUse backslash (\\) to escape quote (\") char inside charset specifier\n"); print("\t\t\tDefault charset is: \"{}\"\n", s_szDefaultCharset); // -out @@ -140,6 +140,7 @@ int main(int lArgCount, const char *pArgs[]) } else { nLog::error("Unsupported output type"); + return 1; } } fmt::print("All done!\n"); From 48b9194f62ce753d0608b06ef666fe5cb33b6b97 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 4 May 2019 13:58:57 +0200 Subject: [PATCH 47/56] showcase builds again --- showcase/src/input.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/showcase/src/input.c b/showcase/src/input.c index f32ed85c..649dae99 100644 --- a/showcase/src/input.c +++ b/showcase/src/input.c @@ -10,7 +10,7 @@ /* Functions */ void inputOpen(void) { - joyOpen(); + joyOpen(0); keyCreate(); } From 4ae30626a46927915d98be2dab4e87f0bcb67573 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 4 May 2019 14:28:45 +0200 Subject: [PATCH 48/56] added missing include --- include/ace/utils/extview.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/ace/utils/extview.h b/include/ace/utils/extview.h index 2d99b065..7b05ac69 100644 --- a/include/ace/utils/extview.h +++ b/include/ace/utils/extview.h @@ -11,6 +11,7 @@ */ #include +#include #include #include #include From 315b5eea8332da78b62e8781544356a3c749c739 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 4 May 2019 18:28:56 +0200 Subject: [PATCH 49/56] added buffer scrolling test --- showcase/CMakeLists.txt | 9 +- showcase/src/menu/menu.c | 9 +- showcase/src/test/buffer_scroll.c | 160 ++++++++++++++++++++++++++++++ showcase/src/test/buffer_scroll.h | 14 +++ 4 files changed, 189 insertions(+), 3 deletions(-) create mode 100644 showcase/src/test/buffer_scroll.c create mode 100644 showcase/src/test/buffer_scroll.h diff --git a/showcase/CMakeLists.txt b/showcase/CMakeLists.txt index 3cde6a73..4dd28dfa 100644 --- a/showcase/CMakeLists.txt +++ b/showcase/CMakeLists.txt @@ -21,9 +21,14 @@ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -DACE_DEBUG") file(GLOB_RECURSE SOURCES src/*.c) file(GLOB_RECURSE HEADERS src/*.h) + include_directories( ${PROJECT_SOURCE_DIR}/src -) + ) + +if(ACE_DEBUG) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DACE_DEBUG") # For ACE headers with ifdefs +endif() # ACE add_subdirectory(.. ace) @@ -32,4 +37,4 @@ include_directories(../include) # Linux/other UNIX get a lower-case binary name set(TARGET_NAME ${PROJECT_NAME_LOWER}) add_executable(${TARGET_NAME} ${SOURCES} ${HEADERS}) -target_link_libraries(${TARGET_NAME} ace) \ No newline at end of file +target_link_libraries(${TARGET_NAME} ace) diff --git a/showcase/src/menu/menu.c b/showcase/src/menu/menu.c index 12545224..96fbd56c 100644 --- a/showcase/src/menu/menu.c +++ b/showcase/src/menu/menu.c @@ -22,6 +22,7 @@ #include "test/blitsmalldest.h" #include "test/interleaved.h" #include "test/lines.h" +#include "test/buffer_scroll.h" static tView *s_pMenuView; static tVPort *s_pMenuVPort; @@ -217,7 +218,7 @@ void menuShowTests(void) { // Prepare new list s_pMenuList->sCoord.sUwCoord.uwX = s_pMenuBfr->uBfrBounds.sUwCoord.uwX >> 1; s_pMenuList->sCoord.sUwCoord.uwY = 100; - menuListResetCount(s_pMenuList, 7); + menuListResetCount(s_pMenuList, 8); menuListSetEntry(s_pMenuList, 0, MENULIST_ENABLED, "Back"); menuListSetEntry(s_pMenuList, 1, MENULIST_ENABLED, "Blits"); menuListSetEntry(s_pMenuList, 2, MENULIST_ENABLED, "Fonts"); @@ -225,6 +226,7 @@ void menuShowTests(void) { menuListSetEntry(s_pMenuList, 4, MENULIST_ENABLED, "Blitter lines"); menuListSetEntry(s_pMenuList, 5, MENULIST_ENABLED, "Blits with small dst"); menuListSetEntry(s_pMenuList, 6, MENULIST_ENABLED, "Interleaved bitmaps"); + menuListSetEntry(s_pMenuList, 7, MENULIST_ENABLED, "Scroll buffer wrap"); s_ubMenuType = MENU_TESTS; // Redraw list @@ -260,6 +262,11 @@ void menuSelectTests(void) { gsTestInterleavedCreate, gsTestInterleavedLoop, gsTestInterleavedDestroy ); break; + case 7: + gameChangeState( + gsTestBufferScrollCreate, gsTestBufferScrollLoop, gsTestBufferScrollDestroy + ); + break; } } diff --git a/showcase/src/test/buffer_scroll.c b/showcase/src/test/buffer_scroll.c new file mode 100644 index 00000000..64209190 --- /dev/null +++ b/showcase/src/test/buffer_scroll.c @@ -0,0 +1,160 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "buffer_scroll.h" +#include +#include +#include +#include +#include +#include +#include "main.h" +#include "menu/menu.h" + +static tView *s_pView; +static tVPort *s_pVPort; +static tCameraManager *s_pCamera; + +static void fillBfr(tBitMap *pBfr, UWORD uwWidth, UWORD uwHeight) { + uwWidth -= 1; + uwHeight -= 1; + + // Short lines + for(UWORD x = 4; x <= uwWidth; x += 10) { + blitRect(pBfr, x, 0, 1, 3, 7); + blitRect(pBfr, x, uwHeight-3, 1, 3, 7); + } + for(UWORD y = 4; y <= uwHeight; y += 10) { + blitRect(pBfr, 0, y, 3, 1, 7); + blitRect(pBfr, uwWidth-3, y, 3, 1, 7); + } + + // Long lines + for(UWORD x = 9; x <= uwWidth; x += 10) { + blitRect(pBfr, x, 0, 1, 5, 7); + blitRect(pBfr, x, uwHeight-5, 1, 5, 7); + } + for(UWORD y = 9; y <= uwHeight; y += 10) { + blitRect(pBfr, 0, y, 5, 1, 7); + blitRect(pBfr, uwWidth-5, y, 5, 1, 7); + } + + // Border + blitRect(pBfr, 0, 0, uwWidth, 1, 31); + blitRect(pBfr, 0, uwHeight, uwWidth, 1, 31); + blitRect(pBfr, 0, 0, 1, uwHeight, 31); + blitRect(pBfr, uwWidth, 0, 1, uwHeight, 31); +} + +void initSimple(void) { + viewLoad(0); + systemUse(); + if(s_pView->pFirstVPort) { + vPortDestroy(s_pView->pFirstVPort); + } + + s_pVPort = vPortCreate(0, + TAG_VPORT_VIEW, s_pView, + TAG_VPORT_BPP, SHOWCASE_BPP, + TAG_DONE); + paletteLoad("data/amidb32.plt", s_pVPort->pPalette, 1 << SHOWCASE_BPP); + + tSimpleBufferManager *s_pBfr = simpleBufferCreate(0, + TAG_SIMPLEBUFFER_VPORT, s_pVPort, + TAG_SIMPLEBUFFER_BITMAP_FLAGS, BMF_CLEAR | BMF_INTERLEAVED, + TAG_SIMPLEBUFFER_BOUND_WIDTH, 640, + TAG_SIMPLEBUFFER_BOUND_HEIGHT, 384, + TAG_DONE); + s_pCamera = s_pBfr->pCamera; + + fillBfr(s_pBfr->pBack, 640, 384); + + viewLoad(s_pView); + systemUnuse(); +} + +void initScroll(void) { + viewLoad(0); + systemUse(); + if(s_pView->pFirstVPort) { + vPortDestroy(s_pView->pFirstVPort); + } + + s_pVPort = vPortCreate(0, + TAG_VPORT_VIEW, s_pView, + TAG_VPORT_BPP, SHOWCASE_BPP, + TAG_DONE); + paletteLoad("data/amidb32.plt", s_pVPort->pPalette, 1 << SHOWCASE_BPP); + + tScrollBufferManager *s_pBfr = scrollBufferCreate(0, + TAG_SCROLLBUFFER_VPORT, s_pVPort, + TAG_SCROLLBUFFER_BITMAP_FLAGS, BMF_CLEAR | BMF_INTERLEAVED, + TAG_SCROLLBUFFER_BOUND_HEIGHT, 640, + TAG_SCROLLBUFFER_BOUND_WIDTH, 384, + TAG_SCROLLBUFFER_MARGIN_WIDTH, 32, + TAG_DONE); + s_pCamera = s_pBfr->pCamera; + + blitRect(s_pBfr->pBack, 0, 0, 4, 4, 3); + fillBfr( + s_pBfr->pBack, + bitmapGetByteWidth(s_pBfr->pBack) * 8, s_pBfr->uwBmAvailHeight + ); + + blitRect(s_pBfr->pBack, 32, 32, 32, 32, 5); + viewLoad(s_pView); + systemUnuse(); +} + +void gsTestBufferScrollCreate(void) { + logBlockBegin("gsTestBufferScrollCreate()"); + + s_pView = viewCreate(0, + TAG_VIEW_GLOBAL_CLUT, 1, + TAG_DONE); + + initScroll(); + logBlockEnd("gsTestBufferScrollCreate()"); + systemUnuse(); +} + +void gsTestBufferScrollLoop(void) { + if (keyUse(KEY_ESCAPE)) { + gameChangeState(gsMenuCreate, gsMenuLoop, gsMenuDestroy); + return; + } + + WORD wDx = 0, wDy = 0; + if(keyCheck(KEY_W)) { + wDy = -1; + } + else if(keyCheck(KEY_S)) { + wDy = 1; + } + if(keyCheck(KEY_A)) { + wDx = -1; + } + if(keyCheck(KEY_D)) { + wDx = 1; + } + + if(keyUse(KEY_1)) { + initSimple(); + } + else if(keyUse(KEY_2)) { + initScroll(); + } + + cameraMoveBy(s_pCamera, wDx, wDy); + viewProcessManagers(s_pView); + copProcessBlocks(); + vPortWaitForEnd(s_pVPort); +} + +void gsTestBufferScrollDestroy(void) { + logBlockBegin("gsTestBufferScrollDestroy()"); + systemUse(); + viewDestroy(s_pView); + logBlockEnd("gsTestBufferScrollDestroy()"); +} diff --git a/showcase/src/test/buffer_scroll.h b/showcase/src/test/buffer_scroll.h new file mode 100644 index 00000000..41beda60 --- /dev/null +++ b/showcase/src/test/buffer_scroll.h @@ -0,0 +1,14 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#ifndef _SHOWCASE_TEST_BUFFER_SCROLL_H_ +#define _SHOWCASE_TEST_BUFFER_SCROLL_H_ + +#include + +void gsTestBufferScrollCreate(void); +void gsTestBufferScrollLoop(void); +void gsTestBufferScrollDestroy(void); + +#endif // _SHOWCASE_TEST_BUFFER_SCROLL_H_ From eacf0396e0d5cd72b4cf446d6fe5d5c77912c7dd Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 4 May 2019 18:29:13 +0200 Subject: [PATCH 50/56] fixed first line not being displayed on simple buffer --- src/ace/managers/viewport/simplebuffer.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 8fcb4532..842b9872 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -241,18 +241,17 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { pCamera = pManager->pCamera; pCopList = pManager->sCommon.pVPort->pView->pCopList; - // Calculate X movement + // Calculate X movement: bitplane shift, starting word to fetch if(pManager->ubFlags & SIMPLEBUFFER_FLAG_X_SCROLLABLE) { - uwShift = 15-(pCamera->uPos.sUwCoord.uwX & 0xF); + uwShift = (16-(pCamera->uPos.sUwCoord.uwX & 0xF)) & 0xF; uwShift = (uwShift << 4) | uwShift; + ulBplOffs = ((pCamera->uPos.sUwCoord.uwX-1) >> 4) << 1; } else { uwShift = 0; + ulBplOffs = (pCamera->uPos.sUwCoord.uwX >> 4) << 1; } - // X offset on bitplane - ulBplOffs = (pCamera->uPos.sUwCoord.uwX >> 4) << 1; - // Calculate Y movement ulBplOffs += pManager->pBack->BytesPerRow*pCamera->uPos.sUwCoord.uwY; From 971784e995eb3c9bc234eec6a34454edf25bc033 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 4 May 2019 18:36:23 +0200 Subject: [PATCH 51/56] added unimplemented notice --- src/ace/managers/viewport/scrollbuffer.c | 2 ++ src/ace/managers/viewport/simplebuffer.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 044e099a..c1018618 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -89,6 +89,7 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { } else { // TODO Raw mode + logWrite("ERR: Unimplemented %s:%d\n", __FILE__, __LINE__); goto fail; } @@ -169,6 +170,7 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { if(pManager->ubFlags & SCROLLBUFFER_FLAG_COPLIST_RAW) { // TODO: Raw mode + logWrite("ERR: Unimplemented %s:%d\n", __FILE__, __LINE__); } else { // Initial copper block diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index 842b9872..b0bc9b35 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -243,9 +243,9 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { // Calculate X movement: bitplane shift, starting word to fetch if(pManager->ubFlags & SIMPLEBUFFER_FLAG_X_SCROLLABLE) { - uwShift = (16-(pCamera->uPos.sUwCoord.uwX & 0xF)) & 0xF; + uwShift = (16 - (pCamera->uPos.sUwCoord.uwX & 0xF)) & 0xF; uwShift = (uwShift << 4) | uwShift; - ulBplOffs = ((pCamera->uPos.sUwCoord.uwX-1) >> 4) << 1; + ulBplOffs = ((pCamera->uPos.sUwCoord.uwX - 1) >> 4) << 1; } else { uwShift = 0; From 5ec857319394a2c9366871ef0775e4312bdba3f9 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 4 May 2019 19:12:46 +0200 Subject: [PATCH 52/56] fixed scrollBuffer not displaying y=0 line --- src/ace/managers/viewport/scrollbuffer.c | 15 +++++++-------- src/ace/managers/viewport/simplebuffer.c | 16 +++++++--------- 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index c1018618..d913ad93 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -161,10 +161,9 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { UWORD uwScrollY = pManager->pCamera->uPos.sUwCoord.uwY & (pManager->uwBmAvailHeight - 1); // preparations for new copperlist - UWORD uwOffsX = 15 - (uwScrollX & 0xF); // Bitplane shift - single - uwOffsX = (uwOffsX << 4) | uwOffsX; // Bitplane shift - PF1 | PF2 - - uwScrollX >>= 3; + UWORD uwShift = (16 - (uwScrollX & 0xF)) & 0xF; // Bitplane shift - single + uwShift = (uwShift << 4) | uwShift; // Bitplane shift - PF1 | PF2 + ULONG ulBplAddX = ((uwScrollX - 1) >> 4) << 1; // must be ULONG! tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; @@ -176,8 +175,8 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { // Initial copper block tCopBlock *pBlock = pManager->pStartBlock; pBlock->uwCurrCount = 0; // Rewind copBlock - copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwOffsX); // Bitplane shift - ULONG ulPlaneOffs = uwScrollX + (pManager->pBack->BytesPerRow*uwScrollY); + copMove(pCopList, pBlock, &g_pCustom->bplcon1, uwShift); + ULONG ulPlaneOffs = ulBplAddX + (pManager->pBack->BytesPerRow*uwScrollY); for(UBYTE i = pManager->sCommon.pVPort->ubBPP; i--;) { ULONG ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + ulPlaneOffs; copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); @@ -197,7 +196,7 @@ void scrollBufferProcess(tScrollBufferManager *pManager) { } copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY + pManager->uwBmAvailHeight - uwScrollY); for(UBYTE i = pManager->sCommon.pVPort->ubBPP; i--;) { - ULONG ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + uwScrollX; + ULONG ulPlaneAddr = (ULONG)(pManager->pBack->Planes[i]) + ulBplAddX; copMove(pCopList, pBlock, &g_pBplFetch[i].uwHi, ulPlaneAddr >> 16); copMove(pCopList, pBlock, &g_pBplFetch[i].uwLo, ulPlaneAddr & 0xFFFF); } @@ -272,7 +271,7 @@ void scrollBufferReset( copBlockWait(pCopList, pBlock, 0, 0x2C + pManager->sCommon.pVPort->uwOffsY); // After bitplane ptrs & bplcon pBlock->uwCurrCount = 2 * pManager->sCommon.pVPort->ubBPP + 1; - copMove(pCopList, pBlock, &g_pCustom->ddfstrt, 0x30); // Fetch start + copMove(pCopList, pBlock, &g_pCustom->ddfstrt, 0x0030); // Fetch start copMove(pCopList, pBlock, &g_pCustom->bpl1mod, pManager->uwModulo); // Odd planes modulo copMove(pCopList, pBlock, &g_pCustom->bpl2mod, pManager->uwModulo); // Even planes modulo copMove(pCopList, pBlock, &g_pCustom->ddfstop, 0x00D0); // Fetch stop diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index b0bc9b35..d42c3046 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -46,7 +46,7 @@ void simpleBufferSetFront(tSimpleBufferManager *pManager, tBitMap *pFront) { else { pManager->ubFlags |= SIMPLEBUFFER_FLAG_X_SCROLLABLE; uwDDfStrt = 0x0030; - uwModulo -= 1; + uwModulo -= 2; } logWrite("Modulo: %u\n", uwModulo); @@ -235,17 +235,15 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { UWORD uwShift; ULONG ulBplOffs; ULONG ulPlaneAddr; - tCameraManager *pCamera; - tCopList *pCopList; - pCamera = pManager->pCamera; - pCopList = pManager->sCommon.pVPort->pView->pCopList; + const tCameraManager *pCamera = pManager->pCamera; + tCopList *pCopList = pManager->sCommon.pVPort->pView->pCopList; // Calculate X movement: bitplane shift, starting word to fetch if(pManager->ubFlags & SIMPLEBUFFER_FLAG_X_SCROLLABLE) { - uwShift = (16 - (pCamera->uPos.sUwCoord.uwX & 0xF)) & 0xF; - uwShift = (uwShift << 4) | uwShift; - ulBplOffs = ((pCamera->uPos.sUwCoord.uwX - 1) >> 4) << 1; + uwShift = (16 - (pCamera->uPos.sUwCoord.uwX & 0xF)) & 0xF; // Bitplane shift - single + uwShift = (uwShift << 4) | uwShift; // Bitplane shift - PF1 | PF2 + ulBplOffs = ((pCamera->uPos.sUwCoord.uwX - 1) >> 4) << 1; // Must be ULONG! } else { uwShift = 0; @@ -253,7 +251,7 @@ void simpleBufferProcess(tSimpleBufferManager *pManager) { } // Calculate Y movement - ulBplOffs += pManager->pBack->BytesPerRow*pCamera->uPos.sUwCoord.uwY; + ulBplOffs += pManager->pBack->BytesPerRow * pCamera->uPos.sUwCoord.uwY; // Copperlist - regen bitplane ptrs, update shift // TODO could be unified by using copSetMove in copBlock From 1e7e64e5ef0e60dfd518a518a95650ef11da12c9 Mon Sep 17 00:00:00 2001 From: KaiN Date: Sat, 4 May 2019 20:01:39 +0200 Subject: [PATCH 53/56] fixed destroying simplebuffer in runtime by adding copBlock freeing --- src/ace/managers/viewport/simplebuffer.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index d42c3046..f6b6b445 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -221,12 +221,11 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { void simpleBufferDestroy(tSimpleBufferManager *pManager) { logBlockBegin("simpleBufferDestroy()"); - logWrite("Destroying bitmap...\n"); + copBlockDestroy(pManager->sCommon.pVPort->pView->pCopList, pManager->pCopBlock); if(pManager->pBack != pManager->pFront) { bitmapDestroy(pManager->pBack); } bitmapDestroy(pManager->pFront); - logWrite("Freeing mem...\n"); memFree(pManager, sizeof(tSimpleBufferManager)); logBlockEnd("simpleBufferDestroy()"); } From 227a3d7b5b76156aea94686cbbb7663b3755dc54 Mon Sep 17 00:00:00 2001 From: KaiN Date: Tue, 7 May 2019 13:31:31 +0200 Subject: [PATCH 54/56] obvious fix --- showcase/src/test/buffer_scroll.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/showcase/src/test/buffer_scroll.c b/showcase/src/test/buffer_scroll.c index 64209190..ebf917e2 100644 --- a/showcase/src/test/buffer_scroll.c +++ b/showcase/src/test/buffer_scroll.c @@ -87,11 +87,13 @@ void initScroll(void) { TAG_DONE); paletteLoad("data/amidb32.plt", s_pVPort->pPalette, 1 << SHOWCASE_BPP); + // This will create buffer which is shorter than 640 with capability of + // wrapped scrolling to simulate bigger buffer size tScrollBufferManager *s_pBfr = scrollBufferCreate(0, TAG_SCROLLBUFFER_VPORT, s_pVPort, TAG_SCROLLBUFFER_BITMAP_FLAGS, BMF_CLEAR | BMF_INTERLEAVED, - TAG_SCROLLBUFFER_BOUND_HEIGHT, 640, - TAG_SCROLLBUFFER_BOUND_WIDTH, 384, + TAG_SCROLLBUFFER_BOUND_WIDTH, 640, + TAG_SCROLLBUFFER_BOUND_HEIGHT, 384, TAG_SCROLLBUFFER_MARGIN_WIDTH, 32, TAG_DONE); s_pCamera = s_pBfr->pCamera; From 9f2c2a5ad0d740d9b445f8ae1e5bd30d93e9ff35 Mon Sep 17 00:00:00 2001 From: KaiN Date: Tue, 7 May 2019 13:31:40 +0200 Subject: [PATCH 55/56] increased ruler scale --- showcase/src/test/buffer_scroll.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/showcase/src/test/buffer_scroll.c b/showcase/src/test/buffer_scroll.c index ebf917e2..6b18d666 100644 --- a/showcase/src/test/buffer_scroll.c +++ b/showcase/src/test/buffer_scroll.c @@ -21,21 +21,21 @@ static void fillBfr(tBitMap *pBfr, UWORD uwWidth, UWORD uwHeight) { uwHeight -= 1; // Short lines - for(UWORD x = 4; x <= uwWidth; x += 10) { + for(UWORD x = 10; x <= uwWidth; x += 10) { blitRect(pBfr, x, 0, 1, 3, 7); blitRect(pBfr, x, uwHeight-3, 1, 3, 7); } - for(UWORD y = 4; y <= uwHeight; y += 10) { + for(UWORD y = 10; y <= uwHeight; y += 10) { blitRect(pBfr, 0, y, 3, 1, 7); blitRect(pBfr, uwWidth-3, y, 3, 1, 7); } // Long lines - for(UWORD x = 9; x <= uwWidth; x += 10) { + for(UWORD x = 100; x <= uwWidth; x += 100) { blitRect(pBfr, x, 0, 1, 5, 7); blitRect(pBfr, x, uwHeight-5, 1, 5, 7); } - for(UWORD y = 9; y <= uwHeight; y += 10) { + for(UWORD y = 100; y <= uwHeight; y += 100) { blitRect(pBfr, 0, y, 5, 1, 7); blitRect(pBfr, uwWidth-5, y, 5, 1, 7); } From 5e20ad953204f515f81de61ef309f7b3ea7e0a06 Mon Sep 17 00:00:00 2001 From: KaiN Date: Tue, 7 May 2019 14:18:58 +0200 Subject: [PATCH 56/56] added check for proper scroll buffer y-wrap --- showcase/src/test/buffer_scroll.c | 38 +++++++++++++++++++++++-------- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/showcase/src/test/buffer_scroll.c b/showcase/src/test/buffer_scroll.c index 6b18d666..c9a2a52c 100644 --- a/showcase/src/test/buffer_scroll.c +++ b/showcase/src/test/buffer_scroll.c @@ -12,11 +12,17 @@ #include "main.h" #include "menu/menu.h" +#define TEST_SCROLL_BPP 6 + static tView *s_pView; static tVPort *s_pVPort; static tCameraManager *s_pCamera; static void fillBfr(tBitMap *pBfr, UWORD uwWidth, UWORD uwHeight) { + logBlockBegin( + "fillBfr(pBfr: *%p, uwWidth: %hu, uwHeight: %hu)", + pBfr, uwWidth, uwHeight + ); uwWidth -= 1; uwHeight -= 1; @@ -41,10 +47,11 @@ static void fillBfr(tBitMap *pBfr, UWORD uwWidth, UWORD uwHeight) { } // Border - blitRect(pBfr, 0, 0, uwWidth, 1, 31); - blitRect(pBfr, 0, uwHeight, uwWidth, 1, 31); - blitRect(pBfr, 0, 0, 1, uwHeight, 31); - blitRect(pBfr, uwWidth, 0, 1, uwHeight, 31); + blitRect(pBfr, 0, 0, uwWidth, 1, 6); + blitRect(pBfr, 0, uwHeight, uwWidth, 1, 6); + blitRect(pBfr, 0, 0, 1, uwHeight, 6); + blitRect(pBfr, uwWidth, 0, 1, uwHeight, 6); + logBlockEnd("fillBfr()"); } void initSimple(void) { @@ -56,7 +63,7 @@ void initSimple(void) { s_pVPort = vPortCreate(0, TAG_VPORT_VIEW, s_pView, - TAG_VPORT_BPP, SHOWCASE_BPP, + TAG_VPORT_BPP, TEST_SCROLL_BPP, TAG_DONE); paletteLoad("data/amidb32.plt", s_pVPort->pPalette, 1 << SHOWCASE_BPP); @@ -64,11 +71,11 @@ void initSimple(void) { TAG_SIMPLEBUFFER_VPORT, s_pVPort, TAG_SIMPLEBUFFER_BITMAP_FLAGS, BMF_CLEAR | BMF_INTERLEAVED, TAG_SIMPLEBUFFER_BOUND_WIDTH, 640, - TAG_SIMPLEBUFFER_BOUND_HEIGHT, 384, + TAG_SIMPLEBUFFER_BOUND_HEIGHT, 720, TAG_DONE); s_pCamera = s_pBfr->pCamera; - fillBfr(s_pBfr->pBack, 640, 384); + fillBfr(s_pBfr->pBack, 640, 720); viewLoad(s_pView); systemUnuse(); @@ -83,7 +90,7 @@ void initScroll(void) { s_pVPort = vPortCreate(0, TAG_VPORT_VIEW, s_pView, - TAG_VPORT_BPP, SHOWCASE_BPP, + TAG_VPORT_BPP, TEST_SCROLL_BPP, TAG_DONE); paletteLoad("data/amidb32.plt", s_pVPort->pPalette, 1 << SHOWCASE_BPP); @@ -93,17 +100,28 @@ void initScroll(void) { TAG_SCROLLBUFFER_VPORT, s_pVPort, TAG_SCROLLBUFFER_BITMAP_FLAGS, BMF_CLEAR | BMF_INTERLEAVED, TAG_SCROLLBUFFER_BOUND_WIDTH, 640, - TAG_SCROLLBUFFER_BOUND_HEIGHT, 384, + TAG_SCROLLBUFFER_BOUND_HEIGHT, 720, TAG_SCROLLBUFFER_MARGIN_WIDTH, 32, TAG_DONE); s_pCamera = s_pBfr->pCamera; - blitRect(s_pBfr->pBack, 0, 0, 4, 4, 3); fillBfr( s_pBfr->pBack, bitmapGetByteWidth(s_pBfr->pBack) * 8, s_pBfr->uwBmAvailHeight ); + // Ensure that scroll buffer y-wraps nicely + UBYTE ubColor = (1 << TEST_SCROLL_BPP) - 1; + blitRect(s_pBfr->pBack, 0, 508, 1, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 509, 2, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 510, 3, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 511, 4, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 0, 5, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 1, 4, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 2, 3, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 3, 2, 1, ubColor); + blitRect(s_pBfr->pBack, 0, 4, 1, 1, ubColor); + blitRect(s_pBfr->pBack, 32, 32, 32, 32, 5); viewLoad(s_pView); systemUnuse();