summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-20 01:38:05 -0700
committerDavid Vazgenovich Shakaryan <dvshakaryan@gmail.com>2022-05-20 01:38:05 -0700
commita4f1e60ece6dac22c4d913fc70124873803f30ab (patch)
tree405793459509a17f37a1223196b9deaf71514ba7
parent2886add52aeed172289f3bddd995eda0b0c92a67 (diff)
downloaddartboat-a4f1e60ece6dac22c4d913fc70124873803f30ab.tar.gz
dartboat-a4f1e60ece6dac22c4d913fc70124873803f30ab.tar.xz
web: add (incomplete) support for 3+ player matches
-rw-r--r--web/static/dartboat.js5
-rw-r--r--web/static/fonts/bootstrap-icons-sub.woff2bin1088 -> 1116 bytes
-rw-r--r--web/static/index.html2
-rw-r--r--web/static/style.css50
-rw-r--r--web/web_control.c22
-rw-r--r--web/web_match.c2
-rw-r--r--web/web_match.h3
-rw-r--r--web/web_prompt.c5
-rw-r--r--web/web_scoreboard.c128
-rw-r--r--web/web_scoreboard.h4
10 files changed, 193 insertions, 28 deletions
diff --git a/web/static/dartboat.js b/web/static/dartboat.js
index 54cb29b..5c7f011 100644
--- a/web/static/dartboat.js
+++ b/web/static/dartboat.js
@@ -185,6 +185,11 @@ document.addEventListener('DOMContentLoaded', () => {
e.currentTarget.style.display = 'none';
};
$$('.modal').forEach(x => x.addEventListener('click', f));
+
+ $('#info-slot-prev').addEventListener('click', () =>
+ _scoreboard_prev_slot());
+ $('#info-slot-next').addEventListener('click', () =>
+ _scoreboard_next_slot());
});
document.addEventListener('keydown', e => {
diff --git a/web/static/fonts/bootstrap-icons-sub.woff2 b/web/static/fonts/bootstrap-icons-sub.woff2
index 391919f..116a249 100644
--- a/web/static/fonts/bootstrap-icons-sub.woff2
+++ b/web/static/fonts/bootstrap-icons-sub.woff2
Binary files differ
diff --git a/web/static/index.html b/web/static/index.html
index 8da5baa..196db91 100644
--- a/web/static/index.html
+++ b/web/static/index.html
@@ -24,6 +24,8 @@
</div>
<div id="info">
<div id="oi">oi!</div>
+ <div id="info-slot-prev" class="icon">&#xf27f;</div>
+ <div id="info-slot-next" class="icon">&#xf280;</div>
<div id="p1-info">
<div id="p1-info-inner">
<div id="p1-name"></div>
diff --git a/web/static/style.css b/web/static/style.css
index 5131eab..f8b6ea0 100644
--- a/web/static/style.css
+++ b/web/static/style.css
@@ -473,6 +473,56 @@ body {
visibility: visible;
}
+#info #info-slot-prev, #info #info-slot-next {
+ visibility: hidden;
+
+ color: #eee;
+ background-color: #583a90;
+ font-size: 2em;
+ height: 1.6em;
+ width: 1em;
+
+ outline: #111 solid 2px;
+
+ position: absolute;
+
+ display: flex;
+ align-items: center;
+ justify-content: center;
+}
+
+#info #info-slot-prev {
+ left: 0%;
+ right: 100%;
+ top: 50%;
+ bottom: 50%;
+ transform: translate(0%, -50%);
+}
+
+#info #info-slot-next {
+ left: 100%;
+ right: 0%;
+ top: 50%;
+ bottom: 50%;
+ transform: translate(-100%, -50%);
+}
+
+#info #info-slot-prev.visible, #info #info-slot-next.visible {
+ visibility: visible;
+}
+
+@media (hover: hover) and (pointer: fine) {
+ #info #info-slot-prev:hover, #info #info-slot-next:hover {
+ color: #fff;
+ background-color: #6e49b4;
+ }
+}
+
+#info #info-slot-prev:active, #info #info-slot-next:active {
+ color: #fff;
+ background-color: #7b51ca;
+}
+
#info #p1-info, #info #p2-info {
background-color: #222;
font-size: 1.5em;
diff --git a/web/web_control.c b/web/web_control.c
index 74d42e2..5389a23 100644
--- a/web/web_control.c
+++ b/web/web_control.c
@@ -260,6 +260,9 @@ void match_mode_selected(int mode)
match_opts->p1_type = PT_COMP;
match_opts->p2_name = "Computer 2";
match_opts->p2_type = PT_COMP;
+ } else if (mode == M_PVPVP) {
+ match_opts->p1_name = "Player 1";
+ match_opts->p2_name = "Player 2";
}
prompt_match_opts();
@@ -273,17 +276,14 @@ void start_match()
match_opts->p1_name);
match_add_player(match_opts->start_pts, match_opts->p2_type,
match_opts->p2_name ? match_opts->p2_name : "oi");
-
- show_player_info(1);
- update_player_name(1, state->legs[0]->name);
- update_player_rem(1, state->legs[0]->rem);
- update_player_avg(1, 0);
-
- if (match_num_players() != 1) {
- show_player_info(2);
- update_player_name(2, state->legs[1]->name);
- update_player_rem(2, state->legs[1]->rem);
- update_player_avg(2, 0);
+ if (match_opts->mode == M_PVPVP)
+ match_add_player(match_opts->start_pts, PT_USER, "Player 3");
+
+ scoreboard_show_info(match_num_players());
+ for (int i = 1; i <= match_num_players(); ++i) {
+ update_player_name(i, state->legs[i - 1]->name);
+ update_player_rem(i, state->legs[i - 1]->rem);
+ update_player_avg(i, 0);
}
dom_enable_exit_dialogue(true);
diff --git a/web/web_match.c b/web/web_match.c
index bdd049d..793aedd 100644
--- a/web/web_match.c
+++ b/web/web_match.c
@@ -72,7 +72,7 @@ int match_num_players()
if (state->mode == M_P)
return 1;
- return 2;
+ return state->num_players;
}
int match_winning_player()
diff --git a/web/web_match.h b/web/web_match.h
index 715be76..0654eb7 100644
--- a/web/web_match.h
+++ b/web/web_match.h
@@ -9,7 +9,8 @@ enum match_mode {
M_P,
M_PVP,
M_CVC,
- M_LAST = M_CVC
+ M_PVPVP,
+ M_LAST = M_PVPVP
};
enum player_type {
diff --git a/web/web_prompt.c b/web/web_prompt.c
index c9e4f55..ad907bc 100644
--- a/web/web_prompt.c
+++ b/web/web_prompt.c
@@ -185,9 +185,7 @@ void prompt_end_match()
void prompt_select_mode()
{
- dom_set_uniq_class(NULL, "visible", "[id$=-info-inner]");
- for (int pn = 1; pn < 3; ++pn)
- clear_player_info(pn);
+ scoreboard_hide_info();
dom_set_content("#visits", NULL);
set_prompt_mode(PM_SELECT_MODE);
@@ -199,6 +197,7 @@ void prompt_select_mode()
add_list_opt("One-player scoreboard");
add_list_opt("Two-player scoreboard");
add_list_opt("Computer vs computer");
+ add_list_opt("Three-player scoreboard");
flush_list_opts();
}
diff --git a/web/web_scoreboard.c b/web/web_scoreboard.c
index fa1a672..79bddb2 100644
--- a/web/web_scoreboard.c
+++ b/web/web_scoreboard.c
@@ -15,20 +15,106 @@
static struct {
bufstr name, rem, sugg, avg;
-} bufs[2];
+} bufs[4];
-void scoreboard_set_player_active(int pn)
+#define NUM_SLOTS 2
+static int slots[NUM_SLOTS];
+static int active_pn = -1;
+
+static void flush_slot(int slot)
+{
+ int pn = slots[slot - 1];
+ if (pn == -1) return;
+
+ // FIXME: should be combined with flushing player info
+ char sel[32];
+ int len = sprintf(sel, "#p%d-", slot);
+ strcpy(sel + len, "name");
+ dom_set_content(sel, bufstr_flush(&bufs[pn-1].name));
+ strcpy(sel + len, "rem");
+ dom_set_content(sel, bufstr_flush(&bufs[pn-1].rem));
+ strcpy(sel + len, "sugg");
+ dom_set_content(sel, bufstr_flush(&bufs[pn-1].sugg));
+ strcpy(sel + len, "avg");
+ dom_set_content(sel, bufstr_flush(&bufs[pn-1].avg));
+}
+
+static int player_slot(int pn)
+{
+ for (int i = 0; i < NUM_SLOTS; ++i) {
+ if (slots[i] == pn)
+ return i + 1;
+ }
+
+ return -1;
+}
+
+static void set_slot_player(int slot, int pn)
+{
+ if (slots[slot - 1] != pn) {
+ slots[slot - 1] = pn;
+ flush_slot(slot);
+ }
+}
+
+static void set_slot_active(int slot)
{
char buf[64], *sel = buf;
- if (pn == -1)
+ if (slot == -1)
sel = NULL;
else
- sprintf(sel, "#p%d-info", pn);
+ sprintf(sel, "#p%d-info", slot);
dom_set_uniq_class(sel, "active", "[id$=-info]");
}
+EMSCRIPTEN_KEEPALIVE
+void scoreboard_prev_slot()
+{
+ set_slot_player(2, slots[0]);
+ set_slot_player(1, slots[1] == 1 ? match_num_players() : slots[1] - 1);
+ set_slot_active(player_slot(active_pn));
+}
+
+EMSCRIPTEN_KEEPALIVE
+void scoreboard_next_slot()
+{
+ set_slot_player(1, slots[1]);
+ set_slot_player(2, slots[0] == match_num_players() ? 1 : slots[0] + 1);
+ set_slot_active(player_slot(active_pn));
+}
+
+void scoreboard_set_player_active(int pn)
+{
+ active_pn = pn;
+
+ if (pn == -1) {
+ set_slot_active(-1);
+ return;
+ }
+
+ int np = match_num_players();
+ int slot1, slot2, pslot;
+ if (np == 1) {
+ slot1 = 1;
+ slot2 = -1;
+ pslot = 1;
+ } else if (np == 2) {
+ slot1 = 1;
+ slot2 = 2;
+ pslot = pn == 1 ? 1 : 2;
+ } else {
+ slot1 = pn;
+ slot2 = pn == np ? 1 : pn + 1;
+ pslot = 1;
+ }
+
+ set_slot_player(1, slot1);
+ set_slot_player(2, slot2);
+ set_slot_active(pslot);
+}
+
void scoreboard_set_player_name(int pn, char *str)
{
bufstr_buf(&bufs[pn-1].name, str);
@@ -53,8 +139,11 @@ void scoreboard_set_player_avg(int pn, double avg)
void scoreboard_flush_player_info(int pn)
{
+ int slot = player_slot(pn);
+ if (slot == -1) return;
+
char sel[32];
- int len = sprintf(sel, "#p%d-", pn);
+ int len = sprintf(sel, "#p%d-", slot);
if (bufstr_changed(&bufs[pn-1].name)) {
strcpy(sel + len, "name");
@@ -133,14 +222,23 @@ void update_player_rem(int pn, int rem)
update_player_sugg(pn, rem);
}
-void show_player_info(int pn)
+void scoreboard_show_info(int num_players)
{
- char sel[64];
- sprintf(sel, "#p%d-info-inner", pn);
- dom_add_class(sel, "visible");
+ set_slot_player(1, 1);
+ dom_add_class("#p1-info-inner", "visible");
+
+ if (num_players > 1) {
+ set_slot_player(2, 2);
+ dom_add_class("#p2-info-inner", "visible");
+ }
+
+ if (num_players > 2) {
+ dom_add_class("#info-slot-prev", "visible");
+ dom_add_class("#info-slot-next", "visible");
+ }
}
-void clear_player_info(int pn)
+static void clear_player_info(int pn)
{
scoreboard_set_player_name(pn, NULL);
scoreboard_set_player_rem(pn, NULL);
@@ -148,6 +246,16 @@ void clear_player_info(int pn)
scoreboard_set_player_avg(pn, 0);
}
+void scoreboard_hide_info()
+{
+ dom_set_uniq_class(NULL, "visible", "[id$=-info-inner]");
+ for (int pn = 1; pn < 4; ++pn) // FIXME
+ clear_player_info(pn);
+
+ dom_remove_class("#info-slot-prev", "visible");
+ dom_remove_class("#info-slot-next", "visible");
+}
+
static struct dom_elem *create_div(char *str, char *class)
{
struct dom_elem *e = dom_elem_init(NULL, "div", 1);
diff --git a/web/web_scoreboard.h b/web/web_scoreboard.h
index 6525654..c712b8e 100644
--- a/web/web_scoreboard.h
+++ b/web/web_scoreboard.h
@@ -15,8 +15,8 @@ void update_player_sugg(int pn, int rem);
void update_player_avg(int pn, int n_darts);
void update_player_rem(int pn, int rem);
-void show_player_info(int pn);
-void clear_player_info(int pn);
+void scoreboard_show_info(int num_players);
+void scoreboard_hide_info();
void draw_visits();