Browse Source

more streamlining

feature/2015
Christian Kroll 14 years ago
parent
commit
e206a60e3f
  1. 81
      games/tetris/bucket.c
  2. 51
      games/tetris/piece.h

81
games/tetris/bucket.c

@ -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)

51
games/tetris/piece.h

@ -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…
Cancel
Save