mirror of
https://git.sr.ht/~leon_plickat/wayneko
synced 2025-09-19 16:03:22 +02:00
let neko run around
This commit is contained in:
parent
c48484663c
commit
abba39daf9
1 changed files with 126 additions and 37 deletions
161
wayneko.c
161
wayneko.c
|
@ -22,12 +22,17 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#define MIN(A, B) (A < B ? A : B)
|
||||
|
||||
#include "wlr-layer-shell-unstable-v1.h"
|
||||
|
||||
pixman_color_t bg_colour;
|
||||
pixman_color_t border_colour;
|
||||
|
||||
/* Note: Atlas width must be divisable by 4. */
|
||||
#include "neko-bitmap.xbm"
|
||||
const int neko_bitmap_stride = neko_bitmap_width / 8;
|
||||
const int neko_size = 32;
|
||||
const uint8_t neko_size = 32;
|
||||
pixman_image_t *neko_atlas = NULL;
|
||||
pixman_image_t *neko_atlas_bg_fill = NULL;
|
||||
pixman_image_t *neko_atlas_border_fill = NULL;
|
||||
|
@ -70,14 +75,15 @@ struct Surface
|
|||
{
|
||||
struct wl_surface *wl_surface;
|
||||
struct zwlr_layer_surface_v1 *layer_surface;
|
||||
uint32_t width, height;
|
||||
uint16_t neko_x, prev_neko_x;
|
||||
bool configured;
|
||||
};
|
||||
|
||||
struct Surface surface = { 0 };
|
||||
|
||||
// TODO wide surface and let the neko run around.
|
||||
const uint32_t surface_width = neko_size;
|
||||
const uint32_t surface_height = neko_size;
|
||||
const uint32_t desired_surface_height = neko_size;
|
||||
const uint8_t neko_x_advance = 15;
|
||||
|
||||
int ret = EXIT_SUCCESS;
|
||||
bool loop = true;
|
||||
|
@ -429,25 +435,6 @@ static void buffer_pool_destroy_all_buffers (void)
|
|||
* Atlas *
|
||||
* *
|
||||
***********/
|
||||
static bool colour_from_hex (pixman_color_t *colour, const char *hex)
|
||||
{
|
||||
uint16_t r = 0, g = 0, b = 0, a = 255;
|
||||
|
||||
if ( 4 != sscanf(hex, "0x%02hx%02hx%02hx%02hx", &r, &g, &b, &a)
|
||||
&& 3 != sscanf(hex, "0x%02hx%02hx%02hx", &r, &g, &b) )
|
||||
{
|
||||
fprintf(stderr, "ERROR: Invalid colour: %s\n", hex);
|
||||
return false;
|
||||
}
|
||||
|
||||
colour->alpha = (uint16_t)(((double)a / 255.0) * 65535.0);
|
||||
colour->red = (uint16_t)((((double)r / 255.0) * 65535.0) * colour->alpha / 0xffff);
|
||||
colour->green = (uint16_t)((((double)g / 255.0) * 65535.0) * colour->alpha / 0xffff);
|
||||
colour->blue = (uint16_t)((((double)b / 255.0) * 65535.0) * colour->alpha / 0xffff);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void atlas_deinit (void)
|
||||
{
|
||||
if ( neko_atlas != NULL )
|
||||
|
@ -482,8 +469,6 @@ static bool atlas_init (void)
|
|||
return false;
|
||||
}
|
||||
|
||||
pixman_color_t bg_colour;
|
||||
colour_from_hex(&bg_colour, "0xFFFFFF");
|
||||
neko_atlas_bg_fill = pixman_image_create_solid_fill(&bg_colour);
|
||||
if ( neko_atlas_bg_fill == NULL )
|
||||
{
|
||||
|
@ -492,8 +477,6 @@ static bool atlas_init (void)
|
|||
return false;
|
||||
}
|
||||
|
||||
pixman_color_t border_colour;
|
||||
colour_from_hex(&border_colour, "0x000000");
|
||||
neko_atlas_border_fill = pixman_image_create_solid_fill(&border_colour);
|
||||
if ( neko_atlas_border_fill == NULL )
|
||||
{
|
||||
|
@ -537,6 +520,16 @@ static void atlas_composite_neko (struct Buffer *buffer, enum Neko neko_type, ui
|
|||
);
|
||||
}
|
||||
|
||||
static bool animation_can_run_left (void)
|
||||
{
|
||||
return surface.neko_x > neko_x_advance;
|
||||
}
|
||||
|
||||
static bool animation_can_run_right (void)
|
||||
{
|
||||
return surface.neko_x < surface.width - neko_size;
|
||||
}
|
||||
|
||||
/** Returns true if new frame is needed. */
|
||||
static bool animation_next_state (void)
|
||||
{
|
||||
|
@ -570,11 +563,73 @@ static bool animation_next_state (void)
|
|||
animation_ticks_until_next_frame = 15;
|
||||
return true;
|
||||
|
||||
case 4:
|
||||
if (!animation_can_run_left())
|
||||
return false;
|
||||
current_neko = NEKO_RUN_LEFT_1;
|
||||
surface.prev_neko_x = surface.neko_x;
|
||||
surface.neko_x -= neko_x_advance;
|
||||
return true;
|
||||
|
||||
case 5:
|
||||
if (!animation_can_run_right())
|
||||
return false;
|
||||
current_neko = NEKO_RUN_RIGHT_1;
|
||||
surface.prev_neko_x = surface.neko_x;
|
||||
surface.neko_x += neko_x_advance;
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
|
||||
case NEKO_RUN_RIGHT_1:
|
||||
case NEKO_RUN_RIGHT_2:
|
||||
case NEKO_RUN_LEFT_1:
|
||||
case NEKO_RUN_LEFT_2:
|
||||
if ( current_neko == NEKO_RUN_LEFT_1 || current_neko == NEKO_RUN_LEFT_2 )
|
||||
{
|
||||
if (!animation_can_run_left())
|
||||
{
|
||||
current_neko = NEKO_STARE;
|
||||
animation_ticks_until_next_frame = 10;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!animation_can_run_right())
|
||||
{
|
||||
current_neko = NEKO_STARE;
|
||||
animation_ticks_until_next_frame = 10;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( rand() % 4 == 0 )
|
||||
{
|
||||
current_neko = NEKO_STARE;
|
||||
animation_ticks_until_next_frame = 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (current_neko)
|
||||
{
|
||||
case NEKO_RUN_RIGHT_1: current_neko = NEKO_RUN_RIGHT_2; break;
|
||||
case NEKO_RUN_RIGHT_2: current_neko = NEKO_RUN_RIGHT_1; break;
|
||||
case NEKO_RUN_LEFT_1: current_neko = NEKO_RUN_LEFT_2; break;
|
||||
case NEKO_RUN_LEFT_2: current_neko = NEKO_RUN_LEFT_1; break;
|
||||
default: /* unreachable. */ break;
|
||||
}
|
||||
surface.prev_neko_x = surface.neko_x;
|
||||
if ( current_neko == NEKO_RUN_LEFT_1 || current_neko == NEKO_RUN_LEFT_2 )
|
||||
surface.neko_x -= neko_x_advance;
|
||||
else
|
||||
surface.neko_x += neko_x_advance;
|
||||
}
|
||||
return true;
|
||||
|
||||
case NEKO_SLEEP_1:
|
||||
case NEKO_SLEEP_2:
|
||||
case NEKO_SCRATCH_1:
|
||||
|
@ -655,15 +710,21 @@ static void surface_next_frame (void)
|
|||
{
|
||||
if (!surface.configured)
|
||||
return;
|
||||
struct Buffer *buffer = buffer_pool_next_buffer(surface_width, surface_height);
|
||||
struct Buffer *buffer = buffer_pool_next_buffer(surface.width, surface.height);
|
||||
if ( buffer == NULL )
|
||||
return;
|
||||
|
||||
atlas_composite_neko(buffer, current_neko, 0, 0);
|
||||
pixman_image_fill_rectangles(PIXMAN_OP_CLEAR, buffer->pixman_image, &bg_colour,
|
||||
1, &(pixman_rectangle16_t){ (int16_t)surface.prev_neko_x, (int16_t)0, (uint16_t)neko_size, (uint16_t)neko_size, });
|
||||
atlas_composite_neko(buffer, current_neko, surface.neko_x, 0);
|
||||
|
||||
wl_surface_set_buffer_scale(surface.wl_surface, 1);
|
||||
wl_surface_attach(surface.wl_surface, buffer->wl_buffer, 0, 0);
|
||||
wl_surface_damage_buffer(surface.wl_surface, 0, 0, INT32_MAX, INT32_MAX);
|
||||
wl_surface_damage_buffer(
|
||||
surface.wl_surface,
|
||||
MIN(surface.neko_x, surface.prev_neko_x), 0,
|
||||
neko_size + neko_x_advance, neko_size
|
||||
);
|
||||
buffer->busy = true;
|
||||
wl_surface_commit(surface.wl_surface);
|
||||
}
|
||||
|
@ -683,10 +744,17 @@ static void layer_surface_handle_configure (void *data, struct zwlr_layer_surfac
|
|||
(void)layer_surface;
|
||||
|
||||
zwlr_layer_surface_v1_ack_configure(surface.layer_surface, serial);
|
||||
surface.configured = true;
|
||||
surface.width = width;
|
||||
surface.height = height;
|
||||
|
||||
if ( width != surface_width || height != surface_height )
|
||||
fprintf(stderr, "ERROR: Bad dimensions in configure: %d %d\n", width, height);
|
||||
/* Center neko on first configure. */
|
||||
if (!surface.configured)
|
||||
{
|
||||
surface.neko_x = (uint16_t)((width / 2) - neko_size);
|
||||
surface.prev_neko_x = surface.neko_x;
|
||||
}
|
||||
|
||||
surface.configured = true;
|
||||
|
||||
surface_next_frame();
|
||||
}
|
||||
|
@ -723,12 +791,11 @@ static void surface_create (void)
|
|||
);
|
||||
zwlr_layer_surface_v1_set_size(
|
||||
surface.layer_surface,
|
||||
surface_width,
|
||||
surface_height
|
||||
0, desired_surface_height
|
||||
);
|
||||
zwlr_layer_surface_v1_set_anchor(
|
||||
surface.layer_surface,
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM
|
||||
ZWLR_LAYER_SURFACE_V1_ANCHOR_BOTTOM | ZWLR_LAYER_SURFACE_V1_ANCHOR_LEFT | ZWLR_LAYER_SURFACE_V1_ANCHOR_RIGHT
|
||||
);
|
||||
|
||||
/* Empty input region. */
|
||||
|
@ -805,6 +872,25 @@ static void timespec_diff (struct timespec *a, struct timespec *b, struct timesp
|
|||
}
|
||||
}
|
||||
|
||||
static bool colour_from_hex (pixman_color_t *colour, const char *hex)
|
||||
{
|
||||
uint16_t r = 0, g = 0, b = 0, a = 255;
|
||||
|
||||
if ( 4 != sscanf(hex, "0x%02hx%02hx%02hx%02hx", &r, &g, &b, &a)
|
||||
&& 3 != sscanf(hex, "0x%02hx%02hx%02hx", &r, &g, &b) )
|
||||
{
|
||||
fprintf(stderr, "ERROR: Invalid colour: %s\n", hex);
|
||||
return false;
|
||||
}
|
||||
|
||||
colour->alpha = (uint16_t)(((double)a / 255.0) * 65535.0);
|
||||
colour->red = (uint16_t)((((double)r / 255.0) * 65535.0) * colour->alpha / 0xffff);
|
||||
colour->green = (uint16_t)((((double)g / 255.0) * 65535.0) * colour->alpha / 0xffff);
|
||||
colour->blue = (uint16_t)((((double)b / 255.0) * 65535.0) * colour->alpha / 0xffff);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
int main (void)
|
||||
{
|
||||
init_signals();
|
||||
|
@ -812,6 +898,9 @@ int main (void)
|
|||
wl_list_init(&buffer_pool);
|
||||
srand((unsigned int)time(0));
|
||||
|
||||
colour_from_hex(&bg_colour, "0xFFFFFF");
|
||||
colour_from_hex(&border_colour, "0x000000");
|
||||
|
||||
// TODO command line args
|
||||
|
||||
if (!atlas_init())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue