changeset 903:0e5f9d6135be

Make nexus player remote useable as a controller for games that only require a dpad + start + c. Use warning() instead of fprintf(stder,...) in io.c
author Michael Pavone <pavone@retrodev.com>
date Sat, 28 Nov 2015 14:30:30 -0800
parents 6011409ded0d
children 6bafe1988e8c
files android/assets/default.cfg android/src/org/libsdl/app/SDLActivity.java io.c render.h
diffstat 4 files changed, 158 insertions(+), 33 deletions(-) [+]
line wrap: on
line diff
--- a/android/assets/default.cfg	Fri Nov 27 13:10:02 2015 -0800
+++ b/android/assets/default.cfg	Sat Nov 28 14:30:30 2015 -0800
@@ -1,1 +1,118 @@
-../../default.cfg
\ No newline at end of file
+
+bindings {
+	keys {
+		up gamepads.1.up
+		down gamepads.1.down
+		left gamepads.1.left
+		right gamepads.1.right
+		a gamepads.1.a
+		s gamepads.1.b
+		d gamepads.1.c
+		q gamepads.1.x
+		w gamepads.1.y
+		e gamepads.1.z
+		f gamepads.1.mode
+		enter gamepads.1.start
+
+		[ ui.vdp_debug_mode
+		] ui.vdp_debug_pal
+		u ui.enter_debugger
+		esc ui.exit
+		` ui.save_state
+		0 ui.set_speed.0
+		1 ui.set_speed.1
+		2 ui.set_speed.2
+		3 ui.set_speed.3
+		4 ui.set_speed.4
+		5 ui.set_speed.5
+		6 ui.set_speed.6
+		7 ui.set_speed.7
+		= ui.next_speed
+		- ui.prev_speed
+		
+		
+		select gamepads.1.c
+		play gamepads.1.start
+		back ui.exit
+	}
+	pads {
+		0 {
+			dpads {
+				0 {
+					up gamepads.1.up
+					down gamepads.1.down
+					left gamepads.1.left
+					right gamepads.1.right
+				}
+			}
+			buttons {
+				0 gamepads.1.a
+				1 gamepads.1.b
+				2 gamepads.1.c
+				3 gamepads.1.x
+				4 gamepads.1.y
+				5 gamepads.1.z
+				6 gamepads.1.mode
+				7 gamepads.1.start
+			}
+		}
+		1 {
+			dpads {
+				0 {
+					up gamepads.2.up
+					down gamepads.2.down
+					left gamepads.2.left
+					right gamepads.2.right
+				}
+			}
+			buttons {
+				0 gamepads.2.a
+				1 gamepads.2.b
+				2 gamepads.2.c
+				3 gamepads.2.x
+				4 gamepads.2.y
+				5 gamepads.2.z
+				6 gamepads.2.mode
+				7 gamepads.2.start
+			}
+		}
+	}
+}
+
+io {
+	devices {
+		1 gamepad6.1
+		2 gamepad6.2
+	}
+}
+
+video {
+	width 640
+	vertex_shader default.v.glsl
+	fragment_shader default.f.glsl
+}
+
+audio {
+	rate 48000
+	buffer 512
+}
+
+clocks {
+	max_cycles 3420
+	speeds {
+		1 150
+		2 200
+		3 300
+		4 400
+		5 25
+		6 50
+		7 75
+	}
+}
+
+ui {
+	rom menu.bin
+}
+
+default_region U
+
--- a/android/src/org/libsdl/app/SDLActivity.java	Fri Nov 27 13:10:02 2015 -0800
+++ b/android/src/org/libsdl/app/SDLActivity.java	Sat Nov 28 14:30:30 2015 -0800
@@ -672,8 +672,7 @@
         // Some SOURCE_DPAD or SOURCE_GAMEPAD are also SOURCE_KEYBOARD
         // So, we try to process them as DPAD or GAMEPAD events first, if that fails we try them as KEYBOARD
         
-        if ( (event.getSource() & 0x00000401) != 0 || /* API 12: SOURCE_GAMEPAD */
-                   (event.getSource() & InputDevice.SOURCE_DPAD) != 0 ) {
+        if ( (event.getSource() & InputDevice.SOURCE_GAMEPAD) == InputDevice.SOURCE_GAMEPAD) {
             if (event.getAction() == KeyEvent.ACTION_DOWN) {
                 if (SDLActivity.onNativePadDown(event.getDeviceId(), keyCode) == 0) {
                     return true;
--- a/io.c	Fri Nov 27 13:10:02 2015 -0800
+++ b/io.c	Sat Nov 28 14:30:30 2015 -0800
@@ -18,6 +18,7 @@
 #include "io.h"
 #include "blastem.h"
 #include "render.h"
+#include "util.h"
 
 const char * device_type_names[] = {
 	"3-button gamepad",
@@ -75,7 +76,7 @@
 	uint8_t mode;
 } mousebinding;
 
-keybinding * bindings[256];
+keybinding * bindings[0x10000];
 keybinding * joybindings[MAX_JOYSTICKS];
 joydpad * joydpads[MAX_JOYSTICKS];
 mousebinding *mice[MAX_MICE];
@@ -83,12 +84,12 @@
 
 void bind_key(int keycode, uint8_t bind_type, uint8_t subtype_a, uint8_t subtype_b, uint8_t value)
 {
-	int bucket = keycode >> 8 & 0xFF;
+	int bucket = keycode >> 15 & 0xFFFF;
 	if (!bindings[bucket]) {
-		bindings[bucket] = malloc(sizeof(keybinding) * 256);
-		memset(bindings[bucket], 0, sizeof(keybinding) * 256);
+		bindings[bucket] = malloc(sizeof(keybinding) * 0x8000);
+		memset(bindings[bucket], 0, sizeof(keybinding) * 0x8000);
 	}
-	int idx = keycode & 0xFF;
+	int idx = keycode & 0x7FFF;
 	bindings[bucket][idx].bind_type = bind_type;
 	bindings[bucket][idx].subtype_a = subtype_a;
 	bindings[bucket][idx].subtype_b = subtype_b;
@@ -211,11 +212,11 @@
 
 void handle_keydown(int keycode)
 {
-	int bucket = keycode >> 8 & 0xFF;
+	int bucket = keycode >> 15 & 0xFFFF;
 	if (!bindings[bucket]) {
 		return;
 	}
-	int idx = keycode & 0xFF;
+	int idx = keycode & 0x7FFF;
 	keybinding * binding = bindings[bucket] + idx;
 	handle_binding_down(binding);
 }
@@ -307,11 +308,11 @@
 
 void handle_keyup(int keycode)
 {
-	int bucket = keycode >> 8 & 0xFF;
+	int bucket = keycode >> 15 & 0xFFFF;
 	if (!bindings[bucket]) {
 		return;
 	}
-	int idx = keycode & 0xFF;
+	int idx = keycode & 0x7FFF;
 	keybinding * binding = bindings[bucket] + idx;
 	handle_binding_up(binding);
 }
@@ -365,13 +366,13 @@
 				return 1;
 			} else {
 				if (target[gpadslen+1]) {
-					fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid button '%s'\n", target, target + gpadslen + 1);
+					warning("Gamepad mapping string '%s' refers to an invalid button '%s'\n", target, target + gpadslen + 1);
 				} else {
-					fprintf(stderr, "Gamepad mapping string '%s' has no button component\n", target);
+					warning("Gamepad mapping string '%s' has no button component\n", target);
 				}
 			}
 		} else {
-			fprintf(stderr, "Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]);
+			warning("Gamepad mapping string '%s' refers to an invalid gamepad number %c\n", target, target[gpadslen]);
 		}
 	} else if(!strncmp(target, "ui.", strlen("ui."))) {
 		*padbutton_out = 0;
@@ -393,12 +394,12 @@
 		} else if(!strcmp(target + 3, "exit")) {
 			*ui_out = UI_EXIT;
 		} else {
-			fprintf(stderr, "Unreconized UI binding type %s\n", target);
+			warning("Unreconized UI binding type %s\n", target);
 			return 0;
 		}
 		return 2;
 	} else {
-		fprintf(stderr, "Unrecognized binding type %s\n", target);
+		warning("Unrecognized binding type %s\n", target);
 	}
 	return 0;
 }
@@ -428,7 +429,7 @@
 		if (!keycode) {
 			keycode = curstr[0];
 			if (curstr[1] != 0) {
-				fprintf(stderr, "%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]);
+				warning("%s is not recognized as a key identifier, truncating to %c\n", curstr, curstr[0]);
 			}
 		}
 		char * target = cur->straight.value.ptrval;
@@ -471,9 +472,9 @@
 		int speed_index = atoi(curstr);
 		if (speed_index < 1) {
 			if (!strcmp(curstr, "0")) {
-				fputs("Speed index 0 cannot be set to a custom value\n", stderr);
+				warning("Speed index 0 cannot be set to a custom value\n");
 			} else {
-				fprintf(stderr, "%s is not a valid speed index", curstr);
+				warning("%s is not a valid speed index", curstr);
 			}
 		} else {
 			if (speed_index >= num_speeds) {
@@ -510,7 +511,7 @@
 			|| device_type[gamepad_len+2] > '8' || device_type[gamepad_len+3] != 0
 		)
 		{
-			fprintf(stderr, "%s is not a valid gamepad type\n", device_type);
+			warning("%s is not a valid gamepad type\n", device_type);
 		} else if (device_type[gamepad_len] == '3')
 		{
 			port->device_type = IO_GAMEPAD3;
@@ -572,7 +573,7 @@
 			char *pipe_name = tern_find_path(config, "io\0parallel_pipe\0").ptrval;
 			if (!pipe_name)
 			{
-				fprintf(stderr, "IO port %s is configured to use the sega parallel board, but no paralell_pipe is set!\n", io_name(i));
+				warning("IO port %s is configured to use the sega parallel board, but no paralell_pipe is set!\n", io_name(i));
 				ports[i].device_type = IO_NONE;
 			} else {
 				printf("IO port: %s connected to device '%s' with pipe name: %s\n", io_name(i), device_type_names[ports[i].device_type], pipe_name);
@@ -582,13 +583,13 @@
 				} else {
 					if (mkfifo(pipe_name, 0666) && errno != EEXIST)
 					{
-						fprintf(stderr, "Failed to create fifo %s for Sega parallel board emulation: %d %s\n", pipe_name, errno, strerror(errno));
+						warning("Failed to create fifo %s for Sega parallel board emulation: %d %s\n", pipe_name, errno, strerror(errno));
 						ports[i].device_type = IO_NONE;
 					} else {
 						ports[i].device.stream.data_fd = open(pipe_name, O_NONBLOCK | O_RDONLY);
 						if (ports[i].device.stream.data_fd == -1)
 						{
-							fprintf(stderr, "Failed to open fifo %s for Sega parallel board emulation: %d %s\n", pipe_name, errno, strerror(errno));
+							warning("Failed to open fifo %s for Sega parallel board emulation: %d %s\n", pipe_name, errno, strerror(errno));
 							ports[i].device_type = IO_NONE;
 						}
 					}
@@ -598,7 +599,7 @@
 			char *sock_name = tern_find_path(config, "io\0socket\0").ptrval;
 			if (!sock_name)
 			{
-				fprintf(stderr, "IO port %s is configured to use generic IO, but no socket is set!\n", io_name(i));
+				warning("IO port %s is configured to use generic IO, but no socket is set!\n", io_name(i));
 				ports[i].device_type = IO_NONE;
 			} else {
 				printf("IO port: %s connected to device '%s' with socket name: %s\n", io_name(i), device_type_names[ports[i].device_type], sock_name);
@@ -611,12 +612,12 @@
 				memcpy(saddr->sun_path, sock_name, pathlen+1);
 				if (bind(ports[i].device.stream.listen_fd, (struct sockaddr *)saddr, addrlen))
 				{
-					fprintf(stderr, "Failed to bind socket for IO Port %s to path %s: %d %s\n", io_name(i), sock_name, errno, strerror(errno));
+					warning("Failed to bind socket for IO Port %s to path %s: %d %s\n", io_name(i), sock_name, errno, strerror(errno));
 					goto cleanup_sock;
 				}
 				if (listen(ports[i].device.stream.listen_fd, 1))
 				{
-					fprintf(stderr, "Failed to listen on socket for IO Port %s: %d %s\n", io_name(i), errno, strerror(errno));
+					warning("Failed to listen on socket for IO Port %s: %d %s\n", io_name(i), errno, strerror(errno));
 					goto cleanup_sockfile;
 				}
 				sockfile_name = sock_name;
@@ -671,6 +672,10 @@
 	special = tern_insert_int(special, "esc", RENDERKEY_ESC);
 	special = tern_insert_int(special, "lshift", RENDERKEY_LSHIFT);
 	special = tern_insert_int(special, "rshift", RENDERKEY_RSHIFT);
+	special = tern_insert_int(special, "select", RENDERKEY_SELECT);
+	special = tern_insert_int(special, "play", RENDERKEY_PLAY);
+	special = tern_insert_int(special, "search", RENDERKEY_SEARCH);
+	special = tern_insert_int(special, "back", RENDERKEY_BACK);
 
 	tern_node * padbuttons = tern_insert_int(NULL, ".up", DPAD_UP);
 	padbuttons = tern_insert_int(padbuttons, ".down", DPAD_DOWN);
@@ -758,7 +763,7 @@
 	for (int i = 0; i < num_speeds; i++)
 	{
 		if (!speeds[i]) {
-			fprintf(stderr, "Speed index %d was not set to a valid percentage!", i);
+			warning("Speed index %d was not set to a valid percentage!", i);
 			speeds[i] = 100;
 		}
 	}
@@ -767,11 +772,11 @@
 
 void map_all_bindings(io_port *ports)
 {
-	for (int bucket = 0; bucket < 256; bucket++)
+	for (int bucket = 0; bucket < 0x10000; bucket++)
 	{
 		if (bindings[bucket])
 		{
-			map_bindings(ports, bindings[bucket], 256);
+			map_bindings(ports, bindings[bucket], 0x8000);
 		}
 	}
 	for (int stick = 0; stick < MAX_JOYSTICKS; stick++)
@@ -830,7 +835,7 @@
 		port->input[IO_TH0] = (value & 0xF) | 0x10;
 		port->input[IO_TH1] = (value >> 4) | 0x10;
 	} else if(numRead == -1 && errno != EAGAIN && errno != EWOULDBLOCK) {
-		fprintf(stderr, "Error reading pipe for IO port: %d %s\n", errno, strerror(errno));
+		warning("Error reading pipe for IO port: %d %s\n", errno, strerror(errno));
 	}
 }
 
@@ -860,7 +865,7 @@
 			port->device.stream.data_fd = -1;
 			wait_for_connection(port);
 		} else if (errno != EAGAIN && errno != EWOULDBLOCK) {
-			fprintf(stderr, "Error reading from socket for IO port: %d %s\n", errno, strerror(errno));
+			warning("Error reading from socket for IO port: %d %s\n", errno, strerror(errno));
 			close(port->device.stream.data_fd);
 			wait_for_connection(port);
 		} else if (port->input[IO_STATE] == IO_READ_PENDING) {
@@ -896,7 +901,7 @@
 				port->device.stream.data_fd = -1;
 				wait_for_connection(port);
 			} else if (errno != EAGAIN && errno != EWOULDBLOCK) {
-				fprintf(stderr, "Error writing to socket for IO port: %d %s\n", errno, strerror(errno));
+				warning("Error writing to socket for IO port: %d %s\n", errno, strerror(errno));
 				close(port->device.stream.data_fd);
 				wait_for_connection(port);
 			} else {
--- a/render.h	Fri Nov 27 13:10:02 2015 -0800
+++ b/render.h	Sat Nov 28 14:30:30 2015 -0800
@@ -15,6 +15,10 @@
 #define RENDERKEY_ESC     SDLK_ESCAPE
 #define RENDERKEY_LSHIFT  SDLK_LSHIFT
 #define RENDERKEY_RSHIFT  SDLK_RSHIFT
+#define RENDERKEY_SELECT  SDLK_SELECT
+#define RENDERKEY_PLAY    SDLK_AUDIOPLAY
+#define RENDERKEY_SEARCH  SDLK_AC_SEARCH
+#define RENDERKEY_BACK    SDLK_AC_BACK
 #define RENDER_DPAD_UP    SDL_HAT_UP
 #define RENDER_DPAD_DOWN  SDL_HAT_DOWN
 #define RENDER_DPAD_LEFT  SDL_HAT_LEFT