cleaned up removeCompleteLines(...) and inlined the get functions

This commit is contained in:
Christian Kroll 2010-12-12 07:50:51 +00:00
parent 7df70ca765
commit 4ce8ac5421
2 changed files with 83 additions and 135 deletions

View File

@ -55,9 +55,12 @@ tetris_bucket_t *tetris_bucket_construct(int8_t nWidth,
if (pBucket->dump != NULL) if (pBucket->dump != NULL)
{ {
// setting requested attributes // setting requested attributes
pBucket->nFirstMatterRow = nHeight - 1; pBucket->nFirstTaintedRow = nHeight;
pBucket->nWidth = nWidth; pBucket->nWidth = nWidth;
pBucket->nHeight = nHeight; pBucket->nHeight = nHeight;
// bit mask of a full row
pBucket->nFullRow = 0xFFFF >> (16 - pBucket->nWidth);
tetris_bucket_reset(pBucket); tetris_bucket_reset(pBucket);
return pBucket; return pBucket;
@ -290,8 +293,8 @@ void tetris_bucket_advancePiece(tetris_bucket_t *pBucket)
break; break;
} }
} }
pBucket->nFirstMatterRow = (pBucket->nFirstMatterRow > nPieceRow) ? pBucket->nFirstTaintedRow = (pBucket->nFirstTaintedRow > nPieceRow) ?
nPieceRow : pBucket->nFirstMatterRow; nPieceRow : pBucket->nFirstTaintedRow;
// the piece has finally been docked // the piece has finally been docked
pBucket->status = TETRIS_BUS_DOCKED; pBucket->status = TETRIS_BUS_DOCKED;
@ -374,144 +377,53 @@ void tetris_bucket_removeCompleteLines(tetris_bucket_t *pBucket)
// rows can only be removed if we are in state TETRIS_BUS_DOCKED // rows can only be removed if we are in state TETRIS_BUS_DOCKED
assert(pBucket->status == TETRIS_BUS_DOCKED); assert(pBucket->status == TETRIS_BUS_DOCKED);
// bit mask of a full row
uint16_t nFullRow = 0xFFFF >> (16 - pBucket->nWidth);
// bit mask (only 4 bits) that tells us if the n-th row after the // bit mask (only 4 bits) that tells us if the n-th row after the
// current nRow is complete (n-th bit set to 1, LSB represents nRow itself) // current nRow is complete (n-th bit set to 1, LSB represents nRow itself)
uint8_t nRowMask = 0; pBucket->nRowMask = 0;
// determine sane start and stop values for the dump' index // only consider rows which are affected by the piece (from low to high)
int8_t nStartRow = ((pBucket->nRow + 3) >= pBucket->nHeight) ? // for incomplete rows, both i and nShiftIndex will be decremented
pBucket->nHeight - 1 : pBucket->nRow + 3;
int8_t nStopRow = (pBucket->nRow < 0) ? 0 : pBucket->nRow;
// dump index variables
// for incomplete rows, both variables will be decremented
// for complete rows, only i gets decremented // for complete rows, only i gets decremented
int8_t nLowestRow = nStartRow; int8_t nLowestRow = (pBucket->nRow + 3) < pBucket->nHeight ?
pBucket->nRow + 3 : pBucket->nHeight - 1;
// save old value for the first dump index with matter int8_t nShiftIndex = nLowestRow;
int8_t nFormerFirstMatterRow = pBucket->nFirstMatterRow; for (int8_t i = nLowestRow; i >= pBucket->nFirstTaintedRow; --i)
// this loop only considers rows which are affected by the piece
for (int8_t i = nStartRow; i >= nStopRow; --i)
{ {
// is current row a full row? // is current row a full row?
if ((nFullRow & pBucket->dump[i]) == nFullRow) if ((pBucket->nFullRow & pBucket->dump[i]) == pBucket->nFullRow)
{ {
// adjust value for the highest row with matter
pBucket->nFirstMatterRow++;
// set corresponding bit for the row mask // set corresponding bit for the row mask
// nRowMask |= 0x08 >> (nStartRow - i); pBucket->nRowMask |= 0x01 << (i - pBucket->nRow);
nRowMask |= 0x01 << (i - pBucket->nRow);
} }
else else
{ {
// if nLowestRow and i differ, the dump has to be shifted // if nShiftIndex and i differ, the dump has to be shifted
if (i < nLowestRow) if (i < nShiftIndex)
{ {
pBucket->dump[nLowestRow] = pBucket->dump[i]; pBucket->dump[nShiftIndex] = pBucket->dump[i];
} }
--nLowestRow; // if there were no completed lines within the range covered by the
// piece, we don't need to look for those any further
else if ((nLowestRow - i) >= 3)
{
break;
}
--nShiftIndex;
} }
} }
// any completed rows removed?
// if rows have been removed, this loop shifts the rest of the dump if (pBucket->nRowMask != 0)
uint8_t nComplete = nLowestRow - nStopRow + 1;
if (nComplete > 0)
{ {
for (int8_t i = nStopRow - 1; nLowestRow >= nFormerFirstMatterRow; --i) // clear space from which the rows have been shifted away
for (int8_t i = nShiftIndex; i >= pBucket->nFirstTaintedRow; --i)
{ {
// is the row we are copying from below the upper border? pBucket->dump[i] = 0;
if (i >= nFormerFirstMatterRow)
{
// just copy from that row
pBucket->dump[nLowestRow] = pBucket->dump[i];
}
else
{
// rows above the upper border are always empty
pBucket->dump[nLowestRow] = 0;
}
--nLowestRow;
} }
pBucket->nFirstTaintedRow = nShiftIndex + 1;
} }
// ready to get the next piece // ready to get the next piece
pBucket->status = TETRIS_BUS_READY; pBucket->status = TETRIS_BUS_READY;
pBucket->nRowMask = nRowMask;
}
/*****************
* get functions *
*****************/
int8_t tetris_bucket_getWidth(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nWidth;
}
int8_t tetris_bucket_getHeight(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nHeight;
}
tetris_piece_t *tetris_bucket_getPiece(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->pPiece;
}
int8_t tetris_bucket_getColumn(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nColumn;
}
int8_t tetris_bucket_getRow(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nRow;
}
int8_t tetris_bucket_getFirstMatterRow(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nFirstMatterRow;
}
uint8_t tetris_bucket_getRowMask(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nRowMask;
}
tetris_bucket_status_t tetris_bucket_getStatus(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->status;
}
uint16_t tetris_bucket_getDumpRow(tetris_bucket_t *pBucket,
int8_t nRow)
{
assert(pBucket != NULL);
assert((0 <= nRow) && (nRow < pBucket->nHeight));
return pBucket->dump[nRow];
} }
@ -625,7 +537,6 @@ uint16_t* tetris_bucket_predictBottomRow(tetris_bucket_iterator_t *pIt,
pIt->pBucket = pBucket; pIt->pBucket = pBucket;
pIt->pPiece = pPiece; pIt->pPiece = pPiece;
pIt->nColumn = nColumn; pIt->nColumn = nColumn;
pIt->nFullRow = 0xFFFF >> (16 - pBucket->nWidth);
pIt->nCurrentRow = pBucket->nHeight - 1; pIt->nCurrentRow = pBucket->nHeight - 1;
pIt->nRowBuffer = 0; pIt->nRowBuffer = 0;
@ -635,8 +546,8 @@ uint16_t* tetris_bucket_predictBottomRow(tetris_bucket_iterator_t *pIt,
(pIt->nPieceHighestRow + 3) : pBucket->nHeight - 1; (pIt->nPieceHighestRow + 3) : pBucket->nHeight - 1;
// don't return any trailing rows which are empty, so we look for a stop row // don't return any trailing rows which are empty, so we look for a stop row
pIt->nStopRow = pBucket->nFirstMatterRow < nRow ? pIt->nStopRow = pBucket->nFirstTaintedRow < nRow ?
pBucket->nFirstMatterRow : nRow; pBucket->nFirstTaintedRow : nRow;
pIt->nStopRow = pIt->nStopRow < 0 ? 0 : pIt->nStopRow; pIt->nStopRow = pIt->nStopRow < 0 ? 0 : pIt->nStopRow;
return tetris_bucket_predictNextRow(pIt); return tetris_bucket_predictNextRow(pIt);
@ -672,7 +583,7 @@ uint16_t* tetris_bucket_predictNextRow(tetris_bucket_iterator_t *pIt)
pIt->nRowBuffer = pIt->pBucket->dump[pIt->nCurrentRow--] | nPieceMap; pIt->nRowBuffer = pIt->pBucket->dump[pIt->nCurrentRow--] | nPieceMap;
// don't return full (and therefore removed) rows // don't return full (and therefore removed) rows
if (pIt->nRowBuffer == pIt->nFullRow) if (pIt->nRowBuffer == pIt->pBucket->nFullRow)
{ {
// recursively determine next (?) row instead // recursively determine next (?) row instead
return tetris_bucket_predictNextRow(pIt); return tetris_bucket_predictNextRow(pIt);

View File

@ -48,7 +48,8 @@ typedef struct tetris_bucket_t
int8_t nRow; /** vert. piece pos. (0 is top) */ int8_t nRow; /** vert. piece pos. (0 is top) */
uint8_t nRowMask; /** removed lines relative to nRow */ uint8_t nRowMask; /** removed lines relative to nRow */
tetris_bucket_status_t status; /** status of the bucket */ tetris_bucket_status_t status; /** status of the bucket */
int8_t nFirstMatterRow; /** top most row which has matter */ int8_t nFirstTaintedRow; /** top most row which has matter */
uint16_t nFullRow; /** value of a full row */
uint16_t *dump; /** bucket itself */ uint16_t *dump; /** bucket itself */
} }
tetris_bucket_t; tetris_bucket_t;
@ -60,7 +61,6 @@ typedef struct tetris_bucket_iterator_t
tetris_bucket_t *pBucket; /** bucket to be examined */ tetris_bucket_t *pBucket; /** bucket to be examined */
tetris_piece_t *pPiece; /** piece which should be tested */ tetris_piece_t *pPiece; /** piece which should be tested */
int8_t nColumn; /** column where piece should be dropped */ int8_t nColumn; /** column where piece should be dropped */
uint16_t nFullRow; /** value of a full row */
int8_t nCurrentRow; /** the actual row in the bucket */ int8_t nCurrentRow; /** the actual row in the bucket */
int8_t nPieceHighestRow; /** the highest row index of the piece */ int8_t nPieceHighestRow; /** the highest row index of the piece */
int8_t nPieceLowestRow; /** the lowest row index of the piece */ int8_t nPieceLowestRow; /** the lowest row index of the piece */
@ -177,7 +177,11 @@ void tetris_bucket_removeCompleteLines(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return width of the bucket * @return width of the bucket
*/ */
int8_t tetris_bucket_getWidth(tetris_bucket_t *pBucket); inline static int8_t tetris_bucket_getWidth(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nWidth;
}
/** /**
@ -185,7 +189,11 @@ int8_t tetris_bucket_getWidth(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return height of the bucket * @return height of the bucket
*/ */
int8_t tetris_bucket_getHeight(tetris_bucket_t *pBucket); inline static int8_t tetris_bucket_getHeight(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nHeight;
}
/** /**
@ -193,7 +201,11 @@ int8_t tetris_bucket_getHeight(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return pointer to the currently falling piece * @return pointer to the currently falling piece
*/ */
tetris_piece_t *tetris_bucket_getPiece(tetris_bucket_t *pBucket); inline static tetris_piece_t *tetris_bucket_getPiece(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->pPiece;
}
/** /**
@ -201,7 +213,11 @@ tetris_piece_t *tetris_bucket_getPiece(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return column of the currently falling piece * @return column of the currently falling piece
*/ */
int8_t tetris_bucket_getColumn(tetris_bucket_t *pBucket); inline static int8_t tetris_bucket_getColumn(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nColumn;
}
/** /**
@ -209,7 +225,11 @@ int8_t tetris_bucket_getColumn(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return row of the currently falling piece * @return row of the currently falling piece
*/ */
int8_t tetris_bucket_getRow(tetris_bucket_t *pBucket); inline static int8_t tetris_bucket_getRow(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nRow;
}
/** /**
@ -217,7 +237,11 @@ int8_t tetris_bucket_getRow(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return highest row with matter * @return highest row with matter
*/ */
int8_t tetris_bucket_getFirstMatterRow(tetris_bucket_t *pBucket); inline static int8_t tetris_bucket_getFirstTaintedRow(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nFirstTaintedRow;
}
/** /**
@ -225,7 +249,11 @@ int8_t tetris_bucket_getFirstMatterRow(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return bit mask of removed lines (relative to current position) * @return bit mask of removed lines (relative to current position)
*/ */
uint8_t tetris_bucket_getRowMask(tetris_bucket_t *pBucket); inline static uint8_t tetris_bucket_getRowMask(tetris_bucket_t *pBucket)
{
assert(pBucket != NULL);
return pBucket->nRowMask;
}
/** /**
@ -233,7 +261,11 @@ uint8_t tetris_bucket_getRowMask(tetris_bucket_t *pBucket);
* @param pBucket the bucket we want information from * @param pBucket the bucket we want information from
* @return status of the bucket (see tetris_bucket_status_t) * @return status of the bucket (see tetris_bucket_status_t)
*/ */
tetris_bucket_status_t tetris_bucket_getStatus(tetris_bucket_t *pBucket); inline static tetris_bucket_status_t tetris_bucket_getStatus(tetris_bucket_t *p)
{
assert(p != NULL);
return p->status;
}
/** /**
@ -242,8 +274,13 @@ tetris_bucket_status_t tetris_bucket_getStatus(tetris_bucket_t *pBucket);
* @param nRow the number of the row (0 <= nRow <= 124) * @param nRow the number of the row (0 <= nRow <= 124)
* @return bitmap of the requested row (LSB is leftmost column) * @return bitmap of the requested row (LSB is leftmost column)
*/ */
uint16_t tetris_bucket_getDumpRow(tetris_bucket_t *pBucket, inline static uint16_t tetris_bucket_getDumpRow(tetris_bucket_t *pBucket,
int8_t nRow); int8_t nRow)
{
assert(pBucket != NULL);
assert((0 <= nRow) && (nRow < pBucket->nHeight));
return pBucket->dump[nRow];
}
#ifdef GAME_BASTET #ifdef GAME_BASTET