cleaned up removeCompleteLines(...) and inlined the get functions
This commit is contained in:
parent
7df70ca765
commit
4ce8ac5421
|
@ -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);
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue