Mercurial > remote-gamepad
comparison source/main.c @ 0:4e831ec746e4
Hello world!
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Sun, 22 Feb 2015 17:41:32 +0100 |
parents | |
children | 5ba54fc65608 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4e831ec746e4 |
---|---|
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 | |
25 static u32 *SOC_buffer = NULL; | |
26 | |
27 int create_socket(int domain, int type, struct sockaddr *addr) | |
28 { | |
29 int fd = socket(domain, type, 0); | |
30 if (fd < 0) { | |
31 printf("socket() failed.\n"); | |
32 return -1; | |
33 } | |
34 | |
35 if (addr) { | |
36 if (connect(fd, addr, sizeof(*addr)) < 0) { | |
37 printf("connect() failed.\n"); | |
38 return -1; | |
39 } | |
40 } | |
41 | |
42 return fd; | |
43 } | |
44 | |
45 struct sockaddr* get_sockaddr_from_hostname(const char *hostname, int port) | |
46 { | |
47 struct hostent *server = gethostbyname(hostname); | |
48 if (!server) { | |
49 printf("gethostbyname() failed.\n"); | |
50 return NULL; | |
51 } | |
52 | |
53 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); | |
54 if (!addr) { | |
55 printf("calloc() failed.\n"); | |
56 return NULL; | |
57 } | |
58 | |
59 //memset(&addr, 0, sizeof(struct sockaddr_in)); | |
60 addr->sin_family = AF_INET; | |
61 addr->sin_port = htons(port); | |
62 memcpy(&addr->sin_addr.s_addr, server->h_addr_list[0], server->h_length); | |
63 | |
64 return (struct sockaddr*) addr; | |
65 } | |
66 | |
67 struct sockaddr* get_sockaddr_from_ip(const char *hostname, int port) | |
68 { | |
69 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); | |
70 if (!addr) { | |
71 printf("calloc() failed.\n"); | |
72 return NULL; | |
73 } | |
74 | |
75 //memset(&addr, 0, sizeof(struct sockaddr_in)); | |
76 addr->sin_family = AF_INET; | |
77 addr->sin_port = htons(port); | |
78 addr->sin_addr.s_addr = inet_addr(hostname); | |
79 | |
80 return (struct sockaddr*) addr; | |
81 } | |
82 | |
83 struct network_t { | |
84 int tcp_fd; | |
85 int udp_fd; | |
86 struct sockaddr *addr; | |
87 int addr_size; | |
88 }; | |
89 | |
90 struct network_t *networkInit(const char *hostname, int port) | |
91 { | |
92 const unsigned SOC_ALIGN = 0x1000; | |
93 const unsigned SOC_BUFFERSIZE = 0x100000; | |
94 | |
95 SOC_buffer = (u32*)calloc(SOC_ALIGN, SOC_BUFFERSIZE); | |
96 if (!SOC_buffer) { | |
97 printf("calloc() failed.\n"); | |
98 return NULL; | |
99 } | |
100 | |
101 unsigned initialized = SOC_Initialize(SOC_buffer, SOC_BUFFERSIZE); | |
102 if (initialized) { | |
103 printf("SOC_Initialize() failed.\n"); | |
104 return NULL; | |
105 } | |
106 | |
107 //struct sockaddr *addr = get_sockaddr_from_hostname(hostname, port); | |
108 struct sockaddr *addr = get_sockaddr_from_ip(hostname, port); | |
109 if (!addr) | |
110 return NULL; | |
111 | |
112 // TODO: IPv6 | |
113 int domain = AF_INET; | |
114 | |
115 struct network_t *n = malloc(sizeof(struct network_t)); | |
116 //n->tcp_fd = create_socket(domain, SOCK_STREAM, addr); | |
117 n->udp_fd = create_socket(domain, SOCK_DGRAM, NULL); | |
118 n->addr = addr; | |
119 n->addr_size = sizeof(struct sockaddr_in); | |
120 return n; | |
121 } | |
122 | |
123 int sendKeys(struct network_t *n, u32 keys) | |
124 { | |
125 const char *msg = (const char*) &keys; | |
126 int msglen = sizeof(keys); | |
127 return sendto(n->udp_fd, msg, msglen, 0, n->addr, n->addr_size); | |
128 } | |
129 | |
130 int main(int argc, char **argv) | |
131 { | |
132 //Matrix containing the name of each key. Useful for printing when a key is pressed | |
133 char keysNames[32][32] = { | |
134 "KEY_A", "KEY_B", "KEY_SELECT", "KEY_START", | |
135 "KEY_DRIGHT", "KEY_DLEFT", "KEY_DUP", "KEY_DDOWN", | |
136 "KEY_R", "KEY_L", "KEY_X", "KEY_Y", | |
137 "", "", "KEY_ZL", "KEY_ZR", | |
138 "", "", "", "", | |
139 "KEY_TOUCH", "", "", "", | |
140 "KEY_CSTICK_RIGHT", "KEY_CSTICK_LEFT", "KEY_CSTICK_UP", "KEY_CSTICK_DOWN", | |
141 "KEY_CPAD_RIGHT", "KEY_CPAD_LEFT", "KEY_CPAD_UP", "KEY_CPAD_DOWN" | |
142 }; | |
143 | |
144 // Initialize services | |
145 gfxInitDefault(); | |
146 | |
147 //Initialize console on top screen. Using NULL as the second argument tells the console library to use the internal console structure as current one | |
148 consoleInit(GFX_TOP, NULL); | |
149 | |
150 u32 old_keys = 0; //In these variables there will be information about keys detected in the previous frame | |
151 | |
152 // Initialize the network | |
153 struct network_t *n = networkInit("192.168.0.13", 16150); | |
154 if (!n) { | |
155 printf("HORROR!"); | |
156 fflush(stdout); | |
157 gfxFlushBuffers(); | |
158 gfxSwapBuffers(); | |
159 for(;;); | |
160 } | |
161 | |
162 printf("\x1b[0;0HPress Start to exit."); | |
163 printf("\x1b[1;0HCirclePad position:"); | |
164 | |
165 // Main loop | |
166 while (aptMainLoop()) | |
167 { | |
168 //Scan all the inputs. This should be done once for each frame | |
169 hidScanInput(); | |
170 | |
171 //hidKeysHeld returns information about which buttons have are held down in this frame | |
172 u32 keys = hidKeysHeld(); | |
173 | |
174 //if (keys & KEY_START) break; // break in order to return to hbmenu | |
175 | |
176 //Do the keys printing only if keys have changed | |
177 if (keys != old_keys) | |
178 { | |
179 //Clear console | |
180 consoleClear(); | |
181 | |
182 //These two lines must be rewritten because we cleared the whole console | |
183 printf("\x1b[0;0HPress Start to exit."); | |
184 printf("\x1b[1;0HCirclePad position:"); | |
185 | |
186 printf("\x1b[3;0H"); //Move the cursor to the fourth row because on the third one we'll write the circle pad position | |
187 | |
188 //Check if some of the keys are down, held or up | |
189 for (int i = 0; i < 32; i++) | |
190 { | |
191 if (keys & BIT(i)) printf("%s\n", keysNames[i]); | |
192 } | |
193 | |
194 if (sendKeys(n, keys) < 0) { | |
195 perror("sendKeys"); | |
196 printf("HORROR! sendKeys()!"); | |
197 fflush(stdout); | |
198 gfxFlushBuffers(); | |
199 gfxSwapBuffers(); | |
200 for(;;); | |
201 } | |
202 } | |
203 | |
204 //Set keys old values for the next frame | |
205 old_keys = keys; | |
206 | |
207 circlePosition pos; | |
208 | |
209 //Read the CirclePad position | |
210 hidCircleRead(&pos); | |
211 | |
212 //Print the CirclePad position | |
213 printf("\x1b[2;0H%04d; %04d", pos.dx, pos.dy); | |
214 | |
215 // Flush and swap framebuffers | |
216 gfxFlushBuffers(); | |
217 gfxSwapBuffers(); | |
218 | |
219 //Wait for VBlank | |
220 gspWaitForVBlank(); | |
221 } | |
222 | |
223 // Exit services | |
224 gfxExit(); | |
225 return 0; | |
226 } |