1 #include <string.h>
2 #include <ctype.h>
3 #include "menu.h"
4 #include "../input/input.h"
5 #include "../textgfx/textgfx.h"
6 #include "../options.h"
7 #undef JOYSTICK
8 #define JOYSTICK 1
9 #include "internal.h"
10 
11 static char devices_str[14];
12 
upd_devstr()13 static void upd_devstr()
14 {
15 	strcpy(devices_str, "keybd js0 js1");
16 	if (num_joyst == 1)
17 		inputdevs_fd[2] = -1;
18 	if (num_joyst && (inputdevs_fd[1] > -1 || inputdevs_fd[2] > -1)) {
19 		if (inputdevs_fd[2] < 0)
20 			devices_str[9] = '\0';
21 		if (inputdevs_fd[1] < 0) {
22 			devices_str[8] = '1';
23 			devices_str[9] = '\0';
24 		}
25 	} else
26 		devices_str[5] = '\0';
27 }
28 
getdevstr(int i)29 static const char *getdevstr(int i)
30 {
31 	char *p = devices_str;
32 	while (i) {
33 		p = strchr(p, ' ');
34 		if (!p)
35 			return NULL;
36 		p++;
37 		i--;
38 	}
39 	return p;
40 }
41 
getdev(const char * key)42 static int getdev(const char *key)
43 {
44 	char *p;
45 	if (key && (p = strchr(devices_str, key[2])) && isdigit(*p))
46 		return *p-'0'+1;
47 	return 0;
48 }
49 
player_devstr(const char ** sect_name)50 static const char *player_devstr(const char **sect_name)
51 {
52 	const char *s = "";
53 	const char *dev;
54 	if (player_)
55 		s = (player_==1) ? "player1" : "player2";
56 	dev = getopt_str(s, "input");
57 	if (sect_name)
58 		*sect_name = s;
59 	return dev;
60 }
61 
inp_devhandler(int keypr,int * pos)62 static int inp_devhandler(int keypr, int *pos)
63 {
64 	const char *sect_name;
65 	const char *dev = player_devstr(&sect_name);
66 	const char *dev2;
67 	int i = 0;
68 	union val v;
69 	upd_devstr();
70 	if (dev) {
71 		do i++;
72 		while ((dev2 = getdevstr(i)) && strncmp(dev, dev2, 3));
73 		if (!dev2)
74 			i = 0;
75 		else if (player_) {
76 			v.integ = inputdevs_player[getdev(dev)];
77 			if (v.integ && v.integ != player_)
78 				i = 0;
79 		}
80 	}
81 	switch (keypr) {
82 	case 0:
83 		break;
84 	case MVLEFT:
85 		i--; break;
86 	case MVRIGHT:
87 		i++; break;
88 	case MVDOWN:
89 	case '\t':
90 		*pos = 2;
91 		return 2;
92 	default:
93 		return 0;
94 	}
95 	dev = getdevstr(i);
96 	if (!dev)
97 		return 1;
98 	printmenuitem_options(devices_str, i);
99 	if (!i)
100 		unsetoption(sect_name, "input");
101 	else {
102 		strncpy(v.str, dev, 4);
103 		setoption(sect_name, "input", v, 1);
104 	}
105 #if TWOPLAYER
106 	if (player_) {
107 		i = getdev(dev);
108 		inputdevs_player[i] = player_;
109 		if (!i) {
110 			sect_name = player_==1 ? "player2" : "player1";
111 			if (!getdev(getopt_str(sect_name, "input")))
112 				inputdevs_player[0] = 0;
113 		}
114 	}
115 #endif
116 	if (keypr) {
117 		*pos = 1;
118 		return 2;
119 	}
120 	return 1;
121 }
122 
inp_devlist(int * dev,int x,int y)123 int inp_devlist(int *dev, int x, int y)
124 {
125 	const char *device = "Device";
126 	menuhandler handler = inp_devhandler;
127 	int ret = 0;
128 	drawmenu(&device, 1, 0, x, y, &handler);
129 	while (1) {
130 		*dev = getdev(player_devstr(NULL));
131 		if (ret == 3)
132 			break;
133 		inp_printkeys(*dev, x, y+1);
134 		ret = openmenu(&device, 1, 0, x, y, &handler);
135 		if (ret < 2)
136 			return 0;
137 	}
138 	setcurs(x, y);
139 	printmenuitem(device, 0);
140 	newln(x);
141 	return 1;
142 }
143 
144 #ifndef NO_MENU
inputsetup_menuitem(int k,int * pos)145 int inputsetup_menuitem(int k, int *pos)
146 {
147 	int i = 0;
148 	if (!num_joyst) {
149 		i = rarrow_menuitem(k, pos);
150 		cleartoeol();
151 		return i;
152 	}
153 	if (inp_devhandler(k, &i)) {
154 		if (k && i!=1)
155 			movefwd(strlen(devices_str));
156 		printstr(" ->");
157 		if (i==1)
158 			return 3;
159 		return k <= MVRIGHT;
160 	}
161 	return 0;
162 }
163 #endif
164