diff 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
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/source/main.c
@@ -0,0 +1,226 @@
+/*
+	Circle Pad example made by Aurelio Mannara for ctrulib
+	Please refer to https://github.com/smealum/ctrulib/blob/master/libctru/include/3ds/services/hid.h for more information
+	This code was modified for the last time on: 12/13/2014 2:20 UTC+1
+
+	This wouldn't be possible without the amazing work done by:
+	-Smealum
+	-fincs
+	-WinterMute
+	-yellows8
+	-plutoo
+	-mtheall
+	-Many others who worked on 3DS and I'm surely forgetting about
+*/
+
+#include <3ds.h>
+#include <arpa/inet.h>
+#include <assert.h>
+#include <malloc.h>
+#include <netdb.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/socket.h>
+
+static u32 *SOC_buffer = NULL;
+
+int create_socket(int domain, int type, struct sockaddr *addr)
+{
+	int fd = socket(domain, type, 0);
+	if (fd < 0) {
+		printf("socket() failed.\n");
+		return -1;
+	}
+
+	if (addr) {
+		if (connect(fd, addr, sizeof(*addr)) < 0) {
+			printf("connect() failed.\n");
+			return -1;
+		}
+	}
+
+	return fd;
+}
+
+struct sockaddr* get_sockaddr_from_hostname(const char *hostname, int port)
+{
+	struct hostent *server = gethostbyname(hostname);
+	if (!server) {
+		printf("gethostbyname() failed.\n");
+		return NULL;
+	}
+
+	struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in));
+	if (!addr) {
+		printf("calloc() failed.\n");
+		return NULL;
+	}
+
+	//memset(&addr, 0, sizeof(struct sockaddr_in));
+	addr->sin_family = AF_INET;
+	addr->sin_port = htons(port);
+	memcpy(&addr->sin_addr.s_addr, server->h_addr_list[0], server->h_length);
+
+	return (struct sockaddr*) addr;
+}
+
+struct sockaddr* get_sockaddr_from_ip(const char *hostname, int port)
+{
+	struct sockaddr_in *addr = calloc(1, sizeof(struct sockaddr_in));
+	if (!addr) {
+		printf("calloc() failed.\n");
+		return NULL;
+	}
+
+	//memset(&addr, 0, sizeof(struct sockaddr_in));
+	addr->sin_family = AF_INET;
+	addr->sin_port = htons(port);
+	addr->sin_addr.s_addr = inet_addr(hostname);
+
+	return (struct sockaddr*) addr;
+}
+
+struct network_t {
+	int tcp_fd;
+	int udp_fd;
+	struct sockaddr *addr;
+	int addr_size;
+};
+
+struct network_t *networkInit(const char *hostname, int port)
+{
+	const unsigned SOC_ALIGN       = 0x1000;
+	const unsigned SOC_BUFFERSIZE  = 0x100000;
+
+	SOC_buffer = (u32*)calloc(SOC_ALIGN, SOC_BUFFERSIZE);
+	if (!SOC_buffer) {
+		printf("calloc() failed.\n");
+		return NULL;
+	}
+
+	unsigned initialized = SOC_Initialize(SOC_buffer, SOC_BUFFERSIZE);
+	if (initialized) {
+		printf("SOC_Initialize() failed.\n");
+		return NULL;
+	}
+
+	//struct sockaddr *addr = get_sockaddr_from_hostname(hostname, port);
+	struct sockaddr *addr = get_sockaddr_from_ip(hostname, port);
+	if (!addr)
+		return NULL;
+
+	// TODO: IPv6
+	int domain = AF_INET;
+
+	struct network_t *n = malloc(sizeof(struct network_t));
+	//n->tcp_fd = create_socket(domain, SOCK_STREAM, addr);
+	n->udp_fd = create_socket(domain, SOCK_DGRAM, NULL);
+	n->addr = addr;
+	n->addr_size = sizeof(struct sockaddr_in);
+	return n;
+}
+
+int sendKeys(struct network_t *n, u32 keys)
+{
+	const char *msg = (const char*) &keys;
+	int msglen = sizeof(keys);
+	return sendto(n->udp_fd, msg, msglen, 0, n->addr, n->addr_size);
+}
+
+int main(int argc, char **argv)
+{
+	//Matrix containing the name of each key. Useful for printing when a key is pressed
+	char keysNames[32][32] = {
+		"KEY_A", "KEY_B", "KEY_SELECT", "KEY_START",
+		"KEY_DRIGHT", "KEY_DLEFT", "KEY_DUP", "KEY_DDOWN",
+		"KEY_R", "KEY_L", "KEY_X", "KEY_Y",
+		"", "", "KEY_ZL", "KEY_ZR",
+		"", "", "", "",
+		"KEY_TOUCH", "", "", "",
+		"KEY_CSTICK_RIGHT", "KEY_CSTICK_LEFT", "KEY_CSTICK_UP", "KEY_CSTICK_DOWN",
+		"KEY_CPAD_RIGHT", "KEY_CPAD_LEFT", "KEY_CPAD_UP", "KEY_CPAD_DOWN"
+	};
+
+	// Initialize services
+	gfxInitDefault();
+
+	//Initialize console on top screen. Using NULL as the second argument tells the console library to use the internal console structure as current one
+	consoleInit(GFX_TOP, NULL);
+
+	u32 old_keys = 0; //In these variables there will be information about keys detected in the previous frame
+
+	// Initialize the network
+	struct network_t *n = networkInit("192.168.0.13", 16150);
+	if (!n) {
+		printf("HORROR!");
+		fflush(stdout);
+		gfxFlushBuffers();
+		gfxSwapBuffers();
+		for(;;);
+	}
+
+	printf("\x1b[0;0HPress Start to exit.");
+	printf("\x1b[1;0HCirclePad position:");
+
+	// Main loop
+	while (aptMainLoop())
+	{
+		//Scan all the inputs. This should be done once for each frame
+		hidScanInput();
+
+		//hidKeysHeld returns information about which buttons have are held down in this frame
+		u32 keys = hidKeysHeld();
+
+		//if (keys & KEY_START) break; // break in order to return to hbmenu
+
+		//Do the keys printing only if keys have changed
+		if (keys != old_keys)
+		{
+			//Clear console
+			consoleClear();
+
+			//These two lines must be rewritten because we cleared the whole console
+			printf("\x1b[0;0HPress Start to exit.");
+			printf("\x1b[1;0HCirclePad position:");
+
+			printf("\x1b[3;0H"); //Move the cursor to the fourth row because on the third one we'll write the circle pad position
+
+			//Check if some of the keys are down, held or up
+			for (int i = 0; i < 32; i++)
+			{
+				if (keys & BIT(i)) printf("%s\n", keysNames[i]);
+			}
+
+			if (sendKeys(n, keys) < 0) {
+				perror("sendKeys");
+				printf("HORROR! sendKeys()!");
+				fflush(stdout);
+				gfxFlushBuffers();
+				gfxSwapBuffers();
+				for(;;);
+			}
+		}
+
+		//Set keys old values for the next frame
+		old_keys = keys;
+
+		circlePosition pos;
+
+		//Read the CirclePad position
+		hidCircleRead(&pos);
+
+		//Print the CirclePad position
+		printf("\x1b[2;0H%04d; %04d", pos.dx, pos.dy);
+
+		// Flush and swap framebuffers
+		gfxFlushBuffers();
+		gfxSwapBuffers();
+
+		//Wait for VBlank
+		gspWaitForVBlank();
+	}
+
+	// Exit services
+	gfxExit();
+	return 0;
+}