void process_key(void) //키 프로세스 { key = 0; //키값 초기화 if (kbhit()) { key = getch(); //키값을 받음 if (key == 224) //방향키인경우 { do { key = getch(); } while (key == 224); //방향키지시값을 버림 switch (key) { case LEFT: //왼쪽키 눌렀을때 if (check_crush(bx - 1, by, b_rotation) == true) //왼쪽으로 갈 수 있는지 체크 후 가능하면 이동 move_block(LEFT); break; case RIGHT: if (check_crush(bx + 1, by, b_rotation) == true) move_block(RIGHT); break; case DOWN: if (check_crush(bx, by + 1, b_rotation) == true) move_block(DOWN); break; case UP: //위쪽키 눌렀을때 회전 if (check_crush(bx, by, (b_rotation + 1) % 4) == true) move_block(UP); else if (crush_on == 1 && check_crush(bx, by - 1, (b_rotation + 1) % 4) == true) move_block(100); } //바닥에 닿은 경우 위쪽으로 한칸띄워서 회전이 가능하면 그렇게 함 } else //방향키가 아닌경우 { switch (key) //스페이스키 눌렀을때 { case SPACE: space_key_on = 1; //스페이스키 flag를 띄움 while (crush_on == 0) //바닥에 닿을때까지 이동시킴 { move_down(); score = score + level; //보너스점수 } break; case z: //테스트용 맛살 b_type_next = 1; break; case ESC: system("cls"); exit(0); } } } while (kbhit()) getch(); //키버퍼를 비우기 }
/* Compact allocations and handle table, adjusting handle pointers as needed. * Return true if any space was freed or consolidated, false otherwise. */ static bool buflib_compact(struct buflib_context *ctx) { BDEBUGF("%s(): Compacting!\n", __func__); union buflib_data *first_free = ctx->first_free_block, *block; int shift = 0, len; /* Store the results of attempting to shrink the handle table */ bool ret = handle_table_shrink(ctx); for(block = first_free; block != ctx->alloc_end; block += len) { len = block->val; /* This block is free, add its length to the shift value */ if (len < 0) { shift += len; len = -len; continue; } /* attempt to fill any hole */ if (abs(ctx->first_free_block->val) > block->val) { intptr_t size = first_free->val; if (move_block(ctx, block, first_free - block)) { block->val *= -1; block = ctx->first_free_block; ctx->first_free_block += block->val; ctx->first_free_block->val = size + block->val; continue; } } /* attempt move the allocation by shift */ if (shift) { /* failing to move creates a hole, therefore mark this * block as not allocated anymore and move first_free_block up */ if (!move_block(ctx, block, shift)) { union buflib_data* hole = block + shift; hole->val = shift; if (ctx->first_free_block > hole) ctx->first_free_block = hole; shift = 0; } } } /* Move the end-of-allocation mark, and return true if any new space has * been freed. */ ctx->alloc_end += shift; /* only move first_free_block up if it wasn't already by a hole */ if (ctx->first_free_block > ctx->alloc_end) ctx->first_free_block = ctx->alloc_end; ctx->compact = true; return ret || shift; }
void handle_keyboard_event(nstate *state) { GR_EVENT_KEYSTROKE *event = &state->event.keystroke; switch(event->ch) { case 'q': case 'Q': case MWKEY_CANCEL: state->state = STATE_EXIT; return; case 'n': case 'N': case MWKEY_APP1: state->state = STATE_NEWGAME; return; } if(state->state == STATE_STOPPED) return; state->state = STATE_RUNNING; switch(event->ch) { case 'p': case 'P': state->state = STATE_PAUSED; break; case 'j': case 'J': case MWKEY_LEFT: move_block(state, 0); break; case 'k': case 'K': case MWKEY_RIGHT: move_block(state, 1); break; case 'd': case 'D': case MWKEY_UP: rotate_block(state, 0); break; case 'f': case 'F': case MWKEY_DOWN: rotate_block(state, 1); break; case ' ': case MWKEY_MENU: drop_block(state); break; } }
void move_down(void) //블록 밑으로 이동하는 함수 { int i, j; if (crush_on&&check_crush(bx, by + 1, b_rotation) == true) crush_on = 0; //밑이 비어있으면 crush flag 끔 if (crush_on&&check_crush(bx, by + 1, b_rotation) == false) //밑이 비어있지않고 crush flag가 켜저있으면 { for (i = 0; i<height_y; i++) //현재 조작중인 블럭을 굳힘 { for (j = 0; j<width_x; j++) { if (game_scr[i][j] == moving_block) game_scr[i][j] = fixed_block; } } crush_on = 0; //flag를 끔 check_line(); //라인체크를 함 new_block_on = 1; //새로운 블럭생성 flag를 켬 return; //함수 종료 } if (check_crush(bx, by + 1, b_rotation) == true) move_block(DOWN); //밑이 비어있으면 밑으로 한칸 이동 if (check_crush(bx, by + 1, b_rotation) == false) crush_on++; //밑으로 이동이 안되면 crush flag를 켬 }
void drop_block(Block * block, Field field) { if (NULL_BLOCK(*block)) return; while (! NULL_BLOCK(*block)) { move_block(block, 0, 1, field); } }
/* moves down the figure and returns true if gameover */ static void move_down (void) { int l, i, rx, ry; if (!canMoveTo (rockblox_status.cx, rockblox_status.cy + 1, rockblox_status.co)) { /* save figure to board */ for (i = 0; i < 4; i++) { rx = getRelativeX (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cx; ry = getRelativeY (rockblox_status.cf, i, rockblox_status.co) + rockblox_status.cy; rockblox_status.board[ry][rx] = rockblox_status.cf; } /* check if formed some lines */ l = check_lines (); if (l) { /* the original scoring from "http://en.wikipedia.org/wiki/Rockblox" */ rockblox_status.score += scoring[l - 1] * rockblox_status.level; rockblox_status.lines += l; rockblox_status.level = (int) rockblox_status.lines / 10 + 1; } /* show details */ show_details (); /* generate a new figure */ new_block (); } else move_block (0, 1, rockblox_status.co); }
int move_block(int i, int j, int x, int y, int execute) { int newi, newj; newi = i+y; newj = j+x; if(newi < 0 || newi >= 4) return 0; // nao pode escapar do tabuleiro if(newj < 0 || newj >= 4) return 0; if(game.tabuleiro[newi][newj] == 0) { if(!execute) return 1; game.tabuleiro[newi][newj] = game.tabuleiro[i][j]; game.tabuleiro[i][j] = 0; move_block(newi, newj, x, y, execute); return 1; } else if(game.tabuleiro[newi][newj] == game.tabuleiro[i][j]) { if(combinated[newi][newj]) { // combina duas vezes return 0; } else if(!execute) { return 1; } combinated[newi][newj] = 1; game.tabuleiro[newi][newj] = 2*game.tabuleiro[i][j]; game.score += game.tabuleiro[newi][newj]; game.tabuleiro[i][j] = 0; if(game.tabuleiro[newi][newj] == 2048 && game.win == 0) { win(); } return 1; } return 0; }
int main() { /*------------------------------main function------------------------------*/ setcursortype(NOCURSOR); create_world(); int i; srand((unsigned)time(NULL)); for(;;) { ModTick(); check_wall();//checck_crash set_block(); new_block(); check_move();//move_block(); i++; Sleep(1); if (i>399) { i=0; move_block(DOWN); } gotoxy(0,0); printf("%3d",b_x); gotoxy(0,1); printf("%3d",b_y); gotoxy(0,3); printf("%3d",b_type); } gotoxy(0,0); getch(); } /*------------------------------main function------------------------------*/
void game_start_stop(GtkMenuItem *widget, gpointer user_data) { game_play=!game_play; gtk_widget_set_sensitive(GTK_WIDGET(widget), FALSE); if(game_play) { gtk_widget_set_sensitive(menu_game_stop,TRUE); gtk_widget_set_sensitive(menu_game_quick,FALSE); gtk_widget_set_sensitive(menu_game_start,FALSE); gtk_widget_set_sensitive(Start_stop_button,TRUE); gtk_label_set(GTK_LABEL(Start_stop_button_label),start_stop_str[1]); gtk_widget_set_sensitive(Pause_button,TRUE); gtk_widget_grab_default(Pause_button); game_init(); make_noise(options.noise_l,options.noise_h); from_virtual(); move_block(0,0,0); current_level = options.level; update_game_values(0,current_level,0); timer = gtk_timeout_add(level_speeds[current_level],(GtkFunction)game_loop,NULL); } else game_over_init(); }
gint keyboard_event_handler(GtkWidget *widget, GdkEventKey *event, gpointer data) { int dropbonus = 0; if(game_over || game_pause) return FALSE; switch(event->keyval) { case GDK_x: case GDK_X: move_block(0,0,1); event->keyval=0; return TRUE; break; case GDK_w: case GDK_W: case GDK_Up: move_block(0,0,-1); event->keyval=0; return TRUE; break; case GDK_s: case GDK_S: move_down(); event->keyval=0; return TRUE; break; case GDK_a: case GDK_A: case GDK_Left: move_block(-1,0,0); event->keyval=0; return TRUE; break; case GDK_d: case GDK_D: case GDK_Right: move_block(1,0,0); event->keyval=0; return TRUE; break; case GDK_space: case GDK_Down: while(move_down()) dropbonus++; current_score += dropbonus*(current_level+1); update_game_values(); event->keyval=0; return TRUE; break; } return FALSE; }
/*! * @brief ブロックを落下させる * * ブロックの重なりも検出する。 * @see check_overlap() */ static void drop_block(void) { if (!check_overlap(x, y + 1)) { /* 重なりがなければ移動 */ move_block(x, y + 1); } else { /* 重なりがあれば壁にする */ lock_block(); create_block(); show_field(field, MY_FIELD_X); } }
//키 입력받는 함수 void key_ent() { key = 0; if (kbhit()) { key = getch(); if (key == 224) { do { key = getch(); } while (key == 244); switch (key) { case DOWN: { check_crash(b_x, b_y + 1); if (crash_num == 1) move_block(DOWN); break; } case RIGHT: { check_crash(b_x + 1, b_y); if (crash_num == 1) move_block(RIGHT); break; } case LEFT: { check_crash(b_x - 1, b_y); if (crash_num == 1) move_block(LEFT); break; } case UP: { block_turn(temp); break; } default: break; } } else { } } fflush(stdin); }
void check_move() { int k; if(kbhit()) { k=getch(); if(k==224){ while(k==224)break; k=getch(); move_block(k);//gotoxy(0,0);printf("%d",k); }else if(k==32){ /*-------------SPACE BAR-------------*/ }else{} } }
void handle_mouse_event(nstate *state) { GR_EVENT_MOUSE *event = &state->event.mouse; if(event->wid == state->new_game_button) { state->state = STATE_NEWGAME; return; } if(event->wid == state->pause_continue_button) { if(state->state == STATE_PAUSED) state->state = STATE_RUNNING; else state->state = STATE_PAUSED; return; } if(event->wid == state->anticlockwise_button) { if(state->state == STATE_PAUSED) state->state = STATE_RUNNING; rotate_block(state, 0); return; } if(event->wid == state->clockwise_button) { if(state->state == STATE_PAUSED) state->state = STATE_RUNNING; rotate_block(state, 1); return; } if(event->wid == state->left_button) { if(state->state == STATE_PAUSED) state->state = STATE_RUNNING; move_block(state, 0); return; } if(event->wid == state->right_button) { if(state->state == STATE_PAUSED) state->state = STATE_RUNNING; move_block(state, 1); return; } if(event->wid == state->drop_button) { if(state->state == STATE_PAUSED) state->state = STATE_RUNNING; drop_block(state); return; } }
//자동으로 내려가는 부분 void auto_down_blcok(void *p) { Sleep(1000); while (1) { int temp_ = 0; check_crash(b_x, b_y + 1); if(crash_num==1) move_block(DOWN); else { for (int i = 0; i < MAP_Y; i++) for (int j = 0; j < MAP_X; j++) if (main_org[i][j] == ACTIVE_BLOCK) main_org[i][j] = INACTIVE_BLOCK; new_block(); } Sleep(game_speed); } }
gint game_area_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer user_data) { if(!game_over) { from_virtual(); move_block(0,0,0); } else gdk_draw_rectangle(widget->window, widget->style->black_gc, TRUE, 0,0, widget->allocation.width, widget->allocation.height); return FALSE; }
static void check_input(mpGame *g) { int b = SDL_JoystickGetHat(g->stick, 0); if( b & SDL_HAT_LEFT ) { move_left(g); } if(b & SDL_HAT_RIGHT ) { move_right(g); } if(b & SDL_HAT_DOWN) { static int w = 0; if((++w % 4) == 0) move_block(g); } if(b & SDL_HAT_UP) { static int w = 0; if((++w % 8) == 0) shift_blocks(&g->gblock, 0); } }
void game_new_wrapper() { options.level = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin_level)); options.noise_l = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin_noise_level)); options.noise_h = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(spin_noise_height)); gtk_widget_set_sensitive(menu_game_quick,FALSE); gtk_widget_set_sensitive(menu_game_start,FALSE); gtk_widget_set_sensitive(menu_game_stop,TRUE); game_play=!game_play; gtk_label_set(GTK_LABEL(Start_stop_button_label),start_stop_str[1]); gtk_widget_set_sensitive(Pause_button,TRUE); gtk_widget_grab_default(Pause_button); game_init(); make_noise(options.noise_l,options.noise_h); from_virtual(); move_block(0,0,0); current_level = options.level; update_game_values(0,current_level,0); timer = gtk_timeout_add(level_speeds[current_level],(GtkFunction)game_loop,NULL); gtk_widget_hide(new_game_window); }
/*! * @brief キー入力に応じてブロックを処理 * * キー操作により、ブロックの操作を行う * ブロックの移動方法はviエディタに似せた */ static void control_block(void) { switch (getch()) { /* ----- vi風 ----- */ case 'l': if (!check_overlap(x + 1, y)) { move_block(x + 1, y); } break; case 'h': if (!check_overlap(x - 1, y)) { move_block(x - 1, y); } break; case 'j': if (!check_overlap(x, y + 1)) { move_block(x, y + 1); } break; /* ----- Emacs風 ----- */ case CTRL_F: if (!check_overlap(x + 1, y)) { move_block(x + 1, y); } break; case CTRL_B: if (!check_overlap(x - 1, y)) { move_block(x - 1, y); } break; case CTRL_N: if (!check_overlap(x, y + 1)) { move_block(x, y + 1); } break; /* ----- ブロックの回転 ----- */ case 'a': turn_block(RIGHT); break; case 's': turn_block(LEFT); break; case ' ': turn_block(RIGHT); break; } }
int move(int dir, int execute) { int x = 0, y = 0, i, j; // coordenadas para andar int line[4], col[4]; int nummoves = 0; switch(dir) { case KEY_RIGHT: x = 1; break; case KEY_LEFT: x = -1; break; case KEY_UP: y = -1; break; case KEY_DOWN: y = 1; break; } clear_combinated(); set_line_col(line, col, x, y); for(i=0; i<4; i++) { int li; int co; for(j=0; j<4; j++) { li = line[i]; co = col[j]; if(game.tabuleiro[li][co]) { nummoves += move_block(li, co, x, y, execute); // retorna se mveu } } } return nummoves; }
Uint32 PlayerCall(Uint32 interval) { move_block(&game[0]); move_block(&game[1]); return interval; }
void denoise_frame(void) { uint16_t x,y; uint32_t bad_vector = 0; /* adjust contrast for luma and chroma */ contrast_frame(); switch(denoiser.mode) { case 0: /* progressive mode */ { /* deinterlacing wanted ? */ if(denoiser.deinterlace) deinterlace(); /* Generate subsampled images */ subsample_frame (denoiser.frame.sub2ref,denoiser.frame.ref); subsample_frame (denoiser.frame.sub4ref,denoiser.frame.sub2ref); subsample_frame (denoiser.frame.sub2avg,denoiser.frame.avg); subsample_frame (denoiser.frame.sub4avg,denoiser.frame.sub2avg); for(y=32;y<(denoiser.frame.h+32);y+=8) { for(x=0;x<denoiser.frame.w;x+=8) { vector.x=0; vector.y=0; if( !low_contrast_block(x,y) && x>(denoiser.border.x) && y>(denoiser.border.y+32) && x<(denoiser.border.x+denoiser.border.w) && y<(denoiser.border.y+32+denoiser.border.h) ) { mb_search_44(x,y); mb_search_22(x,y); mb_search_11(x,y); if (mb_search_00(x,y) > denoiser.block_thres) bad_vector++; } if ( (vector.x+x)>0 && (vector.x+x)<W && (vector.y+y)>32 && (vector.y+y)<(32+H) ) { move_block(x,y); } else { vector.x=0; vector.y=0; move_block(x,y); } } } /* scene change? */ if ( denoiser.do_reset && denoiser.frame.w*denoiser.frame.h*denoiser.scene_thres/(64*100) < bad_vector) { denoiser.reset = denoiser.do_reset; } bad_vector = 0; average_frame(); correct_frame2(); denoise_frame_pass2(); sharpen_frame(); black_border(); ac_memcpy(denoiser.frame.avg[Yy],denoiser.frame.tmp[Yy],denoiser.frame.w*(denoiser.frame.h+64)); ac_memcpy(denoiser.frame.avg[Cr],denoiser.frame.tmp[Cr],denoiser.frame.w*(denoiser.frame.h+64)/4); ac_memcpy(denoiser.frame.avg[Cb],denoiser.frame.tmp[Cb],denoiser.frame.w*(denoiser.frame.h+64)/4); break; } case 1: /* interlaced mode */ { /* Generate subsampled images */ subsample_frame (denoiser.frame.sub2ref,denoiser.frame.ref); subsample_frame (denoiser.frame.sub4ref,denoiser.frame.sub2ref); subsample_frame (denoiser.frame.sub2avg,denoiser.frame.avg); subsample_frame (denoiser.frame.sub4avg,denoiser.frame.sub2avg); /* process the fields as two seperate images */ denoiser.frame.h /= 2; denoiser.frame.w *= 2; /* if lines are twice as wide as normal the offset is only 16 lines * despite 32 in progressive mode... */ for(y=16;y<(denoiser.frame.h+16);y+=8) for(x=0;x<denoiser.frame.w;x+=8) { vector.x=0; vector.y=0; if(!low_contrast_block(x,y) && x>(denoiser.border.x) && y>(denoiser.border.y+32) && x<(denoiser.border.x+denoiser.border.w) && y<(denoiser.border.y+32+denoiser.border.h) ) { mb_search_44(x,y); mb_search_22(x,y); mb_search_11(x,y); mb_search_00(x,y); } if ( (vector.x+x)>0 && (vector.x+x)<W && (vector.y+y)>32 && (vector.y+y)<(32+H) ) { move_block(x,y); } else { vector.x=0; vector.y=0; move_block(x,y); } } /* process the fields in one image again */ denoiser.frame.h *= 2; denoiser.frame.w /= 2; average_frame(); correct_frame2(); denoise_frame_pass2(); sharpen_frame(); black_border(); ac_memcpy(denoiser.frame.avg[0],denoiser.frame.tmp[0],denoiser.frame.w*(denoiser.frame.h+64)); ac_memcpy(denoiser.frame.avg[1],denoiser.frame.tmp[1],denoiser.frame.w*(denoiser.frame.h+64)/4); ac_memcpy(denoiser.frame.avg[2],denoiser.frame.tmp[2],denoiser.frame.w*(denoiser.frame.h+64)/4); break; } case 2: /* PASS II only mode */ { /* deinterlacing wanted ? */ if(denoiser.deinterlace) deinterlace(); /* as the normal denoising functions are not used we need to copy ... */ ac_memcpy(denoiser.frame.tmp[0],denoiser.frame.ref[0],denoiser.frame.w*(denoiser.frame.h+64)); ac_memcpy(denoiser.frame.tmp[1],denoiser.frame.ref[1],denoiser.frame.w*(denoiser.frame.h+64)/4); ac_memcpy(denoiser.frame.tmp[2],denoiser.frame.ref[2],denoiser.frame.w*(denoiser.frame.h+64)/4); denoise_frame_pass2(); sharpen_frame(); black_border(); break; } } }
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 play_game(struct thread_data *data) { int status; input_t input; int did_user_quit = 0; /* 0 if game-over, otherwise if user quits */ while (1) { /* take user input */ input = fetch_user_input(); if (input == INPUT_INVALID) continue; pthread_mutex_lock(&data->lock); /* check if the game is still going on */ if (data->game_over) { pthread_mutex_unlock(&data->lock); break; } /* in case there's no "current block", don't do anything */ if (input != INPUT_PAUSE_QUIT && (data->block_dropped_ignore_input || !data->current)) { pthread_mutex_unlock(&data->lock); continue; } /* take appropriate action based on user input */ switch (input) { case INPUT_MOVE_LEFT: status = move_block(data->current, ACTION_MOVE_LEFT); if (status == SUCCESS) draw_game_board(data->current); break; case INPUT_MOVE_RIGHT: status = move_block(data->current, ACTION_MOVE_RIGHT); if (status == SUCCESS) draw_game_board(data->current); break; case INPUT_MOVE_DOWN: status = move_block(data->current, ACTION_MOVE_DOWN); if (status == SUCCESS) draw_game_board(data->current); break; case INPUT_MOVE_UP_DROP: status = move_block(data->current, ACTION_MOVE_UP_DROP); if (status == SUCCESS) { data->block_dropped_ignore_input = 1; draw_game_board(data->current); } break; case INPUT_ROTATE_LEFT: status = move_block(data->current, ACTION_ROTATE_LEFT); if (status == SUCCESS) draw_game_board(data->current); break; case INPUT_ROTATE_RIGHT: status = move_block(data->current, ACTION_ROTATE_RIGHT); if (status == SUCCESS) draw_game_board(data->current); break; case INPUT_PAUSE_QUIT: status = display_quit_dialog(); draw_game_board(data->current); if (status == FAILURE) { /* if the user chooses to quit */ data->game_over = 1; did_user_quit = 1; } break; case INPUT_TIMEOUT: /* nothing to do */ break; default: break; } pthread_mutex_unlock(&data->lock); } draw_gameover(did_user_quit); }
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; }
/* Compact allocations and handle table, adjusting handle pointers as needed. * Return true if any space was freed or consolidated, false otherwise. */ static bool buflib_compact(struct buflib_context *ctx) { BDEBUGF("%s(): Compacting!\n", __func__); union buflib_data *block, *hole = NULL; int shift = 0, len; /* Store the results of attempting to shrink the handle table */ bool ret = handle_table_shrink(ctx); /* compaction has basically two modes of operation: * 1) the buffer is nicely movable: In this mode, blocks can be simply * moved towards the beginning. Free blocks add to a shift value, * which is the amount to move. * 2) the buffer contains unmovable blocks: unmovable blocks create * holes and reset shift. Once a hole is found, we're trying to fill * holes first, moving by shift is the fallback. As the shift is reset, * this effectively splits the buffer into portions of movable blocks. * This mode cannot be used if no holes are found yet as it only works * when it moves blocks across the portions. On the other side, * moving by shift only works within the same portion * For simplicity only 1 hole at a time is considered */ for(block = find_first_free(ctx); block < ctx->alloc_end; block += len) { bool movable = true; /* cache result to avoid 2nd call to move_block */ len = block->val; /* This block is free, add its length to the shift value */ if (len < 0) { shift += len; len = -len; continue; } /* attempt to fill any hole */ if (hole && -hole->val >= len) { intptr_t hlen = -hole->val; if ((movable = move_block(ctx, block, hole - block))) { ret = true; /* Move was successful. The memory at block is now free */ block->val = -len; /* add its length to shift */ shift += -len; /* Reduce the size of the hole accordingly * but be careful to not overwrite an existing block */ if (hlen != len) { hole += len; hole->val = len - hlen; /* negative */ } else /* hole closed */ hole = NULL; continue; } } /* attempt move the allocation by shift */ if (shift) { union buflib_data* target_block = block + shift; if (!movable || !move_block(ctx, block, shift)) { /* free space before an unmovable block becomes a hole, * therefore mark this block free and track the hole */ target_block->val = shift; hole = target_block; shift = 0; } else ret = true; } } /* Move the end-of-allocation mark, and return true if any new space has * been freed. */ ctx->alloc_end += shift; ctx->compact = true; return ret || shift; }