From cb7ab67abdb129b404060310ae28eb7159b2abb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arkadiusz=20Rychli=C5=84ski?= Date: Sun, 7 Apr 2024 12:46:33 +0200 Subject: [PATCH] Clumsy animation Program can change the content of the surface. --- CMakeLists.txt | 9 ++-- include/puzzle.h | 10 ++++ tetris.c | 116 ++++++++++++++++++++++++++++++++--------------- 3 files changed, 95 insertions(+), 40 deletions(-) create mode 100644 include/puzzle.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 86d9ff8..f277b0a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,15 +24,18 @@ set(SOURCES ) # Dodaj pliki nagłówkowe do źródeł tetris -set(HEADERS +set(GENHEADERS ${CMAKE_CURRENT_BINARY_DIR}/include/xdg-shell.h ) # Kompilacja -add_executable(tetris ${SOURCES} ${HEADERS}) +add_executable(tetris ${SOURCES} ${GENHEADERS}) # Dodaj pliki nagłówkowe do kompilacji -target_include_directories(tetris PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include) +target_include_directories(tetris + PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include +) # Dodanie biblioteki wayland-client target_link_libraries(tetris wayland-client) diff --git a/include/puzzle.h b/include/puzzle.h new file mode 100644 index 0000000..a115ab6 --- /dev/null +++ b/include/puzzle.h @@ -0,0 +1,10 @@ +#ifndef PUZZLE_H +#define PUZZLE_H + +struct puzzle { + int with; + int height; + unsigned char *data; +}; + +#endif diff --git a/tetris.c b/tetris.c index c22d4d3..a495bce 100644 --- a/tetris.c +++ b/tetris.c @@ -10,12 +10,26 @@ #include #include +#include + struct wl_compositor *compositor; struct wl_shm *shm; struct xdg_wm_base *xdg_shell; struct wl_seat *wl_seat; int running = 1; +int released = 0; + +struct canvas +{ + int width; + int height; + int stride; + int size; + struct wl_buffer *buffer; + unsigned char *data; + struct wl_surface *surface; +} canvas; // registry void registry_global_handler( @@ -103,12 +117,22 @@ void xdg_wm_base_ping_handler(void *data, struct xdg_wm_base *xdg_shell, uint32_t serial) { xdg_wm_base_pong(xdg_shell, serial); - printf("wm_base ping-pong\n"); + // printf("wm_base ping-pong\n"); } const struct xdg_wm_base_listener xdg_shell_listener = { .ping = xdg_wm_base_ping_handler}; + +void wl_buffer_release_handler(void *data, struct wl_buffer * wl_buffer) { + printf("wl_buffer_release\n"); + released = 1; +} + +const struct wl_buffer_listener wl_buffer_listener = { + .release = wl_buffer_release_handler}; + +void redraw(); // main int main(void) @@ -122,45 +146,76 @@ int main(void) xdg_wm_base_add_listener(xdg_shell, &xdg_shell_listener, NULL); - struct wl_surface *surface = wl_compositor_create_surface(compositor); - struct xdg_surface *xdg_surface = xdg_wm_base_get_xdg_surface(xdg_shell, surface); + canvas.surface = wl_compositor_create_surface(compositor); + struct xdg_surface *xdg_surface = xdg_wm_base_get_xdg_surface(xdg_shell, canvas.surface); struct xdg_toplevel *xdg_toplevel = xdg_surface_get_toplevel(xdg_surface); xdg_surface_add_listener(xdg_surface, &xdg_surface_listener, NULL); xdg_toplevel_add_listener(xdg_toplevel, &xdg_toplevel_listener, NULL); - xdg_toplevel_set_app_id(xdg_toplevel, "ark-1"); + xdg_toplevel_set_app_id(xdg_toplevel, "eu.ar76.tetris"); xdg_toplevel_set_title(xdg_toplevel, "Ark Jeden."); // signal that the surface is ready to be configured - wl_surface_commit(surface); + wl_surface_commit(canvas.surface); struct wl_keyboard *wl_keyboard = wl_seat_get_keyboard(wl_seat); - int width = 600; - int height = 800; - int stride = width * 4; - int size = stride * height; // bytes + canvas.width = 600; + canvas.height = 800; + canvas.stride = canvas.width * 4; + canvas.size = canvas.stride * canvas.height; // bytes // open an anonymous file and write some zero bytes to it int fd = syscall(SYS_memfd_create, "buffer", 0); - ftruncate(fd, size); + ftruncate(fd, canvas.size); // map it to the memory - unsigned char *data = - mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + canvas.data = + mmap(NULL, canvas.size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); // turn it into a shared memory pool - struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, size); + struct wl_shm_pool *pool = wl_shm_create_pool(shm, fd, canvas.size); + + close(fd); // mapped, so can be closed // allocate the buffer in that pool - struct wl_buffer *buffer = wl_shm_pool_create_buffer( - pool, 0, width, height, stride, WL_SHM_FORMAT_ARGB8888); + canvas.buffer = wl_shm_pool_create_buffer( + pool, 0, canvas.width, canvas.height, canvas.stride, WL_SHM_FORMAT_ARGB8888); - // draw into buffer - for (int x = 0; x < width; x++) + wl_buffer_add_listener(canvas.buffer, &wl_buffer_listener, NULL); + // wait for the surface to be configured + wl_display_roundtrip(display); + + redraw(); + + int counter = 0; + while (wl_display_dispatch(display) != -1 && running) { - for (int y = 0; y < height; y++) + // nothing inside + if (released && ++counter > 10) { + redraw(); + released = 0; + counter = 0; + } + } + + xdg_toplevel_destroy(xdg_toplevel); + xdg_surface_destroy(xdg_surface); + wl_surface_destroy(canvas.surface); + wl_shm_pool_destroy(pool); + wl_registry_destroy(registry); +} + +unsigned char dred = 1; +void redraw() +{ + dred = 1-dred; + printf("dred=%d\n", dred); + // draw into buffer + for (int x = 0; x < canvas.width; x++) + { + for (int y = 0; y < canvas.height; y++) { struct pixel @@ -170,7 +225,7 @@ int main(void) unsigned char green; unsigned char red; unsigned char alpha; - } *px = (struct pixel *)(data + y * stride + x * 4); + } *px = (struct pixel *)(canvas.data + y * canvas.stride + x * 4); // draw a stripes pattern if ((x + y) % 30 < 10) @@ -190,27 +245,14 @@ int main(void) { // semitransparent red px->alpha = 128; - px->red = 255; + px->red = dred * 255; px->green = 0; - px->blue = 0; + px->blue = (1 - dred) * 255; } } } - // wait for the surface to be configured - wl_display_roundtrip(display); - - wl_surface_attach(surface, buffer, 0, 0); - wl_surface_damage(surface, 0, 0, UINT32_MAX, UINT32_MAX); - wl_surface_commit(surface); - - while (wl_display_dispatch(display) != -1 && running) - { - // nothing inside - } - - xdg_toplevel_destroy(xdg_toplevel); - xdg_surface_destroy(xdg_surface); - wl_surface_destroy(surface); - wl_registry_destroy(registry); + wl_surface_attach(canvas.surface, canvas.buffer, 0, 0); + wl_surface_damage(canvas.surface, 0, 0, canvas.width, canvas.height); + wl_surface_commit(canvas.surface); }