1 /**
2  * \file main-test.c
3  * \brief Pseudo-UI for end-to-end testing.
4  *
5  * Copyright (c) 2011 Elly <elly+angband@leptoquark.net>
6  *
7  * This work is free software; you can redistribute it and/or modify it
8  * under the terms of either:
9  *
10  * a) the GNU General Public License as published by the Free Software
11  *    Foundation, version 2, or
12  *
13  * b) the "Angband licence":
14  *    This software may be copied and distributed for educational, research,
15  *    and not for profit purposes provided that this copyright and statement
16  *    are included in all such copies.  Other copyrights may also apply.
17  */
18 
19 #include "angband.h"
20 #include "buildid.h"
21 #include "main.h"
22 #include "player.h"
23 #include "player-birth.h"
24 
25 #ifdef USE_TEST
26 
27 static int prompt = 0;
28 static int verbose = 0;
29 static int nextkey = 0;
30 
c_key(char * rest)31 static void c_key(char *rest) {
32 	if (!strcmp(rest, "left")) {
33 		nextkey = ARROW_LEFT;
34 	} else if (!strcmp(rest, "right")) {
35 		nextkey = ARROW_RIGHT;
36 	} else if (!strcmp(rest, "up")) {
37 		nextkey = ARROW_UP;
38 	} else if (!strcmp(rest, "down")) {
39 		nextkey = ARROW_DOWN;
40 	} else if (!strcmp(rest, "space")) {
41 		nextkey = ' ';
42 	} else if (!strcmp(rest, "enter")) {
43 		nextkey = '\n';
44 	} else if (rest[0] == 'C' && rest[1] == '-') {
45 		nextkey = KTRL(rest[2]);
46 	} else {
47 		nextkey = rest[0];
48 	}
49 }
50 
c_noop(char * rest)51 static void c_noop(char *rest) {
52 
53 }
54 
c_quit(char * rest)55 static void c_quit(char *rest) {
56 	quit(NULL);
57 }
58 
c_verbose(char * rest)59 static void c_verbose(char *rest) {
60 	if (rest && !strcmp(rest, "0")) {
61 		printf("cmd-verbose: off\n");
62 		verbose = 0;
63 	} else {
64 		printf("cmd-verbose: on\n");
65 		verbose = 1;
66 	}
67 }
68 
c_version(char * rest)69 static void c_version(char *rest) {
70 	printf("cmd-version: %s %s\n", VERSION_NAME, VERSION_STRING);
71 }
72 
73 /**
74  * Player commands
75  */
c_player_birth(char * rest)76 static void c_player_birth(char *rest) {
77 	char *race = strtok(rest, " ");
78 	char *class = strtok(NULL, " ");
79 	struct player_class *c;
80 	struct player_race *r;
81 
82 	if (!race) race = "Human";
83 	if (!class) class = "Warrior";
84 
85 	for (r = races; r; r = r->next)
86 		if (!strcmp(race, r->name))
87 			break;
88 	if (!r) {
89 		printf("player-birth: bad race '%s'\n", race);
90 		return;
91 	}
92 
93 	for (c = classes; c; c = c->next)
94 		if (!strcmp(class, c->name))
95 			break;
96 
97 	if (!c) {
98 		printf("player-birth: bad class '%s'\n", class);
99 		return;
100 	}
101 
102 	player_generate(player, r, c, false);
103 }
104 
c_player_class(char * rest)105 static void c_player_class(char *rest) {
106 	printf("player-class: %s\n", player->class->name);
107 }
108 
c_player_race(char * rest)109 static void c_player_race(char *rest) {
110 	printf("player-race: %s\n", player->race->name);
111 }
112 
113 typedef struct {
114 	const char *name;
115 	void (*func)(char *args);
116 } test_cmd;
117 
118 static test_cmd cmds[] = {
119 	{ "#", c_noop },
120 	{ "key", c_key },
121 	{ "noop", c_noop },
122 	{ "quit", c_quit },
123 	{ "verbose", c_verbose },
124 	{ "version?", c_version },
125 
126 	{ "player-birth", c_player_birth },
127 	{ "player-class?", c_player_class },
128 	{ "player-race?", c_player_race },
129 
130 	{ NULL, NULL }
131 };
132 
test_docmd(void)133 static errr test_docmd(void) {
134 	char buf[1024];
135 	char *cmd;
136 	char *rest;
137 	int i;
138 
139 	memset(buf, 0, sizeof(buf));
140 
141 	if (prompt) {
142 		printf("test> ");
143 		fflush(stdout);
144 	}
145 	if (!fgets(buf, sizeof(buf), stdin)) {
146 		return -1;
147 	}
148 	if (strchr(buf, '\n')) {
149 		*strchr(buf, '\n') = '\0';
150 	}
151 
152 	if (verbose) printf("test-docmd: %s\n", buf);
153 	cmd = strtok(buf, " ");
154 	if (!cmd) return 0;
155 	rest = strtok(NULL, "");
156 
157 	for (i = 0; cmds[i].name; i++) {
158 		if (!strcmp(cmds[i].name, cmd)) {
159 			cmds[i].func(rest);
160 			return 0;
161 		}
162 	}
163 
164 	return 0;
165 }
166 
167 typedef struct term_data term_data;
168 struct term_data {
169 	term t;
170 };
171 
172 static term_data td;
173 typedef struct {
174 	int key;
175 	errr (*func)(int v);
176 } term_xtra_func;
177 
term_init_test(term * t)178 static void term_init_test(term *t) {
179 	if (verbose) printf("term-init %s %s\n", VERSION_NAME, VERSION_STRING);
180 }
181 
term_nuke_test(term * t)182 static void term_nuke_test(term *t) {
183 	if (verbose) printf("term-end\n");
184 }
185 
term_xtra_clear(int v)186 static errr term_xtra_clear(int v) {
187 	if (verbose) printf("term-xtra-clear %d\n", v);
188 	return 0;
189 }
190 
term_xtra_noise(int v)191 static errr term_xtra_noise(int v) {
192 	if (verbose) printf("term-xtra-noise %d\n", v);
193 	return 0;
194 }
195 
term_xtra_fresh(int v)196 static errr term_xtra_fresh(int v) {
197 	if (verbose) printf("term-xtra-fresh %d\n", v);
198 	return 0;
199 }
200 
term_xtra_shape(int v)201 static errr term_xtra_shape(int v) {
202 	if (verbose) printf("term-xtra-shape %d\n", v);
203 	return 0;
204 }
205 
term_xtra_alive(int v)206 static errr term_xtra_alive(int v) {
207 	if (verbose) printf("term-xtra-alive %d\n", v);
208 	return 0;
209 }
210 
term_xtra_event(int v)211 static errr term_xtra_event(int v) {
212 	if (verbose) printf("term-xtra-event %d\n", v);
213 	if (nextkey) {
214 		Term_keypress(nextkey, 0);
215 		nextkey = 0;
216 	}
217 	return test_docmd();
218 }
219 
term_xtra_flush(int v)220 static errr term_xtra_flush(int v) {
221 	if (verbose) printf("term-xtra-flush %d\n", v);
222 	return 0;
223 }
224 
term_xtra_delay(int v)225 static errr term_xtra_delay(int v) {
226 	if (verbose) printf("term-xtra-delay %d\n", v);
227 	return 0;
228 }
229 
term_xtra_react(int v)230 static errr term_xtra_react(int v) {
231 	if (verbose) printf("term-xtra-react\n");
232 	return 0;
233 }
234 
235 static term_xtra_func xtras[] = {
236 	{ TERM_XTRA_CLEAR, term_xtra_clear },
237 	{ TERM_XTRA_NOISE, term_xtra_noise },
238 	{ TERM_XTRA_FRESH, term_xtra_fresh },
239 	{ TERM_XTRA_SHAPE, term_xtra_shape },
240 	{ TERM_XTRA_ALIVE, term_xtra_alive },
241 	{ TERM_XTRA_EVENT, term_xtra_event },
242 	{ TERM_XTRA_FLUSH, term_xtra_flush },
243 	{ TERM_XTRA_DELAY, term_xtra_delay },
244 	{ TERM_XTRA_REACT, term_xtra_react },
245 	{ 0, NULL },
246 };
247 
term_xtra_test(int n,int v)248 static errr term_xtra_test(int n, int v) {
249 	int i;
250 	for (i = 0; xtras[i].func; i++) {
251 		if (xtras[i].key == n) {
252 			return xtras[i].func(v);
253 		}
254 	}
255 	if (verbose) printf("term-xtra-unknown %d %d\n", n, v);
256 	return 0;
257 }
258 
term_curs_test(int x,int y)259 static errr term_curs_test(int x, int y) {
260 	if (verbose) printf("term-curs %d %d\n", x, y);
261 	return 0;
262 }
263 
term_wipe_test(int x,int y,int n)264 static errr term_wipe_test(int x, int y, int n) {
265 	if (verbose) printf("term-wipe %d %d %d\n", x, y, n);
266 	return 0;
267 }
268 
term_text_test(int x,int y,int n,int a,const wchar_t * s)269 static errr term_text_test(int x, int y, int n, int a, const wchar_t *s) {
270 	if (verbose) {
271 		char str[256];
272 		wcstombs(str, s, 256);
273 		printf("term-text %d %d %d %02x %s\n", x, y, n, a, str);
274 	}
275 	return 0;
276 }
277 
term_data_link(int i)278 static void term_data_link(int i) {
279 	term *t = &td.t;
280 
281 	term_init(t, 80, 24, 256);
282 
283 	t->init_hook = term_init_test;
284 	t->nuke_hook = term_nuke_test;
285 
286 	t->xtra_hook = term_xtra_test;
287 	t->curs_hook = term_curs_test;
288 	t->wipe_hook = term_wipe_test;
289 	t->text_hook = term_text_test;
290 
291 	t->data = &td;
292 
293 	Term_activate(t);
294 
295 	angband_term[i] = t;
296 }
297 
298 const char help_test[] = "Test mode, subopts -p(rompt)";
299 
init_test(int argc,char * argv[])300 errr init_test(int argc, char *argv[]) {
301 	int i;
302 
303 	/* Skip over argv[0] */
304 	for (i = 1; i < argc; i++) {
305 		if (!strcmp(argv[i], "-p")) {
306 			prompt = 1;
307 			continue;
308 		}
309 		printf("init-test: bad argument '%s'\n", argv[i]);
310 	}
311 
312 	term_data_link(0);
313 	return 0;
314 }
315 #endif
316