more streamlining
This commit is contained in:
parent
14d8dc969a
commit
e206a60e3f
|
@ -128,26 +128,6 @@ void tetris_bucket_reset(tetris_bucket_t *pBucket)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int8_t tetris_bucket_getPieceStartPos(tetris_piece_t *pPiece)
|
|
||||||
{
|
|
||||||
// set vertical start position (first piece row with matter at pos. 1)
|
|
||||||
uint16_t nPieceMap = tetris_piece_getBitmap(pPiece);
|
|
||||||
uint16_t nElementMask = 0xF000;
|
|
||||||
int8_t nRow = -3;
|
|
||||||
while ((nPieceMap & nElementMask) == 0)
|
|
||||||
{
|
|
||||||
++nRow;
|
|
||||||
nElementMask >>= 4;
|
|
||||||
}
|
|
||||||
if (nRow < 0)
|
|
||||||
{
|
|
||||||
++nRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
return nRow;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void tetris_bucket_insertPiece(tetris_bucket_t *pBucket,
|
void tetris_bucket_insertPiece(tetris_bucket_t *pBucket,
|
||||||
tetris_piece_t *pPiece,
|
tetris_piece_t *pPiece,
|
||||||
tetris_piece_t **ppOldPiece)
|
tetris_piece_t **ppOldPiece)
|
||||||
|
@ -168,7 +148,8 @@ void tetris_bucket_insertPiece(tetris_bucket_t *pBucket,
|
||||||
pBucket->nColumn = (pBucket->nWidth - 2) / 2;
|
pBucket->nColumn = (pBucket->nWidth - 2) / 2;
|
||||||
|
|
||||||
// set vertical start position (first piece row with matter at pos. 1)
|
// set vertical start position (first piece row with matter at pos. 1)
|
||||||
pBucket->nRow = tetris_bucket_getPieceStartPos(pBucket->pPiece);
|
pBucket->nRow =
|
||||||
|
1 - tetris_piece_getBottomOffset(tetris_piece_getBitmap(pPiece));
|
||||||
|
|
||||||
// did we already collide with something?
|
// did we already collide with something?
|
||||||
if (tetris_bucket_collision(pBucket, pBucket->nColumn, pBucket->nRow) == 1)
|
if (tetris_bucket_collision(pBucket, pBucket->nColumn, pBucket->nRow) == 1)
|
||||||
|
@ -185,7 +166,7 @@ void tetris_bucket_insertPiece(tetris_bucket_t *pBucket,
|
||||||
|
|
||||||
|
|
||||||
uint8_t tetris_bucket_collision(tetris_bucket_t *pBucket,
|
uint8_t tetris_bucket_collision(tetris_bucket_t *pBucket,
|
||||||
int8_t nColumn,
|
int8_t nCol,
|
||||||
int8_t nRow)
|
int8_t nRow)
|
||||||
{
|
{
|
||||||
// A piece is represented by 16 bits (4 bits per row where the LSB marks the
|
// A piece is represented by 16 bits (4 bits per row where the LSB marks the
|
||||||
|
@ -195,21 +176,21 @@ uint8_t tetris_bucket_collision(tetris_bucket_t *pBucket,
|
||||||
|
|
||||||
// only allow coordinates which are within sane ranges
|
// only allow coordinates which are within sane ranges
|
||||||
assert(pBucket != NULL);
|
assert(pBucket != NULL);
|
||||||
assert((nColumn > -4) && (nColumn < pBucket->nWidth));
|
assert((nCol > -4) && (nCol < pBucket->nWidth));
|
||||||
assert((nRow > -4) && (nRow < pBucket->nHeight));
|
assert((nRow > -4) && (nRow < pBucket->nHeight));
|
||||||
|
|
||||||
// left and right borders
|
// left and right borders
|
||||||
uint16_t const nPieceMap = tetris_piece_getBitmap(pBucket->pPiece);
|
uint16_t const nPieceMap = tetris_piece_getBitmap(pBucket->pPiece);
|
||||||
uint16_t nBucketPart = 0;
|
uint16_t nBucketPart = 0;
|
||||||
if (nColumn < 0)
|
if (nCol < 0)
|
||||||
{
|
{
|
||||||
static uint16_t const nLeftPart[] PROGMEM = {0x7777, 0x3333, 0x1111};
|
static uint16_t const nLeftPart[] PROGMEM = {0x7777, 0x3333, 0x1111};
|
||||||
nBucketPart = pgm_read_word(&nLeftPart[nColumn + 3]);
|
nBucketPart = pgm_read_word(&nLeftPart[nCol + 3]);
|
||||||
}
|
}
|
||||||
else if (nColumn >= pBucket->nWidth - 3)
|
else if (nCol >= pBucket->nWidth - 3)
|
||||||
{
|
{
|
||||||
static uint16_t const nRightPart[] PROGMEM = {0xEEEE, 0xCCCC, 0x8888};
|
static uint16_t const nRightPart[] PROGMEM = {0xEEEE, 0xCCCC, 0x8888};
|
||||||
nBucketPart = pgm_read_word(&nRightPart[pBucket->nWidth - nColumn - 1]);
|
nBucketPart = pgm_read_word(&nRightPart[pBucket->nWidth - nCol - 1]);
|
||||||
}
|
}
|
||||||
// lower border
|
// lower border
|
||||||
if (nRow > pBucket->nHeight - 4)
|
if (nRow > pBucket->nHeight - 4)
|
||||||
|
@ -225,25 +206,12 @@ uint8_t tetris_bucket_collision(tetris_bucket_t *pBucket,
|
||||||
}
|
}
|
||||||
|
|
||||||
// range for inspecting the piece row by row (starting at the bottom)
|
// range for inspecting the piece row by row (starting at the bottom)
|
||||||
int8_t nStart = nRow;
|
int8_t const nStart = nRow + tetris_piece_getBottomOffset(nPieceMap);
|
||||||
// skip empty rows at the bottom at the piece
|
|
||||||
if (nPieceMap > 0x0FFF)
|
|
||||||
{
|
|
||||||
nStart += 3; // piece spans over 4 rows
|
|
||||||
}
|
|
||||||
else if (nPieceMap > 0x00FF)
|
|
||||||
{
|
|
||||||
nStart += 2; // last row of the piece is empty
|
|
||||||
}
|
|
||||||
else if (nPieceMap > 0x000F)
|
|
||||||
{
|
|
||||||
nStart += 1; // last two rows of the piece are empty
|
|
||||||
}
|
|
||||||
int8_t const nStop = nRow >= 0 ? nRow : 0;
|
int8_t const nStop = nRow >= 0 ? nRow : 0;
|
||||||
// mask those blocks which are not covered by the piece
|
// mask those blocks which are not covered by the piece
|
||||||
uint16_t nDumpMask = nColumn >= 0 ? 0x000F << nColumn : 0x000F >> -nColumn;
|
uint16_t const nDumpMask = nCol >= 0 ? 0x000F << nCol : 0x000F >> -nCol;
|
||||||
// value for shifting blocks to the corresponding part of the piece
|
// value for shifting blocks to the corresponding part of the piece
|
||||||
int8_t nShift = 12 - nColumn - 4 * (nRow + 3 - nStart);
|
int8_t nShift = 12 - nCol - 4 * (nRow + 3 - nStart);
|
||||||
// compare piece with dump
|
// compare piece with dump
|
||||||
for (int8_t y = nStart; y >= nStop; --y)
|
for (int8_t y = nStart; y >= nStop; --y)
|
||||||
{
|
{
|
||||||
|
@ -274,19 +242,7 @@ void tetris_bucket_advancePiece(tetris_bucket_t *pBucket)
|
||||||
{
|
{
|
||||||
uint16_t nPieceMap = tetris_piece_getBitmap(pBucket->pPiece);
|
uint16_t nPieceMap = tetris_piece_getBitmap(pBucket->pPiece);
|
||||||
// determine first row of the piece (skipping empty lines at the top)
|
// determine first row of the piece (skipping empty lines at the top)
|
||||||
int8_t nPieceTop = pBucket->nRow;
|
int8_t nPieceTop = pBucket->nRow + tetris_piece_getTopRow(nPieceMap);
|
||||||
if (!(nPieceMap & 0x0FFF))
|
|
||||||
{
|
|
||||||
nPieceTop += 3;
|
|
||||||
}
|
|
||||||
else if (!(nPieceMap & 0x00FF))
|
|
||||||
{
|
|
||||||
nPieceTop += 2;
|
|
||||||
}
|
|
||||||
else if (!(nPieceMap & 0x000F))
|
|
||||||
{
|
|
||||||
nPieceTop += 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Is the bucket filled up?
|
// Is the bucket filled up?
|
||||||
if (nPieceTop < 0)
|
if (nPieceTop < 0)
|
||||||
|
@ -450,18 +406,7 @@ int8_t tetris_bucket_predictDeepestRow(tetris_bucket_t *pBucket,
|
||||||
|
|
||||||
// skip empty rows at the bottom of the piece which may overlap the dump
|
// skip empty rows at the bottom of the piece which may overlap the dump
|
||||||
uint16_t nMap = tetris_piece_getBitmap(pPiece);
|
uint16_t nMap = tetris_piece_getBitmap(pPiece);
|
||||||
if (nMap > 0x0FFF)
|
nStartingRow -= tetris_piece_getBottomOffset(nMap);
|
||||||
{
|
|
||||||
nStartingRow -= 3; // piece spans over 4 rows
|
|
||||||
}
|
|
||||||
else if (nMap > 0x00FF)
|
|
||||||
{
|
|
||||||
nStartingRow -= 2; // last row of the piece is empty
|
|
||||||
}
|
|
||||||
else if (nMap > 0x000F)
|
|
||||||
{
|
|
||||||
nStartingRow -= 1; // last two rows of the piece are empty
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if the piece collides with one of the side borders
|
// check if the piece collides with one of the side borders
|
||||||
if (nStartingRow >= -3)
|
if (nStartingRow >= -3)
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
#define TETRIS_PIECE_H_
|
#define TETRIS_PIECE_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \defgroup TetrisPieceTypes Piece: Data types
|
* \defgroup TetrisPieceTypes Piece: Data types
|
||||||
|
@ -116,7 +117,7 @@ inline static void tetris_piece_setShape(tetris_piece_t *pPc,
|
||||||
tetris_piece_shape_t shape)
|
tetris_piece_shape_t shape)
|
||||||
{
|
{
|
||||||
assert(pPc != NULL);
|
assert(pPc != NULL);
|
||||||
assert((shape >= 0) && (shape <= TETRIS_PC_Z));
|
assert(shape <= TETRIS_PC_Z);
|
||||||
|
|
||||||
pPc->shape = shape;
|
pPc->shape = shape;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +132,7 @@ inline static void tetris_piece_setAngle(tetris_piece_t *pPc,
|
||||||
tetris_piece_angle_t angle)
|
tetris_piece_angle_t angle)
|
||||||
{
|
{
|
||||||
assert(pPc != NULL);
|
assert(pPc != NULL);
|
||||||
assert((angle >= TETRIS_PC_ANGLE_0) && (angle <= TETRIS_PC_ANGLE_270));
|
assert(angle <= TETRIS_PC_ANGLE_270);
|
||||||
|
|
||||||
pPc->angle = angle;
|
pPc->angle = angle;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +145,52 @@ inline static void tetris_piece_setAngle(tetris_piece_t *pPc,
|
||||||
*/
|
*/
|
||||||
int8_t tetris_piece_getAngleCount(tetris_piece_t *pPc);
|
int8_t tetris_piece_getAngleCount(tetris_piece_t *pPc);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the index of the first filled row of a piece
|
||||||
|
* @param nBitmap the bitmap of the piece of interest
|
||||||
|
* @return index of the first filled row
|
||||||
|
*/
|
||||||
|
inline static int8_t tetris_piece_getTopRow(uint16_t const nBitmap)
|
||||||
|
{
|
||||||
|
if (!(nBitmap & 0x0FFF))
|
||||||
|
{
|
||||||
|
return 3; // first three rows can be skipped
|
||||||
|
}
|
||||||
|
else if (!(nBitmap & 0x00FF))
|
||||||
|
{
|
||||||
|
return 2; // first two rows can be skipped
|
||||||
|
}
|
||||||
|
else if (!(nBitmap & 0x000F))
|
||||||
|
{
|
||||||
|
return 1; // first row can be skipped
|
||||||
|
}
|
||||||
|
return 0; // no row can be skipped
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* returns the offset to the last filled row of a piece
|
||||||
|
* @param nBitmap the bitmap of the piece of interest
|
||||||
|
* @return offset to the last filled row
|
||||||
|
*/
|
||||||
|
inline static int8_t tetris_piece_getBottomOffset(uint16_t const nBitmap)
|
||||||
|
{
|
||||||
|
if (nBitmap > 0x0FFF)
|
||||||
|
{
|
||||||
|
return 3; // piece spans over 4 rows
|
||||||
|
}
|
||||||
|
else if (nBitmap > 0x00FF)
|
||||||
|
{
|
||||||
|
return 2; // last row of the piece is empty
|
||||||
|
}
|
||||||
|
else if (nBitmap > 0x000F)
|
||||||
|
{
|
||||||
|
return 1; // last two rows of the piece are empty
|
||||||
|
}
|
||||||
|
return 0; // last three rows of the piece are empty
|
||||||
|
}
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
|
|
||||||
#endif /*TETRIS_PIECE_H_*/
|
#endif /*TETRIS_PIECE_H_*/
|
||||||
|
|
Loading…
Reference in New Issue