I'm making a simple version of Tetris using Allegro 4 and C++. I've got most of the code in place and everything is working except user input. The keypresses are only being detected by the game on a few, random occasions. I fear it's a timing problem but I can't seem to catch it. Here are the relevant bits of code...
//Tetris.h
//Tetris class definition...
volatile long tet_counter = 0;
void increment_tet_counter()
{
tet_counter++;
}
END_OF_FUNCTION(increment_tet_counter);
//this function gets called by the menu class when the user selects the Tetris option
//contains main loop, calls all other functions etc.
void Tetris::show(BITMAP* buffer, int& scr)
{
LOCK_VARIABLE(tet_counter);
LOCK_FUNCTION(increment_tet_counter);
install_int_ex(increment_tet_counter, BPS_TO_TIMER(120));
while(tet_counter > 0)
{
if(tet_scr == 1) //welcome screen logic
{
if(key[KEY_E])
{
game_init(); //initialize game variables, etc.
tet_scr = 2; // go to main game screen
}
else if(key[KEY_I])
{
tet_scr = 3; //go to instructions screen
}
else if(key[KEY_Q]) //quit tetris
{
scr = 5; //reference to a variable in the main.cpp, basically reverting the
//main screen to the menu screen upon return
return;
}
}
else if(tet_scr == 2) //main game screen
{
if(cannot_move()) //managing auto-block movement, making the last line of blocks
{ //permanent, etc... all of this works fine
put_block();
update_score(remove_filled_line());
get_next_block();
}
move_block(); //handles auto-block movement and user input
if(is_game_over())
{textprintf_ex(screen, font, 500, 300, WHITE, -1, "GAME OVER!");
rest(2000);
tet_scr = 5;
}
if(key[KEY_P]) //pause game
tet_scr = 4;
if(key[KEY_Q]) //quit game
tet_scr = 5;
}
//else ifs for other screens of the game... all work fine
tet_counter--;
}
//drawing functions ... work fine
}
//handles block movement... CPU-generated movement works, user input not detected mot of the time
void Tetris::move_block()
{
timer = (timer+1) % time_factor;
if(timer == time_factor-1) //move block every couple of seconds
block_y += 20;
int k;
if(keypressed()) //this is where the problem is (i think)
{ //the game only picks up the keypresses some of the times
k = readkey(); //and sometimes when I keep the keypressed for a long time it work
if(k >> 8 == KEY_DOWN) //but it's very buggy and erratic and no way to predict
block_y+=20; //when it'll work and when it won't
else if(k >> 8 == KEY_LEFT)
block_x-=20;
else if(k >> 8 == KEY_RIGHT)
block_x+=20;
else if(k >> 8 == KEY_UP)
rotate_block();
}
if(block_x < BOARD_X)
block_x = BOARD_X;
if(block_x > x_lim)
block_x = x_lim;
if(block_y < BOARD_Y)
block_y = BOARD_Y;
if(block_y > y_lim)
block_y = y_lim;
}
//various other functions handling game logic/drawing etc are all working fine
I implemented Tetris exactly the same manner previously but without any overarching menu-class. Just run .exe and you are faced with the Tetris game. That time there were no such problems. So there is obviously something in conjunction with code outside the Tetris.h file that is mucking with the game. The only other place where I use 'keypressed()' is in the main like so...
while (counter > 0)
{
if(keypressed())
{
switch(readkey() >> 8)
{
case KEY_DOWN:
option++;
break;
case KEY_UP:
option--;
break;
}
}
if (option < 0)
option = 5;
else if (option > 5)
option = 0;
screen_handler(option, done); //updates a variable using which the appropriate game is called in show_screen(), pong, breakout, snake are the other games
counter--;
}
show_screen(); //this is where Tetris::show() is called
blit(main_buffer, screen, 0, 0, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
clear_bitmap(main_buffer);
Any and all help to fix this mess would be greatly appreciated. Thanks.
My comment ended up solving the issue for the OP. Putting in answer form for future reference:
If that keyPressed() function in the main() is being called every frame by accident, perhaps it is making the second keyPressed() call malfunction in a sense. If a call to keyPressed looks for the last key pressed since the last call then the first call could be "receiving" that key and then the second call where you actually want to receive the key is getting nada. Sometimes though you are lucky and press that key between keyPressed() call number 1 and call number 2. If this is a tight loop this could be a short window which explains the behaviors you are getting with it "working" sometimes.