Mercurial > remote-gamepad
comparison source/main.c @ 3:4c4be527a8d5
Send the entire state (including both pads and touch screen), and other fixes.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Tue, 18 Aug 2015 00:25:10 +0100 |
parents | 5ba54fc65608 |
children | 557d35fcf15a |
comparison
equal
deleted
inserted
replaced
2:5ee81fece0fa | 3:4c4be527a8d5 |
---|---|
20 #include <netdb.h> | 20 #include <netdb.h> |
21 #include <stdio.h> | 21 #include <stdio.h> |
22 #include <string.h> | 22 #include <string.h> |
23 #include <sys/socket.h> | 23 #include <sys/socket.h> |
24 | 24 |
25 struct state_t { | |
26 u32 keys; | |
27 circlePosition pad, cpad; | |
28 touchPosition touch; | |
29 }; | |
30 | |
25 static u32 *SOC_buffer = NULL; | 31 static u32 *SOC_buffer = NULL; |
26 | 32 |
27 int create_socket(int domain, int type, struct sockaddr *addr) | 33 int create_socket(int domain, int type, struct sockaddr *addr) |
28 { | 34 { |
29 int fd = socket(domain, type, 0); | 35 int fd = socket(domain, type, 0); |
30 if (fd < 0) { | 36 if (fd < 0) { |
31 printf("socket() failed.\n"); | 37 puts("socket() failed."); |
32 return -1; | 38 return -1; |
33 } | 39 } |
34 | 40 |
35 if (addr) { | 41 if (addr) { |
36 if (connect(fd, addr, sizeof(*addr)) < 0) { | 42 if (connect(fd, addr, sizeof(*addr)) < 0) { |
37 printf("connect() failed.\n"); | 43 puts("connect() failed."); |
38 return -1; | 44 return -1; |
39 } | 45 } |
40 } | 46 } |
41 | 47 |
42 return fd; | 48 return fd; |
44 | 50 |
45 struct sockaddr* get_sockaddr_from_hostname(const char *hostname, int port) | 51 struct sockaddr* get_sockaddr_from_hostname(const char *hostname, int port) |
46 { | 52 { |
47 struct hostent *server = gethostbyname(hostname); | 53 struct hostent *server = gethostbyname(hostname); |
48 if (!server) { | 54 if (!server) { |
49 printf("gethostbyname() failed.\n"); | 55 puts("gethostbyname() failed."); |
50 return NULL; | 56 return NULL; |
51 } | 57 } |
52 | 58 |
53 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); | 59 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); |
54 if (!addr) { | 60 if (!addr) { |
55 printf("calloc() failed.\n"); | 61 puts("calloc() failed."); |
56 return NULL; | 62 return NULL; |
57 } | 63 } |
58 | 64 |
59 //memset(&addr, 0, sizeof(struct sockaddr_in)); | 65 //memset(&addr, 0, sizeof(struct sockaddr_in)); |
60 addr->sin_family = AF_INET; | 66 addr->sin_family = AF_INET; |
66 | 72 |
67 struct sockaddr* get_sockaddr_from_ip(const char *hostname, int port) | 73 struct sockaddr* get_sockaddr_from_ip(const char *hostname, int port) |
68 { | 74 { |
69 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); | 75 struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in)); |
70 if (!addr) { | 76 if (!addr) { |
71 printf("calloc() failed.\n"); | 77 puts("calloc() failed."); |
72 return NULL; | 78 return NULL; |
73 } | 79 } |
74 | 80 |
75 //memset(&addr, 0, sizeof(struct sockaddr_in)); | 81 //memset(&addr, 0, sizeof(struct sockaddr_in)); |
76 addr->sin_family = AF_INET; | 82 addr->sin_family = AF_INET; |
92 const unsigned SOC_ALIGN = 0x1000; | 98 const unsigned SOC_ALIGN = 0x1000; |
93 const unsigned SOC_BUFFERSIZE = 0x100000; | 99 const unsigned SOC_BUFFERSIZE = 0x100000; |
94 | 100 |
95 SOC_buffer = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE); | 101 SOC_buffer = (u32*)memalign(SOC_ALIGN, SOC_BUFFERSIZE); |
96 if (!SOC_buffer) { | 102 if (!SOC_buffer) { |
97 printf("calloc() failed.\n"); | 103 puts("memalign() failed."); |
98 return NULL; | 104 return NULL; |
99 } | 105 } |
100 | 106 |
101 unsigned initialized = SOC_Initialize(SOC_buffer, SOC_BUFFERSIZE); | 107 unsigned initialized = SOC_Initialize(SOC_buffer, SOC_BUFFERSIZE); |
102 if (initialized) { | 108 if (initialized) { |
103 printf("SOC_Initialize() failed.\n"); | 109 puts("SOC_Initialize() failed."); |
104 return NULL; | 110 return NULL; |
105 } | 111 } |
106 | 112 |
107 //struct sockaddr *addr = get_sockaddr_from_hostname(hostname, port); | 113 //struct sockaddr *addr = get_sockaddr_from_hostname(hostname, port); |
108 struct sockaddr *addr = get_sockaddr_from_ip(hostname, port); | 114 struct sockaddr *addr = get_sockaddr_from_ip(hostname, port); |
109 if (!addr) | 115 if (!addr) { |
110 return NULL; | 116 puts("get_sockaddr_from_ip() failed."); |
117 return NULL; | |
118 } | |
111 | 119 |
112 // TODO: IPv6 | 120 // TODO: IPv6 |
113 int domain = AF_INET; | 121 int domain = AF_INET; |
114 | 122 |
115 struct network_t *n = malloc(sizeof(struct network_t)); | 123 struct network_t *n = malloc(sizeof(struct network_t)); |
118 n->addr = addr; | 126 n->addr = addr; |
119 n->addr_size = sizeof(struct sockaddr_in); | 127 n->addr_size = sizeof(struct sockaddr_in); |
120 return n; | 128 return n; |
121 } | 129 } |
122 | 130 |
123 int sendKeys(struct network_t *n, u32 keys) | 131 int sendState(struct network_t *n, struct state_t *state) |
124 { | 132 { |
125 const char *msg = (const char*) &keys; | 133 const char *msg = (const char*) state; |
126 int msglen = sizeof(keys); | 134 const int msglen = sizeof(struct state_t); |
127 return sendto(n->udp_fd, msg, msglen, 0, n->addr, n->addr_size); | 135 return sendto(n->udp_fd, msg, msglen, 0, n->addr, n->addr_size); |
128 } | 136 } |
129 | 137 |
130 int main(int argc, char **argv) | 138 void exitWithMessage(const char *message) |
139 { | |
140 puts(message); | |
141 fflush(stdout); | |
142 gfxFlushBuffers(); | |
143 gfxSwapBuffers(); | |
144 for (int i=0; i < 60; ++i) | |
145 gspWaitForVBlank(); | |
146 gfxExit(); | |
147 } | |
148 | |
149 int main(void) | |
131 { | 150 { |
132 //Matrix containing the name of each key. Useful for printing when a key is pressed | 151 //Matrix containing the name of each key. Useful for printing when a key is pressed |
133 char keysNames[32][32] = { | 152 char keysNames[32][32] = { |
134 "KEY_A", "KEY_B", "KEY_SELECT", "KEY_START", | 153 "KEY_A", "KEY_B", "KEY_SELECT", "KEY_START", |
135 "KEY_DRIGHT", "KEY_DLEFT", "KEY_DUP", "KEY_DDOWN", | 154 "KEY_DRIGHT", "KEY_DLEFT", "KEY_DUP", "KEY_DDOWN", |
145 gfxInitDefault(); | 164 gfxInitDefault(); |
146 | 165 |
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 | 166 //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); | 167 consoleInit(GFX_TOP, NULL); |
149 | 168 |
150 u32 old_keys = 0; //In these variables there will be information about keys detected in the previous frame | 169 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 |
151 | 170 |
152 // Initialize the network | 171 // Initialize the network |
153 struct network_t *n = networkInit("192.168.0.13", 16150); | 172 struct network_t *n = networkInit("192.168.0.13", 16150); |
154 if (!n) { | 173 if (!n) { |
155 printf("HORROR!"); | 174 exitWithMessage("networkInit() failed."); |
156 fflush(stdout); | 175 return 1; |
157 gfxFlushBuffers(); | 176 } |
158 gfxSwapBuffers(); | |
159 for(;;); | |
160 } | |
161 | |
162 printf("\x1b[0;0HPress Start to exit."); | |
163 printf("\x1b[1;0HCirclePad position:"); | |
164 | 177 |
165 // Main loop | 178 // Main loop |
166 while (aptMainLoop()) | 179 while (aptMainLoop()) |
167 { | 180 { |
181 static struct state_t state; | |
182 | |
168 //Scan all the inputs. This should be done once for each frame | 183 //Scan all the inputs. This should be done once for each frame |
169 hidScanInput(); | 184 hidScanInput(); |
170 | 185 |
171 //hidKeysHeld returns information about which buttons have are held down in this frame | 186 //hidKeysHeld returns information about which buttons have are held down in this frame |
172 u32 keys = hidKeysHeld(); | 187 state.keys = hidKeysHeld(); |
173 | 188 |
174 //if (keys & KEY_START) break; // break in order to return to hbmenu | 189 //Read both pads position |
190 hidCircleRead(&state.pad); | |
191 hidCstickRead(&state.cpad); | |
192 | |
193 // FIXME: use HOME instead | |
194 if (state.keys & KEY_START) break; // break in order to return to hbmenu | |
175 | 195 |
176 //Do the keys printing only if keys have changed | 196 //Do the keys printing only if keys have changed |
177 if (keys != old_keys) | 197 if (memcmp(&state, &old_state, sizeof(struct state_t))) |
178 { | 198 { |
179 //Clear console | 199 //Clear console |
180 consoleClear(); | 200 consoleClear(); |
181 | 201 |
182 //These two lines must be rewritten because we cleared the whole console | 202 //Every line must be rewritten because we cleared the whole console |
183 printf("\x1b[0;0HPress Start to exit."); | 203 printf("\x1b[0;0HPress Start to exit.\n"); |
184 printf("\x1b[1;0HCirclePad position:"); | 204 |
185 | 205 //Print both pads position |
186 printf("\x1b[3;0H"); //Move the cursor to the fourth row because on the third one we'll write the circle pad position | 206 printf("CirclePad position: %04d; %04d\n", state.pad.dx, state.pad.dy); |
207 printf("CPad position: %04d; %04d\n", state.cpad.dx, state.cpad.dy); | |
208 | |
209 //Move the cursor to the fourth row because on the third one we'll write the circle pad position | |
210 printf("\x1b[3;0H"); | |
187 | 211 |
188 //Check if some of the keys are down, held or up | 212 //Check if some of the keys are down, held or up |
189 for (int i = 0; i < 32; i++) | 213 for (int i = 0; i < 32; i++) |
190 { | 214 { |
191 if (keys & BIT(i)) printf("%s\n", keysNames[i]); | 215 if (state.keys & BIT(i)) |
216 printf("%s\n", keysNames[i]); | |
192 } | 217 } |
193 | 218 |
194 if (sendKeys(n, keys) < 0) { | 219 if (sendState(n, &state) < 0) { |
195 perror("sendKeys"); | 220 exitWithMessage("sendState() failed."); |
196 printf("HORROR! sendKeys()!"); | 221 return 1; |
197 fflush(stdout); | |
198 gfxFlushBuffers(); | |
199 gfxSwapBuffers(); | |
200 for(;;); | |
201 } | 222 } |
202 } | 223 } |
203 | 224 |
204 //Set keys old values for the next frame | 225 //Set keys old values for the next frame |
205 old_keys = keys; | 226 memcpy(&old_state, &state, sizeof(struct state_t)); |
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 | 227 |
215 // Flush and swap framebuffers | 228 // Flush and swap framebuffers |
216 gfxFlushBuffers(); | 229 gfxFlushBuffers(); |
217 gfxSwapBuffers(); | 230 gfxSwapBuffers(); |
218 | 231 |
219 //Wait for VBlank | 232 //Wait for VBlank |
220 gspWaitForVBlank(); | 233 gspWaitForVBlank(); |
221 } | 234 } |
222 | 235 |
223 // Exit services | 236 // Exit services |
224 gfxExit(); | 237 exitWithMessage("Exiting..."); |
225 return 0; | 238 return 0; |
226 } | 239 } |