int do_test_rectangles(const char *test_parm) { (void) test_parm; rect_t out1, out2, oldw, neww; oldw.x = 1; oldw.y = 1; oldw.xsize = 10; oldw.ysize = 10; neww.x = 2; neww.y = 2; neww.xsize = 10; neww.ysize = 10; //int o2 = rect_sub( &out1, &out2, &oldw, &neww ); //rect_dump( &out1 ); //rect_dump( &out2 ); test_check_eq(out1.x,1); test_check_eq(out1.y,1); test_check_eq(out1.xsize,1); test_check_eq(out1.ysize,10); test_check_eq(out2.x,1); test_check_eq(out2.y,1); test_check_eq(out2.xsize,10); test_check_eq(out2.ysize,1); rect_t a, b; a.x = 10; a.y = 10; a.xsize = 10; a.ysize = 10; b.x = 15; b.y = 15; b.xsize = 10; b.ysize = 10; test_check_false( rect_includes( &a, &b ) ); test_check_true( rect_intersects( &a, &b ) ); b.xsize = 2; b.ysize = 2; test_check_true( rect_includes( &a, &b ) ); test_check_true( rect_intersects( &a, &b ) ); b.x = 35; b.y = 35; test_check_false( rect_includes( &a, &b ) ); test_check_false( rect_intersects( &a, &b ) ); return 0; }
// Subtract rectangle from q void paint_q_sub( rect_t *r ) { pqel_t *pqel; ASSERT_LOCKED_MUTEX( &rect_list_lock ); again: queue_iterate( &rect_list, pqel, pqel_t *, chain ) { // r includes qe - delete qe if( rect_includes( r, &pqel->r ) ) { queue_remove( &rect_list, pqel, pqel_t *, chain ); goto again; } // r intersects w qe - divide in two if( rect_intersects( r, &pqel->r ) ) { rect_t out1, out2; rect_sub( &out1, &out2, r, &pqel->r ); if( !rect_empty( &out1 ) ) { pqel_t *new1 = mkel( &out1 ); if( !new1 ) return; queue_enter(&rect_list, new1, pqel_t *, chain); }
void paint_q_add( rect_t *r ) { hal_mutex_lock( &rect_list_lock ); pqel_t *new_el = mkel( r ); // Don't die, just let some garbage onscreen? if(0 == new_el) return; hal_sem_release( &painter_sem ); if(paint_q_empty()) { queue_enter(&rect_list, new_el, pqel_t *, chain); goto finish; } pqel_t *pqel; again: queue_iterate( &rect_list, pqel, pqel_t *, chain ) { // r includes qe - delete qe if( rect_includes( r, &pqel->r ) ) { queue_remove( &rect_list, pqel, pqel_t *, chain ); goto again; } // qe includes r - skip addition if( rect_includes( &pqel->r, r ) ) { free( new_el ); goto finish; } }
int main(int argc, char **argv) { int return_status = 1; #define MAIN_SDL_CHECK(expression, error_prefix) { \ if (!(expression)) { \ log_error(error_prefix, SDL_GetError()); \ goto exit; \ } \ } MAIN_SDL_CHECK(SDL_Init(SDL_INIT_VIDEO) == 0, "SDL_Init"); if (IMG_Init(IMG_INIT_PNG) != IMG_INIT_PNG) { log_error("IMG_Init", IMG_GetError()); goto exit; } MAIN_SDL_CHECK(SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "2"), "SDL_SetHint SDL_HINT_RENDER_SCALE_QUALITY"); startup_info_t info = startup(argc, argv); if (!info.success) goto exit; net_mode_t net_mode = info.net_mode; network = info.network; char wtitle[256]; if (net_mode == NET_SERVER) { snprintf(wtitle, sizeof(wtitle), "NetCheckers - server (%s)", info.port); } else { snprintf(wtitle, sizeof(wtitle), "NetCheckers - client (%s:%s)", info.host, info.port); } window = SDL_CreateWindow( wtitle, #if 1 SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, #else (net_mode == NET_SERVER ? 10 : window_width + 20), SDL_WINDOWPOS_CENTERED, #endif window_width, window_height, SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI ); MAIN_SDL_CHECK(window, "SDL_CreateWindow"); renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); MAIN_SDL_CHECK(renderer, "SDL_CreateRenderer"); MAIN_SDL_CHECK(SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND) == 0, "SDL_SetRenderDrawBlendMode SDL_BLENDMODE_BLEND"); char *error = 0; char path[1024]; #define LOAD_TEXTURE_CHECKED(var, file) { \ sprintf(path, "%s/" file, info.assets_path); \ var = load_png_texture(path, &error); \ if (error) { \ log_error("load_png_texture " file, error); \ goto exit; \ } \ } LOAD_TEXTURE_CHECKED(tex.textures.board, "board.png"); LOAD_TEXTURE_CHECKED(tex.textures.red_piece, "piece_red.png"); LOAD_TEXTURE_CHECKED(tex.textures.red_piece_king, "piece_red_king.png"); LOAD_TEXTURE_CHECKED(tex.textures.white_piece, "piece_white.png"); LOAD_TEXTURE_CHECKED(tex.textures.white_piece_king, "piece_white_king.png"); LOAD_TEXTURE_CHECKED(tex.textures.highlight, "highlight.png"); LOAD_TEXTURE_CHECKED(tex.textures.player_turn, "player_turn.png"); LOAD_TEXTURE_CHECKED(tex.textures.opponent_turn, "opponent_turn.png"); LOAD_TEXTURE_CHECKED(tex.textures.victory, "victory.png"); LOAD_TEXTURE_CHECKED(tex.textures.defeat, "defeat.png"); window_resized(window_width, window_height); // Put the pieces on the board #if 0 // Game over testing for (int i = 0; i < 24; i++) { piece_t *piece = pieces + i; piece->color = (i >= 12) ? PIECE_BLACK : PIECE_WHITE; piece->captured = true; } pieces[0].captured = false; pieces[0].king = true; pieces[0].pos = cell_pos(1, 3); board[1][3] = &pieces[0]; pieces[12].captured = false; pieces[12].king = true; pieces[12].pos = cell_pos(5, 3); board[5][3] = &pieces[12]; #else int fill_row = 0; int fill_col = 0; for (int i = 0; i < 12; i++) { piece_t *piece = pieces + i; piece->color = PIECE_WHITE; piece->pos = cell_pos(fill_row, fill_col); board[fill_row][fill_col] = piece; advance_board_row_col(&fill_row, &fill_col); } fill_row = 5; fill_col = 1; for (int i = 12; i < 24; i++) { piece_t *piece = pieces + i; piece->color = PIECE_BLACK; piece->pos = cell_pos(fill_row, fill_col); board[fill_row][fill_col] = piece; advance_board_row_col(&fill_row, &fill_col); } #endif game_over = false; current_turn = PIECE_BLACK; local_color = (net_mode == NET_SERVER) ? PIECE_BLACK : PIECE_WHITE; bool running = true; int last_time = SDL_GetTicks(); while (running) { int current_time = SDL_GetTicks(); int ellapsed_ms = current_time - last_time; last_time = current_time; float delta_time = (float)ellapsed_ms / 1000.0f; SDL_Event event = {0}; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: { running = false; } break; case SDL_WINDOWEVENT: { if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { window_resized(event.window.data1, event.window.data2); } } break; case SDL_MOUSEBUTTONDOWN: { #if 1 if (event.button.state == SDL_PRESSED && event.button.button == SDL_BUTTON_RIGHT) { message_t net_msg = {0}; net_msg.move_piece = cell_pos(5, 1); net_msg.move_target = cell_pos(4, 0); net_send_message(network, &net_msg); } #endif if (event.button.state == SDL_PRESSED && event.button.button == SDL_BUTTON_LEFT) { if (!game_over && !animating_piece && current_turn == local_color) { int click_x = event.button.x * dpi_rate; int click_y = event.button.y * dpi_rate; if (rect_includes(&board_rect, click_x, click_y)) { cell_pos_t clicked_cell = point_to_cell(click_x, click_y); piece_t *clicked_piece = board[clicked_cell.row][clicked_cell.col]; if (clicked_piece && clicked_piece->color == current_turn) { piece_moves_t moves = find_valid_moves(clicked_piece); if (moves.count) { selected_piece = clicked_piece; available_moves = moves; } } else if (selected_piece) { cell_pos_t from_cell = selected_piece->pos; move_result_t res = perform_move(selected_piece, clicked_cell); if (res != MOVE_INVALID) { if (res == MOVE_END_TURN) { selected_piece = 0; } else { available_moves = find_valid_moves(selected_piece); } message_t net_msg = {0}; net_msg.move_piece = from_cell; net_msg.move_target = clicked_cell; if (!net_send_message(network, &net_msg)) { int err = SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Erro - Falha de comunicação", "Falha ao enviar movimento para o adversário.", window ); if (err) { log_error("SDL_ShowSimpleMessageBox invalid movement", SDL_GetError()); } goto exit; } } } } } } } break; } } if (net_get_state(network) != NET_RUNNING) { int err = SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Erro - Conexão Interrompida", "A conexão foi interrompida pelo adversário", window ); if (err) { log_error("SDL_ShowSimpleMessageBox invalid movement", SDL_GetError()); } goto exit; } message_t net_msg; if (net_poll_message(network, &net_msg)) { bool valid_move = false; piece_t *piece = board[net_msg.move_piece.row][net_msg.move_piece.col]; if (piece && current_turn != local_color && piece->color != local_color) { move_result_t res = perform_move(piece, net_msg.move_target); if (res != MOVE_INVALID) valid_move = true; } if (!valid_move) { int err = SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Erro - Movimento inválido", "Seu adversário enviou um movimento inválido.", window ); if (err) { log_error("SDL_ShowSimpleMessageBox invalid movement", SDL_GetError()); } goto exit; } } render(delta_time); } return_status = 0; exit: if (network) net_destroy(network); for (int i = 0; i < ARRAY_SIZE(tex.array); i++) { if (tex.array[i]) SDL_DestroyTexture(tex.array[i]); } if (renderer) SDL_DestroyRenderer(renderer); if (window) SDL_DestroyWindow(window); IMG_Quit(); SDL_Quit(); return return_status; }