Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // LICENSE - WTFPL
- #include <stdlib.h>
- #include <stdio.h>
- #include <stdbool.h>
- #include <xcb/xcb.h>
- #include <inttypes.h>
- #define WIN_W 800
- #define WIN_H 800
- #define BOARD_W 30
- #define BOARD_H 30
- #define TILE_W 20
- #define TILE_H 20
- #define START_DR_X 20
- #define START_DR_Y 20
- xcb_point_t coord_to_num(int x, int y)
- {
- x -= START_DR_X;
- y -= START_DR_Y;
- if
- (
- (x < 0) || (x >= (BOARD_W*TILE_W) ) ||
- (y < 0) || (y >= (BOARD_H*TILE_H) )
- )
- {
- return (xcb_point_t){-1, -1};
- }
- //printf("%i %i\n", x, y);
- return (xcb_point_t){(x/TILE_W), (y/TILE_H)};
- }
- void draw_board(xcb_connection_t *connection, xcb_drawable_t window, xcb_gcontext_t foreground)
- {
- int shell_w = TILE_W * BOARD_W;
- int shell_h = TILE_H * BOARD_H;
- int shell_x = START_DR_X;
- int shell_y = START_DR_Y;
- xcb_rectangle_t shell[] =
- {
- {shell_x, shell_y, shell_w, shell_h},
- };
- uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
- uint32_t color[2] = {0x000000, 0};
- xcb_change_gc (connection, foreground, mask, color);
- xcb_poly_rectangle(connection, window, foreground, 1, shell);
- for (int i = 1; i < BOARD_W; ++i)
- {
- xcb_point_t line[] = {{shell_x + i*TILE_W, shell_y}, {0, shell_h}};
- xcb_poly_line (connection, XCB_COORD_MODE_PREVIOUS, window, foreground, 2, line);
- }
- for (int i = 1; i < BOARD_H; ++i)
- {
- xcb_point_t line[] = {{shell_x, shell_y + i*TILE_H}, {shell_w, 0}};
- xcb_poly_line (connection, XCB_COORD_MODE_PREVIOUS, window, foreground, 2, line);
- }
- }
- // указатель на ф-цию которая рисует крестик или нолик
- typedef void (*draw_func)(xcb_connection_t *, xcb_drawable_t, xcb_gcontext_t , xcb_point_t);
- typedef struct
- {
- draw_func func;
- xcb_point_t point;
- } draw_this;
- typedef struct
- {
- draw_func func;
- char* name;
- } Player;
- void draw_smth(draw_this drw, xcb_connection_t *connection, xcb_drawable_t window, xcb_gcontext_t foreground)
- {
- drw.func(connection, window, foreground, drw.point);
- }
- void draw_all_figures(draw_this *drw, size_t num_figures, xcb_connection_t *connection, xcb_drawable_t window, xcb_gcontext_t foreground)
- {
- for(size_t i = 0; i < num_figures; i++)
- {
- draw_smth(drw[i], connection, window, foreground);
- }
- }
- void draw_circle(xcb_connection_t *connection, xcb_drawable_t window, xcb_gcontext_t foreground, xcb_point_t point)
- {
- xcb_arc_t arcs[] = {{point.x, point.y, TILE_W, TILE_H, 0, (360 << 6)}};
- xcb_poly_arc (connection, window, foreground, 1, arcs);
- }
- void draw_cross(xcb_connection_t *connection, xcb_drawable_t window, xcb_gcontext_t foreground, xcb_point_t point)
- {
- xcb_point_t line[] = {{point.x, point.y}, {TILE_W, TILE_H}};
- xcb_point_t line2[] = {{point.x, point.y + TILE_H}, {TILE_W, -TILE_H}};
- xcb_poly_line (connection, XCB_COORD_MODE_PREVIOUS, window, foreground, 2, line);
- xcb_poly_line (connection, XCB_COORD_MODE_PREVIOUS, window, foreground, 2, line2);
- }
- void* create_board()
- {
- int (* board)[BOARD_H][BOARD_W] = malloc( sizeof(int) * BOARD_W * BOARD_H);
- if (board)
- {
- for (size_t i = 0; i < BOARD_W; ++i)
- {
- //board[i] = malloc(sizeof *board[i] * BOARD_H);
- for (size_t j = 0; j < BOARD_H; ++j)
- {
- (*board)[i][j] = -1; // empty tile
- // тут вообще можно сделать одним for-ом т.к. этот массив board[][] идет непрерывным куском
- }
- }
- }
- return board;
- }
- int main(int argc, char const *argv[])
- {
- xcb_connection_t *connection = xcb_connect (NULL, NULL);
- /* Get the first screen */
- xcb_screen_t *screen = xcb_setup_roots_iterator (xcb_get_setup (connection)).data;
- /* Create black (foreground) graphic context */
- xcb_drawable_t window = screen->root;
- xcb_gcontext_t foreground = xcb_generate_id (connection);
- uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
- uint32_t values[2] = {0xff0000, 0};
- xcb_create_gc (connection, foreground, window, mask, values);
- window = xcb_generate_id (connection);
- mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
- values[0] = screen->white_pixel;
- //values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW | XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_KEY_RELEASE; не нужно столько эвентов, достаточно EXPOSURE и BUTTON_PRESS
- values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS ;
- xcb_create_window(
- connection, /* connection */
- XCB_COPY_FROM_PARENT, /* depth */
- window, /* window Id */
- screen->root, /* parent window */
- 0, 0, /* x, y */
- WIN_W, WIN_H, /* width, height */
- 10, /* border_width */
- XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
- screen->root_visual, /* visual */
- mask, values /* masks */
- );
- xcb_map_window (connection, window);
- xcb_flush (connection);
- int (*board)[BOARD_H][BOARD_W] = create_board();
- xcb_generic_event_t *event;
- draw_this figures[BOARD_W*BOARD_H]; size_t num_figures = 0;
- xcb_point_t point;
- bool turn = false;
- Player players[2] = { {draw_cross, "Cross"}, {draw_circle, "Circle"} };
- while ((event = xcb_wait_for_event (connection)))
- {
- switch (event->response_type & ~0x80)
- {
- case XCB_EXPOSE:
- draw_board(connection, window, foreground);
- draw_all_figures(figures, num_figures, connection, window, foreground);
- xcb_flush (connection);
- case XCB_BUTTON_PRESS:
- {
- xcb_button_press_event_t *bp = (xcb_button_press_event_t *)event;
- //switch (bp->detail) // НЕНУЖНО Т.К. ТОЛЬКО ОДНА ШТУКА default В switch
- //{
- // default:
- ;
- /*printf ("Button %"PRIu8" pressed in window %"PRIu32", at coordinates (%"PRIi16",%"PRIi16")\n",
- bp->detail, bp->event, bp->event_x, bp->event_y );*/
- //xcb_point_t click = click_on_board(bp->event_x, bp->event_y, hitboxes);
- xcb_point_t click = coord_to_num(bp->event_x, bp->event_y);
- if ((click.x != -1) && ((*board)[click.x][click.y] == -1))
- {
- (*board)[click.x][click.y] = turn;
- figures[num_figures] = (draw_this){ players[turn].func, {click.x * TILE_W + START_DR_X, click.y*TILE_H + START_DR_Y}};
- num_figures++;
- players[turn].func(connection, window, foreground, (xcb_point_t){click.x * TILE_W + START_DR_Y, click.y * TILE_H + START_DR_Y} );
- xcb_flush (connection);
- (*board)[click.x][click.y] = turn;
- turn = !turn;
- }
- /*
- if (click.x != -1 && click.y != -1)
- {
- if ((*board)[click.x][click.y] == -1)
- {
- printf(
- "%" PRId16" %" PRId16" -- %" PRId16" %" PRId16"\n",
- click.x, click.y, bp->event_x, bp->event_y
- );
- (*board)[click.x][click.y] = turn; // это помечает что тут крестик или нолик
- figures[num_figures] = (draw_this){ players[turn].func, {hitboxes[click.x][click.y].x, hitboxes[click.x][click.y].y}};
- num_figures++;
- players[turn].func(connection, window, foreground, (xcb_point_t){hitboxes[click.x][click.y].x, hitboxes[click.x][click.y].y} );
- xcb_flush (connection);
- (*board)[click.x][click.y] = turn;
- turn = !turn;
- }
- }
- */
- //}
- }
- default:
- break;
- }
- free(event);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment