From c293fbe0c79a758650ad1104c4e18d3985d44b6e Mon Sep 17 00:00:00 2001 From: jfreegman Date: Fri, 23 Apr 2021 18:10:53 -0400 Subject: [PATCH] Add support for game window notifications --- src/game_base.c | 49 +++++++++++++++++++++++++++++++++++++++++------- src/game_base.h | 7 +++++++ src/game_chess.c | 30 +++++++++++++++++++++++++++++ 3 files changed, 79 insertions(+), 7 deletions(-) diff --git a/src/game_base.c b/src/game_base.c index 65a63b8..9e74ef7 100644 --- a/src/game_base.c +++ b/src/game_base.c @@ -32,9 +32,12 @@ #include "game_snake.h" #include "line_info.h" #include "misc_tools.h" +#include "notify.h" +#include "settings.h" #include "windows.h" extern struct Winthread Winthread; +extern struct user_settings *user_settings; /* * Determines the base rate at which game objects should update their state. @@ -64,7 +67,7 @@ extern struct Winthread Winthread; && ((max_x) >= (GAME_MAX_RECT_X_SMALL))) -static ToxWindow *game_new_window(GameType type, uint32_t friendnumber); +static ToxWindow *game_new_window(Tox *m, GameType type, uint32_t friendnumber); struct GameList { const char *name; @@ -123,6 +126,28 @@ bool game_type_is_multiplayer(GameType type) return type == GT_Chess; } +/* + * Sends a notification to the window associated with `game`. + * + * `message` - the notification message that will be displayed. + */ +void game_window_notify(const GameData *game, const char *message) +{ + ToxWindow *self = get_window_ptr(game->window_id); + + if (self == NULL) { + return; + } + + if (self->active_box != -1) { + box_notify2(self, generic_message, NT_WNDALERT_0 | NT_NOFOCUS | user_settings->bell_on_message, + self->active_box, "%s", message); + } else { + box_notify(self, generic_message, NT_WNDALERT_0 | NT_NOFOCUS | user_settings->bell_on_message, + &self->active_box, self->name, "%s", message); + } +} + /* Returns the current wall time in milliseconds */ TIME_MS get_time_millis(void) { @@ -221,7 +246,7 @@ int game_initialize(const ToxWindow *parent, Tox *m, GameType type, uint32_t id, } } - ToxWindow *self = game_new_window(type, parent->num); + ToxWindow *self = game_new_window(m, type, parent->num); if (self == NULL) { return -4; @@ -751,9 +776,10 @@ void game_onInit(ToxWindow *self, Tox *m) } /* - * Byte 0: Game type - * Byte 1-4: Game ID - * Byte 5-* Game data + * Byte 0: Version + * Byte 1: Game type + * Byte 2-5: Game ID + * Byte 6-* Game data */ void game_onPacket(ToxWindow *self, Tox *m, uint32_t friendnumber, const uint8_t *data, size_t length) { @@ -798,7 +824,7 @@ void game_onPacket(ToxWindow *self, Tox *m, uint32_t friendnumber, const uint8_t } } -static ToxWindow *game_new_window(GameType type, uint32_t friendnumber) +static ToxWindow *game_new_window(Tox *m, GameType type, uint32_t friendnumber) { const char *window_name = game_get_name_string(type); @@ -827,7 +853,16 @@ static ToxWindow *game_new_window(GameType type, uint32_t friendnumber) return NULL; } - snprintf(ret->name, sizeof(ret->name), "%s", window_name); + ret->active_box = -1; + + if (game_type_is_multiplayer(type)) { + char nick[TOX_MAX_NAME_LENGTH]; + get_nick_truncate(m, nick, friendnumber); + + snprintf(ret->name, sizeof(ret->name), "%s (%s)", window_name, nick); + } else { + snprintf(ret->name, sizeof(ret->name), "%s", window_name); + } return ret; } diff --git a/src/game_base.h b/src/game_base.h index d87a855..7a7d30d 100644 --- a/src/game_base.h +++ b/src/game_base.h @@ -285,6 +285,13 @@ void game_show_high_score(GameData *game, bool show_high_score); void game_show_lives(GameData *game, bool show_lives); void game_show_level(GameData *game, bool show_level); +/* + * Sends a notification to the window associated with `game`. + * + * `message` - the notification message that will be displayed. + */ +void game_window_notify(const GameData *game, const char *message); + /* * Updates game score. */ diff --git a/src/game_chess.c b/src/game_chess.c index 40c32d1..e2beb9c 100644 --- a/src/game_chess.c +++ b/src/game_chess.c @@ -1854,6 +1854,34 @@ static int chess_handle_opponent_move_packet(const GameData *game, ChessState *s } +static void chess_notify(const GameData *game, ChessPacketType type) +{ + const char *msg = NULL; + + switch (type) { + case CHESS_PACKET_INIT_ACCEPT_INVITE: { + msg = "Game on!"; + break; + } + + case CHESS_PACKET_RESIGN: { + msg = "Opponnet has resigned"; + break; + } + + case CHESS_PACKET_MOVE_PIECE: { + msg = "Opponent has moved"; + break; + } + + default: { + return; + } + } + + game_window_notify(game, msg); +} + static void chess_cb_on_packet(GameData *game, const uint8_t *data, size_t length, void *cb_data) { if (length == 0 || data == NULL) { @@ -1904,6 +1932,8 @@ static void chess_cb_on_packet(GameData *game, const uint8_t *data, size_t lengt break; } } + + chess_notify(game, type); } static int chess_init_board(GameData *game, ChessState *state, bool self_is_white)