saved 40 bytes

This commit is contained in:
Christian Kroll 2011-03-14 10:30:04 +00:00
parent fa820f9dd7
commit 01347c853b
2 changed files with 26 additions and 83 deletions

View File

@ -37,9 +37,6 @@
*/ */
#define TETRIS_INPUT_PAUSE_CYCLES 60000 #define TETRIS_INPUT_PAUSE_CYCLES 60000
/** minimum of cycles in gliding mode */
#define TETRIS_INPUT_GLIDE_CYCLES 75
/** initial delay (in loop cycles) for key repeat */ /** initial delay (in loop cycles) for key repeat */
#define TETRIS_INPUT_REPEAT_INITIALDELAY 35 #define TETRIS_INPUT_REPEAT_INITIALDELAY 35
/** delay (in loop cycles) for key repeat */ /** delay (in loop cycles) for key repeat */
@ -128,7 +125,7 @@ static void tetris_input_chatterProtect(tetris_input_t *pIn,
uint8_t const nDown = pIn->nIgnoreCmdCounter[TETRIS_INCMD_DOWN]; uint8_t const nDown = pIn->nIgnoreCmdCounter[TETRIS_INCMD_DOWN];
pIn->nIgnoreCmdCounter[TETRIS_INCMD_PAUSE] = pIn->nIgnoreCmdCounter[TETRIS_INCMD_PAUSE] =
(nRotCw > nDown ? nRotCw : nDown); nRotCw > nDown ? nRotCw : nDown;
} }
} }
@ -233,7 +230,6 @@ tetris_input_t *tetris_input_construct(void)
pIn->cmdRawLast = pIn->cmdLast = TETRIS_INCMD_NONE; pIn->cmdRawLast = pIn->cmdLast = TETRIS_INCMD_NONE;
pIn->nBearing = TETRIS_BEARING_0; pIn->nBearing = TETRIS_BEARING_0;
pIn->nLevel = 0xFF;
tetris_input_setLevel(pIn, 0); tetris_input_setLevel(pIn, 0);
pIn->nLoopCycles = 0; pIn->nLoopCycles = 0;
pIn->nRepeatCount = -TETRIS_INPUT_REPEAT_INITIALDELAY; pIn->nRepeatCount = -TETRIS_INPUT_REPEAT_INITIALDELAY;
@ -253,41 +249,29 @@ tetris_input_command_t tetris_input_getCommand(tetris_input_t *pIn,
{ {
assert (pIn != NULL); assert (pIn != NULL);
// holds the translated command value of the joystick
tetris_input_command_t cmdJoystick = TETRIS_INCMD_NONE;
// this variable both serves as the return value and as a flag for not // this variable both serves as the return value and as a flag for not
// leaving the function as long as its value is TETRIS_INCMD_NONE // leaving the function as long as its value is TETRIS_INCMD_NONE
tetris_input_command_t cmdReturn = TETRIS_INCMD_NONE; tetris_input_command_t cmdReturn = TETRIS_INCMD_NONE;
uint8_t nMaxCycles;
// if the piece is gliding we grant the player a reasonable amount of time // if the piece is gliding we grant the player a reasonable amount of time
// to make the game more controllable at higher falling speeds // to make the game more controllable at higher falling speeds
if ((nPace == TETRIS_INPACE_GLIDING) && uint8_t nMaxCycles = pIn->nMaxCycles > nPace ? pIn->nMaxCycles : nPace;
(pIn->nMaxCycles < TETRIS_INPUT_GLIDE_CYCLES))
{
nMaxCycles = TETRIS_INPUT_GLIDE_CYCLES;
}
else
{
nMaxCycles = pIn->nMaxCycles;
}
while (pIn->nLoopCycles < nMaxCycles) while (pIn->nLoopCycles < nMaxCycles)
{ {
cmdJoystick = tetris_input_queryJoystick(pIn); // holds the (mapped) command value of the joystick
tetris_input_command_t cmdJoystick = tetris_input_queryJoystick(pIn);
switch (cmdJoystick) switch (cmdJoystick)
{ {
case TETRIS_INCMD_LEFT: case TETRIS_INCMD_LEFT:
case TETRIS_INCMD_RIGHT: case TETRIS_INCMD_RIGHT:
case TETRIS_INCMD_DOWN: case TETRIS_INCMD_DOWN:
// only react if either the current command differs from the // only react if either the current command differs from the last
// last one or enough loop cycles have been run on the same // one or enough loop cycles have been run on the same command (for
// command (for key repeat) // key repeat)
if ((pIn->cmdLast != cmdJoystick) || ((pIn->cmdLast == cmdJoystick) if (pIn->cmdLast != cmdJoystick ||
&& (pIn->nRepeatCount >= TETRIS_INPUT_REPEAT_DELAY))) pIn->nRepeatCount++ >= TETRIS_INPUT_REPEAT_DELAY)
{ {
// reset repeat counter // reset repeat counter
if (pIn->cmdLast != cmdJoystick) if (pIn->cmdLast != cmdJoystick)
@ -304,14 +288,6 @@ tetris_input_command_t tetris_input_getCommand(tetris_input_t *pIn,
// update cmdLast and return value // update cmdLast and return value
pIn->cmdLast = cmdReturn = cmdJoystick; pIn->cmdLast = cmdReturn = cmdJoystick;
} }
else
{
// if not enough loop cycles have been run we increment the
// repeat counter, ensure that we continue the loop and
// keep the key repeat functioning
++pIn->nRepeatCount;
cmdReturn = TETRIS_INCMD_NONE;
}
break; break;
case TETRIS_INCMD_DROP: case TETRIS_INCMD_DROP:
@ -322,11 +298,6 @@ tetris_input_command_t tetris_input_getCommand(tetris_input_t *pIn,
{ {
pIn->cmdLast = cmdReturn = cmdJoystick; pIn->cmdLast = cmdReturn = cmdJoystick;
} }
else
{
// if we reach here the command is ignored
cmdReturn = TETRIS_INCMD_NONE;
}
break; break;
case TETRIS_INCMD_PAUSE: case TETRIS_INCMD_PAUSE:
@ -337,20 +308,15 @@ tetris_input_command_t tetris_input_getCommand(tetris_input_t *pIn,
pIn->cmdLast = cmdReturn = cmdJoystick; pIn->cmdLast = cmdReturn = cmdJoystick;
pIn->nPauseCount = 0; pIn->nPauseCount = 0;
} }
// consecutive pause commands should not cause the loop to leave
else
{
cmdReturn = TETRIS_INCMD_NONE;
}
break; break;
case TETRIS_INCMD_NONE: case TETRIS_INCMD_NONE:
// If the game is paused (last command was TETRIS_INCMD_PAUSE) // If the game is paused (last command was TETRIS_INCMD_PAUSE) we
// we ensure that the variable which holds that last command // ensure that the variable which holds that last command isn't
// isn't touched. We use this as a flag so that the loop cycle // touched. We use this as a flag so that the loop cycle counter
// counter doesn't get incremented. // doesn't get incremented. We count the number of pause cycles,
// We count the number of pause cycles, though. If enough cycles // though. If enough cycles have been run, we enforce the
// have been run, we enforce the continuation of the game. // continuation of the game.
if ((pIn->cmdLast != TETRIS_INCMD_PAUSE) || if ((pIn->cmdLast != TETRIS_INCMD_PAUSE) ||
(++pIn->nPauseCount > TETRIS_INPUT_PAUSE_CYCLES)) (++pIn->nPauseCount > TETRIS_INPUT_PAUSE_CYCLES))
{ {
@ -359,9 +325,6 @@ tetris_input_command_t tetris_input_getCommand(tetris_input_t *pIn,
// reset repeat counter // reset repeat counter
pIn->nRepeatCount = -TETRIS_INPUT_REPEAT_INITIALDELAY; pIn->nRepeatCount = -TETRIS_INPUT_REPEAT_INITIALDELAY;
// using cmdReturn as a flag for not leaving the loop
cmdReturn = TETRIS_INCMD_NONE;
break; break;
default: default:
@ -369,15 +332,12 @@ tetris_input_command_t tetris_input_getCommand(tetris_input_t *pIn,
} }
// reset automatic falling if the player has dropped a piece // reset automatic falling if the player has dropped a piece
if ((cmdReturn == TETRIS_INCMD_DOWN) if (cmdReturn == TETRIS_INCMD_DOWN || cmdReturn == TETRIS_INCMD_DROP)
|| (cmdReturn == TETRIS_INCMD_DROP))
{ {
pIn->nLoopCycles = 0; pIn->nLoopCycles = 0;
} }
// otherwise ensure automatic falling (unless the game is running) // otherwise ensure automatic falling (unless the game is running)
else if ((cmdReturn != TETRIS_INCMD_PAUSE) && else if (pIn->cmdLast != TETRIS_INCMD_PAUSE)
!((cmdReturn == TETRIS_INCMD_NONE) &&
(pIn->cmdLast == TETRIS_INCMD_PAUSE)))
{ {
++pIn->nLoopCycles; ++pIn->nLoopCycles;
} }
@ -403,13 +363,8 @@ void tetris_input_setLevel(tetris_input_t *pIn,
assert(nLvl <= TETRIS_INPUT_LEVELS - 1); assert(nLvl <= TETRIS_INPUT_LEVELS - 1);
static uint8_t const nCycles[] PROGMEM = {TETRIS_INPUT_LVL_CYCLES}; static uint8_t const nCycles[] PROGMEM = {TETRIS_INPUT_LVL_CYCLES};
if (pIn->nLevel != nLvl)
{
pIn->nLevel = nLvl;
pIn->nMaxCycles = PM(nCycles[nLvl]); pIn->nMaxCycles = PM(nCycles[nLvl]);
} }
}
void tetris_input_resetDownKeyRepeat(tetris_input_t *pIn) void tetris_input_resetDownKeyRepeat(tetris_input_t *pIn)
@ -424,14 +379,10 @@ void tetris_input_resetDownKeyRepeat(tetris_input_t *pIn)
void tetris_input_setBearing(tetris_input_t *pIn, void tetris_input_setBearing(tetris_input_t *pIn,
tetris_bearing_t nBearing) tetris_bearing_t nBearing)
{
if (pIn->nBearing != nBearing)
{ {
pIn->nBearing = nBearing; pIn->nBearing = nBearing;
// avoid weird key repeating effects because the currently pressed // avoid weird key repeating effects because the currently pressed button
// button changes its meaning as soon as the bearing changes // changes its meaning as soon as the bearing changes
pIn->cmdLast = tetris_input_mapCommand(pIn->nBearing, pIn->cmdRawLast); pIn->cmdLast = tetris_input_mapCommand(pIn->nBearing, pIn->cmdRawLast);
pIn->nRepeatCount = -TETRIS_INPUT_REPEAT_INITIALDELAY;
}
} }

View File

@ -41,7 +41,7 @@ enum tetris_input_command
TETRIS_INCMD_DROP, /**< move piece to the ground immediately */ TETRIS_INCMD_DROP, /**< move piece to the ground immediately */
TETRIS_INCMD_GRAVITY, /**< piece gets pulled by gravity */ TETRIS_INCMD_GRAVITY, /**< piece gets pulled by gravity */
TETRIS_INCMD_PAUSE, /**< pause the game */ TETRIS_INCMD_PAUSE, /**< pause the game */
TETRIS_INCMD_NONE /**< idle (must alway be the last one) */ TETRIS_INCMD_NONE /**< idle (must always be the last one) */
}; };
#ifdef NDEBUG #ifdef NDEBUG
typedef uint8_t tetris_input_command_t; typedef uint8_t tetris_input_command_t;
@ -55,9 +55,9 @@ enum tetris_input_command
*/ */
enum tetris_input_pace enum tetris_input_pace
{ {
TETRIS_INPACE_HOVERING, /**< normal falling pace */ TETRIS_INPACE_HOVERING = 0, /**< normal falling pace */
TETRIS_INPACE_GLIDING /**< guarantees a minimum docking time to avoid TETRIS_INPACE_GLIDING = 75 /**< guarantees a minimum docking time to avoid
accidentally docked pieces in higher levels */ accidentally docked pieces at high speeds*/
}; };
#ifdef NDEBUG #ifdef NDEBUG
typedef uint8_t tetris_input_pace_t; typedef uint8_t tetris_input_pace_t;
@ -71,11 +71,6 @@ enum tetris_input_pace
*/ */
typedef struct tetris_input typedef struct tetris_input
{ {
/**
* current level (determines falling speed)
*/
uint8_t nLevel;
/** /**
* Amount of loop cycles between forced piece movements. This value gets * Amount of loop cycles between forced piece movements. This value gets
* set via the tetris_input_setLevel() function. * set via the tetris_input_setLevel() function.
@ -106,19 +101,16 @@ typedef struct tetris_input
*/ */
uint16_t nPauseCount; uint16_t nPauseCount;
/** /**
* last real command (important for key repeat and chatter protection) * last real command (important for key repeat and chatter protection)
*/ */
tetris_input_command_t cmdRawLast; tetris_input_command_t cmdRawLast;
/** /**
* last mapped command (important for key repeat) * last mapped command (important for key repeat)
*/ */
tetris_input_command_t cmdLast; tetris_input_command_t cmdLast;
/** /**
* Every command has its own counter. A command is ignored as long as its * Every command has its own counter. A command is ignored as long as its
* counter is unequal to 0. A counter gets set to a specific value (or 0) * counter is unequal to 0. A counter gets set to a specific value (or 0)