From 8892e69e93d369d822ddf059081c776b6fd3452e Mon Sep 17 00:00:00 2001 From: Virt <41426325+VirtCode@users.noreply.github.com> Date: Tue, 15 Apr 2025 14:16:10 +0200 Subject: [PATCH] allow neko to scratch the walls of the monitor --- README | 2 + wayneko.1 | 6 +++ wayneko.c | 134 +++++++++++++++++++++++++++++++++++++++++++----------- 3 files changed, 116 insertions(+), 26 deletions(-) diff --git a/README b/README index 57bc5bc..1937d79 100644 --- a/README +++ b/README @@ -19,6 +19,8 @@ neko with the `--type` flag. The bitmaps were obtained and modified from here (use the wayback machine to access it): https://users.frii.com/suzannem/neko/ +Neko will also scratch the sides of your monitor with this fork, if one is nearby. + Refer to the man page or `--help` command to see how to use this fork and which options are new or no longer available. diff --git a/wayneko.1 b/wayneko.1 index 39d2f0a..69daee8 100644 --- a/wayneko.1 +++ b/wayneko.1 @@ -65,6 +65,12 @@ This option lets you set the fur of neko. You can choose by a plain single color .RE . .P +\fB\-\-wall\fR \fBnone\fR|\fBleft\fR|\fBright\fR|\fBboth\fR +.RS +Set which walls neko is allowed to scratch. By default, neko will any wall if she feels like it. +.RE +. +.P \fB\-\-idle-sleep\fR \fIseconds\fR .RS Set the time in seconds after which neko will go to sleep when the user is diff --git a/wayneko.c b/wayneko.c index b5f06c0..91fac29 100644 --- a/wayneko.c +++ b/wayneko.c @@ -33,6 +33,7 @@ const char usage[] = " --background-colour 0xRRGGBB[AA]\n" " --outline-colour 0xRRGGBB[AA]\n" " --type plain|striped|random\n" + " --wall none|left|right|both\n" " --idle-sleep seconds\n" " --sleep-phase seconds-seconds\n" " --awake-phase seconds-seconds\n" @@ -74,6 +75,18 @@ enum Neko NEKO_RUN_RIGHT_2, NEKO_RUN_LEFT_1, NEKO_RUN_LEFT_2, + NEKO_WALL_RIGHT_1, + NEKO_WALL_RIGHT_2, + NEKO_WALL_LEFT_1, + NEKO_WALL_LEFT_2, +}; + +// lsb is right, next bit is left +enum Wall { + WALL_NONE = 0, + WALL_RIGHT, + WALL_LEFT, + WALL_BOTH }; const uint16_t animation_timeout = 200; /* milliseconds */ @@ -84,6 +97,7 @@ bool follow_pointer = false; // TODO: implement this again bool recreate_surface_on_close = false; enum zwlr_layer_shell_v1_layer layer = ZWLR_LAYER_SHELL_V1_LAYER_BOTTOM; float start_position = 0.5; +enum Wall wall_behaviour = WALL_BOTH; struct ext_idle_notifier_v1 *idle_notifier = NULL; uint32_t neko_idle_timeout_ms = 180000; /* 3 minutes. */ @@ -150,6 +164,7 @@ struct Surface surface = { 0 }; const uint32_t desired_surface_height = neko_size; const uint8_t neko_x_advance = 15; +const uint32_t neko_x_wall_attraction = 400; int ret = EXIT_SUCCESS; bool loop = true; @@ -772,9 +787,9 @@ static void atlas_composite_neko (struct Buffer *buffer, enum Neko neko_type, ui ); } -static bool animation_can_run_left (void) +static bool animation_can_run_left (bool tight) { - return surface.neko_x > neko_x_advance; + return surface.neko_x > (tight ? 0 : neko_x_advance); } static void animation_neko_do_run_left (void) @@ -783,9 +798,9 @@ static void animation_neko_do_run_left (void) animation_ticks_until_next_frame = 0; } -static bool animation_can_run_right (void) +static bool animation_can_run_right (bool tight) { - return surface.neko_x < surface.width - neko_size - neko_x_advance; + return surface.neko_x < surface.width - neko_size - (tight ? 0 : neko_x_advance); } static void animation_neko_do_run_right (void) @@ -794,16 +809,20 @@ static void animation_neko_do_run_right (void) animation_ticks_until_next_frame = 0; } -static void animation_neko_advance_left (void) +static void animation_neko_advance_left (bool tight) { surface.prev_neko_x = surface.neko_x; - surface.neko_x -= neko_x_advance; + + if (tight) surface.neko_x = 0; + else surface.neko_x -= neko_x_advance; } -static void animation_neko_advance_right (void) +static void animation_neko_advance_right (bool tight) { surface.prev_neko_x = surface.neko_x; - surface.neko_x += neko_x_advance; + + if (tight) surface.neko_x = (uint16_t) surface.width - neko_size; + else surface.neko_x += neko_x_advance; } static void animation_neko_do_stare (bool quick) @@ -842,6 +861,18 @@ static void animation_neko_do_scratch (void) animation_ticks_until_next_frame = 0; } +static void animation_neko_do_wall_left (void) +{ + current_neko = current_neko == NEKO_WALL_LEFT_1 ? NEKO_WALL_LEFT_2 : NEKO_WALL_LEFT_1; + animation_ticks_until_next_frame = 0; +} + +static void animation_neko_do_wall_right (void) +{ + current_neko = current_neko == NEKO_WALL_RIGHT_1 ? NEKO_WALL_RIGHT_2 : NEKO_WALL_RIGHT_1; + animation_ticks_until_next_frame = 0; +} + static bool animtation_neko_wants_sleep (void) { /* Neko likes to sleep at night. */ @@ -875,12 +906,12 @@ static bool animation_next_state_with_hotspot (uint32_t x) case NEKO_SHOCK: case NEKO_RUN_LEFT_1: case NEKO_RUN_LEFT_2: - if (!animation_can_run_left()) + if (!animation_can_run_left(false)) { animation_neko_do_stare(true); return true; } - animation_neko_advance_left(); + animation_neko_advance_left(false); animation_neko_do_run_left(); return true; @@ -896,12 +927,12 @@ static bool animation_next_state_with_hotspot (uint32_t x) case NEKO_SHOCK: case NEKO_RUN_RIGHT_1: case NEKO_RUN_RIGHT_2: - if (!animation_can_run_right()) + if (!animation_can_run_right(false)) { animation_neko_do_stare(true); return true; } - animation_neko_advance_right(); + animation_neko_advance_right(false); animation_neko_do_run_right(); return true; @@ -972,19 +1003,31 @@ static bool animation_next_state_awake (void) break; case 4: - if (!animation_can_run_left()) + if (!animation_can_run_left(false)) return false; - animation_neko_advance_left(); + animation_neko_advance_left(false); animation_neko_do_run_left(); break; case 5: - if (!animation_can_run_right()) + if (!animation_can_run_right(false)) return false; - animation_neko_advance_right(); + animation_neko_advance_right(false); animation_neko_do_run_right(); break; + case 6: + case 7: + case 8: + case 9: + if (surface.neko_x == 0 && (wall_behaviour & WALL_LEFT)) + animation_neko_do_wall_left(); + else if (surface.neko_x + neko_size == surface.width && (wall_behaviour & WALL_RIGHT)) + animation_neko_do_wall_right(); + else + return false; + break; + default: return false; } @@ -992,23 +1035,30 @@ static bool animation_next_state_awake (void) case NEKO_RUN_RIGHT_1: case NEKO_RUN_RIGHT_2: - if ( animation_can_run_right() && rand() % 4 != 0 ) - { + bool attracted_right = surface.width - surface.neko_x + neko_size < neko_x_wall_attraction; + + if (!animation_can_run_right(false) && animation_can_run_right(true) && rand() % 8 != 0) { animation_neko_do_run_right(); - animation_neko_advance_right(); - } - else + animation_neko_advance_right(true); + } else if ( animation_can_run_right(false) && rand() % (attracted_right ? 8 : 4) != 0 ) { + animation_neko_do_run_right(); + animation_neko_advance_right(false); + } else animation_neko_do_stare(false); + return true; case NEKO_RUN_LEFT_1: case NEKO_RUN_LEFT_2: - if ( animation_can_run_left() && rand() % 4 != 0 ) - { + bool attracted_left = surface.neko_x < neko_x_wall_attraction; + + if (!animation_can_run_left(false) && animation_can_run_left(true) && rand() % 8 != 0) { animation_neko_do_run_left(); - animation_neko_advance_left(); - } - else + animation_neko_advance_left(true); + } else if ( animation_can_run_left(false) && rand() % (attracted_left ? 8 : 4) != 0 ) { + animation_neko_do_run_left(); + animation_neko_advance_left(false); + } else animation_neko_do_stare(false); return true; @@ -1028,6 +1078,22 @@ static bool animation_next_state_awake (void) animation_neko_do_scratch(); return true; + case NEKO_WALL_LEFT_1: + case NEKO_WALL_LEFT_2: + if ( rand() % 12 == 0 ) + animation_neko_do_stare(false); + else + animation_neko_do_wall_left(); + return true; + + case NEKO_WALL_RIGHT_1: + case NEKO_WALL_RIGHT_2: + if ( rand() % 12 == 0 ) + animation_neko_do_stare(false); + else + animation_neko_do_wall_right(); + return true; + case NEKO_THINK: if ( rand() % 2 == 0 ) animation_neko_do_stare(false); @@ -1456,6 +1522,22 @@ int main (int argc, char *argv[]) return EXIT_FAILURE; } } + else if ( strcmp(argv[i], "--wall") == 0 ) + { + const char *t = get_argument(argc, argv, &i); + if ( t == NULL ) + return EXIT_FAILURE; + + if (strcmp(t, "none") == 0) wall_behaviour = WALL_NONE; + else if (strcmp(t, "right") == 0) wall_behaviour = WALL_RIGHT; + else if (strcmp(t, "left") == 0) wall_behaviour = WALL_LEFT; + else if (strcmp(t, "both") == 0) wall_behaviour = WALL_BOTH; + else + { + fprintf(stderr, "ERROR: Unknown argument '%s' for flag '--wall'.\n", t); + return EXIT_FAILURE; + } + } else if ( strcmp(argv[i], "--follow-pointer") == 0 ) { fprintf(stderr, "ERROR: Functionality for flag '--follow-pointer' is not yet implemented in this fork.\n");