static int console_reader(void *arg) { char buf[1024]; _key_event kevents[16]; ssize_t len; ssize_t write_len; struct console *con = (struct console *)arg; for(;;) { len = read(con->keyboard_fd, kevents, sizeof(kevents)); if(len < 0) break; len = process_key_events(kevents, len / sizeof(_key_event), buf, sizeof(buf), con->keyboard_fd); if(len <= 0) continue; write_len = write(con->tty_master_fd, buf, len); } _kern_sem_release(con->wait_sem, 1); return 0; }
// run_martet: The game loop. Returns final score. int run_martet(SDL_Surface* screen, SDL_Surface* board) { Tetromino* active_tetromino; Tetromino* next_tetromino; // Create ingame menu struct Menu* ingame_menu = menu_create(); menu_addelement(ingame_menu, "Continue"); menu_addelement(ingame_menu, "Quit Current Game"); ingame_menu->active_element = &ingame_menu->elements[0]; ingame_menu->active_element->active = 1; int score = 0; srand((unsigned) time(NULL)); board_create(); next_tetromino = tetcreaterand(); update_status_bar(next_tetromino, screen, score); active_tetromino = tetcreaterand(); active_tetromino->position[0] = 4; struct Timer* timer = create_timer(); timer_change_alarm_interval(timer, GAME_SPEED); timer_start(timer); bool running = true; while (running){ int event = process_key_events(active_tetromino, tetaction); if (event == KEYEVENT_EXIT) exit(0); else if (event == KEYEVENT_MENU) { if (ingame_menu_martet(screen, board, ingame_menu) == 1) running = false; } else if (event == KEYEVENT_PAUSE) pause_martet(screen, board); if (timer_update(timer)) { // If collision and tetromino not deleted if ( tetmove('d', active_tetromino) == 0 && active_tetromino->color != TETROMINO_DELETE) { place_tetromino(active_tetromino); active_tetromino->color = TETROMINO_DELETE; } else if ( active_tetromino->color == TETROMINO_DELETE ) { free(active_tetromino); active_tetromino = next_tetromino; next_tetromino = tetcreaterand(); if (check_rows(&score)) { // If score has increased. timer_change_alarm_interval(timer, GAME_SPEED / sqrt( (double) score/5) + 1); } } if ( next_tetromino == NULL ) // If game over break; update_status_bar(next_tetromino, screen, score); } clear_surface(board, NULL); draw_board(board); draw_tetromino(board, active_tetromino); draw_ghost_tetromino(board, active_tetromino); draw_surface(0, 0, board, screen, NULL); SDL_Flip(screen); } if (active_tetromino) { free(active_tetromino); } free(next_tetromino); free(timer); menu_destroy(ingame_menu); return score; }