Mercurial > remote-gamepad
annotate source/main.c @ 4:557d35fcf15a default tip
Properly exit the soc:U subsystem so we don’t crash on exit.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 18 Aug 2015 01:42:36 +0100 |
parents | 4c4be527a8d5 |
children |
rev | line source |
---|---|
0 | 1 /* |
2 Circle Pad example made by Aurelio Mannara for ctrulib | |
3 Please refer to https://github.com/smealum/ctrulib/blob/master/libctru/include/3ds/services/hid.h for more information | |
4 This code was modified for the last time on: 12/13/2014 2:20 UTC+1 | |
5 | |
6 This wouldn't be possible without the amazing work done by: | |
7 -Smealum | |
8 -fincs | |
9 -WinterMute | |
10 -yellows8 | |
11 -plutoo | |
12 -mtheall | |
13 -Many others who worked on 3DS and I'm surely forgetting about | |
14 */ | |
15 | |
16 #include <3ds.h> | |
17 #include <arpa/inet.h> | |
18 #include <assert.h> | |
19 #include <malloc.h> | |
20 #include <netdb.h> | |
21 #include <stdio.h> | |
22 #include <string.h> | |
23 #include <sys/socket.h> | |
24 | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
25 struct state_t { |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
26 u32 keys; |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
27 circlePosition pad, cpad; |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
28 touchPosition touch; |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
29 }; |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
30 |
0 | 31 static u32 *SOC_buffer = NULL; |
32 | |
33 int create_socket(int domain, int type, struct sockaddr *addr) | |
34 { | |
35 int fd = socket(domain, type, 0); | |
36 if (fd < 0) { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
37 puts("socket() failed."); |
0 | 38 return -1; |
39 } | |
40 | |
41 if (addr) { | |
42 if (connect(fd, addr, sizeof(*addr)) < 0) { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
43 puts("connect() failed."); |
0 | 44 return -1; |
45 } | |
46 } | |
47 | |
48 return fd; | |
49 } | |
50 | |
51 struct sockaddr* get_sockaddr_from_hostname(const char *hostname, int port) | |
52 { | |
53 struct hostent *server = gethostbyname(hostname); | |
54 if (!server) { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
55 puts("gethostbyname() failed."); |
0 | 56 return NULL; |
57 } | |
58 | |
59 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); | |
60 if (!addr) { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
61 puts("calloc() failed."); |
0 | 62 return NULL; |
63 } | |
64 | |
65 //memset(&addr, 0, sizeof(struct sockaddr_in)); | |
66 addr->sin_family = AF_INET; | |
67 addr->sin_port = htons(port); | |
68 memcpy(&addr->sin_addr.s_addr, server->h_addr_list[0], server->h_length); | |
69 | |
70 return (struct sockaddr*) addr; | |
71 } | |
72 | |
73 struct sockaddr* get_sockaddr_from_ip(const char *hostname, int port) | |
74 { | |
75 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); | |
76 if (!addr) { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
77 puts("calloc() failed."); |
0 | 78 return NULL; |
79 } | |
80 | |
81 //memset(&addr, 0, sizeof(struct sockaddr_in)); | |
82 addr->sin_family = AF_INET; | |
83 addr->sin_port = htons(port); | |
84 addr->sin_addr.s_addr = inet_addr(hostname); | |
85 | |
86 return (struct sockaddr*) addr; | |
87 } | |
88 | |
89 struct network_t { | |
90 int tcp_fd; | |
91 int udp_fd; | |
92 struct sockaddr *addr; | |
93 int addr_size; | |
94 }; | |
95 | |
96 struct network_t *networkInit(const char *hostname, int port) | |
97 { | |
98 const unsigned SOC_ALIGN = 0x1000; | |
99 const unsigned SOC_BUFFERSIZE = 0x100000; | |
100 | |
1
5ba54fc65608
Revert a stupid s/memalign/calloc/ in soc:U initialisation.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
0
diff
changeset
|
101 SOC_buffer = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE); |
0 | 102 if (!SOC_buffer) { |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
103 puts("memalign() failed."); |
0 | 104 return NULL; |
105 } | |
106 | |
107 unsigned initialized = SOC_Initialize(SOC_buffer, SOC_BUFFERSIZE); | |
108 if (initialized) { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
109 puts("SOC_Initialize() failed."); |
0 | 110 return NULL; |
111 } | |
112 | |
113 //struct sockaddr *addr = get_sockaddr_from_hostname(hostname, port); | |
114 struct sockaddr *addr = get_sockaddr_from_ip(hostname, port); | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
115 if (!addr) { |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
116 puts("get_sockaddr_from_ip() failed."); |
0 | 117 return NULL; |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
118 } |
0 | 119 |
120 // TODO: IPv6 | |
121 int domain = AF_INET; | |
122 | |
123 struct network_t *n = malloc(sizeof(struct network_t)); | |
124 //n->tcp_fd = create_socket(domain, SOCK_STREAM, addr); | |
125 n->udp_fd = create_socket(domain, SOCK_DGRAM, NULL); | |
126 n->addr = addr; | |
127 n->addr_size = sizeof(struct sockaddr_in); | |
128 return n; | |
129 } | |
130 | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
131 int sendState(struct network_t *n, struct state_t *state) |
0 | 132 { |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
133 const char *msg = (const char*) state; |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
134 const int msglen = sizeof(struct state_t); |
0 | 135 return sendto(n->udp_fd, msg, msglen, 0, n->addr, n->addr_size); |
136 } | |
137 | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
138 void exitWithMessage(const char *message) |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
139 { |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
140 puts(message); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
141 fflush(stdout); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
142 gfxFlushBuffers(); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
143 gfxSwapBuffers(); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
144 for (int i=0; i < 60; ++i) |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
145 gspWaitForVBlank(); |
4
557d35fcf15a
Properly exit the soc:U subsystem so we don’t crash on exit.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
3
diff
changeset
|
146 SOC_Shutdown(); |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
147 gfxExit(); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
148 } |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
149 |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
150 int main(void) |
0 | 151 { |
152 //Matrix containing the name of each key. Useful for printing when a key is pressed | |
153 char keysNames[32][32] = { | |
154 "KEY_A", "KEY_B", "KEY_SELECT", "KEY_START", | |
155 "KEY_DRIGHT", "KEY_DLEFT", "KEY_DUP", "KEY_DDOWN", | |
156 "KEY_R", "KEY_L", "KEY_X", "KEY_Y", | |
157 "", "", "KEY_ZL", "KEY_ZR", | |
158 "", "", "", "", | |
159 "KEY_TOUCH", "", "", "", | |
160 "KEY_CSTICK_RIGHT", "KEY_CSTICK_LEFT", "KEY_CSTICK_UP", "KEY_CSTICK_DOWN", | |
161 "KEY_CPAD_RIGHT", "KEY_CPAD_LEFT", "KEY_CPAD_UP", "KEY_CPAD_DOWN" | |
162 }; | |
163 | |
164 // Initialize services | |
165 gfxInitDefault(); | |
166 | |
167 //Initialize console on top screen. Using NULL as the second argument tells the console library to use the internal console structure as current one | |
168 consoleInit(GFX_TOP, NULL); | |
169 | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
170 struct state_t old_state = {0xffffffff, {0xffff, 0xffff}, {0xffff, 0xffff}, {0xffff, 0xffff}}; //In these variables there will be information about keys detected in the previous frame |
0 | 171 |
172 // Initialize the network | |
173 struct network_t *n = networkInit("192.168.0.13", 16150); | |
174 if (!n) { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
175 exitWithMessage("networkInit() failed."); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
176 return 1; |
0 | 177 } |
178 | |
179 // Main loop | |
180 while (aptMainLoop()) | |
181 { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
182 static struct state_t state; |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
183 |
0 | 184 //Scan all the inputs. This should be done once for each frame |
185 hidScanInput(); | |
186 | |
187 //hidKeysHeld returns information about which buttons have are held down in this frame | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
188 state.keys = hidKeysHeld(); |
0 | 189 |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
190 //Read both pads position |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
191 hidCircleRead(&state.pad); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
192 hidCstickRead(&state.cpad); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
193 |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
194 // FIXME: use HOME instead |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
195 if (state.keys & KEY_START) break; // break in order to return to hbmenu |
0 | 196 |
197 //Do the keys printing only if keys have changed | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
198 if (memcmp(&state, &old_state, sizeof(struct state_t))) |
0 | 199 { |
200 //Clear console | |
201 consoleClear(); | |
202 | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
203 //Every line must be rewritten because we cleared the whole console |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
204 printf("\x1b[0;0HPress Start to exit.\n"); |
0 | 205 |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
206 //Print both pads position |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
207 printf("CirclePad position: %04d; %04d\n", state.pad.dx, state.pad.dy); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
208 printf("CPad position: %04d; %04d\n", state.cpad.dx, state.cpad.dy); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
209 |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
210 //Move the cursor to the fourth row because on the third one we'll write the circle pad position |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
211 printf("\x1b[3;0H"); |
0 | 212 |
213 //Check if some of the keys are down, held or up | |
214 for (int i = 0; i < 32; i++) | |
215 { | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
216 if (state.keys & BIT(i)) |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
217 printf("%s\n", keysNames[i]); |
0 | 218 } |
219 | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
220 if (sendState(n, &state) < 0) { |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
221 exitWithMessage("sendState() failed."); |
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
222 return 1; |
0 | 223 } |
224 } | |
225 | |
226 //Set keys old values for the next frame | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
227 memcpy(&old_state, &state, sizeof(struct state_t)); |
0 | 228 |
229 // Flush and swap framebuffers | |
230 gfxFlushBuffers(); | |
231 gfxSwapBuffers(); | |
232 | |
233 //Wait for VBlank | |
234 gspWaitForVBlank(); | |
235 } | |
236 | |
237 // Exit services | |
3
4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
1
diff
changeset
|
238 exitWithMessage("Exiting..."); |
0 | 239 return 0; |
240 } |