summaryrefslogtreecommitdiff
path: root/web/web_opts.c
blob: b59330697516b59fffa01c7d5c78582fa240abd9 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
#include "web_dom.h"
#include "web_opts.h"

#include "comp.h"

#include <math.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <emscripten/emscripten.h>

#define PREFIX "dartboat_"

int delay_ms = 1000;

static int difficulty = 32;
static struct { int diff; double stdev; } DIFF_PRESETS[] = {
	{ 0, 66.80}, // 10
	{ 8, 40.24}, // 20
	{16, 28.14}, // 30
	{24, 21.35}, // 40
	{32, 17.20}, // 50
	{40, 14.34}, // 60
	{48, 12.15}, // 70
	{56, 10.36}, // 80
	{64,  8.83}, // 90
	{72,  7.48}, // 100
	{80,  6.32}, // 110
	{88,  5.34}, // 120
	{99,  0.00}, // 167
};
#define NUM_DIFF_PRESETS (sizeof(DIFF_PRESETS) / sizeof(*DIFF_PRESETS))

static void set_delay(char *val)
{
	delay_ms = atoi(val);
}

static void set_stdev(int diff)
{
	if (diff < DIFF_PRESETS[0].diff)
		diff = DIFF_PRESETS[0].diff;
	else if (diff > DIFF_PRESETS[NUM_DIFF_PRESETS - 1].diff)
		diff = DIFF_PRESETS[NUM_DIFF_PRESETS - 1].diff;

	size_t ind = 1;
	while (ind < NUM_DIFF_PRESETS - 1 && DIFF_PRESETS[ind].diff <= diff)
		ind++;

	double step = (DIFF_PRESETS[ind - 1].stdev - DIFF_PRESETS[ind].stdev) /
		(DIFF_PRESETS[ind].diff - DIFF_PRESETS[ind - 1].diff);
	horizontal_stdev = vertical_stdev = DIFF_PRESETS[ind - 1].stdev -
		((diff - DIFF_PRESETS[ind - 1].diff) * step);
}

static void set_difficulty(char *val)
{
	int diff = atoi(val);
	difficulty = diff < 0 ? 0 : diff > 99 ? 99 : diff;

	set_stdev(difficulty);
}

static char *prefix_opt(char *opt)
{
	char len = strlen(opt);
	char *s = malloc(len + sizeof(PREFIX));
	memcpy(s, PREFIX, sizeof(PREFIX) - 1);
	memcpy(s + sizeof(PREFIX) - 1, opt, len + 1);

	return s;
}

static char *read_opt(char *opt)
{
	char *s = prefix_opt(opt);
	char *val = (char *)EM_ASM_INT({return readOpt($0)}, s);
	free(s);
	return val;
}

static bool read_delay()
{
	char *val = read_opt("delay");
	if (!val) return false;

	set_delay(val);
	free(val);
	return true;
}

static bool read_difficulty()
{
	char *val = read_opt("difficulty");
	if (!val) return false;

	set_difficulty(val);
	free(val);
	return true;
}

void opts_init()
{
	read_delay();
	if (!read_difficulty())
		set_stdev(difficulty);

	char buf[64];
	sprintf(buf, "%d", delay_ms);
	dom_set_value("#delay", buf);

	sprintf(buf, "%d", difficulty);
	dom_set_value("#difficulty", buf);
}

static void store_opt(char *opt, char  *val)
{
	char *s = prefix_opt(opt);
	EM_ASM({storeOpt($0, $1)}, s, val);
	free(s);
}

EMSCRIPTEN_KEEPALIVE
void set_opt(char *opt, char *val)
{
	if (!strcmp(opt, "delay"))
		set_delay(val);
	else if (!strcmp(opt, "difficulty"))
		set_difficulty(val);
	else
		return;

	store_opt(opt, val);
}