diff options
author | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2022-05-02 20:03:01 -0700 |
---|---|---|
committer | David Vazgenovich Shakaryan <dvshakaryan@gmail.com> | 2022-05-02 20:03:01 -0700 |
commit | f4c0da6517e3a5bf4e87d2ac0acf474fbc75d62c (patch) | |
tree | e08dbb1336f9bf74a7e7d2d1cefd4728c9b57e18 /web/web_scoreboard.c | |
parent | 309a8042a3a84476637ad9c0f6535a1d71369759 (diff) | |
download | dartboat-f4c0da6517e3a5bf4e87d2ac0acf474fbc75d62c.tar.gz dartboat-f4c0da6517e3a5bf4e87d2ac0acf474fbc75d62c.tar.xz |
web: more renaming
Diffstat (limited to 'web/web_scoreboard.c')
-rw-r--r-- | web/web_scoreboard.c | 185 |
1 files changed, 185 insertions, 0 deletions
diff --git a/web/web_scoreboard.c b/web/web_scoreboard.c new file mode 100644 index 0000000..6be1cd4 --- /dev/null +++ b/web/web_scoreboard.c @@ -0,0 +1,185 @@ +#include "web_match.h" +#include "web_scoreboard.h" + +#include "checkouts.h" +#include "match.h" + +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <emscripten/emscripten.h> + +struct player_info { + char *name, *rem, *sugg; + double avg; +}; + +struct player_info buffered_info[2], flushed_info[2]; + +static inline void buffer_str(char *str, char **buffer, char *flushed) +{ + if (str == *buffer || (str && *buffer && !strcmp(str, *buffer))) + return; + + if (*buffer && *buffer != flushed) + free(*buffer); + + *buffer = str ? strdup(str) : NULL; +} + +void scoreboard_set_player_name(int pn, char *str) +{ + buffer_str(str, &buffered_info[pn-1].name, flushed_info[pn-1].name); +} + +void scoreboard_set_player_rem(int pn, char *str) +{ + buffer_str(str, &buffered_info[pn-1].rem, flushed_info[pn-1].rem); +} + +void scoreboard_set_player_sugg(int pn, char *str) +{ + buffer_str(str, &buffered_info[pn-1].sugg, flushed_info[pn-1].sugg); +} + +void scoreboard_set_player_avg(int pn, double avg) +{ + buffered_info[pn-1].avg = avg; +} + +static inline bool buffered_str_changed(char *buffered, char *flushed) +{ + return (!buffered != !flushed) || + (buffered && flushed && strcmp(buffered, flushed)); +} + +static inline void free_flushed_str(char *flushed, char *buffered) +{ + if (flushed && flushed != buffered) + free(flushed); +} + +void scoreboard_flush_player_info(int pn) +{ + if (buffered_str_changed(buffered_info[pn-1].name, + flushed_info[pn-1].name)) + EM_ASM({updatePlayerName($0, $1)}, pn, buffered_info[pn-1].name); + + if (buffered_str_changed(buffered_info[pn-1].rem, + flushed_info[pn-1].rem)) + EM_ASM({updatePlayerRem($0, $1)}, pn, buffered_info[pn-1].rem); + + if (buffered_str_changed(buffered_info[pn-1].sugg, + flushed_info[pn-1].sugg)) + EM_ASM({updatePlayerSugg($0, $1)}, pn, buffered_info[pn-1].sugg); + + if (buffered_info[pn-1].avg != flushed_info[pn-1].avg) + EM_ASM({updatePlayerAvg($0, $1)}, pn, buffered_info[pn-1].avg); + + free_flushed_str(flushed_info[pn-1].name, buffered_info[pn-1].name); + free_flushed_str(flushed_info[pn-1].rem, buffered_info[pn-1].rem); + free_flushed_str(flushed_info[pn-1].sugg, buffered_info[pn-1].sugg); + flushed_info[pn-1] = buffered_info[pn-1]; +} + +void scoreboard_flush() +{ + scoreboard_flush_player_info(1); + scoreboard_flush_player_info(2); +} + +void update_player_name(int pn, char *str) +{ + scoreboard_set_player_name(pn, str); +} + +void update_player_sugg(int pn, int rem) +{ + char str[15] = {0}, *p = str; + + if (rem > 1 && rem <= 170) { + char *target; + int i = 3, trem = rem; + while (i && trem && (target = CHECKOUTS[--i][trem-1])) { + p += sprintf(p, i == 2 ? "%s" : "-%s", target); + trem -= segment_points(segment_from_name(target)); + } + } + + scoreboard_set_player_sugg(pn, str); +} + +void update_player_avg(int pn, int n_darts) +{ + struct leg *l = state->legs[pn-1]; + scoreboard_set_player_avg(pn, + l->n_visits ? + (l->rem > 0 ? ((double)(l->start - l->rem) / l->n_visits) : + ((double)l->start / (((l->n_visits - 1) * 3) + n_darts) * 3)) : + 0); +} + +void update_player_rem(int pn, int rem) +{ + char str[5]; + if (rem < 0 || rem == 1) + strcpy(str, "BUST"); + else + sprintf(str, "%d", rem); + + scoreboard_set_player_rem(pn, str); + if (pn == 1 || state->mode != M_PVC) + update_player_sugg(pn, rem); +} + +void clear_player_info(int pn) +{ + scoreboard_set_player_name(pn, NULL); + scoreboard_set_player_rem(pn, NULL); + scoreboard_set_player_sugg(pn, NULL); + scoreboard_set_player_avg(pn, 0); +} + +void draw_visits() +{ + EM_ASM({clearVisits()}); + + char visit_no[10], p1_pts[10], p1_rem[10], + p2_pts[10], p2_rem[10], p2_darts[100]; + + sprintf(p1_rem, "%d", state->legs[0]->start); + sprintf(p2_rem, "%d", state->legs[1]->start); + EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)}, + "0", "", p1_rem, "", state->mode == M_P ? "" : p2_rem, ""); + + int n_visits = state->legs[0]->n_visits > state->legs[1]->n_visits ? + state->legs[0]->n_visits : state->legs[1]->n_visits; + for (int i = 0; i < n_visits; ++i) { + visit_no[0] = p1_pts[0] = p1_rem[0] = + p2_pts[0] = p2_rem[0] = p2_darts[0] = 0; + + sprintf(visit_no, "%d", i + 1); + + struct visit *v = state->legs[0]->visits + i; + sprintf(p1_pts, "%d", v->points); + sprintf(p1_rem, "%d", v->rem); + + if (i < state->legs[1]->n_visits) { + v = state->legs[1]->visits + i; + sprintf(p2_pts, "%d", v->points); + sprintf(p2_rem, "%d", v->rem); + + for (int j = 0; j < v->n_darts; ++j) { + char *n = segment_name(v->darts[j]); + sprintf(p2_darts + (j ? (j*5 - 1) : 0), + j == 0 ? "%4s" : " %4s", n); + free(n); + } + } + + EM_ASM({drawVisit($0, $1, $2, $3, $4, $5)}, + visit_no, p1_pts, p1_rem, p2_pts, p2_rem, p2_darts); + } +} |