summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorTom Black <[email protected]>2017-12-02 21:58:07 -0800
committerTom Black <[email protected]>2017-12-02 22:27:16 -0800
commitb13074ebe542aa25c5b3b08afed4b60e1d23e1c6 (patch)
tree6ed6ca0e0bdf74198981bf01f626c6ade21b251c
parent18e5a492e9f3f3ba6c69998f577f7cc0d6ea085d (diff)
downloadruby2d-b13074ebe542aa25c5b3b08afed4b60e1d23e1c6.tar.gz
ruby2d-b13074ebe542aa25c5b3b08afed4b60e1d23e1c6.zip
Use controller mappings
-rw-r--r--ext/ruby2d/ruby2d.c111
-rw-r--r--lib/ruby2d/window.rb18
-rw-r--r--test/controller.rb204
3 files changed, 302 insertions, 31 deletions
diff --git a/ext/ruby2d/ruby2d.c b/ext/ruby2d/ruby2d.c
index 6cbe219..1b1bb5e 100644
--- a/ext/ruby2d/ruby2d.c
+++ b/ext/ruby2d/ruby2d.c
@@ -68,7 +68,7 @@
#define r_args_none (MRB_ARGS_NONE())
#define r_args_req(n) MRB_ARGS_REQ(n)
// Helpers
- #define r_char_to_sym(str) mrb_check_intern_cstr(mrb, str)
+ #define r_char_to_sym(str) mrb_symbol_value(mrb_intern_cstr(mrb, str))
#else
// Ruby
#define R_VAL VALUE
@@ -145,6 +145,14 @@ static void free_window() {
/*
+ * Normalize controller axis values to 0.0...1.0
+ */
+double normalize_controller_axis(int val) {
+ return val > 0 ? val / 32767.0 : val / 32768.0;
+}
+
+
+/*
* File#exists? for MRuby
*/
#if MRUBY
@@ -696,7 +704,7 @@ void on_mouse(S2D_Event e) {
// type, direction, delta_x, delta_y
type = r_char_to_sym("scroll");
direction = e.direction == S2D_MOUSE_SCROLL_NORMAL ?
- r_str_new("normal") : r_str_new("inverted");
+ r_char_to_sym("normal") : r_char_to_sym("inverted");
break;
case S2D_MOUSE_MOVE:
// type, x, y, delta_x, delta_y
@@ -707,26 +715,23 @@ void on_mouse(S2D_Event e) {
if (e.type == S2D_MOUSE_DOWN || e.type == S2D_MOUSE_UP) {
switch (e.button) {
case S2D_MOUSE_LEFT:
- button = r_str_new("left");
+ button = r_char_to_sym("left");
break;
case S2D_MOUSE_MIDDLE:
- button = r_str_new("middle");
+ button = r_char_to_sym("middle");
break;
case S2D_MOUSE_RIGHT:
- button = r_str_new("right");
+ button = r_char_to_sym("right");
break;
case S2D_MOUSE_X1:
- button = r_str_new("x1");
+ button = r_char_to_sym("x1");
break;
case S2D_MOUSE_X2:
- button = r_str_new("x2");
+ button = r_char_to_sym("x2");
break;
}
}
- // Bug in MRuby: If `button` or `direction` are symbols (created with
- // r_char_to_sym), they will always both be `nil`. Use `r_str_new` for now.
-
r_funcall(
ruby2d_window, "mouse_callback", 7, type, button, direction,
INT2NUM(e.x), INT2NUM(e.y), INT2NUM(e.delta_x), INT2NUM(e.delta_y)
@@ -739,23 +744,93 @@ void on_mouse(S2D_Event e) {
*/
static void on_controller(S2D_Event e) {
- R_VAL type = R_NIL;
+ R_VAL type = R_NIL; R_VAL axis = R_NIL; R_VAL button = R_NIL;
switch (e.type) {
case S2D_AXIS:
type = r_char_to_sym("axis");
+ switch (e.axis) {
+ case S2D_AXIS_LEFTX:
+ axis = r_char_to_sym("left_x");
+ break;
+ case S2D_AXIS_LEFTY:
+ axis = r_char_to_sym("left_y");
+ break;
+ case S2D_AXIS_RIGHTX:
+ axis = r_char_to_sym("right_x");
+ break;
+ case S2D_AXIS_RIGHTY:
+ axis = r_char_to_sym("right_y");
+ break;
+ case S2D_AXIS_TRIGGERLEFT:
+ axis = r_char_to_sym("trigger_left");
+ break;
+ case S2D_AXIS_TRIGGERRIGHT:
+ axis = r_char_to_sym("trigger_right");
+ break;
+ case S2D_AXIS_INVALID:
+ axis = r_char_to_sym("invalid");
+ break;
+ }
break;
- case S2D_BUTTON_DOWN:
- type = r_char_to_sym("button_down");
- break;
- case S2D_BUTTON_UP:
- type = r_char_to_sym("button_up");
+ case S2D_BUTTON_DOWN: case S2D_BUTTON_UP:
+ type = e.type == S2D_BUTTON_DOWN ? r_char_to_sym("button_down") : r_char_to_sym("button_up");
+ switch (e.button) {
+ case S2D_BUTTON_A:
+ button = r_char_to_sym("a");
+ break;
+ case S2D_BUTTON_B:
+ button = r_char_to_sym("b");
+ break;
+ case S2D_BUTTON_X:
+ button = r_char_to_sym("x");
+ break;
+ case S2D_BUTTON_Y:
+ button = r_char_to_sym("y");
+ break;
+ case S2D_BUTTON_BACK:
+ button = r_char_to_sym("back");
+ break;
+ case S2D_BUTTON_GUIDE:
+ button = r_char_to_sym("guide");
+ break;
+ case S2D_BUTTON_START:
+ button = r_char_to_sym("start");
+ break;
+ case S2D_BUTTON_LEFTSTICK:
+ button = r_char_to_sym("left_stick");
+ break;
+ case S2D_BUTTON_RIGHTSTICK:
+ button = r_char_to_sym("right_stick");
+ break;
+ case S2D_BUTTON_LEFTSHOULDER:
+ button = r_char_to_sym("left_shoulder");
+ break;
+ case S2D_BUTTON_RIGHTSHOULDER:
+ button = r_char_to_sym("right_shoulder");
+ break;
+ case S2D_BUTTON_DPAD_UP:
+ button = r_char_to_sym("up");
+ break;
+ case S2D_BUTTON_DPAD_DOWN:
+ button = r_char_to_sym("down");
+ break;
+ case S2D_BUTTON_DPAD_LEFT:
+ button = r_char_to_sym("left");
+ break;
+ case S2D_BUTTON_DPAD_RIGHT:
+ button = r_char_to_sym("right");
+ break;
+ case S2D_BUTTON_INVALID:
+ button = r_char_to_sym("invalid");
+ break;
+ }
break;
}
r_funcall(
- ruby2d_window, "controller_callback", 5, INT2NUM(e.which), type,
- INT2NUM(e.axis), INT2NUM(e.value), INT2NUM(e.button)
+ ruby2d_window, "controller_callback", 5, INT2NUM(e.which),
+ type, axis, DBL2NUM(normalize_controller_axis(e.value)), button
);
}
diff --git a/lib/ruby2d/window.rb b/lib/ruby2d/window.rb
index 0a5a995..686c6b0 100644
--- a/lib/ruby2d/window.rb
+++ b/lib/ruby2d/window.rb
@@ -6,10 +6,12 @@ module Ruby2D
attr_reader :objects
attr_accessor :mouse_x, :mouse_y, :frames, :fps
- MouseEvent = Struct.new(:type, :button, :direction, :x, :y, :delta_x, :delta_y)
- KeyEvent = Struct.new(:type, :key)
- ControllerEvent = Struct.new(:which, :type, :axis, :value, :button)
EventDescriptor = Struct.new(:type, :id)
+ MouseEvent = Struct.new(:type, :button, :direction, :x, :y, :delta_x, :delta_y)
+ KeyEvent = Struct.new(:type, :key)
+ ControllerEvent = Struct.new(:which, :type, :axis, :value, :button)
+ ControllerAxisEvent = Struct.new(:which, :axis, :value)
+ ControllerButtonEvent = Struct.new(:which, :button)
def initialize(args = {})
@title = args[:title] || "Ruby 2D"
@@ -173,10 +175,6 @@ module Ruby2D
end
def mouse_callback(type, button, direction, x, y, delta_x, delta_y)
- # Convert to symbols (see MRuby bug in native extension)
- button = button.to_sym unless button == nil
- direction = direction.to_sym unless direction == nil
-
# All mouse events
@events[:mouse].each do |id, e|
e.call(MouseEvent.new(type, button, direction, x, y, delta_x, delta_y))
@@ -216,17 +214,17 @@ module Ruby2D
# When controller axis motion, like analog sticks
when :axis
@events[:controller_axis].each do |id, e|
- e.call(ControllerEvent.new(which, type, axis, value, nil))
+ e.call(ControllerAxisEvent.new(which, axis, value))
end
# When controller button is pressed
when :button_down
@events[:controller_button_down].each do |id, e|
- e.call(ControllerEvent.new(which, type, nil, nil, button))
+ e.call(ControllerButtonEvent.new(which, button))
end
# When controller button is released
when :button_up
@events[:controller_button_up].each do |id, e|
- e.call(ControllerEvent.new(which, type, nil, nil, button))
+ e.call(ControllerButtonEvent.new(which, button))
end
end
end
diff --git a/test/controller.rb b/test/controller.rb
index b4de79a..5035ebb 100644
--- a/test/controller.rb
+++ b/test/controller.rb
@@ -1,6 +1,180 @@
require 'ruby2d'
-set title: "Ruby 2D — Controller", width: 300, height: 200
+set title: "Ruby 2D — Controller", width: 600, height: 425
+set diagnostics: true
+
+# Controller outline image
+controller = Image.new(path: 'media/controller.png')
+
+scale = 80
+
+axis_left_x = Quad.new(
+ x1: 156, y1: 130,
+ x2: 156, y2: 130,
+ x3: 156, y3: 159,
+ x4: 156, y4: 159,
+ color: [0, 1, 0, 1]
+)
+
+axis_left_y = Quad.new(
+ x1: 142, y1: 145,
+ x2: 171, y2: 145,
+ x3: 171, y3: 145,
+ x4: 142, y4: 145,
+ color: [0, 1, 0, 1]
+)
+
+axis_right_x = Quad.new(
+ x1: 374, y1: 215,
+ x2: 374, y2: 215,
+ x3: 374, y3: 244,
+ x4: 374, y4: 244,
+ color: [0, 1, 0, 1]
+)
+
+axis_right_y = Quad.new(
+ x1: 359, y1: 229,
+ x2: 388, y2: 229,
+ x3: 388, y3: 229,
+ x4: 359, y4: 229,
+ color: [0, 1, 0, 1]
+)
+
+axis_trigger_left = Quad.new(
+ x1: 8, y1: 71,
+ x2: 42, y2: 71,
+ x3: 42, y3: 71,
+ x4: 8, y4: 71,
+ color: [0, 1, 0, 1]
+)
+
+axis_trigger_right = Quad.new(
+ x1: 8 + 550, y1: 71,
+ x2: 42 + 550, y2: 71,
+ x3: 42 + 550, y3: 71,
+ x4: 8 + 550, y4: 71,
+ color: [0, 1, 0, 1]
+)
+
+@btn_a = Quad.new(
+ x1: 426, y1: 167,
+ x2: 426 + 33, y2: 167,
+ x3: 426 + 33, y3: 167 + 33,
+ x4: 426, y4: 167 + 33,
+ color: [0, 1, 0, 0]
+)
+
+@btn_b = Quad.new(
+ x1: 464, y1: 129,
+ x2: 464 + 33, y2: 129,
+ x3: 464 + 33, y3: 129 + 33,
+ x4: 464, y4: 129 + 33,
+ color: [1, 0, 0, 0]
+)
+
+@btn_x = Quad.new(
+ x1: 388, y1: 128,
+ x2: 388 + 33, y2: 128,
+ x3: 388 + 33, y3: 128 + 33,
+ x4: 388, y4: 128 + 33,
+ color: [0, 0.7, 1, 0]
+)
+
+@btn_y = Quad.new(
+ x1: 426, y1: 91,
+ x2: 426 + 33, y2: 91,
+ x3: 426 + 33, y3: 91 + 33,
+ x4: 426, y4: 91 + 33,
+ color: [1, 1, 0, 0]
+)
+
+@btn_back = Quad.new(
+ x1: 248, y1: 133,
+ x2: 248 + 23, y2: 133,
+ x3: 248 + 23, y3: 133 + 23,
+ x4: 248, y4: 133 + 23,
+ color: [1, 0.5, 0, 0]
+)
+
+@btn_guide = Quad.new(
+ x1: 281, y1: 69,
+ x2: 281 + 38, y2: 69,
+ x3: 281 + 38, y3: 69 + 38,
+ x4: 281, y4: 69 + 38,
+ color: [0.5, 1, 0.5, 0]
+)
+
+@btn_start = Quad.new(
+ x1: 331, y1: 133,
+ x2: 331 + 23, y2: 133,
+ x3: 331 + 23, y3: 133 + 23,
+ x4: 331, y4: 133 + 23,
+ color: [1, 0.5, 0, 0]
+)
+
+@btn_left_stick = Quad.new(
+ x1: 8, y1: 4,
+ x2: 8 + 34, y2: 4,
+ x3: 8 + 38, y3: 4 + 67,
+ x4: 8 - 4, y4: 4 + 67,
+ color: [1, 0, 0, 0]
+)
+
+@btn_right_stick = Quad.new(
+ x1: 558, y1: 4,
+ x2: 558 + 34, y2: 4,
+ x3: 558 + 38, y3: 4 + 67,
+ x4: 558 - 4, y4: 4 + 67,
+ color: [1, 0, 0, 0]
+)
+
+@btn_left_shoulder = Quad.new(
+ x1: 111, y1: 84,
+ x2: 117, y2: 64,
+ x3: 198, y3: 39,
+ x4: 225, y4: 52,
+ color: [0.5, 0, 1, 0]
+)
+
+@btn_right_shoulder = Quad.new(
+ x1: 494, y1: 85,
+ x2: 484, y2: 64,
+ x3: 401, y3: 39,
+ x4: 378, y4: 51,
+ color: [0.5, 0, 1, 0]
+)
+
+@btn_up = Quad.new(
+ x1: 216, y1: 194,
+ x2: 216 + 23, y2: 194,
+ x3: 216 + 23, y3: 194 + 28,
+ x4: 216, y4: 194 + 28,
+ color: [1, 0, 0.5, 0]
+)
+
+@btn_down = Quad.new(
+ x1: 216, y1: 243,
+ x2: 216 + 23, y2: 243,
+ x3: 216 + 23, y3: 243 + 27,
+ x4: 216, y4: 243 + 27,
+ color: [1, 0, 0.5, 0]
+)
+
+@btn_left = Quad.new(
+ x1: 189, y1: 221,
+ x2: 189 + 28, y2: 221,
+ x3: 189 + 28, y3: 221 + 22,
+ x4: 189, y4: 221 + 22,
+ color: [1, 0, 0.5, 0]
+)
+
+@btn_right = Quad.new(
+ x1: 238, y1: 221,
+ x2: 238 + 28, y2: 221,
+ x3: 238 + 28, y3: 221 + 22,
+ x4: 238, y4: 221 + 22,
+ color: [1, 0, 0.5, 0]
+)
on :controller do |event|
puts event
@@ -8,14 +182,38 @@ end
on :controller_axis do |event|
puts "Axis: #{event.axis}, Value: #{event.value}"
+ case event.axis
+ when :left_x
+ axis_left_x.x2 = 156 + event.value * scale
+ axis_left_x.x3 = 156 + event.value * scale
+ when :left_y
+ axis_left_y.y1 = 145 + event.value * scale
+ axis_left_y.y2 = 145 + event.value * scale
+ when :right_x
+ axis_right_x.x2 = 374 + event.value * scale
+ axis_right_x.x3 = 374 + event.value * scale
+ when :right_y
+ axis_right_y.y1 = 229 + event.value * scale
+ axis_right_y.y2 = 229 + event.value * scale
+ when :trigger_left
+ axis_trigger_left.y1 = 71 - event.value * 67
+ axis_trigger_left.y2 = 71 - event.value * 67
+ when :trigger_right
+ axis_trigger_right.y1 = 71 - event.value * 67
+ axis_trigger_right.y2 = 71 - event.value * 67
+ end
end
on :controller_button_down do |event|
- puts "Button down: #{event.button}"
+ instance_variable_get("@btn_#{event.button}").opacity = 1.0
end
on :controller_button_up do |event|
- puts "Button up: #{event.button}"
+ instance_variable_get("@btn_#{event.button}").opacity = 0
+end
+
+on :key_down do |event|
+ close if event.key == 'escape'
end
show