From 63bf4d3e187bb11126ba59430d6194e177b8077a Mon Sep 17 00:00:00 2001 From: Christian Kroll Date: Sun, 22 Aug 2010 03:08:57 +0000 Subject: [PATCH] renamed some modules --- games/config.in | 25 +- games/tetris/orientation.h | 13 - games/tetris/playfield.c | 718 ------------------------------------- games/tetris/playfield.h | 293 --------------- 4 files changed, 9 insertions(+), 1040 deletions(-) delete mode 100644 games/tetris/orientation.h delete mode 100644 games/tetris/playfield.c delete mode 100644 games/tetris/playfield.h diff --git a/games/config.in b/games/config.in index ba7ba94..72d2a84 100644 --- a/games/config.in +++ b/games/config.in @@ -1,19 +1,12 @@ mainmenu_option next_comment comment "Games" - -mainmenu_option next_comment -dep_bool_menu "Tetris" GAME_TETRIS_CORE y $JOYSTICK_SUPPORT -if [ "$GAME_TETRIS_CORE" = "y" ]; then - GAME_TETRIS=y - dep_bool "Standard Tetris" GAME_TETRIS $GAME_TETRIS_CORE - dep_bool "Bastard Tetris" GAME_BASTET $GAME_TETRIS_CORE - dep_bool "First Person Tetris" GAME_TETRIS_FP $GAME_TETRIS_CORE -fi -endmenu - -dep_bool "space invaders" GAME_SPACE_INVADERS $JOYSTICK_SUPPORT $RANDOM_SUPPORT -dep_bool "snake" GAME_SNAKE $JOYSTICK_SUPPORT $RANDOM_SUPPORT -dep_bool "breakout" GAME_BREAKOUT $JOYSTICK_SUPPORT $RANDOM_SUPPORT - - + dep_bool_menu "Tetris" GAME_TETRIS_CORE y $JOYSTICK_SUPPORT $RANDOM_SUPPORT + dep_bool "Standard Tetris" GAME_TETRIS $GAME_TETRIS_CORE + dep_bool "Bastard Tetris" GAME_BASTET $GAME_TETRIS_CORE + dep_bool "First Person Tetris" GAME_TETRIS_FP $GAME_TETRIS_CORE + endmenu + + dep_bool "Space Invaders" GAME_SPACE_INVADERS $JOYSTICK_SUPPORT $RANDOM_SUPPORT + dep_bool "Snake" GAME_SNAKE $JOYSTICK_SUPPORT $RANDOM_SUPPORT + dep_bool "Breakout" GAME_BREAKOUT $JOYSTICK_SUPPORT $RANDOM_SUPPORT endmenu diff --git a/games/tetris/orientation.h b/games/tetris/orientation.h deleted file mode 100644 index 044f6cc..0000000 --- a/games/tetris/orientation.h +++ /dev/null @@ -1,13 +0,0 @@ -#ifndef ORIENTATION_H_ -#define ORIENTATION_H_ - -typedef enum tetris_orientation_t -{ - TETRIS_ORIENTATION_0, - TETRIS_ORIENTATION_90, - TETRIS_ORIENTATION_180, - TETRIS_ORIENTATION_270 -} -tetris_orientation_t; - -#endif /* ORIENTATION_H_ */ diff --git a/games/tetris/playfield.c b/games/tetris/playfield.c deleted file mode 100644 index 04ab99f..0000000 --- a/games/tetris/playfield.c +++ /dev/null @@ -1,718 +0,0 @@ -#include -#include -#include -#include -#include "../../autoconf.h" -#include "playfield.h" -#include "piece.h" - - -/*************************** - * non-interface functions * - ***************************/ - -/** - * determines if piece is either hovering or gliding - * @param pPl the playfield we want information from - * @eturn TETRIS_PFS_HOVERING or TETRIS_PFS_GLIDING - */ -tetris_playfield_status_t tetris_playfield_hoverStatus(tetris_playfield_t* pPl) -{ - // if the piece touches the dump we ensure that the status is "gliding" - if (tetris_playfield_collision(pPl, pPl->nColumn, pPl->nRow + 1)) - { - return TETRIS_PFS_GLIDING; - } - // otherwise the status must be "hovering" - else - { - return TETRIS_PFS_HOVERING; - } -} - - -/**************************** - * construction/destruction * - ****************************/ - -tetris_playfield_t *tetris_playfield_construct(int8_t nWidth, - int8_t nHeight) -{ - assert((nWidth >= 4) && (nWidth <= 16)); - assert((nHeight >= 4) && (nHeight <= 124)); - - tetris_playfield_t *pPlayfield = - (tetris_playfield_t*) malloc(sizeof(tetris_playfield_t)); - - if (pPlayfield != NULL) - { - // allocating mem for dump array - pPlayfield->dump = (uint16_t*) calloc(nHeight, sizeof(uint16_t)); - - if (pPlayfield->dump != NULL) - { - // setting desired attributes - pPlayfield->nFirstMatterRow = nHeight - 1; - pPlayfield->nWidth = nWidth; - pPlayfield->nHeight = nHeight; - tetris_playfield_reset(pPlayfield); - - return pPlayfield; - } - else - { - free(pPlayfield); - pPlayfield = NULL; - } - } - return NULL; -} - - -void tetris_playfield_destruct(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - - // if memory for the dump array has been allocated, free it - if (pPl->dump != NULL) - { - free(pPl->dump); - } - free(pPl); -} - - -/******************************* - * playfield related functions * - *******************************/ - -uint8_t tetris_playfield_calculateLines(uint8_t nRowMask) -{ - uint8_t nMask = 0x0001; - uint8_t nLines = 0; - for (uint8_t i = 0; i < 4; ++i) - { - if ((nMask & nRowMask) != 0) - { - ++nLines; - } - nMask <<= 1; - } - - return nLines; -} - - -void tetris_playfield_reset(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - - pPl->pPiece = NULL; - pPl->nColumn = 0; - pPl->nRow = 0; - pPl->nRowMask = 0; - - // clear dump if it has been allocated in memory - if (pPl->dump != NULL) - { - memset(pPl->dump, 0, pPl->nHeight); - } - - pPl->status = TETRIS_PFS_READY; -} - - -int8_t tetris_playfield_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_playfield_insertPiece(tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - tetris_piece_t** ppOldPiece) -{ - assert((pPl != NULL) && (pPiece != NULL) && (ppOldPiece != NULL)); - - // a piece can only be inserted in state TETRIS_PFS_READY - assert(pPl->status == TETRIS_PFS_READY); - - // row mask is now meaningless - pPl->nRowMask = 0; - - // replace old piece - *ppOldPiece = pPl->pPiece; - pPl->pPiece = pPiece; - - // set horizontal start position (in the middle of the top line) - pPl->nColumn = (pPl->nWidth - 2) / 2; - - // set vertical start position (first piece row with matter at pos. 1) - pPl->nRow = tetris_playfield_getPieceStartPos(pPl->pPiece); - - // did we already collide with something? - if (tetris_playfield_collision(pPl, pPl->nColumn, pPl->nRow) == 1) - { - // game over man, game over!! - pPl->status = TETRIS_PFS_GAMEOVER; - } - else - { - // bring it on! - pPl->status = tetris_playfield_hoverStatus(pPl); - } -} - - -uint8_t tetris_playfield_collision(tetris_playfield_t *pPl, - int8_t nColumn, - int8_t nRow) -{ - assert(pPl != NULL); - - // only allow coordinates which are within sane ranges - assert((nColumn > -4) && (nColumn < pPl->nWidth)); - assert((nRow > -4) && (nRow < pPl->nHeight)); - - // The rows of a piece get compared with the background one by one - // until either a collision occures or all rows are compared. Both the - // piece row and the part of the playfield it covers are represented in - // 4 bits which were singled out from their corresponding uint16_t - // values and are aligned to LSB. In case where a piece overlaps with - // either the left or the right border we "enhance" the playfield part - // via bit shifting and set all bits representing the border to 1. - // - // NOTE: LSB represents the left most position. - uint16_t nPieceMap = tetris_piece_getBitmap(pPl->pPiece); - uint16_t nPlayfieldPart; - uint16_t nPieceRowMap; - - // negative nRow values indicate that the piece hasn't fully entered the - // playfield yet which requires special treatment if the piece overlaps - // with either the left or the right border - if (nRow < 0) - { - uint16_t nBorderMask = 0x0000; - // piece overlaps with left border - if (nColumn < 0) - { - nBorderMask = 0x1111 << (-nColumn - 1); - } - // piece overlaps with right border - else if ((nColumn + 3) >= pPl->nWidth) - { - nBorderMask = 0x8888 >> ((nColumn + 3) - pPl->nWidth); - } - // return if piece collides with border - if ((nPieceMap & nBorderMask) != 0) - { - return 1; - } - } - - // here we check the part which has already entered the playfield - for (int8_t y = (nRow < 0) ? -nRow : 0; y < 4; ++y) - { - // current piece row overlaps with lower border - if ((y + nRow) >= pPl->nHeight) - { - // all 4 bits represent the lower border - nPlayfieldPart = 0x000F; - } - // piece overlaps with left border - else if (nColumn < 0) - { - // clear all bits we are not interested in - nPlayfieldPart = (pPl->dump[y + nRow] & (0x000F >> -nColumn)); - // add zeros to the left (the bits "behind" the left border) - nPlayfieldPart <<= -nColumn; - // set bits beyond left border to 1 - nPlayfieldPart |= 0x000F >> (4 + nColumn); - } - // piece overlaps with right border - else if ((nColumn + 3) >= pPl->nWidth) - { - // align the bits we are interested in to LSB - // (thereby clearing the rest) - nPlayfieldPart = pPl->dump[y + nRow] >> nColumn; - // set bits beyond right border to 1 - nPlayfieldPart |= 0xFFF8 >> (nColumn + 3 - pPl->nWidth); - } - // current row neither overlaps with left, right nor lower border - else - { - // clear all bits we are not interested in and align the - // remaing row to LSB - nPlayfieldPart = - (pPl->dump[y + nRow] & (0x000F << nColumn)) >> nColumn; - } - - // clear all bits of the piece we are not interested in and - // align the remaing row to LSB - nPieceRowMap = (nPieceMap & (0x000F << (y << 2))) >> (y << 2); - - // finally check for a collision - if ((nPlayfieldPart & nPieceRowMap) != 0) - { - return 1; - } - } - - // if we reach here, no collision was detected - return 0; -} - - -void tetris_playfield_advancePiece(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - - // a piece can only be lowered if it is hovering or gliding - assert ((pPl->status == TETRIS_PFS_HOVERING) || - (pPl->status == TETRIS_PFS_GLIDING)); - - if (tetris_playfield_collision(pPl, pPl->nColumn, pPl->nRow + 1)) - { - uint16_t nPiece = tetris_piece_getBitmap(pPl->pPiece); - - // Is the playfield filled up? - if ((pPl->nRow < 0) && (nPiece & (0x0FFF >> ((3 + pPl->nRow) << 2))) != 0) - { - pPl->status = TETRIS_PFS_GAMEOVER; - } - else - { - // determine valid start point for dump index - int8_t nStartRow = ((pPl->nRow + 3) < pPl->nHeight) ? - (pPl->nRow + 3) : pPl->nHeight - 1; - for (int8_t i = nStartRow; i >= pPl->nRow; --i) - { - int8_t y = i - pPl->nRow; - - // clear all bits of the piece we are not interested in and - // align the rest to LSB - uint16_t nPieceMap = (nPiece & (0x000F << (y << 2))) >> (y << 2); - // shift the remaining content to the current column - if (pPl->nColumn >= 0) - { - nPieceMap <<= pPl->nColumn; - } - else - { - nPieceMap >>= -pPl->nColumn; - } - // embed piece in playfield - pPl->dump[i] |= nPieceMap; - } - - // update value for the highest row with matter - int8_t nPieceRow = pPl->nRow; - uint16_t nMask = 0x000F; - for (int i = 0; i < 4; ++i, nMask <<= 4) - { - if ((nMask & nPiece) != 0) - { - nPieceRow += i; - break; - } - } - pPl->nFirstMatterRow = (pPl->nFirstMatterRow > nPieceRow) ? - nPieceRow : pPl->nFirstMatterRow; - - // the piece has finally been docked - pPl->status = TETRIS_PFS_DOCKED; - } - } - else - { - // since there is no collision the piece may continue its travel - // to the ground... - pPl->nRow++; - - // are we gliding? - pPl->status = tetris_playfield_hoverStatus(pPl); - } -} - - -uint8_t tetris_playfield_movePiece(tetris_playfield_t *pPl, - tetris_playfield_direction_t direction) -{ - assert(pPl != NULL); - - // a piece can only be moved if it is still hovering or gliding - assert((pPl->status == TETRIS_PFS_HOVERING) || - (pPl->status == TETRIS_PFS_GLIDING)); - - int8_t nOffset = (direction == TETRIS_PFD_LEFT) ? -1 : 1; - if (tetris_playfield_collision(pPl, pPl->nColumn + nOffset, pPl->nRow) == 0) - { - pPl->nColumn += nOffset; - - // are we gliding? - pPl->status = tetris_playfield_hoverStatus(pPl); - return 1; - } - - return 0; -} - - -uint8_t tetris_playfield_rotatePiece(tetris_playfield_t *pPl, - tetris_piece_rotation_t rotation) -{ - assert(pPl != NULL); - - // a piece can only be rotation if it is still hovering or gliding - assert((pPl->status == TETRIS_PFS_HOVERING) || - (pPl->status == TETRIS_PFS_GLIDING)); - - tetris_piece_rotate(pPl->pPiece, rotation); - - // does the rotated piece cause a collision? - if (tetris_playfield_collision(pPl, pPl->nColumn, pPl->nRow) != 0) - { - // in that case we revert the rotation - if (rotation == TETRIS_PC_ROT_CW) - { - tetris_piece_rotate(pPl->pPiece, TETRIS_PC_ROT_CCW); - } - else - { - tetris_piece_rotate(pPl->pPiece, TETRIS_PC_ROT_CW); - } - - return 0; - } - - // are we gliding? - pPl->status = tetris_playfield_hoverStatus(pPl); - - return 1; -} - - -void tetris_playfield_removeCompleteLines(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - - // rows can only be removed if we are in state TETRIS_PFS_DOCKED - assert(pPl->status == TETRIS_PFS_DOCKED); - - // bit mask of a full row - uint16_t nFullRow = 0xFFFF >> (16 - pPl->nWidth); - - // 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) - uint8_t nRowMask = 0; - - // determine sane start and stop values for the dump' index - int8_t nStartRow = - ((pPl->nRow + 3) >= pPl->nHeight) ? pPl->nHeight - 1 : pPl->nRow + 3; - int8_t nStopRow = (pPl->nRow < 0) ? 0 : pPl->nRow; - - // dump index variables - // for incomplete rows, both variables will be decremented - // for complete rows, only i gets decremented - int8_t nLowestRow = nStartRow; - - // save old value for the first dump index with matter - int8_t nFormerFirstMatterRow = pPl->nFirstMatterRow; - - // 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? - if ((nFullRow & pPl->dump[i]) == nFullRow) - { - // adjust value for the highest row with matter - pPl->nFirstMatterRow++; - - // set corresponding bit for the row mask - // nRowMask |= 0x08 >> (nStartRow - i); - nRowMask |= 0x01 << (i - pPl->nRow); - } - else - { - // if nLowestRow and i differ, the dump has to be shifted - if (i < nLowestRow) - { - pPl->dump[nLowestRow] = pPl->dump[i]; - } - --nLowestRow; - } - } - - // if rows have been removed, this loop shifts the rest of the dump - uint8_t nComplete = nLowestRow - nStopRow + 1; - if (nComplete > 0) - { - for (int8_t i = nStopRow - 1; nLowestRow >= nFormerFirstMatterRow; --i) - { - // is the row we are copying from below the upper border? - if (i >= nFormerFirstMatterRow) - { - // just copy from that row - pPl->dump[nLowestRow] = pPl->dump[i]; - } - else - { - // rows above the upper border are always empty - pPl->dump[nLowestRow] = 0; - } - --nLowestRow; - } - } - - // ready to get the next piece - pPl->status = TETRIS_PFS_READY; - - pPl->nRowMask = nRowMask; -} - - -/***************** - * get functions * - *****************/ - -int8_t tetris_playfield_getWidth(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->nWidth; -} - - -/* Function: tetris_playfield_getHeight - * Description: returns the height of the ayfield we want information from - * Return value: height of the playfield - */ -int8_t tetris_playfield_getHeight(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->nHeight; -} - - -tetris_piece_t *tetris_playfield_getPiece(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->pPiece; -} - - -int8_t tetris_playfield_getColumn(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->nColumn; -} - - -int8_t tetris_playfield_getRow(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->nRow; -} - - -int8_t tetris_playfield_getFirstMatterRow(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->nFirstMatterRow; -} - - -uint8_t tetris_playfield_getRowMask(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->nRowMask; -} - - -tetris_playfield_status_t tetris_playfield_getStatus(tetris_playfield_t *pPl) -{ - assert(pPl != NULL); - return pPl->status; -} - - -uint16_t tetris_playfield_getDumpRow(tetris_playfield_t *pPl, - int8_t nRow) -{ - assert(pPl != NULL); - assert((0 <= nRow) && (nRow < pPl->nHeight)); - return pPl->dump[nRow]; -} - - -#ifdef GAME_BASTET - -int8_t tetris_playfield_predictDeepestRow(tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - int8_t nColumn) -{ - int8_t nRow = tetris_playfield_getPieceStartPos(pPiece); - tetris_piece_t *pActualPiece = pPl->pPiece; - pPl->pPiece = pPiece; - - // is it actually possible to use this piece? - if (tetris_playfield_collision(pPl, (pPl->nWidth - 2) / 2, nRow) || - (tetris_playfield_collision(pPl, nColumn, nRow))) - { - // restore real piece - pPl->pPiece = pActualPiece; - - return -4; - } - - // determine deepest row - nRow = (nRow < pPl->nFirstMatterRow - 4) ? pPl->nFirstMatterRow - 4 : nRow; - while ((nRow < pPl->nHeight) && - (!tetris_playfield_collision(pPl, nColumn, nRow + 1))) - { - ++nRow; - } - - // restore real piece - pPl->pPiece = pActualPiece; - - return nRow; -} - - -int8_t tetris_playfield_predictCompleteLines(tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - int8_t nRow, - int8_t nColumn) -{ - int8_t nCompleteRows = 0; - - // bit mask of a full row - uint16_t nFullRow = 0xFFFF >> (16 - pPl->nWidth); - - if (nRow > -4) - { - // determine sane start and stop values for the dump's index - int8_t nStartRow = - ((nRow + 3) >= pPl->nHeight) ? pPl->nHeight - 1 : nRow + 3; - int8_t nStopRow = (nRow < 0) ? 0 : nRow; - - uint16_t nPiece = tetris_piece_getBitmap(pPiece); - - for (int8_t i = nStartRow; i >= nStopRow; --i) - { - int8_t y = i - nRow; - - // clear all bits of the piece we are not interested in and - // align the rest to LSB - uint16_t nPieceMap = (nPiece & (0x000F << (y << 2))) >> (y << 2); - // shift the remaining content to the current column - if (nColumn >= 0) - { - nPieceMap <<= nColumn; - } - else - { - nPieceMap >>= -nColumn; - } - // embed piece in dump map - uint16_t nDumpMap = pPl->dump[i] | nPieceMap; - - // is current row a full row? - if ((nFullRow & nDumpMap) == nFullRow) - { - ++nCompleteRows; - } - } - } - - return nCompleteRows; -} - - -uint16_t* tetris_playfield_predictBottomRow(tetris_playfield_iterator_t *pIt, - tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - int8_t nRow, - int8_t nColumn) -{ - pIt->pPlayfield = pPl; - pIt->pPiece = pPiece; - pIt->nColumn = nColumn; - pIt->nFullRow = 0xFFFF >> (16 - pPl->nWidth); - pIt->nCurrentRow = pPl->nHeight - 1; - pIt->nRowBuffer = 0; - - // determine sane start and stop values for the piece's row indices - pIt->nPieceHighestRow = nRow; - pIt->nPieceLowestRow = ((pIt->nPieceHighestRow + 3) < pPl->nHeight) ? - (pIt->nPieceHighestRow + 3) : pPl->nHeight - 1; - - // don't return any trailing rows which are empty, so we look for a stop row - pIt->nStopRow = pPl->nFirstMatterRow < nRow ? pPl->nFirstMatterRow : nRow; - pIt->nStopRow = pIt->nStopRow < 0 ? 0 : pIt->nStopRow; - - return tetris_playfield_predictNextRow(pIt); -} - - -uint16_t* tetris_playfield_predictNextRow(tetris_playfield_iterator_t *pIt) -{ - uint16_t nPieceMap = 0; - - if ((pIt->nPieceHighestRow > -4) && (pIt->nCurrentRow >= pIt->nStopRow)) - { - uint16_t nPiece = tetris_piece_getBitmap(pIt->pPiece); - - if ((pIt->nCurrentRow <= pIt->nPieceLowestRow) && - (pIt->nCurrentRow >= pIt->nPieceHighestRow)) - { - int8_t y = pIt->nCurrentRow - pIt->nPieceHighestRow; - - // clear all bits of the piece we are not interested in and - // align the rest to LSB - nPieceMap = (nPiece & (0x000F << (y << 2))) >> (y << 2); - // shift the remaining content to the current column - if (pIt->nColumn >= 0) - { - nPieceMap <<= pIt->nColumn; - } - else - { - nPieceMap >>= -pIt->nColumn; - } - } - - pIt->nRowBuffer = pIt->pPlayfield->dump[pIt->nCurrentRow--] | nPieceMap; - // don't return full (and therefore removed) rows - if (pIt->nRowBuffer == pIt->nFullRow) - { - // recursively determine next (?) row instead - return tetris_playfield_predictNextRow(pIt); - } - // row isn't full - else - { - return &pIt->nRowBuffer; - } - } - else - { - return NULL; - } -} - -#endif /* GAME_BASTET */ diff --git a/games/tetris/playfield.h b/games/tetris/playfield.h deleted file mode 100644 index e5fc2ab..0000000 --- a/games/tetris/playfield.h +++ /dev/null @@ -1,293 +0,0 @@ -#ifndef TETRIS_PLAYFIELD_H_ -#define TETRIS_PLAYFIELD_H_ - -#include -#include "../../autoconf.h" -#include "piece.h" - - -/********* - * types * - *********/ - -// directions to which a piece can be moved -typedef enum tetris_playfield_direction_t -{ - TETRIS_PFD_LEFT, - TETRIS_PFD_RIGHT -} -tetris_playfield_direction_t; - - -// status of the playfield -typedef enum tetris_playfield_status_t -{ - TETRIS_PFS_READY, /** ready to get next piece */ - TETRIS_PFS_HOVERING, /** piece is still hovering */ - TETRIS_PFS_GLIDING, /** piece is gliding on the dump */ - TETRIS_PFS_DOCKED, /** piece has been docked */ - TETRIS_PFS_GAMEOVER /** playfield is filled up */ -} -tetris_playfield_status_t; - - -// tetris_playfield_t -typedef struct tetris_playfield_t -{ - int8_t nWidth; /** width of playfield */ - int8_t nHeight; /** height of playfield */ - tetris_piece_t *pPiece; /** currently falling piece */ - int8_t nColumn; /** horz. piece pos. (0 is left) */ - int8_t nRow; /** vert. piece pos. (0 is top) */ - uint8_t nRowMask; /** removed lines relative to nRow */ - tetris_playfield_status_t status; /** status */ - int8_t nFirstMatterRow; /** first row from top which has matter */ - uint16_t *dump; /** playfield itself */ -} -tetris_playfield_t; - - -// iterator for predicted dump rows -typedef struct tetris_playfield_iterator_t -{ - tetris_playfield_t *pPlayfield; /** playfield to be examined */ - tetris_piece_t *pPiece; /** piece which should be tested */ - 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 playfield */ - int8_t nPieceHighestRow; /** the highest row index of the piece */ - int8_t nPieceLowestRow; /** the lowest row index of the piece */ - int8_t nStopRow; /** the last row to be examined */ - uint16_t nRowBuffer; /** internal buffer for returned rows */ -} -tetris_playfield_iterator_t; - - -/**************************** - * construction/destruction * - ****************************/ - -/** - * constructs a playfield with the given diemensions - * @param nWidth width of playfield (4 <= n <= 16) - * @param nHeight height of playfield (4 <= n <= 124) - * @return pointer to a newly created playfield - */ -tetris_playfield_t *tetris_playfield_construct(int8_t nWidth, int8_t nHeight); - - -/** - * destructs a playfield - * @param pPl pointer to the playfield to be destructed - */ -void tetris_playfield_destruct(tetris_playfield_t *pPl); - - -/******************************* - * playfield related functions * - *******************************/ - -/** - * calculates number of lines for the given row mask - * @param nRowMask row mask from which the no. of lines will be calculated - * @return number of lines of the row mask - */ -uint8_t tetris_playfield_calculateLines(uint8_t nRowMask); - - -/** - * resets playfield to begin a new game - * @param pPl playfield to perform action on - */ -void tetris_playfield_reset(tetris_playfield_t *pPl); - - -/** - * inserts a new piece - * @param pPl playfield to perform action on - * @param pPiece piece to be inserted - * @param ppOldPiece [out] indirect pointer to former piece for deallocation - */ -void tetris_playfield_insertPiece(tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - tetris_piece_t** ppOldPiece); - - -/** - * detects if piece collides with s.th. at a given position - * @param pPl playfield to perform action on - * @param nColumn column where the piece should be moved - * @param nRow row where the piece should be moved - * @return 1 for collision, 0 otherwise - */ -uint8_t tetris_playfield_collision(tetris_playfield_t *pPl, - int8_t nColumn, - int8_t nRow); - - -/** - * lowers piece by one row or finally docks it - * @param pPl playfield to perform action on - */ -void tetris_playfield_advancePiece(tetris_playfield_t *pPl); - - -/** - * moves piece to the given direction - * @param pPl playfield to perform action on - * @param direction direction (see tetris_playfield_direction_t) - * @return 1 if piece could be moved, 0 otherwise - */ -uint8_t tetris_playfield_movePiece(tetris_playfield_t *pPl, - tetris_playfield_direction_t direction); - - -/** - * rotates piece to the given direction - * @param pPl playfield to perform action on - * @param r type of rotation (see tetris_piece_rotation_t) - * @return 1 if piece could be rotated, 0 otherwise - */ -uint8_t tetris_playfield_rotatePiece(tetris_playfield_t *pPl, - tetris_piece_rotation_t rotation); - - -/** - * removes completed lines (if any) and lowers the dump - * @param pPl playfield to perform action on - */ -void tetris_playfield_removeCompleteLines(tetris_playfield_t *pPl); - - -/***************** - * get functions * - *****************/ - -/** - * returns the width of the playfield - * @param pPl the playfield we want information from - * @return width of the playfield - */ -int8_t tetris_playfield_getWidth(tetris_playfield_t *pPl); - - -/** - * returns the height of the playfield - * @param pPl the playfield we want information from - * @return height of the playfield - */ -int8_t tetris_playfield_getHeight(tetris_playfield_t *pPl); - - -/** - * returns the currently falling piece - * @param pPl the playfield we want information from - * @return pointer to the currently falling piece - */ -tetris_piece_t *tetris_playfield_getPiece(tetris_playfield_t *pPl); - - -/** - * returns the column of the currently falling piece - * @param pPl the playfield we want information from - * @return column of the currently falling piece - */ -int8_t tetris_playfield_getColumn(tetris_playfield_t *pPl); - - -/** - * returns the row of the currently falling piece - * @param pPl the playfield we want information from - * @return row of the currently falling piece - */ -int8_t tetris_playfield_getRow(tetris_playfield_t *pPl); - - -/** - * returns the row of the currently falling piece - * @param pPl the playfield we want information from - * @return highest row with matter - */ -int8_t tetris_playfield_getFirstMatterRow(tetris_playfield_t *pPl); - - -/** - * returns the row mask relative to nRow - * @param pPl the playfield we want information from - * @return bit mask of removed lines (relative to current position) - */ -uint8_t tetris_playfield_getRowMask(tetris_playfield_t *pPl); - - -/** - * returns the status of the playfield - * @param pPl the playfield we want information from - * @return status of the playfield (see tetris_playfield_status_t) - */ -tetris_playfield_status_t tetris_playfield_getStatus(tetris_playfield_t *pPl); - - -/** - * returns the given row of the dump (as bitmap) - * @param pPl the playfield we want information from - * @param nRow the number of the row (0 <= nRow <= 124) - * @return bitmap of the requested row (LSB is leftmost column) - */ -uint16_t tetris_playfield_getDumpRow(tetris_playfield_t *pPl, - int8_t nRow); - - -#ifdef GAME_BASTET - -/** - * returns the deepest possible row for a given piece - * @param pPl the playfield on which we want to test a piece - * @param pPiece the piece which should be tested - * @param nColumn the column where the piece should be dropped - * @return the row of the piece (playfield compliant coordinates) - */ -int8_t tetris_playfield_predictDeepestRow(tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - int8_t nColumn); - - -/** - * predicts the number of complete lines for a piece at a given column - * @param pPl the playfield on which we want to test a piece - * @param pPiece the piece which should be tested - * @param nRow the row where the given piece collides - * @param nColumn the column where the piece should be dropped - * @return amount of complete lines - */ -int8_t tetris_playfield_predictCompleteLines(tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - int8_t nRow, - int8_t nColumn); - - -/** - * predicts appearance of the bottom row and initializes an iterator structure - * @param pIt a pointer to an iterator which should be initialized - * @param pPl the playfield on which we want to test a piece - * @param pPiece the piece which should be tested - * @param nRow the row where the given piece collides - * @param nColumn the column where the piece should be dropped - * @return appearance of the predicted dump row at the bottom as bit mask - */ -uint16_t* tetris_playfield_predictBottomRow(tetris_playfield_iterator_t *pIt, - tetris_playfield_t *pPl, - tetris_piece_t *pPiece, - int8_t nRow, - int8_t nColumn); - - -/** - * predicts appearance of the next row of the playfield (for a given iterator) - * @param pIt a pointer to a dump iterator - * @return appearance of next predicted row (or NULL -> no next line) - */ -uint16_t* tetris_playfield_predictNextRow(tetris_playfield_iterator_t *pIt); - -#endif /* GAME_BASTET */ - -#endif /*TETRIS_PLAYFIELD_H_*/