diff --git a/include/ace/utils/assume.h b/include/ace/utils/assume.h new file mode 100644 index 00000000..f22d27e2 --- /dev/null +++ b/include/ace/utils/assume.h @@ -0,0 +1,43 @@ +/* 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 _ACE_UTILS_ASSUME_H_ +#define _ACE_UTILS_ASSUME_H_ + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#if defined(ACE_DEBUG) + +#define assume(cond) _assume(cond, 0, __FILE__, __LINE__) +#define assumeMsg(cond, szErrorMsg) _assume(cond, szErrorMsg, __FILE__, __LINE__) +#define assumeNotNull(ptr) assumeMsg(ptr != 0, "Null pointer: " #ptr); + +void _assume(ULONG ulExprValue, const char *szErrorMsg, const char *szFile, ULONG ulLine); + +#else + +#if __GNUC__ >= 13 +#define assume(cond) __attribute__((__assume__(cond))) +#else +// https://stackoverflow.com/questions/25667901/ - this isn't optimized away! +// #define assume(cond) do { if (!(cond)) __builtin_unreachable(); } while (0) +// https://stackoverflow.com/questions/30919802/ - no footprint on code +#define assume(cond) ((void) sizeof(cond)) +#endif +#define assumeMsg(cond, szErrorMsg) assume(cond) +#define assumeNotNull(ptr) assume(ptr != 0) + +#endif + +#ifdef __cplusplus +} +#endif + +#endif // _ACE_UTILS_ASSUME_H_ diff --git a/src/ace/managers/blit.c b/src/ace/managers/blit.c index 7c8b0274..db9b6702 100644 --- a/src/ace/managers/blit.c +++ b/src/ace/managers/blit.c @@ -4,6 +4,7 @@ #include #include +#include #define BLIT_LINE_OR ((ABC | ABNC | NABC | NANBC) | (SRCA | SRCC | DEST)) #define BLIT_LINE_XOR ((ABNC | NABC | NANBC) | (SRCA | SRCC | DEST)) @@ -313,10 +314,10 @@ UBYTE blitSafeCopyAligned( tBitMap *pDst, WORD wDstX, WORD wDstY, WORD wWidth, WORD wHeight, UWORD uwLine, const char *szFile ) { - if((wSrcX | wDstX | wWidth) & 0x000F) { - logWrite("ERR: Dimensions are not divisible by 16\n"); - return 0; - } + assumeMsg((wSrcX & 0xF) == 0, "wSrcX isn't divisible by 16"); + assumeMsg((wDstX & 0xF) == 0, "wDstX isn't divisible by 16"); + assumeMsg((wWidth & 0xF) == 0, "wWidth isn't divisible by 16"); + if(!blitCheck( pSrc, wSrcX, wSrcY, pDst, wDstX, wDstY, wWidth, wHeight, uwLine, szFile )) { diff --git a/src/ace/managers/bob.c b/src/ace/managers/bob.c index eebc182a..c41b7339 100644 --- a/src/ace/managers/bob.c +++ b/src/ace/managers/bob.c @@ -7,6 +7,7 @@ #include #include #include +#include #if !defined(ACE_NO_BOB_WRAP_Y) // Enables support for Y-wrapping of bobs. Required for scroll- and tileBuffer. @@ -90,13 +91,8 @@ void bobManagerCreate( pFront, pBack, uwAvailHeight ); - if(!bitmapIsInterleaved(pFront)) { - logWrite("ERR: front buffer bitmap %p isn't interleaved\n", pFront); - } - - if(!bitmapIsInterleaved(pBack)) { - logWrite("ERR: back buffer bitmap %p isn't interleaved\n", pBack); - } + assumeMsg(bitmapIsInterleaved(pFront), "Front buffer bitmap isn't interleaved"); + assumeMsg(bitmapIsInterleaved(pBack), "Back buffer bitmap isn't interleaved"); s_ubBpp = pFront->Depth; s_pQueues[0].pDst = pBack; @@ -427,12 +423,7 @@ void bobBegin(tBitMap *pBuffer) { } #ifdef GAME_DEBUG UWORD uwDrawLimit = s_pQueues[0].pBg->Rows * s_pQueues[0].pBg->Depth; - if(uwDrawnHeight > uwDrawLimit) { - logWrite( - "ERR: BG restore out of bounds: used %hu, limit: %hu", - uwDrawnHeight, uwDrawLimit - ); - } + assumeMsg(uwDrawnHeight <= uwDrawLimit, "BG restore out of bounds"); #endif s_ubBobsSaved = 0; s_ubBobsDrawn = 0; diff --git a/src/ace/managers/copper.c b/src/ace/managers/copper.c index 8396a797..fb370063 100644 --- a/src/ace/managers/copper.c +++ b/src/ace/managers/copper.c @@ -5,8 +5,9 @@ #include #ifdef AMIGA #include -#include #include +#include +#include #include tCopManager g_sCopManager; @@ -203,17 +204,9 @@ tCopList *copListCreate(void *pTagList, ...) { ULONG ulListSize = tagGet( pTagList, vaTags, TAG_COPPER_RAW_COUNT, ulInvalidSize ); - if(ulListSize == ulInvalidSize) { - logWrite("ERR: no size specified for raw list\n"); - goto fail; - } - if(ulListSize > USHRT_MAX) { - logWrite( - "ERR: raw copperlist size too big: %lu, max is %u\n", - ulListSize, USHRT_MAX - ); - goto fail; - } + assumeMsg(ulListSize != ulInvalidSize, "No size specified for raw list"); + assumeMsg(ulListSize <= USHRT_MAX, "Raw copperlist size is too big"); + logWrite("RAW mode, size: %lu + WAIT(0xFFFF)\n", ulListSize); // Front bfr pCopList->pFrontBfr->uwCmdCount = ulListSize+1; @@ -233,12 +226,6 @@ tCopList *copListCreate(void *pTagList, ...) { logBlockEnd("copListCreate()"); va_end(vaTags); return pCopList; - -fail: - va_end(vaTags); - copListDestroy(pCopList); - logBlockEnd("copListCreate()"); - return 0; } void copListDestroy(tCopList *pCopList) { diff --git a/src/ace/managers/joy.c b/src/ace/managers/joy.c index 48171048..db0a3cb0 100644 --- a/src/ace/managers/joy.c +++ b/src/ace/managers/joy.c @@ -10,6 +10,7 @@ #include #include #include +#include #if defined ACE_DEBUG static UBYTE s_bInitCount = 0; @@ -34,19 +35,15 @@ static inline const char *myAllocMiscResource( void joyOpen(void) { #if defined(ACE_DEBUG) - if(s_bInitCount++ != 0) { - // You should call keyCreate() only once - logWrite("ERR: Joy already initialized!\n"); - } + assumeMsg(s_bInitCount == 0, "Joy already initialized"); + ++s_bInitCount; #endif } void joyClose(void) { #if defined(ACE_DEBUG) - if(s_bInitCount-- != 1) { - // You should call joyClose() only once for each joyCreate() - logWrite("ERR: Joy was initialized multiple times!\n"); - } + --s_bInitCount; + assumeMsg(s_bInitCount == 0, "Joy was initialized multiple times"); #endif joyDisableParallel(); } diff --git a/src/ace/managers/key.c b/src/ace/managers/key.c index 86ff6349..52646d8c 100644 --- a/src/ace/managers/key.c +++ b/src/ace/managers/key.c @@ -7,6 +7,7 @@ #include #include #include +#include #include // INTB_PORTS #define KEY_RELEASED_BIT 1 @@ -94,10 +95,8 @@ const UBYTE g_pToAscii[] = { void keyCreate(void) { logBlockBegin("keyCreate()"); #if defined(ACE_DEBUG) - if(s_bInitCount++ != 0) { - // You should call keyCreate() only once - logWrite("ERR: Keyboard already initialized!\n"); - } + assumeMsg(s_bInitCount == 0, "Keyboard already initialized"); + ++s_bInitCount; #endif systemSetCiaInt(CIA_A, CIAICRB_SERIAL, keyIntServer, &g_sKeyManager); logBlockEnd("keyCreate()"); @@ -106,10 +105,8 @@ void keyCreate(void) { void keyDestroy(void) { logBlockBegin("keyDestroy()"); #if defined(ACE_DEBUG) - if(s_bInitCount-- != 1) { - // You should call keyDestroy() only once for each keyCreate() - logWrite("ERR: Keyboard was initialized multiple times!\n"); - } + --s_bInitCount; + assumeMsg(s_bInitCount == 0, "Keyboard was initialized multiple times"); #endif systemSetCiaInt(CIA_A, CIAICRB_SERIAL, 0, 0); logBlockEnd("keyDestroy()"); diff --git a/src/ace/managers/log.c b/src/ace/managers/log.c index 423433a1..5a2ed880 100644 --- a/src/ace/managers/log.c +++ b/src/ace/managers/log.c @@ -6,6 +6,7 @@ #include #include #include +#include #ifdef ACE_DEBUG // Globals @@ -243,9 +244,8 @@ void _logPushInt(void) { } void _logPopInt(void) { - if(--g_sLogManager.wInterruptDepth < 0) { - logWrite("ERR: INT DEPTH NEGATIVE!\n"); - } + --g_sLogManager.wInterruptDepth; + assumeMsg(g_sLogManager.wInterruptDepth >= 0, "INT DEPTH NEGATIVE"); } #endif // ACE_DEBUG diff --git a/src/ace/managers/ptplayer.c b/src/ace/managers/ptplayer.c index 5f17bab1..f685fe36 100644 --- a/src/ace/managers/ptplayer.c +++ b/src/ace/managers/ptplayer.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -1191,11 +1192,7 @@ void moreBlockedFx( ) { // Get cmd idx. See tModVoice's type definition for details. UBYTE ubCmdIdx = (uwCmd >> 8) & 0x0F; -#if defined(ACE_DEBUG_PTPLAYER) - if(ubCmdIdx >= 16) { - logWrite("ERR: blmorefx_tab index out of range: cmd %hu -> %hu\n", uwCmd, uwCmd >> 8); - } -#endif + assumeMsg(ubCmdIdx < 16, "blmorefx_tab index out of range"); blmorefx_tab[ubCmdIdx](uwCmd, pChannelData, pChannelReg); } @@ -1222,11 +1219,7 @@ static void checkmorefx( if(pChannelData->uwFunkSpeed) { mt_updatefunk(pChannelData); } -#if defined(ACE_DEBUG_PTPLAYER) - if(uwCmd >= 16) { - logWrite("ERR: morefx_tab index out of range: cmd %hu\n", uwCmd); - } -#endif + assumeMsg(uwCmd < 16, "morefx_tab index out of range"); morefx_tab[uwCmd](uwCmdArg, pChannelData, pChannelReg); } @@ -1331,11 +1324,7 @@ static void mt_playvoice( set_finetune(uwCmd, uwCmdArg, uwMaskedCmdE, pVoice, pChannelData, pChannelReg); } else { -#if defined(ACE_DEBUG_PTPLAYER) - if(uwCmd >= 16) { - logWrite("ERR: prefx_tab index out of range: cmd %hu\n", uwCmd); - } -#endif + assumeMsg(uwCmd < 16, "prefx_tab index out of range"); prefx_tab[uwCmd]( uwCmd, uwCmdArg, uwMaskedCmdE, pVoice, pChannelData, pChannelReg ); @@ -1382,11 +1371,7 @@ static void mt_checkfx( } else { UBYTE ubCmdIndex = (pChannelData->sVoice.ubCmdHi & 0xF); -#if defined(ACE_DEBUG_PTPLAYER) - if(ubCmdIndex >= 16) { - logWrite("ERR: fx_tab index out of range: cmd %hhu\n", ubCmdIndex); - } -#endif + assumeMsg(ubCmdIndex < 16, "fx_tab index out of range"); fx_tab[ubCmdIndex](pChannelData->sVoice.ubCmdLo, pChannelData, pChannelReg); } } @@ -2193,11 +2178,7 @@ static void mt_e_cmds( // uwCmd: 0x0E'XY (x = command, y = argument) UBYTE ubArgE = ubArgs & 0x0F; UBYTE ubCmdE = (ubArgs & 0xF0) >> 4; -#if defined(ACE_DEBUG_PTPLAYER) - if(ubCmdE >= 16) { - logWrite("ERR: ecmd_tab index out of range: cmd %hhu\n", ubCmdE); - } -#endif + assumeMsg(ubCmdE < 16, "ecmd_tab index out of range"); ecmd_tab[ubCmdE](ubArgE, pChannelData, pChannelReg); } @@ -2265,11 +2246,7 @@ static void blocked_e_cmds( // uwCmd: 0x0E'XY (x = command, y = argument) UBYTE ubArg = ubArgs & 0x0F; UBYTE ubCmdE = (ubArgs & 0xF0) >> 4; -#if defined(ACE_DEBUG_PTPLAYER) - if(ubCmdE >= 16) { - logWrite("ERR: blecmd_tab index out of range: cmd %hhu\n", ubCmdE); - } -#endif + assumeMsg(ubCmdE < 16, "blecmd_tab index out of range"); blecmd_tab[ubCmdE](ubArg, pChannelData, pChannelReg); } @@ -2861,33 +2838,29 @@ tPtplayerSfx *ptplayerSfxCreateFromFile(const char *szPath, UBYTE isFast) { } UBYTE ubVersion; fileRead(pFileSfx, &ubVersion, sizeof(ubVersion)); - if(ubVersion == 1) { - fileRead(pFileSfx, &pSfx->uwWordLength, sizeof(pSfx->uwWordLength)); - ULONG ulByteSize = pSfx->uwWordLength * sizeof(UWORD); + assumeMsg(ubVersion == 1, "Unknown sample format version"); - UWORD uwSampleRateHz; - fileRead(pFileSfx, &uwSampleRateHz, sizeof(uwSampleRateHz)); - pSfx->uwPeriod = (getClockConstant() + uwSampleRateHz/2) / uwSampleRateHz; - logWrite("Length: %lu, sample rate: %hu, period: %hu\n", ulByteSize, uwSampleRateHz, pSfx->uwPeriod); + fileRead(pFileSfx, &pSfx->uwWordLength, sizeof(pSfx->uwWordLength)); + ULONG ulByteSize = pSfx->uwWordLength * sizeof(UWORD); - pSfx->pData = isFast ? memAllocFast(ulByteSize) : memAllocChip(ulByteSize); - if(!pSfx->pData) { - goto fail; - } - fileRead(pFileSfx, pSfx->pData, ulByteSize); - - // Check if pData[0] is zeroed-out - it should be because after sfx playback - // ptplayer sets the channel playback to looped first word. This should - // be done on sfx converter side. If your samples are humming after playback, - // fix your custom conversion tool or use latest ACE tools! - if(pSfx->pData[0] != 0) { - logWrite("WARN: SFX's first word isn't zeroed-out - won't work properly with ptplayer!\n"); - } - } - else { - logWrite("ERR: Unknown sample format version: %hhu\n", ubVersion); + UWORD uwSampleRateHz; + fileRead(pFileSfx, &uwSampleRateHz, sizeof(uwSampleRateHz)); + pSfx->uwPeriod = (getClockConstant() + uwSampleRateHz/2) / uwSampleRateHz; + logWrite("Length: %lu, sample rate: %hu, period: %hu\n", ulByteSize, uwSampleRateHz, pSfx->uwPeriod); + + pSfx->pData = isFast ? memAllocFast(ulByteSize) : memAllocChip(ulByteSize); + if(!pSfx->pData) { goto fail; } + fileRead(pFileSfx, pSfx->pData, ulByteSize); + + // Check if pData[0] is zeroed-out - it should be because after sfx playback + // ptplayer sets the channel playback to looped first word. This should + // be done on sfx converter side. If your samples are humming after playback, + // fix your custom conversion tool or use latest ACE tools! + if(pSfx->pData[0] != 0) { + logWrite("WARN: SFX's first word isn't zeroed-out - won't work properly with ptplayer!\n"); + } fileClose(pFileSfx); logBlockEnd("ptplayerSfxCreateFromFile()"); @@ -2971,9 +2944,7 @@ void ptplayerSfxStopOnChannel(UBYTE ubChannel) { void ptplayerSfxPlayLooped( const tPtplayerSfx *pSfx, UBYTE ubChannel, UBYTE ubVolume ) { - if(memType(pSfx->pData) == MEMF_FAST) { - logWrite("ERR: ptplayer only supports samples located in CHIP mem\n"); - } + assumeMsg(memType(pSfx->pData) == MEMF_CHIP, "ptplayer only supports samples located in CHIP mem"); g_pCustom->intena = INTF_INTEN; tChannelStatus *pChannel = &mt_chan[ubChannel]; channelSetSfx(pChannel, pSfx, ubVolume, SFX_PRIORITY_LOOPED); @@ -2983,9 +2954,7 @@ void ptplayerSfxPlayLooped( void ptplayerSfxPlay( const tPtplayerSfx *pSfx, UBYTE ubChannel, UBYTE ubVolume, UBYTE ubPriority ) { - if(memType(pSfx->pData) == MEMF_FAST) { - logWrite("ERR: ptplayer only supports samples located in CHIP mem\n"); - } + assumeMsg(memType(pSfx->pData) == MEMF_CHIP, "ptplayer only supports samples located in CHIP mem"); g_pCustom->intena = INTF_INTEN; if(ubChannel != PTPLAYER_SFX_CHANNEL_ANY) { // Use fixed channel for effect @@ -3184,7 +3153,7 @@ tPtplayerSamplePack *ptplayerSampleDataCreate(const char *szPath) { tPtplayerSamplePack *pSamplePack = 0; LONG lSize = fileGetSize(szPath); if(lSize <= 0) { - logWrite("ERR: Invalid file size. File exists?\n"); + logWrite("ERR: Invalid file size. Does file exist?\n"); goto fail; } diff --git a/src/ace/managers/rand.c b/src/ace/managers/rand.c index 13ea7455..cf77a09e 100644 --- a/src/ace/managers/rand.c +++ b/src/ace/managers/rand.c @@ -9,6 +9,7 @@ #include #include #include +#include // Coefficients are chosen from the table of original post, with restriction // to use shifts lesser than 8 in order to let compiler use "shift immediate" @@ -28,6 +29,7 @@ tRandManager *randCreate(UWORD uwSeed1, UWORD uwSeed2) { } void randDestroy(tRandManager *pRand) { + assumeNotNull(pRand); memFree(pRand, sizeof(*pRand)); } @@ -35,11 +37,9 @@ void randInit(tRandManager *pRand, UWORD uwSeed1, UWORD uwSeed2) { logBlockBegin( "randInit(pRand: %p, uwSeed1: %hu, uwSeed2: %hu)", pRand, uwSeed1, uwSeed2 ); - if(uwSeed1 == 0 || uwSeed2 == 0) { - logWrite("ERR: Seeds can't be zero!\n"); - logBlockEnd("randInit()"); - return; - } + assumeNotNull(pRand); + assumeMsg(uwSeed1 != 0, "Seeds can't be zero"); + assumeMsg(uwSeed2 != 0, "Seeds can't be zero"); pRand->uwState1 = uwSeed1; pRand->uwState2 = uwSeed2; @@ -47,6 +47,8 @@ void randInit(tRandManager *pRand, UWORD uwSeed1, UWORD uwSeed2) { } UWORD randUw(tRandManager *pRand) { + assumeNotNull(pRand); + UWORD t = (pRand->uwState1 ^ (pRand->uwState1 << RAND_COEFF_A)); pRand->uwState1 = pRand->uwState2; pRand->uwState2 = (pRand->uwState2 ^ (pRand->uwState2 >> RAND_COEFF_C)) ^ (t ^ (t >> RAND_COEFF_B)); @@ -54,24 +56,34 @@ UWORD randUw(tRandManager *pRand) { } UWORD randUwMax(tRandManager *pRand, UWORD uwMax) { + assumeNotNull(pRand); + return randUw(pRand) % (uwMax + 1); } UWORD randUwMinMax(tRandManager *pRand, UWORD uwMin, UWORD uwMax) { + assumeNotNull(pRand); + return uwMin + randUwMax(pRand, uwMax - uwMin); } ULONG randUl(tRandManager *pRand) { + assumeNotNull(pRand); + UWORD uwUpper = randUw(pRand); UWORD uwLower = randUw(pRand); return (uwUpper << 16) | (uwLower); } ULONG randUlMax(tRandManager *pRand, ULONG ulMax) { + assumeNotNull(pRand); + return randUl(pRand) % (ulMax + 1); } ULONG randUlMinMax(tRandManager *pRand, ULONG ulMin, ULONG ulMax) { + assumeNotNull(pRand); + return ulMin + randUlMax(pRand, ulMax - ulMin); } diff --git a/src/ace/managers/sprite.c b/src/ace/managers/sprite.c index ab848598..1efc22da 100644 --- a/src/ace/managers/sprite.c +++ b/src/ace/managers/sprite.c @@ -10,6 +10,7 @@ #include #include #include +#include #define SPRITE_VPOS_BITS 9 #define SPRITE_HEIGHT_MAX ((1 << SPRITE_VPOS_BITS) - 1) @@ -27,10 +28,13 @@ static tHardwareSpriteHeader CHIP s_uBlankSprite; static tCopBlock *s_pInitialClearCopBlock; static void spriteChannelRequestCopperUpdate(tSpriteChannel *pChannel) { + assumeNotNull(pChannel); pChannel->ubCopperRegenCount = 2; // for front/back buffers in raw mode } void spriteManagerCreate(const tView *pView, UWORD uwRawCopPos) { + assumeNotNull(pView); + // TODO: add support for non-chained mode (setting sprxdat with copper)? s_pView = pView; for(UBYTE i = HARDWARE_SPRITE_CHANNEL_COUNT; i--;) { @@ -73,32 +77,27 @@ void spriteManagerDestroy(void) { } tSprite *spriteAdd(UBYTE ubChannelIndex, tBitMap *pBitmap) { + assumeNotNull(pBitmap); + systemUse(); // TODO: add support for attaching next sprite to the chain. // TODO: add support for attached sprites (16-color) tSprite *pSprite = memAllocFastClear(sizeof(*pSprite)); + assumeNotNull(pSprite); // TODO: gracefully fail? pSprite->ubChannelIndex = ubChannelIndex; pSprite->isEnabled = 1; tSpriteChannel *pChannel = &s_pChannelsData[ubChannelIndex]; - if(pChannel->pFirstSprite) { - // TODO: add support for chaining sprites - logWrite("ERR: Sprite channel %hhu is already used\n", ubChannelIndex); - } - else { - spriteChannelRequestCopperUpdate(pChannel); - pChannel->pFirstSprite = pSprite; - if(s_pView->pCopList->ubMode == COPPER_MODE_BLOCK) { -#if defined(ACE_DEBUG) - if(pChannel->pCopBlock) { - logWrite("ERR: Sprite channel %hhu already has copBlock\n", ubChannelIndex); - systemUnuse(); - return 0; - } -#endif - pChannel->pCopBlock = copBlockCreate(s_pView->pCopList, 2, 0, 0); - } + // TODO: add support for chaining sprites + assumeMsg(pChannel->pFirstSprite == 0, "Sprite channel is already used"); + + spriteChannelRequestCopperUpdate(pChannel); + pChannel->pFirstSprite = pSprite; + + if(s_pView->pCopList->ubMode == COPPER_MODE_BLOCK) { + assumeMsg(pChannel->pCopBlock == 0, "Sprite channel already has copBlock"); + pChannel->pCopBlock = copBlockCreate(s_pView->pCopList, 2, 0, 0); } spriteSetBitmap(pSprite, pBitmap); @@ -107,6 +106,8 @@ tSprite *spriteAdd(UBYTE ubChannelIndex, tBitMap *pBitmap) { } void spriteRemove(tSprite *pSprite) { + assumeNotNull(pSprite); + systemUse(); tSpriteChannel *pChannel = &s_pChannelsData[pSprite->ubChannelIndex]; @@ -129,46 +130,31 @@ void spriteRemove(tSprite *pSprite) { } void spriteSetEnabled(tSprite *pSprite, UBYTE isEnabled) { + assumeNotNull(pSprite); + pSprite->isEnabled = isEnabled; // TODO: only after modifying first sprite in chain, change next sprite ptr in the prior one s_pChannelsData[pSprite->ubChannelIndex].ubCopperRegenCount = 2; // for front/back buffers } void spriteSetAttached(tSprite *pSprite, UBYTE isAttached) { -#if defined(ACE_DEBUG) - if(pSprite->ubChannelIndex % 2 == 0) { - logWrite( - "ERR: Invalid sprite to set attachment on. %hhu is not an odd sprite\n", - pSprite->ubChannelIndex - ); - isAttached = 0; - } -#endif + assumeNotNull(pSprite); + assumeMsg((pSprite->ubChannelIndex & 1) == 0, "Invalid sprite to set attachment on - sprite index must be odd"); pSprite->isAttached = isAttached; pSprite->isHeaderToBeUpdated = 1; } void spriteRequestMetadataUpdate(tSprite *pSprite) { + assumeNotNull(pSprite); + pSprite->isHeaderToBeUpdated = 1; } void spriteSetBitmap(tSprite *pSprite, tBitMap *pBitmap) { - if(!(pBitmap->Flags & BMF_INTERLEAVED) || pBitmap->Depth != 2) { - logWrite( - "ERR: Sprite channel %hhu bitmap %p isn't interleaved 2BPP!\n", - pSprite->ubChannelIndex, pBitmap - ); - return; - } - - UBYTE ubByteWidth = bitmapGetByteWidth(pBitmap); - if(ubByteWidth != 2) { - logWrite( - "ERR: Unsupported sprite width: %hhu, expected 16\n", - ubByteWidth * 8 - ); - return; - } + assumeNotNull(pSprite); + assumeNotNull(pBitmap); + assumeMsg((pBitmap->Flags & BMF_INTERLEAVED) && pBitmap->Depth == 2, "Sprite bitmap isn't interleaved 2BPP"); + assumeMsg(bitmapGetByteWidth(pBitmap) == 2, "Unsupported sprite width, expected 16"); pSprite->pBitmap = pBitmap; spriteSetHeight(pSprite, pBitmap->Rows - 2); @@ -217,19 +203,17 @@ void spriteProcessChannel(UBYTE ubChannelIndex) { } void spriteProcess(tSprite *pSprite) { + assumeNotNull(pSprite); + if(!pSprite->isHeaderToBeUpdated) { return; } + UBYTE isAttached = pSprite->isAttached; - #if defined(ACE_DEBUG) - if(pSprite->ubChannelIndex % 2 == 0 && pSprite->isAttached) { - logWrite( - "ERR: Invalid sprite to set attachment on. %hhu is not an odd sprite\n", - pSprite->ubChannelIndex - ); - isAttached = 0; - } - #endif + if(isAttached) { + assumeMsg((pSprite->ubChannelIndex & 1) == 0, "Invalid sprite to set attachment on - sprite index must be odd"); + } + // Sprite in list mode has 2-word header before and after data, each // occupies 1 line of the bitmap. // TODO: get rid of hardcoded 128 X offset in reasonable way. @@ -246,21 +230,15 @@ void spriteProcess(tSprite *pSprite) { (BTST(uwVStop, 8) << 1) | BTST(uwHStart, 0) ); - + } void spriteSetHeight(tSprite *pSprite, UWORD uwHeight) { -#if defined(ACE_DEBUG) + assumeNotNull(pSprite); + UWORD uwVStart = s_pView->ubPosY + pSprite->wY; UWORD uwMaxHeight = SPRITE_HEIGHT_MAX - uwVStart; - if(uwHeight >= uwMaxHeight) { - logWrite( - "ERR: Invalid sprite %hhu height %hu, max is %hu\n", - pSprite->ubChannelIndex, uwHeight, uwMaxHeight - ); - uwHeight = uwMaxHeight; - } -#endif + assumeMsg(uwHeight < uwMaxHeight, "Invalid sprite height"); pSprite->uwHeight = uwHeight; pSprite->isHeaderToBeUpdated = 1; diff --git a/src/ace/managers/state.c b/src/ace/managers/state.c index 12d4a0ad..3759ed0f 100644 --- a/src/ace/managers/state.c +++ b/src/ace/managers/state.c @@ -4,27 +4,10 @@ #include #include +#include /* Functions */ -#ifdef ACE_DEBUG - -#define checkNull(pPointer) _checkNull(pPointer, "##pPointer", __FILE__, __LINE__) -static void _checkNull( - void *pPointer, const char *szPointerName, const char *szFile, UWORD uwLine -) { - if (!pPointer) { - logWrite( - "ERR: Pointer %s is zero at %s:%u! Crash imminent!\n", - szPointerName, szFile, uwLine - ); - } -} - -#else -#define checkNull(pPointer) do {} while(0) -#endif - tStateManager *stateManagerCreate(void) { logBlockBegin("stateManagerCreate()"); @@ -37,11 +20,9 @@ tStateManager *stateManagerCreate(void) { void stateManagerDestroy(tStateManager *pStateManager) { logBlockBegin("stateManagerDestroy(pStateManager: %p)", pStateManager); - - checkNull(pStateManager); + assumeNotNull(pStateManager); statePopAll(pStateManager); - memFree(pStateManager, sizeof(tStateManager)); logBlockEnd("stateManagerDestroy()"); @@ -57,6 +38,7 @@ tState *stateCreate( ); tState *pState = memAllocFast(sizeof(tState)); + assumeNotNull(pState); // TODO: gracefully fail? pState->cbCreate = cbCreate; pState->cbLoop = cbLoop; @@ -72,8 +54,7 @@ tState *stateCreate( void stateDestroy(tState *pState) { logBlockBegin("stateDestroy(pState: %p)", pState); - - checkNull(pState); + assumeNotNull(pState); memFree(pState, sizeof(tState)); @@ -85,9 +66,8 @@ void statePush(tStateManager *pStateManager, tState *pState) { "statePush(pStateManager: %p, pState: %p)", pStateManager, pState ); - - checkNull(pStateManager); - checkNull(pState); + assumeNotNull(pStateManager); + assumeNotNull(pState); if (pStateManager->pCurrent && pStateManager->pCurrent->cbSuspend) { pStateManager->pCurrent->cbSuspend(); @@ -105,8 +85,7 @@ void statePush(tStateManager *pStateManager, tState *pState) { void statePop(tStateManager *pStateManager) { logBlockBegin("statePop(pStateManager: %p)", pStateManager); - - checkNull(pStateManager); + assumeNotNull(pStateManager); if (pStateManager->pCurrent && pStateManager->pCurrent->cbDestroy) { pStateManager->pCurrent->cbDestroy(); @@ -124,8 +103,7 @@ void statePop(tStateManager *pStateManager) { void statePopAll(tStateManager *pStateManager) { logBlockBegin("statePopAll(pStateManager: %p)", pStateManager); - - checkNull(pStateManager); + assumeNotNull(pStateManager); while (pStateManager->pCurrent) { if (pStateManager->pCurrent->cbDestroy) { @@ -143,9 +121,8 @@ void stateChange(tStateManager *pStateManager, tState *pState) { "stateChange(pStateManager: %p, pState: %p)", pStateManager, pState ); - - checkNull(pStateManager); - checkNull(pState); + assumeNotNull(pStateManager); + assumeNotNull(pState); if (pStateManager->pCurrent && pStateManager->pCurrent->cbDestroy) { pStateManager->pCurrent->cbDestroy(); @@ -168,7 +145,7 @@ void stateChange(tStateManager *pStateManager, tState *pState) { } void stateProcess(tStateManager *pStateManager) { - checkNull(pStateManager); + assumeNotNull(pStateManager); if (pStateManager->pCurrent && pStateManager->pCurrent->cbLoop) { pStateManager->pCurrent->cbLoop(); diff --git a/src/ace/managers/viewport/scrollbuffer.c b/src/ace/managers/viewport/scrollbuffer.c index 2c63c858..03dad4a1 100644 --- a/src/ace/managers/viewport/scrollbuffer.c +++ b/src/ace/managers/viewport/scrollbuffer.c @@ -4,6 +4,7 @@ #include #include +#include #include // Has the look up table for the COPPER_X_WAIT values. #include @@ -28,7 +29,6 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { UBYTE ubMarginWidth; UWORD uwBoundWidth, uwBoundHeight; UBYTE ubBitmapFlags; - UBYTE isCameraCreated = 0; UBYTE isDblBuf; logBlockBegin("scrollBufferCreate(pTags: %p, ...)", pTags); @@ -42,22 +42,14 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { logWrite("Addr: %p\n", pManager); tVPort *pVPort = (tVPort*)tagGet(pTags, vaTags, TAG_SCROLLBUFFER_VPORT, 0); - if(!pVPort) { - logWrite("ERR: No parent viewport (TAG_SCROLLBUFFER_VPORT) specified!\n"); - goto fail; - } + assumeMsg(pVPort != 0, "No parent viewport (TAG_SCROLLBUFFER_VPORT) specified"); 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; - } + assumeMsg(ubMarginWidth != UCHAR_MAX, "No margin width (TAG_SCROLLBUFFER_MARGIN_WIDTH) specified"); // Buffer bitmap uwBoundWidth = tagGet( @@ -94,21 +86,11 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { pManager->uwCopperOffsetStart = tagGet( pTags, vaTags, TAG_SCROLLBUFFER_COPLIST_OFFSET_START, uwInvalidCopOffs ); - if(pManager->uwCopperOffsetStart == uwInvalidCopOffs) { - logWrite( - "ERR: Copperlist offset (TAG_SCROLLBUFFER_COPLIST_OFFSET_START) not specified!\n" - ); - goto fail; - } + assumeMsg(pManager->uwCopperOffsetStart != uwInvalidCopOffs, "Copperlist offset (TAG_SCROLLBUFFER_COPLIST_OFFSET_START) not specified"); pManager->uwCopperOffsetBreak = tagGet( pTags, vaTags, TAG_SCROLLBUFFER_COPLIST_OFFSET_BREAK, uwInvalidCopOffs ); - if(pManager->uwCopperOffsetBreak == uwInvalidCopOffs) { - logWrite( - "ERR: Copperlist offset (TAG_SCROLLBUFFER_COPLIST_OFFSET_BREAK) not specified!\n" - ); - goto fail; - } + assumeMsg(pManager->uwCopperOffsetBreak != uwInvalidCopOffs, "Copperlist offset (TAG_SCROLLBUFFER_COPLIST_OFFSET_BREAK) not specified"); logWrite("Copperlist offsets: start: %u, break: %u\n", pManager->uwCopperOffsetStart, pManager->uwCopperOffsetBreak); @@ -128,7 +110,6 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { pManager->pCamera = cameraCreate( pVPort, 0, 0, uwBoundWidth, uwBoundHeight, isDblBuf ); - isCameraCreated = 1; } else { cameraReset(pManager->pCamera, 0,0, uwBoundWidth, uwBoundHeight, isDblBuf); @@ -139,21 +120,6 @@ tScrollBufferManager *scrollBufferCreate(void *pTags, ...) { va_end(vaTags); logBlockEnd("scrollBufferCreate"); return pManager; -fail: - if(isCameraCreated) { - cameraDestroy(pManager->pCamera); - } - if(pCopList && pCopList->ubMode == COPPER_MODE_BLOCK && pManager->pStartBlock) { - copBlockDestroy(pCopList, pManager->pStartBlock); - if(pManager->pBreakBlock) { - copBlockDestroy(pCopList, pManager->pBreakBlock); - } - } - - memFree(pManager, sizeof(tScrollBufferManager)); - va_end(vaTags); - logBlockEnd("scrollBufferCreate"); - return 0; } void scrollBufferDestroy(tScrollBufferManager *pManager) { diff --git a/src/ace/managers/viewport/simplebuffer.c b/src/ace/managers/viewport/simplebuffer.c index d7efe9a2..177135d5 100644 --- a/src/ace/managers/viewport/simplebuffer.c +++ b/src/ace/managers/viewport/simplebuffer.c @@ -6,6 +6,7 @@ #include #include #include +#include #include // Has the look up table for the COPPER_X_WAIT values. #ifdef AMIGA @@ -109,12 +110,9 @@ static void simpleBufferInitializeCopperList( } 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; + if(pManager->pBack) { + assumeMsg(pManager->pBack->Depth == pBack->Depth, "Buffer bitmaps differ in BPP"); } -#endif pManager->pBack = pBack; } @@ -123,12 +121,9 @@ void simpleBufferSetFront(tSimpleBufferManager *pManager, tBitMap *pFront) { "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; + if(pManager->pFront) { + assumeMsg(pManager->pBack->Depth == pFront->Depth, "Buffer bitmaps differ in BPP"); } -#endif pManager->pFront = pFront; logBlockEnd("simplebufferSetFront()"); } @@ -140,7 +135,6 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { UWORD uwBoundWidth, uwBoundHeight; UBYTE ubBitmapFlags; tBitMap *pFront = 0, *pBack = 0; - UBYTE isCameraCreated = 0; logBlockBegin("simpleBufferCreate(pTags: %p, ...)", pTags); va_start(vaTags, pTags); @@ -153,10 +147,7 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { logWrite("Addr: %p\n", pManager); tVPort *pVPort = (tVPort*)tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_VPORT, 0); - if(!pVPort) { - logWrite("ERR: No parent viewport (TAG_SIMPLEBUFFER_VPORT) specified!\n"); - goto fail; - } + assumeMsg(pVPort != 0, "No parent viewport (TAG_SIMPLEBUFFER_VPORT) specified"); pManager->sCommon.pVPort = pVPort; logWrite("Parent VPort: %p\n", pVPort); @@ -174,29 +165,23 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { pFront = bitmapCreate( uwBoundWidth, uwBoundHeight, pVPort->ubBPP, ubBitmapFlags ); - if(!pFront) { - logWrite("ERR: Can't alloc buffer bitmap!\n"); - goto fail; - } + assumeNotNull(pFront); UBYTE isDblBfr = tagGet(pTags, vaTags, TAG_SIMPLEBUFFER_IS_DBLBUF, 0); if(isDblBfr) { pBack = bitmapCreate( uwBoundWidth, uwBoundHeight, pVPort->ubBPP, ubBitmapFlags ); - if(!pBack) { - logWrite("ERR: Can't alloc buffer bitmap!\n"); - goto fail; - } + assumeNotNull(pBack); } // Find camera manager, create if not exists pManager->pCamera = (tCameraManager*)vPortGetManager(pVPort, VPM_CAMERA); if(!pManager->pCamera) { - isCameraCreated = 1; pManager->pCamera = cameraCreate( pVPort, 0, 0, uwBoundWidth, uwBoundHeight, isDblBfr ); + assumeNotNull(pManager->pCamera); } pCopList = pVPort->pView->pCopList; @@ -217,12 +202,10 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { pManager->uwCopperOffset = tagGet( pTags, vaTags, TAG_SIMPLEBUFFER_COPLIST_OFFSET, uwInvalidCopOffs ); - if(pManager->uwCopperOffset == uwInvalidCopOffs) { - logWrite( - "ERR: Copperlist offset (TAG_SIMPLEBUFFER_COPLIST_OFFSET) not specified!\n" - ); - goto fail; - } + assumeMsg( + pManager->uwCopperOffset != uwInvalidCopOffs, + "Copperlist offset (TAG_SIMPLEBUFFER_COPLIST_OFFSET) not specified" + ); logWrite("Copperlist offset: %u\n", pManager->uwCopperOffset); } @@ -236,23 +219,6 @@ tSimpleBufferManager *simpleBufferCreate(void *pTags, ...) { logBlockEnd("simpleBufferCreate()"); va_end(vaTags); return pManager; - -fail: - if(pBack && pBack != pFront) { - bitmapDestroy(pBack); - } - if(pFront) { - bitmapDestroy(pFront); - } - if(pManager) { - if(pManager->pCamera && isCameraCreated) { - cameraDestroy(pManager->pCamera); - } - memFree(pManager, sizeof(tSimpleBufferManager)); - } - logBlockEnd("simpleBufferCreate()"); - va_end(vaTags); - return 0; } void simpleBufferDestroy(tSimpleBufferManager *pManager) { diff --git a/src/ace/managers/viewport/tilebuffer.c b/src/ace/managers/viewport/tilebuffer.c index 97d82de3..48db8a18 100644 --- a/src/ace/managers/viewport/tilebuffer.c +++ b/src/ace/managers/viewport/tilebuffer.c @@ -7,6 +7,7 @@ #include #include #include +#include #include // Bartman's compiler needs this static UBYTE shiftFromPowerOfTwo(UWORD uwPot) { @@ -38,15 +39,14 @@ static void tileBufferQueueAdd( tTileBufferManager *pManager, UWORD uwTileX, UWORD uwTileY ) { // Add two times so that they're drawn properly in double buffering -#if defined ACE_DEBUG - if( - pManager->pRedrawStates[0].ubPendingCount > pManager->ubQueueSize - 2 || - pManager->pRedrawStates[1].ubPendingCount > pManager->ubQueueSize - 2 - ) { - logWrite("ERR: No more space in redraw queue"); - return; - } -#endif + assumeMsg( + pManager->pRedrawStates[0].ubPendingCount <= pManager->ubQueueSize - 2, + "No more space in redraw queue" + ); + assumeMsg( + pManager->pRedrawStates[1].ubPendingCount <= pManager->ubQueueSize - 2, + "No more space in redraw queue" + ); tRedrawState *pState = &pManager->pRedrawStates[0]; pState->pPendingQueue[pState->ubPendingCount].uwX = uwTileX; pState->pPendingQueue[pState->ubPendingCount].uwY = uwTileY; @@ -85,18 +85,12 @@ tTileBufferManager *tileBufferCreate(void *pTags, ...) { 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; - } + assumeMsg(pVPort != 0, "No parent viewport (TAG_TILEBUFFER_VPORT) specified"); 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; - } + assumeMsg(ubTileShift != 0, "No tile shift (TAG_TILEBUFFER_TILE_SHIFT) specified"); pManager->ubTileShift = ubTileShift; pManager->ubTileSize = 1 << ubTileShift; @@ -105,18 +99,13 @@ tTileBufferManager *tileBufferCreate(void *pTags, ...) { ); pManager->pTileSet = (tBitMap*)tagGet(pTags, vaTags, TAG_TILEBUFFER_TILESET, 0); - if(!pManager->pTileSet) { - logWrite("ERR: No tileset (TAG_TILEBUFFER_TILESET) specified!\n"); - goto fail; - } + assumeMsg(pManager->pTileSet != 0, "No tileset (TAG_TILEBUFFER_TILESET) specified"); + uwTileX = tagGet(pTags, vaTags, TAG_TILEBUFFER_BOUND_TILE_X, 0); + assumeMsg(uwTileX != 0, "TAG_TILEBUFFER_BOUND_TILE_X not specified"); + 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" - ); - goto fail; - } + assumeMsg(uwTileY != 0, "TAG_TILEBUFFER_BOUND_TILE_Y not specified"); pManager->pTileData = 0; ubBitmapFlags = tagGet(pTags, vaTags, TAG_TILEBUFFER_BITMAP_FLAGS, BMF_CLEAR); @@ -128,23 +117,14 @@ tTileBufferManager *tileBufferCreate(void *pTags, ...) { 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; - } + assumeMsg(pManager->ubQueueSize != 0, "No queue size (TAG_TILEBUFFER_REDRAW_QUEUE_LENGTH) specified"); // 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; - } + assumeNotNull(pManager->pRedrawStates[0].pPendingQueue); + assumeNotNull(pManager->pRedrawStates[1].pPendingQueue); vPortAddManager(pVPort, (tVpManager*)pManager); @@ -158,17 +138,6 @@ tTileBufferManager *tileBufferCreate(void *pTags, ...) { 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) { diff --git a/src/ace/utils/assume.c b/src/ace/utils/assume.c new file mode 100644 index 00000000..191a5660 --- /dev/null +++ b/src/ace/utils/assume.c @@ -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 + +#if defined(ACE_DEBUG) + +void _assume(ULONG ulExprValue, const char *szErrorMsg, const char *szFile, ULONG ulLine) { + if(!ulExprValue) { + if(szErrorMsg) { + logWrite("ERR: Assumption failed at %s:%lu - %s\n", szFile, ulLine, szErrorMsg); + } + else { + logWrite("ERR: Assumption failed at %s:%lu\n", szFile, ulLine); + } +#if defined(BARTMAN_GCC) + __builtin_trap(); +#else + systemKill("Assumption failed - see logs for details"); +#endif + } +} + +#endif diff --git a/src/ace/utils/bitmap.c b/src/ace/utils/bitmap.c index 45cfdf62..7776e095 100644 --- a/src/ace/utils/bitmap.c +++ b/src/ace/utils/bitmap.c @@ -10,6 +10,7 @@ #include #include #include +#include /* Globals */ @@ -28,18 +29,12 @@ tBitMap *bitmapCreate( uwWidth, uwHeight, ubDepth, ubFlags ); - if(uwWidth == 0 || uwHeight == 0) { - logWrite("ERR: invalid bitmap dimensions\n"); - return 0; - } - - if((uwWidth & 0xF) != 0) { - // Needed for blitter! - logWrite("ERR: bitmap width is not multiple of 16\n"); - return 0; - } + assumeMsg(uwWidth != 0, "zero bitmap width"); + assumeMsg(uwHeight != 0, "zero bitmap height"); + assumeMsg((uwWidth & 0xF) == 0, "bitmap width is not multiple of 16"); pBitMap = (tBitMap*) memAllocFastClear(sizeof(tBitMap)); + assumeNotNull(pBitMap); logWrite("addr: %p\n", pBitMap); pBitMap->BytesPerRow = uwWidth / 8; @@ -134,7 +129,6 @@ void bitmapLoadFromFile( // Open source bitmap tFile *pFile = fileOpen(szFilePath, "r"); if(!pFile) { - logWrite("ERR: File does not exist\n"); logBlockEnd("bitmapLoadFromFile()"); systemUnuse(); return; @@ -147,40 +141,14 @@ void bitmapLoadFromFile( fileRead(pFile, &ubSrcVersion, sizeof(UBYTE)); fileRead(pFile, &ubSrcFlags, sizeof(UBYTE)); fileSeek(pFile, 2*sizeof(UBYTE), FILE_SEEK_CURRENT); // Skip unused 2 bytes - if(ubSrcVersion != 0) { - fileClose(pFile); - logWrite("ERR: Unknown file version: %hu\n", ubSrcVersion); - logBlockEnd("bitmapLoadFromFile()"); - systemUnuse(); - return; - } + assumeMsg(ubSrcVersion == 0, "Unknown file version"); logWrite("Source dimensions: %ux%u\n", uwSrcWidth, uwSrcHeight); - // Interleaved check - if(!!(ubSrcFlags & BITMAP_INTERLEAVED) != bitmapIsInterleaved(pBitMap)) { - logWrite( - "ERR: Interleaved flag conflict (file: %d, bm: %hhu)\n", - !!(ubSrcFlags & BITMAP_INTERLEAVED), bitmapIsInterleaved(pBitMap) - ); - fileClose(pFile); - logBlockEnd("bitmapLoadFromFile()"); - systemUnuse(); - return; - } - - // Depth check - if(ubSrcBpp > pBitMap->Depth) { - logWrite( - "ERR: Source has greater BPP than destination: %hu > %hu\n", - ubSrcBpp, pBitMap->Depth - ); - fileClose(pFile); - logBlockEnd("bitmapLoadFromFile()"); - systemUnuse(); - return; - } + assumeMsg(((ubSrcFlags & BITMAP_INTERLEAVED) != 0) == bitmapIsInterleaved(pBitMap), "Interleaved flag conflict"); + assumeMsg(ubSrcBpp <= pBitMap->Depth, "Source has greater BPP than destination"); // Check bitmap dimensions + // TODO: Assume check? uwDstWidth = bitmapGetByteWidth(pBitMap) << 3; if(uwStartX + uwSrcWidth > uwDstWidth || uwStartY + uwSrcHeight > (pBitMap->Rows)) { logWrite( @@ -224,6 +192,7 @@ void bitmapLoadFromFile( systemUnuse(); } +// TODO: remove, generate initialized bitmap struct in .c/.h with bitmap_conv instead void bitmapLoadFromMem( tBitMap *pBitMap, const UBYTE* pData, UWORD uwStartX, UWORD uwStartY ) { @@ -239,7 +208,6 @@ void bitmapLoadFromMem( pBitMap, uwStartX, uwStartY ); - // Read header memcpy(&uwSrcWidth,&pData[ulCurByte],sizeof(UWORD)); ulCurByte+=sizeof(UWORD); @@ -258,29 +226,11 @@ void bitmapLoadFromMem( ulCurByte+=2*sizeof(UBYTE); - if(ubSrcVersion != 0) { - logWrite("ERR: Unknown file version: %hu\n", ubSrcVersion); - logBlockEnd("bitmapLoadFromMem()"); - return; - } + assumeMsg(ubSrcVersion == 0, "Unknown file version"); logWrite("Source dimensions: %ux%u\n", uwSrcWidth, uwSrcHeight); - // Interleaved check - if(!!(ubSrcFlags & BITMAP_INTERLEAVED) != bitmapIsInterleaved(pBitMap)) { - logWrite("ERR: Interleaved flag conflict\n"); - logBlockEnd("bitmapLoadFromMem()"); - return; - } - - // Depth check - if(ubSrcBpp > pBitMap->Depth) { - logWrite( - "ERR: Source has greater BPP than destination: %hu > %hu\n", - ubSrcBpp, pBitMap->Depth - ); - logBlockEnd("bitmapLoadFromMem()"); - return; - } + assumeMsg(((ubSrcFlags & BITMAP_INTERLEAVED) != 0) == bitmapIsInterleaved(pBitMap), "Interleaved flag conflict"); + assumeMsg(ubSrcBpp <= pBitMap->Depth, "Source has greater BPP than destination"); // Check bitmap dimensions uwDstWidth = bitmapGetByteWidth(pBitMap) << 3; @@ -328,7 +278,6 @@ tBitMap *bitmapCreateFromFile(const char *szFilePath, UBYTE isFast) { pFile = fileOpen(szFilePath, "r"); if(!pFile) { fileClose(pFile); - logWrite("ERR: File does not exist\n"); logBlockEnd("bitmapCreateFromFile()"); return 0; } @@ -340,12 +289,7 @@ tBitMap *bitmapCreateFromFile(const char *szFilePath, UBYTE isFast) { fileRead(pFile, &ubVersion, sizeof(UBYTE)); fileRead(pFile, &ubFlags, sizeof(UBYTE)); fileSeek(pFile, 2 * sizeof(UBYTE), SEEK_CUR); // Skip unused 2 bytes - if(ubVersion != 0) { - fileClose(pFile); - logWrite("ERR: Unknown file version: %hu\n", ubVersion); - logBlockEnd("bitmapCreateFromFile()"); - return 0; - } + assumeMsg(ubVersion == 0, "Unknown file version"); // Init bitmap UBYTE ubBitmapFlags = 0; diff --git a/src/ace/utils/extview.c b/src/ace/utils/extview.c index c15e69e8..3a55e774 100644 --- a/src/ace/utils/extview.c +++ b/src/ace/utils/extview.c @@ -6,6 +6,7 @@ #include #include #include +#include #include static UBYTE s_isPAL; @@ -104,6 +105,8 @@ tView *viewCreate(void *pTags, ...) { void viewDestroy(tView *pView) { logBlockBegin("viewDestroy(pView: %p)", pView); + assumeNotNull(pView); + #ifdef AMIGA if(g_sCopManager.pCopList == pView->pCopList) { viewLoad(0); @@ -123,6 +126,8 @@ void viewDestroy(tView *pView) { } void vPortProcessManagers(tVPort *pVPort) { + assumeNotNull(pVPort); + tVpManager *pManager = pVPort->pFirstManager; while(pManager) { pManager->process(pManager); @@ -131,6 +136,8 @@ void vPortProcessManagers(tVPort *pVPort) { } void viewProcessManagers(tView *pView) { + assumeNotNull(pView); + tVPort *pVPort = pView->pFirstVPort; while(pVPort) { vPortProcessManagers(pVPort); @@ -139,6 +146,7 @@ void viewProcessManagers(tView *pView) { } void viewUpdatePalette(tView *pView) { + assumeNotNull(pView); #ifdef AMIGA if(pView->uwFlags & VIEW_FLAG_GLOBAL_PALETTE) { for(UBYTE i = 0; i < 32; ++i) { @@ -146,7 +154,7 @@ void viewUpdatePalette(tView *pView) { } } else { - // na petli: vPortUpdatePalette(); + // looped: vPortUpdatePalette(); } #endif // AMIGA } @@ -182,12 +190,10 @@ void viewLoad(tView *pView) { while(pVp->pNext) { pVp = pVp->pNext; } - if(pVp->uwOffsY + pVp->uwHeight != pView->uwHeight) { - logWrite( - "ERR: View height %hu doesn't match the total VPort area: %hu", - pView->uwHeight, pVp->uwOffsY + pVp->uwHeight - ); - } + assumeMsg( + pVp->uwOffsY + pVp->uwHeight == pView->uwHeight, + "View height doesn't match the total VPort area" + ); } #endif g_sCopManager.pCopList = pView->pCopList; @@ -196,12 +202,10 @@ void viewLoad(tView *pView) { g_pCustom->bplcon3 = 0; // AGA fix g_pCustom->diwstrt = (pView->ubPosY << 8) | 0x81; // HSTART: 0x81 UWORD uwDiwStopY = pView->ubPosY + pView->uwHeight; - if(BTST(uwDiwStopY, 8) == BTST(uwDiwStopY, 7)) { - logWrite( - "ERR: DiwStopY (%hu) bit 8 (%hhu) must be different than bit 7 (%hhu)\n", - uwDiwStopY, BTST(uwDiwStopY, 8), BTST(uwDiwStopY, 7) - ); - } + assumeMsg( + BTST(uwDiwStopY, 8) != BTST(uwDiwStopY, 7), + "DiwStopY bit 8 must be different than bit 7" + ); g_pCustom->diwstop = ((uwDiwStopY & 0xFF) << 8) | 0xC1; // HSTOP: 0xC1 viewUpdatePalette(pView); } @@ -228,10 +232,7 @@ tVPort *vPortCreate(void *pTagList, ...) { // Determine parent view tView *pView = (tView*)tagGet(pTagList, vaTags, TAG_VPORT_VIEW, 0); - if(!pView) { - logWrite("ERR: no view ptr in TAG_VPORT_VIEW specified!\n"); - goto fail; - } + assumeMsg(pView != 0, "no view ptr in TAG_VPORT_VIEW specified"); pVPort->pView = pView; logWrite("Parent view: %p\n", pView); @@ -283,29 +284,21 @@ tVPort *vPortCreate(void *pTagList, ...) { UWORD *pSrcPalette = (UWORD*)tagGet(pTagList, vaTags, TAG_VPORT_PALETTE_PTR, 0); if(pSrcPalette) { UWORD uwPaletteSize = tagGet(pTagList, vaTags, TAG_VPORT_PALETTE_SIZE, 0xFFFF); - if(uwPaletteSize == 0xFFFF) { - logWrite("WARN: you must specify palette size in TAG_VPORT_PALETTE_SIZE\n"); - } - else if(!uwPaletteSize || uwPaletteSize > 32) { - logWrite("ERR: Wrong palette size: %hu\n", uwPaletteSize); - } - else { - memcpy(pVPort->pPalette, pSrcPalette, uwPaletteSize * sizeof(UWORD)); - } + assumeMsg(uwPaletteSize != 0xFFFF, "unspecified palette size (TAG_VPORT_PALETTE_SIZE)"); + assumeMsg(0 < uwPaletteSize && uwPaletteSize < 32, "invalid palette size"); + memcpy(pVPort->pPalette, pSrcPalette, uwPaletteSize * sizeof(UWORD)); } va_end(vaTags); logBlockEnd("vPortCreate()"); return pVPort; #endif // AMIGA -fail: - va_end(vaTags); - logBlockEnd("vPortCreate()"); - return 0; } void vPortDestroy(tVPort *pVPort) { logBlockBegin("vPortDestroy(pVPort: %p)", pVPort); + assumeNotNull(pVPort); + tView *pView; tVPort *pPrevVPort, *pCurrVPort; @@ -366,23 +359,19 @@ void vPortUpdatePalette(tVPort *pVPort) { // (like expanding HUD to fullscreen like we did in Goblin Villages). // On copblocks implementing it is somewhat easy, but on raw copperlist // something clever must be done. - if(pVPort->uwFlags & VIEWPORT_HAS_OWN_PALETTE) { - logWrite("TODO: implement vPortUpdatePalette!\n"); - } + assumeMsg((pVPort->uwFlags & VIEWPORT_HAS_OWN_PALETTE) == 0, "implement vPortUpdatePalette"); } void vPortWaitForPos(const tVPort *pVPort, UWORD uwPosY, UBYTE isExact) { + assumeNotNull(pVPort); + #ifdef AMIGA // Determine VPort end position UWORD uwEndPos = pVPort->uwOffsY + uwPosY; uwEndPos += pVPort->pView->ubPosY; // Addition from DiWStrt -#if defined(ACE_DEBUG) - UWORD yPos = s_isPAL ? 312 : 272; - if(uwEndPos >= yPos) { - logWrite("ERR: vPortWaitForPos - too big wait pos: %04hx (%hu)\n", uwEndPos, uwEndPos); - logWrite("\tVPort offs: %hu, pos: %hu\n", pVPort->uwOffsY, uwPosY); - } -#endif + + UWORD uwScreenModeMaxPos = s_isPAL ? 312 : 272; + assumeMsg(uwEndPos < uwScreenModeMaxPos, "too big wait pos"); if(isExact) { // If current beam pos is on or past end pos, wait for start of next frame @@ -402,6 +391,9 @@ void vPortWaitForEnd(const tVPort *pVPort) { } void vPortAddManager(tVPort *pVPort, tVpManager *pVpManager) { + assumeNotNull(pVPort); + assumeNotNull(pVpManager); + // Check if we have any other manager - if not, attach as head if(!pVPort->pFirstManager) { pVPort->pFirstManager = pVpManager; @@ -436,10 +428,9 @@ void vPortAddManager(tVPort *pVPort, tVpManager *pVpManager) { } void vPortRmManager(tVPort *pVPort, tVpManager *pVpManager) { - if(!pVPort->pFirstManager) { - logWrite("ERR: vPort %p has no managers!\n", pVPort); - return; - } + assumeNotNull(pVPort); + assumeMsg(pVPort->pFirstManager != 0, "vPort has no managers"); + if(pVPort->pFirstManager == pVpManager) { logWrite("Destroying manager %u @addr: %p\n", pVpManager->ubId, pVpManager); pVPort->pFirstManager = pVpManager->pNext; @@ -459,9 +450,9 @@ void vPortRmManager(tVPort *pVPort, tVpManager *pVpManager) { } tVpManager *vPortGetManager(tVPort *pVPort, UBYTE ubId) { - tVpManager *pManager; + assumeNotNull(pVPort); - pManager = pVPort->pFirstManager; + tVpManager *pManager = pVPort->pFirstManager; while(pManager) { if(pManager->ubId == ubId) { return pManager; diff --git a/src/ace/utils/file.c b/src/ace/utils/file.c index c123b171..1ebc19ba 100644 --- a/src/ace/utils/file.c +++ b/src/ace/utils/file.c @@ -6,8 +6,10 @@ #include #include #include +#include -LONG fileGetSize(const char *szPath) { +LONG fileGetSize(const char *szFilePath) { + assumeNotNull(szFilePath); // One could use std library to seek to end of file and use ftell, // but SEEK_END is not guaranteed to work. // http://www.cplusplus.com/reference/cstdio/fseek/ @@ -17,8 +19,8 @@ LONG fileGetSize(const char *szPath) { systemUse(); systemReleaseBlitterToOs(); - logBlockBegin("fileGetSize(szPath: '%s')", szPath); - FILE *pFile = fopen(szPath, "r"); + logBlockBegin("fileGetSize(szFilePath: '%s')", szFilePath); + FILE *pFile = fopen(szFilePath, "r"); if(!pFile) { logWrite("ERR: File doesn't exist"); logBlockEnd("fileGetSize()"); @@ -37,11 +39,14 @@ LONG fileGetSize(const char *szPath) { return lSize; } -tFile *fileOpen(const char *szPath, const char *szMode) { - // TODO check if disk is read protected when szMode has 'a'/'r'/'x' +tFile *fileOpen(const char *szFilePath, const char *szMode) { + assumeNotNull(szFilePath); + assumeNotNull(szMode); + + // TODO check if disk is write protected when szMode has 'a'/'w'/'x' systemUse(); systemReleaseBlitterToOs(); - FILE *pFile = fopen(szPath, szMode); + FILE *pFile = fopen(szFilePath, szMode); systemGetBlitterFromOs(); systemUnuse(); @@ -49,6 +54,8 @@ tFile *fileOpen(const char *szPath, const char *szMode) { } void fileClose(tFile *pFile) { + assumeNotNull(pFile); + systemUse(); systemReleaseBlitterToOs(); fclose(pFile); @@ -57,11 +64,10 @@ void fileClose(tFile *pFile) { } ULONG fileRead(tFile *pFile, void *pDest, ULONG ulSize) { -#ifdef ACE_DEBUG - if(!ulSize) { - logWrite("ERR: File read size = 0!\n"); - } -#endif + assumeNotNull(pFile); + assumeNotNull(pDest); + assumeMsg(ulSize != 0, "File read size is zero"); + systemUse(); systemReleaseBlitterToOs(); ULONG ulReadCount = fread(pDest, ulSize, 1, pFile); @@ -72,6 +78,10 @@ ULONG fileRead(tFile *pFile, void *pDest, ULONG ulSize) { } ULONG fileWrite(tFile *pFile, const void *pSrc, ULONG ulSize) { + assumeNotNull(pFile); + assumeNotNull(pSrc); + assumeMsg(ulSize != 0, "File write size is zero"); + systemUse(); systemReleaseBlitterToOs(); ULONG ulResult = fwrite(pSrc, ulSize, 1, pFile); @@ -83,6 +93,8 @@ ULONG fileWrite(tFile *pFile, const void *pSrc, ULONG ulSize) { } ULONG fileSeek(tFile *pFile, ULONG ulPos, WORD wMode) { + assumeNotNull(pFile); + systemUse(); systemReleaseBlitterToOs(); ULONG ulResult = fseek(pFile, ulPos, wMode); @@ -93,6 +105,8 @@ ULONG fileSeek(tFile *pFile, ULONG ulPos, WORD wMode) { } ULONG fileGetPos(tFile *pFile) { + assumeNotNull(pFile); + systemUse(); systemReleaseBlitterToOs(); ULONG ulResult = ftell(pFile); @@ -103,6 +117,8 @@ ULONG fileGetPos(tFile *pFile) { } UBYTE fileIsEof(tFile *pFile) { + assumeNotNull(pFile); + systemUse(); systemReleaseBlitterToOs(); UBYTE ubResult = feof(pFile); @@ -114,6 +130,8 @@ UBYTE fileIsEof(tFile *pFile) { #if !defined(BARTMAN_GCC) // Not implemented in mini_std for now, sorry! LONG fileVaPrintf(tFile *pFile, const char *szFmt, va_list vaArgs) { + assumeNotNull(pFile); + systemUse(); systemReleaseBlitterToOs(); LONG lResult = vfprintf(pFile, szFmt, vaArgs); @@ -124,6 +142,8 @@ LONG fileVaPrintf(tFile *pFile, const char *szFmt, va_list vaArgs) { } LONG filePrintf(tFile *pFile, const char *szFmt, ...) { + assumeNotNull(pFile); + va_list vaArgs; va_start(vaArgs, szFmt); LONG lResult = fileVaPrintf(pFile, szFmt, vaArgs); @@ -132,6 +152,8 @@ LONG filePrintf(tFile *pFile, const char *szFmt, ...) { } LONG fileVaScanf(tFile *pFile, const char *szFmt, va_list vaArgs) { + assumeNotNull(pFile); + systemUse(); systemReleaseBlitterToOs(); LONG lResult = vfscanf(pFile, szFmt, vaArgs); @@ -141,6 +163,8 @@ LONG fileVaScanf(tFile *pFile, const char *szFmt, va_list vaArgs) { } LONG fileScanf(tFile *pFile, const char *szFmt, ...) { + assumeNotNull(pFile); + va_list vaArgs; va_start(vaArgs, szFmt); LONG lResult = fileVaScanf(pFile, szFmt, vaArgs); @@ -150,6 +174,8 @@ LONG fileScanf(tFile *pFile, const char *szFmt, ...) { #endif void fileFlush(tFile *pFile) { + assumeNotNull(pFile); + systemUse(); systemReleaseBlitterToOs(); fflush(pFile); @@ -158,14 +184,18 @@ void fileFlush(tFile *pFile) { } void fileWriteStr(tFile *pFile, const char *szLine) { + assumeNotNull(pFile); + fileWrite(pFile, szLine, strlen(szLine)); } -UBYTE fileExists(const char *szPath) { +UBYTE fileExists(const char *szFilePath) { + assumeNotNull(szFilePath); + systemUse(); systemReleaseBlitterToOs(); UBYTE isExisting = 0; - tFile *pFile = fileOpen(szPath, "r"); + tFile *pFile = fileOpen(szFilePath, "r"); if(pFile) { isExisting = 1; fileClose(pFile); @@ -177,6 +207,8 @@ UBYTE fileExists(const char *szPath) { } UBYTE fileDelete(const char *szFilePath) { + assumeNotNull(szFilePath); + systemUse(); systemReleaseBlitterToOs(); UBYTE isSuccess = remove(szFilePath); @@ -185,10 +217,13 @@ UBYTE fileDelete(const char *szFilePath) { return isSuccess; } -UBYTE fileMove(const char *szSource, const char *szDest) { +UBYTE fileMove(const char *szSourcePath, const char *szDestPath) { + assumeNotNull(szSourcePath); + assumeNotNull(szDestPath); + systemUse(); systemReleaseBlitterToOs(); - UBYTE isSuccess = rename(szSource, szDest); + UBYTE isSuccess = rename(szSourcePath, szDestPath); systemGetBlitterFromOs(); systemUnuse(); return isSuccess; diff --git a/src/ace/utils/font.c b/src/ace/utils/font.c index 983d78a6..725edfda 100644 --- a/src/ace/utils/font.c +++ b/src/ace/utils/font.c @@ -7,6 +7,7 @@ #include #include #include +#include /* Globals */ @@ -20,21 +21,19 @@ UBYTE fontGlyphWidth(const tFont *pFont, char c) { } tFont *fontCreate(const char *szFontName) { - tFile *pFontFile; - tFont *pFont; logBlockBegin("fontCreate(szFontName: '%s')", szFontName); + assumeNotNull(szFontName); - pFontFile = fileOpen(szFontName, "r"); + tFile *pFontFile = fileOpen(szFontName, "r"); if (!pFontFile) { logWrite("ERR: Couldn't open file\n"); logBlockEnd("fontCreate()"); return 0; } - pFont = (tFont *) memAllocFast(sizeof(tFont)); + tFont *pFont = (tFont *) memAllocFast(sizeof(tFont)); if (!pFont) { fileClose(pFontFile); - logWrite("ERR: Couldn't alloc mem\n"); logBlockEnd("fontCreate()"); return 0; } @@ -51,38 +50,32 @@ tFont *fontCreate(const char *szFontName) { fileRead(pFontFile, pFont->pCharOffsets, sizeof(UWORD) * pFont->ubChars); pFont->pRawData = bitmapCreate(pFont->uwWidth, pFont->uwHeight, 1, 0); -#ifdef AMIGA + assumeNotNull(pFont->pRawData); + UWORD uwPlaneByteSize = ((pFont->uwWidth+15)/16) * 2 * pFont->uwHeight; fileRead(pFontFile, pFont->pRawData->Planes[0], uwPlaneByteSize); -#else - logWrite("ERR: Unimplemented\n"); - memFree(pFont, sizeof(tFont)); - fileClose(pFontFile); - logBlockEnd("fontCreate()"); - return 0; -#endif // AMIGA fileClose(pFontFile); logBlockEnd("fontCreate()"); return pFont; } +// TODO: remove, generate initialized font struct in .c/.h with font_conv instead tFont *fontCreateFromMem(const UBYTE* pData) { - tFont *pFont; - UWORD uwCurByte = 0; - logBlockBegin("fontCreateFromMem(szFontName: '%p')", pData); - pFont = (tFont *) memAllocFast(sizeof(tFont)); + tFont *pFont = (tFont *) memAllocFast(sizeof(tFont)); if (!pFont) { logBlockEnd("fontCreateFromMem()"); return 0; } - memcpy(&pFont->uwWidth,&pData[uwCurByte],sizeof(UWORD)); - uwCurByte+=sizeof(UWORD); - memcpy(&pFont->uwHeight,&pData[uwCurByte],sizeof(UWORD)); - uwCurByte+=sizeof(UWORD); - memcpy(&pFont->ubChars,&pData[uwCurByte],sizeof(UBYTE)); - uwCurByte+=sizeof(UBYTE); + + UWORD uwCurByte = 0; + memcpy(&pFont->uwWidth, &pData[uwCurByte], sizeof(UWORD)); + uwCurByte += sizeof(UWORD); + memcpy(&pFont->uwHeight, &pData[uwCurByte], sizeof(UWORD)); + uwCurByte += sizeof(UWORD); + memcpy(&pFont->ubChars, &pData[uwCurByte], sizeof(UBYTE)); + uwCurByte += sizeof(UBYTE); logWrite( "Addr: %p, data width: %upx, chars: %u, font height: %upx\n", @@ -95,15 +88,9 @@ tFont *fontCreateFromMem(const UBYTE* pData) { pFont->pRawData = bitmapCreate(pFont->uwWidth, pFont->uwHeight, 1, 0); -#ifdef AMIGA UWORD uwPlaneByteSize = ((pFont->uwWidth+15)/16) * 2 * pFont->uwHeight; memcpy(pFont->pRawData->Planes[0],&pData[uwCurByte],uwPlaneByteSize); -#else - logWrite("ERR: Unimplemented\n"); - memFree(pFont, sizeof(tFont)); - logBlockEnd("fontCreateFromMem()"); - return 0; -#endif // AMIGA + logBlockEnd("fontCreateFromMem()"); return pFont; } @@ -111,7 +98,9 @@ tFont *fontCreateFromMem(const UBYTE* pData) { void fontDestroy(tFont *pFont) { systemUse(); logBlockBegin("fontDestroy(pFont: %p)", pFont); - if (pFont) { + assumeNotNull(pFont); + + if(pFont) { bitmapDestroy(pFont->pRawData); memFree(pFont->pCharOffsets, sizeof(UWORD) * pFont->ubChars); memFree(pFont, sizeof(tFont)); @@ -158,6 +147,10 @@ tTextBitMap *fontCreateTextBitMap(UWORD uwWidth, UWORD uwHeight) { UBYTE fontTextFitsInTextBitmap( const tFont *pFont, const tTextBitMap *pTextBitmap, const char *szText ) { + assumeNotNull(pFont); + assumeNotNull(pTextBitmap); + assumeNotNull(szText); + tUwCoordYX sBounds = fontMeasureText(pFont, szText); if( sBounds.uwX <= bitmapGetByteWidth(pTextBitmap->pBitMap) * 8 && @@ -169,6 +162,9 @@ UBYTE fontTextFitsInTextBitmap( } tUwCoordYX fontMeasureText(const tFont *pFont, const char *szText) { + assumeNotNull(pFont); + assumeNotNull(szText); + UWORD uwWidth = 0, uwHeight = 0, uwMaxWidth = 0; for (const char *p = szText; *p; ++p) { if(*p == '\n') { @@ -177,14 +173,8 @@ tUwCoordYX fontMeasureText(const tFont *pFont, const char *szText) { } else { UBYTE ubGlyphWidth = fontGlyphWidth(pFont, *p); -#if defined(ACE_DEBUG) - if(ubGlyphWidth == 0) { - logWrite( - "ERR: Missing glyph for char '%c' (code %hhu, 0x%hhX), " - "pos %ld in string '%s'\n", *p, *p, *p, p - szText, szText - ); - } -#endif + assumeMsg(ubGlyphWidth != 0, "Missing glyph for char"); + uwWidth += ubGlyphWidth + 1; uwMaxWidth = MAX(uwMaxWidth, uwWidth); } @@ -198,6 +188,9 @@ tTextBitMap *fontCreateTextBitMapFromStr(const tFont *pFont, const char *szText) logBlockBegin( "fontCreateTextBitMapFromStr(pFont: %p, szText: '%s')", pFont, szText ); + assumeNotNull(pFont); + assumeNotNull(szText); + tUwCoordYX sBounds = fontMeasureText(pFont, szText); // If bitmap is too tight then blitter goes nuts with bltXdat caching when // going into next line of blit @@ -213,6 +206,10 @@ tUwCoordYX fontDrawStr1bpp( const tFont *pFont, tBitMap *pBitMap, UWORD uwStartX, UWORD uwStartY, const char *szText ) { + assumeNotNull(pFont); + assumeNotNull(pBitMap); + assumeNotNull(szText); + UWORD uwX = uwStartX; UWORD uwY = uwStartY; UWORD uwBoundX = 0; @@ -224,15 +221,7 @@ tUwCoordYX fontDrawStr1bpp( } else { UBYTE ubGlyphWidth = fontGlyphWidth(pFont, *p); -#if defined(ACE_DEBUG) - if(ubGlyphWidth == 0) { - logWrite( - "ERR: Missing glyph for char '%c' (code %hhu, 0x%hhX), " - "pos %ld in string '%s'\n", *p, *p, *p, p - szText, szText - ); - continue; - } -#endif + assumeMsg(ubGlyphWidth != 0, "Missing glyph for char"); blitCopy( pFont->pRawData, pFont->pCharOffsets[(UBYTE)*p], 0, pBitMap, uwX, uwY, ubGlyphWidth, pFont->uwHeight, MINTERM_COOKIE @@ -247,6 +236,10 @@ tUwCoordYX fontDrawStr1bpp( void fontFillTextBitMap( const tFont *pFont, tTextBitMap *pTextBitMap, const char *szText ) { + assumeNotNull(pFont); + assumeNotNull(pTextBitMap); + assumeNotNull(szText); + if(pTextBitMap->uwActualWidth) { // Clear old contents // TODO: we could remove this clear if letter spacing would be @@ -257,17 +250,10 @@ void fontFillTextBitMap( ); } -#if defined(ACE_DEBUG) - if(!fontTextFitsInTextBitmap(pFont, pTextBitMap, szText)) { - tUwCoordYX sNeededDimensions = fontMeasureText(pFont, szText); - logWrite( - "ERR: Text '%s' doesn't fit in text bitmap, text needs: %hu,%hu, bitmap size: %hu,%hu\n", - szText, sNeededDimensions.uwX, sNeededDimensions.uwY, - bitmapGetByteWidth(pTextBitMap->pBitMap) * 8, pTextBitMap->pBitMap->Rows - ); - return; - } -#endif + assumeMsg( + fontTextFitsInTextBitmap(pFont, pTextBitMap, szText), + "Text doesn't fit in text bitmap" + ); tUwCoordYX sBounds = fontDrawStr1bpp(pFont, pTextBitMap->pBitMap, 0, 0, szText); pTextBitMap->uwActualWidth = sBounds.uwX; @@ -275,6 +261,8 @@ void fontFillTextBitMap( } void fontDestroyTextBitMap(tTextBitMap *pTextBitMap) { + assumeNotNull(pTextBitMap); + systemUse(); bitmapDestroy(pTextBitMap->pBitMap); memFree(pTextBitMap, sizeof(tTextBitMap)); @@ -285,13 +273,9 @@ void fontDrawTextBitMap( tBitMap *pDest, tTextBitMap *pTextBitMap, UWORD uwX, UWORD uwY, UBYTE ubColor, UBYTE ubFlags ) { -#if defined(ACE_DEBUG) - if(!pTextBitMap->uwActualWidth) { - // you can usually figure that out and skip this call before even doing fontDrawStr() or fontFillTextBitMap() - logWrite("ERR: pTextBitMap %p has text of zero width - do the check beforehand!\n", pTextBitMap); - return; - } -#endif + assumeNotNull(pDest); + assumeNotNull(pTextBitMap); + assumeMsg(pTextBitMap->uwActualWidth > 0, "pTextBitMap has text of zero width"); // Alignment flags if (ubFlags & FONT_RIGHT) { @@ -312,13 +296,9 @@ void fontDrawTextBitMap( } // Helper destination bitmap -#if defined(AMIGA) s_sTmpDest.BytesPerRow = pDest->BytesPerRow; s_sTmpDest.Rows = pDest->Rows; s_sTmpDest.Depth = 1; -#else -#error "Something is missing here!" -#endif // Text-drawing loop UBYTE isCookie = ubFlags & FONT_COOKIE; @@ -358,9 +338,6 @@ void fontDrawStr( const tFont *pFont, tBitMap *pDest, UWORD uwX, UWORD uwY, const char *szText, UBYTE ubColor, UBYTE ubFlags, tTextBitMap *pTextBitMap ) { - if(!pTextBitMap) { - logWrite("ERR: pTextBitMap must be non-null!\n"); - } fontFillTextBitMap(pFont, pTextBitMap, szText); fontDrawTextBitMap(pDest, pTextBitMap, uwX, uwY, ubColor, ubFlags); } diff --git a/src/ace/utils/palette.c b/src/ace/utils/palette.c index 9ca500c7..fd60e7b4 100644 --- a/src/ace/utils/palette.c +++ b/src/ace/utils/palette.c @@ -18,7 +18,6 @@ void paletteLoad(const char *szFileName, UWORD *pPalette, UBYTE ubMaxLength) { pFile = fileOpen(szFileName, "r"); if(!pFile) { - logWrite("ERR: File doesn't exist!\n"); logBlockEnd("paletteLoad()"); return; } diff --git a/src/ace/utils/string.c b/src/ace/utils/string.c index 0e8be1ac..b9f6820d 100644 --- a/src/ace/utils/string.c +++ b/src/ace/utils/string.c @@ -4,13 +4,13 @@ #include #include +#include -char *stringDecimalFromULong(ULONG ulVal, char *pDst) { +char *stringDecimalFromULong(ULONG ulVal, char *szDest) { // Modified from https://github.com/german-one/itostr/blob/master/itostr.c - // Relies on prior verification that buffer != NULL and bufsize != 0 - // TODO: add ACE checks for that + assumeNotNull(szDest); - char* pEnd = pDst; // Pointer to the position to write + char* pEnd = szDest; // Pointer to the position to write do { // Get the value of the rightmost digit // (avoid modulo, it would perform another slow division) @@ -24,12 +24,12 @@ char *stringDecimalFromULong(ULONG ulVal, char *pDst) { // Assign the terminating null and decrease the pointer in order to point // To the last digit written *pEnd-- = '\0'; - while (pDst < pEnd) { + while (szDest < pEnd) { // Reverse the digits (only the digits) in the array because they are // LTR written but we need them in RTL order char transfer = *pEnd; - *pEnd-- = *pDst; - *pDst++ = transfer; + *pEnd-- = *szDest; + *szDest++ = transfer; } return pWriteEnd; } @@ -41,21 +41,29 @@ char charToUpper(char c) { return c; } -void strToUpper(const char *szSrc, char *szDst) { +void strToUpper(const char *szSrc, char *szDest) { + assumeNotNull(szSrc); + assumeNotNull(szDest); + while(*szSrc) { char c = *(szSrc++); c = charToUpper(c); - *(szDst++) = c; + *(szDest++) = c; } - *szDst = '\0'; + *szDest = '\0'; } UBYTE stringIsEmpty(const char *szStr) { + assumeNotNull(szStr); + UBYTE isEmpty = (szStr[0] == '\0'); return isEmpty; } char *stringCopy(const char *szSrc, char *szDest) { + assumeNotNull(szSrc); + assumeNotNull(szDest); + while(*szSrc != '\0') { *(szDest++) = *(szSrc++); }; @@ -64,9 +72,9 @@ char *stringCopy(const char *szSrc, char *szDest) { } char *stringCopyLimited(const char *szSrc, char *szDest, UWORD uwMaxLength) { - if(uwMaxLength == 0) { - logWrite("ERR: stringCopyLimited(szSrc: '%s') uwMaxLength is zero!\n", szSrc); - } + assumeNotNull(szSrc); + assumeNotNull(szDest); + assumeMsg(uwMaxLength != 0, "uwMaxLength is zero"); while(*szSrc != '\0' && --uwMaxLength > 0) { *(szDest++) = *(szSrc++); diff --git a/src/ace/utils/tag.c b/src/ace/utils/tag.c index 2dcdad5b..30754f56 100644 --- a/src/ace/utils/tag.c +++ b/src/ace/utils/tag.c @@ -4,13 +4,10 @@ #include #include +#include ULONG tagGet(void *pTagListPtr, va_list vaSrcList, tTag ulTagToFind, ULONG ulOnNotFound) { - if(pTagListPtr) { - // TODO - logWrite("ERR: Unimplemented in tagFindString()"); - return ulOnNotFound; - } + assumeMsg(pTagListPtr == 0, "Unimplemented parsing pTagListPtr"); va_list vaWorkList; va_copy(vaWorkList, vaSrcList);