int start_new_game(void) { struct thread_data data = { NULL, 0, 0, PTHREAD_MUTEX_INITIALIZER, 0, 0 }; initialize_game_elements(); initialize_game_screen(); /* draw the next block, and the begin game message */ draw_next_block(next_block, next_block_orientation); if (draw_start_game() == FAILURE) return SUCCESS; draw_level_info(game_options.initial_level); /* create the worker thread */ if (pthread_create(&data.thread_id, NULL, worker_thread_fn, (void *)&data)) return FAILURE; /* the main thread for the core gameplay */ play_game(&data); pthread_join(data.thread_id, NULL); if (data.new_highscore) draw_highscore(global_highscore); return SUCCESS; }
void GameArea::paint(QPaintEvent *) { QPainter painter(this); painter.drawPixmap(QPoint(_pix_x, _pix_y), *_game_area); if (_is_draw_next) draw_next_block(); }
/* try to add a new block to play with (return true if gameover) */ static void new_block (void) { rockblox_status.cy = 1; rockblox_status.cx = 5; rockblox_status.cf = rockblox_status.nf; rockblox_status.co = 0; /* start at the same orientation all time */ rockblox_status.nf = t_rand (BLOCKS_NUM); rockblox_status.gameover = !canMoveTo (rockblox_status.cx, rockblox_status.cy, rockblox_status.co); draw_next_block (); }
static void init_rockblox (bool resume) { char score_name[50]; struct tm* tm; tm = rb->get_time(); rb->snprintf(score_name, sizeof(score_name), "%04d%02d%02d %02d%02d%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); #ifdef HAVE_LCD_BITMAP rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT); #else /* HAVE_LCD_CHARCELLS */ pgfx_display (0, 0); pgfx_display_block (3, 0, 3, 1); pgfx_display_block (4, 0, 3, 0); rb->lcd_puts(4, 1, " "); pgfx_clear_display(); pgfx_fillrect (3, 0, 2, 14); pgfx_fillrect (15, 7, 2, 7); pgfx_update(); #endif if (!resume) { rockblox_status.level = 1; rockblox_status.lines = 0; rockblox_status.score = 0; rockblox_status.nf = t_rand(BLOCKS_NUM); init_board (); new_block (); } draw_next_block(); show_details (); #ifdef HIGH_SCORE_Y show_highscores (); #endif }
static int rockblox_loop (void) { int button; #if defined(ROCKBLOX_OFF_PRE) || defined(ROCKBLOX_DROP_PRE) int lastbutton = BUTTON_NONE; #endif long next_down_tick = *rb->current_tick + level_speed(rockblox_status.level); if (rockblox_menu()) { return 1; } resume = false; resume_file = false; while (1) { #ifdef HAS_BUTTON_HOLD if (rb->button_hold ()) { /* Turn on backlight timeout (revert to settings) */ backlight_use_settings(); rb->splash(0, "Paused"); while (rb->button_hold ()) rb->sleep(HZ/10); /* Turn off backlight timeout */ backlight_ignore_timeout(); /* get rid of the splash text */ rb->lcd_bitmap (rockblox_background, 0, 0, LCD_WIDTH, LCD_HEIGHT); show_details (); #ifdef HIGH_SCORE_Y show_highscores (); #endif draw_next_block (); refresh_board (); } #endif button = rb->button_get_w_tmo (MAX(next_down_tick - *rb->current_tick, 1)); switch (button) { #ifdef ROCKBLOX_RC_OFF case ROCKBLOX_RC_OFF: #endif case ROCKBLOX_OFF: #ifdef ROCKBLOX_OFF_PRE if (lastbutton != ROCKBLOX_OFF_PRE) break; #endif resume = true; return 0; break; #if defined(ROCKBLOX_ROTATE) case ROCKBLOX_ROTATE: #endif case ROCKBLOX_ROTATE_CCW: case ROCKBLOX_ROTATE_CCW | BUTTON_REPEAT: #ifdef HAVE_SCROLLWHEEL /* if the wheel is disabled, add an event to the stack. */ if(wheel_enabled == false) wheel_events++; /* if it's enabled, go ahead and rotate.. */ if(wheel_enabled) #endif #ifdef ROCKBLOX_ROTATE_CCW2 /* fallback */ case ROCKBLOX_ROTATE_CCW2: #endif move_block (0, 0, (rockblox_status.co + 1) % figures[rockblox_status.cf].max_or); break; case ROCKBLOX_ROTATE_CW: case ROCKBLOX_ROTATE_CW | BUTTON_REPEAT: #ifdef HAVE_SCROLLWHEEL if(wheel_enabled == false) wheel_events++; if(wheel_enabled) #endif #ifdef ROCKBLOX_ROTATE_CW2 /* fallback */ case ROCKBLOX_ROTATE_CW2: #endif move_block (0, 0, (rockblox_status.co + figures[rockblox_status.cf].max_or - 1) % figures[rockblox_status.cf].max_or); break; case ROCKBLOX_DOWN: case ROCKBLOX_DOWN | BUTTON_REPEAT: move_block (0, 1, rockblox_status.co); break; case ROCKBLOX_RIGHT: case ROCKBLOX_RIGHT | BUTTON_REPEAT: move_block (1, 0, rockblox_status.co); break; case ROCKBLOX_LEFT: case ROCKBLOX_LEFT | BUTTON_REPEAT: move_block (-1, 0, rockblox_status.co); break; case ROCKBLOX_DROP: #ifdef ROCKBLOX_DROP_PRE if (lastbutton != ROCKBLOX_DROP_PRE) break; #endif while (canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co)) move_block (0, 1, rockblox_status.co); rockblox_status.dropped = true; break; #ifdef ROCKBLOX_RESTART case ROCKBLOX_RESTART: rb->splash (HZ * 1, "Restarting..."); init_rockblox (false); break; #endif default: if (rb->default_event_handler (button) == SYS_USB_CONNECTED) return PLUGIN_USB_CONNECTED; break; } #if defined(ROCKBLOX_OFF_PRE) || defined(ROCKBLOX_DROP_PRE) if (button != BUTTON_NONE) lastbutton = button; #endif #ifdef HAVE_SCROLLWHEEL /* check if we should enable the scroll wheel, if events * begin to stack up... */ if(wheel_enabled == false) { /* stopped rotating the wheel, reset the count */ if(wheel_events == last_wheel_event) { last_wheel_event = 0; wheel_events = 0; } /* rotated the wheel a while constantly, enable it. */ else if(wheel_events > 3) { wheel_enabled = true; } /* this evens out the last event and the "current" event. * if we get an event next time through button reading, it will * remain ahead of last_event. if we don't, they'll end up equaling * each other.. thus, the scroll count will be reset. */ if(wheel_enabled == false && wheel_events > last_wheel_event) last_wheel_event++; } #endif if (TIME_AFTER(*rb->current_tick, next_down_tick)) { move_down (); next_down_tick += level_speed(rockblox_status.level); if (TIME_AFTER(*rb->current_tick, next_down_tick)) /* restart time "raster" when we had to wait longer than usual * (pause, game restart etc) */ next_down_tick = *rb->current_tick + level_speed(rockblox_status.level); } if (rockblox_status.gameover) { #if LCD_DEPTH >= 2 rb->lcd_set_foreground (LCD_BLACK); #endif show_game_over(); resume = false; return 0; } refresh_board (); } return 0; }
static void *worker_thread_fn(void *arg) { int i; int status; int timeout = INITIAL_TIMEOUT; struct game_score game_score = { game_options.initial_level, 0, 0, 0, global_highscore }; struct thread_data *data = (struct thread_data *)arg; /* setup the initial timeout (by reducing all deltas upto initial_level */ for (i = 1; i <= game_options.initial_level; i++) timeout -= TIMEOUT_DELTA(i); draw_score_board(&game_score); /* main game loop */ while (1) { /* wait till timeout */ snooze(timeout); /* acquire the lock */ pthread_mutex_lock(&data->lock); if (data->game_over) { pthread_mutex_unlock(&data->lock); break; } if (!data->current) { data->current = update_current_block(NULL); status = move_block(data->current, ACTION_PLACE_NEW); if (status == FAILURE) { data->game_over = 1; pthread_mutex_unlock(&data->lock); break; } draw_next_block(next_block, next_block_orientation); } else { /* try moving the block downwards */ status = move_block(data->current, ACTION_MOVE_DOWN); if (status == FAILURE) { int ret, num_rows; /* freeze this block in the game board */ freeze_block(data->current); data->current = NULL; /* reset the current block pointer */ data->block_dropped_ignore_input = 0; /* reset this now */ num_rows = clear_even_rows(); if (num_rows) { ret = update_score_level(&game_score, num_rows, &timeout); draw_score_board(&game_score); /* see if the level has changed */ if (ret) { draw_game_board(data->current); draw_level_info(game_score.level); } } } } draw_game_board(data->current); pthread_mutex_unlock(&data->lock); } if (game_score.score > global_highscore) { global_highscore = game_score.score; data->new_highscore = 1; } return arg; }