gamebox 0.4.0.rc5 → 0.4.0.rc11

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. data/README.md +205 -127
  2. data/bin/gamebox +49 -3
  3. data/bin/gb +87 -0
  4. data/gamebox.gemspec +4 -3
  5. data/lib/gamebox.rb +1 -1
  6. data/lib/gamebox/actors/collidable_debugger.rb +4 -4
  7. data/lib/gamebox/actors/icon.rb +7 -0
  8. data/lib/gamebox/actors/label.rb +41 -42
  9. data/lib/gamebox/behaviors/animated.rb +6 -0
  10. data/lib/gamebox/behaviors/audible.rb +1 -2
  11. data/lib/gamebox/behaviors/collidable.rb +1 -1
  12. data/lib/gamebox/behaviors/graphical.rb +8 -4
  13. data/lib/gamebox/behaviors/physical.rb +6 -1
  14. data/lib/gamebox/behaviors/positioned.rb +4 -11
  15. data/lib/gamebox/behaviors/projectile.rb +8 -0
  16. data/lib/gamebox/behaviors/visible.rb +3 -3
  17. data/lib/gamebox/core/aabb_tree.rb +1 -1
  18. data/lib/gamebox/core/actor.rb +37 -50
  19. data/lib/gamebox/core/actor_definition.rb +41 -0
  20. data/lib/gamebox/core/actor_view.rb +6 -21
  21. data/lib/gamebox/core/actor_view_definition.rb +19 -0
  22. data/lib/gamebox/core/actor_view_factory.rb +9 -3
  23. data/lib/gamebox/core/behavior.rb +8 -27
  24. data/lib/gamebox/core/behavior_definition.rb +24 -0
  25. data/lib/gamebox/core/config_manager.rb +45 -30
  26. data/lib/gamebox/core/configuration.rb +5 -0
  27. data/lib/gamebox/core/core.rb +4 -0
  28. data/lib/gamebox/core/debug_helpers.rb +46 -0
  29. data/lib/gamebox/core/director.rb +32 -5
  30. data/lib/gamebox/core/event_symbols.rb +214 -0
  31. data/lib/gamebox/core/game.rb +1 -1
  32. data/lib/gamebox/core/input_manager.rb +1 -4
  33. data/lib/gamebox/core/input_mapper.rb +85 -0
  34. data/lib/gamebox/core/physics.rb +7 -3
  35. data/lib/gamebox/core/physics_manager.rb +5 -1
  36. data/lib/gamebox/core/renderer.rb +72 -0
  37. data/lib/gamebox/core/stage.rb +25 -81
  38. data/lib/gamebox/core/stage_definition.rb +60 -0
  39. data/lib/gamebox/core/stage_factory.rb +56 -0
  40. data/lib/gamebox/core/stage_manager.rb +5 -11
  41. data/lib/gamebox/core/timer_manager.rb +6 -2
  42. data/lib/gamebox/core/viewport.rb +12 -5
  43. data/lib/gamebox/core/wrapped_screen.rb +8 -5
  44. data/lib/gamebox/gamebox_application.rb +21 -19
  45. data/lib/gamebox/lib/array_ext.rb +9 -0
  46. data/lib/gamebox/lib/observable_attributes.rb +24 -0
  47. data/lib/gamebox/lib/vector2.rb +432 -0
  48. data/lib/gamebox/post_setup_handlers/file_watcher.rb +37 -0
  49. data/lib/gamebox/post_setup_handlers/gamebox_debug_helpers.rb +13 -0
  50. data/lib/gamebox/post_setup_handlers/pry_remote_server.rb +29 -0
  51. data/lib/gamebox/spec/helper.rb +165 -17
  52. data/lib/gamebox/tasks/gamebox_tasks.rake +27 -12
  53. data/lib/gamebox/version.rb +1 -1
  54. data/lib/gamebox/views/graphical_actor_view.rb +4 -5
  55. data/script/perf_aabb.rb +13 -8
  56. data/spec/acceptance/animation_spec.rb +1 -3
  57. data/spec/acceptance/basic_actor_lifecycle_spec.rb +1 -1
  58. data/spec/acceptance/fps_actor_spec.rb +8 -12
  59. data/spec/acceptance/input_mapper_spec.rb +17 -24
  60. data/spec/acceptance/update_ordering_spec.rb +64 -0
  61. data/spec/actors/label_spec.rb +90 -5
  62. data/spec/behaviors/animated_spec.rb +1 -1
  63. data/spec/behaviors/collidable_spec.rb +7 -15
  64. data/spec/behaviors/positioned_spec.rb +12 -5
  65. data/spec/core/actor_spec.rb +31 -3
  66. data/spec/core/actor_view_spec.rb +1 -1
  67. data/spec/core/behavior_spec.rb +3 -0
  68. data/spec/core/configuration_spec.rb +49 -2
  69. data/spec/core/input_mapper_spec.rb +7 -0
  70. data/spec/core/renderer_spec.rb +89 -0
  71. data/spec/core/stage_definition_spec.rb +41 -0
  72. data/spec/core/stage_manager_spec.rb +11 -11
  73. data/spec/core/stage_spec.rb +38 -78
  74. data/spec/core/viewport_spec.rb +5 -2
  75. data/spec/core/wrapped_screen_spec.rb +18 -12
  76. data/spec/views/graphical_actor_view_spec.rb +33 -62
  77. data/templates/actor_template.erb +11 -0
  78. data/templates/app/README.md +1 -0
  79. data/templates/app/src/actors/{player.rb → player_actor.rb} +3 -1
  80. data/templates/app/src/behaviors/.gitkeep +0 -0
  81. data/templates/app/src/stages/demo_stage.rb +14 -0
  82. data/templates/behavior_template.erb +13 -0
  83. data/templates/stage_template.erb +13 -0
  84. metadata +60 -21
  85. data/component_generators/actor_generator.rb +0 -17
  86. data/lib/gamebox/actors/emitter.rb +0 -12
  87. data/lib/gamebox/behaviors/emitting.rb +0 -48
  88. data/lib/gamebox/behaviors/input_mapper.rb +0 -11
  89. data/lib/gamebox/lib/ftor.rb +0 -372
  90. data/spec/actors/emitter_spec.rb +0 -5
  91. data/templates/app/NEXT_STEPS.txt +0 -1
  92. data/templates/app/README.rdoc +0 -24
  93. data/templates/app/src/demo_stage.rb +0 -7
@@ -0,0 +1,41 @@
1
+ class ActorDefinition
2
+ attr_accessor :behaviors, :attributes, :view_blk, :behavior_blk, :source
3
+ def initialize
4
+ @behaviors = []
5
+ @attributes = []
6
+ end
7
+
8
+ def has_behaviors(*behaviors, &blk)
9
+ if block_given?
10
+ collector = MethodMissingCollector.new
11
+ collector.instance_eval &blk
12
+ collector.calls.each do |name, args|
13
+ if args.empty?
14
+ @behaviors << name
15
+ else
16
+ @behaviors << {name => args.first}
17
+ end
18
+ end
19
+ end
20
+ behaviors.each do |beh|
21
+ @behaviors << beh
22
+ end
23
+ end
24
+ alias has_behavior has_behaviors
25
+
26
+ def has_attributes(*attributes)
27
+ attributes.each do |att|
28
+ @attributes << att
29
+ end
30
+ end
31
+ alias has_attribute has_attributes
32
+
33
+ def view(&blk)
34
+ @view_blk = blk
35
+ end
36
+
37
+ def behavior(&blk)
38
+ @behavior_blk = blk
39
+ end
40
+ end
41
+
@@ -1,6 +1,7 @@
1
1
  class ActorView
2
- construct_with :stage, :wrapped_screen, :resource_manager, :actor
3
- public :stage, :wrapped_screen, :resource_manager, :actor
2
+ # TODO remove stage
3
+ construct_with :renderer, :wrapped_screen, :resource_manager, :actor, :stage
4
+ public :wrapped_screen, :resource_manager, :actor, :stage
4
5
 
5
6
  attr_accessor :layer, :parallax
6
7
  def initialize
@@ -15,11 +16,11 @@ class ActorView
15
16
  end
16
17
 
17
18
  def register
18
- stage.register_drawable self
19
+ renderer.register_drawable self
19
20
  end
20
21
 
21
22
  def unregister
22
- stage.unregister_drawable self
23
+ renderer.unregister_drawable self
23
24
  end
24
25
 
25
26
  def screen_width
@@ -34,6 +35,7 @@ class ActorView
34
35
  def define(actor_view_type, &blk)
35
36
  @definitions ||= {}
36
37
  definition = ActorViewDefinition.new
38
+ definition.source = caller.detect{|c|!c.match /core/}
37
39
  definition.instance_eval &blk if block_given?
38
40
  @definitions[actor_view_type] = definition
39
41
  end
@@ -43,21 +45,4 @@ class ActorView
43
45
  end
44
46
  end
45
47
 
46
- # TODO can these defs be unified?
47
- class ActorViewDefinition
48
- attr_accessor :draw_block, :configure_block, :required_injections
49
- def requires(*injections_needed)
50
- @required_injections = injections_needed
51
- end
52
-
53
- def configure(&configure_block)
54
- @configure_block = configure_block
55
- end
56
-
57
- def draw(&draw_block)
58
- @draw_block = draw_block
59
- end
60
- end
61
-
62
-
63
48
  end
@@ -0,0 +1,19 @@
1
+ class ActorViewDefinition
2
+ attr_accessor :draw_block, :setup_block, :required_injections, :helpers_block, :source
3
+ def requires(*injections_needed)
4
+ @required_injections = injections_needed
5
+ end
6
+
7
+ def setup(&setup_block)
8
+ @setup_block = setup_block
9
+ end
10
+
11
+ def draw(&draw_block)
12
+ @draw_block = draw_block
13
+ end
14
+
15
+ def helpers(&helper_block)
16
+ @helpers_block = helper_block
17
+ end
18
+ end
19
+
@@ -27,9 +27,15 @@ class ActorViewFactory
27
27
  end
28
28
 
29
29
  view.define_singleton_method :draw, &view_definition.draw_block if view_definition.draw_block
30
- if view_definition.configure_block
31
- view.define_singleton_method :configure, &view_definition.configure_block
32
- view.configure
30
+ if view_definition.setup_block
31
+ view.define_singleton_method :setup, &view_definition.setup_block
32
+ view.setup
33
+ end
34
+
35
+ helpers = view_definition.helpers_block
36
+ if helpers
37
+ helpers_module = Module.new &helpers
38
+ view.extend helpers_module
33
39
  end
34
40
 
35
41
  behavior_factory.add_behavior(actor, :visible, view: view)
@@ -13,13 +13,14 @@ class Behavior
13
13
  end
14
14
 
15
15
  def reacts_with(*messages_with_methods)
16
+ # TODO do a merge here..
16
17
  @message_handlers = messages_with_methods
17
18
  end
18
19
 
19
- def react_to(message_type, *opts)
20
+ def react_to(message_type, *opts, &blk)
20
21
  # TODO perf analysis, should I use a hash here?
21
22
  if @message_handlers && @message_handlers.include?(message_type)
22
- send message_type, *opts
23
+ send message_type, *opts, &blk
23
24
  end
24
25
  end
25
26
 
@@ -27,11 +28,16 @@ class Behavior
27
28
  behavior_factory.add_behavior actor, behavior_name, opts
28
29
  end
29
30
 
31
+ def remove_behavior(behavior_name)
32
+ actor.remove_behavior(behavior_name)
33
+ end
34
+
30
35
  class << self
31
36
 
32
37
  def define(behavior_type, &blk)
33
38
  @definitions ||= {}
34
39
  definition = BehaviorDefinition.new
40
+ definition.source = caller.detect{|c|!c.match /core/}
35
41
  definition.instance_eval &blk if block_given?
36
42
  @definitions[behavior_type] = definition
37
43
  end
@@ -40,29 +46,4 @@ class Behavior
40
46
  @definitions ||= {}
41
47
  end
42
48
  end
43
-
44
- class BehaviorDefinition
45
- attr_accessor :setup_block, :required_injections, :react_to_block, :required_behaviors,
46
- :helpers_block
47
-
48
- def requires(*injections_needed)
49
- @required_injections = injections_needed
50
- end
51
-
52
- def requires_behaviors(*behaviors_needed)
53
- @required_behaviors = behaviors_needed
54
- end
55
-
56
- def setup(&setup_block)
57
- @setup_block = setup_block
58
- end
59
-
60
- def react_to(&react_to_block)
61
- @react_to_block = react_to_block
62
- end
63
-
64
- def helpers(&helpers_block)
65
- @helpers_block = helpers_block
66
- end
67
- end
68
49
  end
@@ -0,0 +1,24 @@
1
+ class BehaviorDefinition
2
+ attr_accessor :setup_block, :required_injections, :react_to_block, :required_behaviors,
3
+ :helpers_block, :source
4
+
5
+ def requires(*injections_needed)
6
+ @required_injections = injections_needed
7
+ end
8
+
9
+ def requires_behaviors(*behaviors_needed)
10
+ @required_behaviors = behaviors_needed
11
+ end
12
+
13
+ def setup(&setup_block)
14
+ @setup_block = setup_block
15
+ end
16
+
17
+ def react_to(&react_to_block)
18
+ @react_to_block = react_to_block
19
+ end
20
+
21
+ def helpers(&helpers_block)
22
+ @helpers_block = helpers_block
23
+ end
24
+ end
@@ -1,42 +1,57 @@
1
1
  class ConfigManager
2
2
 
3
- attr_accessor :settings
4
- GAME_SETTINGS_FILE = "game"
3
+ def settings
4
+ @settings ||= base_configuration.merge(user_configuration)
5
+ end
5
6
 
6
- def initialize
7
- @settings = load_config(GAME_SETTINGS_FILE)
7
+ def [](key)
8
+ settings[key]
8
9
  end
9
10
 
10
- def save
11
- save_settings(GAME_SETTINGS_FILE, @settings)
11
+ def []=(key,val)
12
+ settings[key] = val
12
13
  end
13
14
 
14
- def [](key)
15
- @settings[key]
15
+
16
+ def game_settings_file
17
+ "game.yml"
16
18
  end
17
19
 
18
- def []=(key,val)
19
- @settings[key] = val
20
- end
21
-
22
- # TODO make this path include that app name?
23
- def load_config(name)
24
- conf = YAML::load_file("#{Gamebox.configuration.config_path}#{name}.yml")
25
- user_file = "#{ENV['HOME']}/.gamebox/#{name}.yml"
26
- if File.exist? user_file
27
- user_conf = YAML::load_file user_file
28
- conf = conf.merge user_conf
29
- end
30
- conf
31
- end
32
-
33
- def save_settings(name, settings)
34
- user_gamebox_dir = "#{ENV['HOME']}/.gamebox"
35
- FileUtils.mkdir_p user_gamebox_dir
36
- user_file = "#{ENV['HOME']}/.gamebox/#{name}.yml"
37
- File.open user_file, "w" do |f|
38
- f.write settings.to_yaml
39
- end
20
+ def user_configuration_directory
21
+ File.join(ENV['HOME'], ".gamebox")
22
+ end
23
+
24
+ def base_configuration_directory
25
+ Gamebox.configuration.config_path
26
+ end
27
+
28
+ def user_configuration_filepath
29
+ File.join(user_configuration_directory, game_settings_file)
30
+ end
31
+
32
+ def base_configuration_filepath
33
+ File.join(base_configuration_directory, game_settings_file)
34
+ end
35
+
36
+ def base_configuration
37
+ load base_configuration_filepath
38
+ end
39
+
40
+ def user_configuration
41
+ load user_configuration_filepath
42
+ end
43
+
44
+ def load(configuration_filepath)
45
+ File.exist?(configuration_filepath) ? YAML::load_file(configuration_filepath) : {}
46
+ end
47
+
48
+ def save
49
+ save_to_file(user_configuration_filepath,settings.to_yaml)
50
+ end
51
+
52
+ def save_to_file(filepath,settings)
53
+ FileUtils.mkdir_p File.dirname(filepath)
54
+ File.write(filepath,settings)
40
55
  end
41
56
 
42
57
  end
@@ -28,9 +28,14 @@ module Gamebox
28
28
  add_setting :gb_fonts_path
29
29
 
30
30
  add_setting :game_name, default: "Untitled Game"
31
+ add_setting :needs_cursor, default: false
31
32
 
32
33
  add_setting :stages, default: [:demo]
33
34
 
35
+ add_setting :default_font_size, default: 30
36
+ add_setting :default_font_name, default: "Asimov.ttf"
37
+ add_setting :default_font_color, default: [250,250,250,255]
38
+
34
39
  def settings
35
40
  @settings ||= {}
36
41
  end
@@ -9,6 +9,10 @@ module Gamebox
9
9
  yield configuration if block_given?
10
10
  end
11
11
 
12
+ def define_stage(name, &blk)
13
+ Stage.define name, &blk
14
+ end
15
+
12
16
  def define_behavior(name, &blk)
13
17
  Behavior.define name, &blk
14
18
  end
@@ -0,0 +1,46 @@
1
+ module DebugHelpers
2
+ def actors(type=nil)
3
+ matching_actors = []
4
+ ObjectSpace.each_object do |obj|
5
+ if obj.class == Actor
6
+ if type.nil? || obj.actor_type == type
7
+ matching_actors << obj
8
+ end
9
+ end
10
+ end
11
+ log "found #{matching_actors.size} actors"
12
+ matching_actors
13
+ end
14
+
15
+ def current_stage
16
+ game.stage_manager.current_stage
17
+ end
18
+
19
+ def reload_behavior(behavior_name)
20
+ behavior = behavior_name.to_sym
21
+ log "reloading behavior: [#{behavior}]"
22
+ load "behaviors/#{behavior}.rb"
23
+
24
+ actors.each do |act|
25
+
26
+ if act.has_behavior?(behavior)
27
+ behaviors = act.instance_variable_get('@behaviors')
28
+ beh_opts = behaviors[behavior].opts
29
+
30
+ factory = act.this_object_context[:behavior_factory]
31
+ act.remove_behavior behavior
32
+
33
+ factory.add_behavior(act, behavior, beh_opts)
34
+ end
35
+ end
36
+ end
37
+
38
+ def load_actor(actor_type)
39
+ type = actor_type.to_sym
40
+ log "loading actor: [#{type}]"
41
+ load "actors/#{type}.rb"
42
+ end
43
+
44
+ module_function :reload_behavior, :actors, :load_actor
45
+
46
+ end
@@ -1,12 +1,19 @@
1
1
  # Directors manage actors.
2
2
  class Director
3
- extend Publisher
4
- can_fire_anything
5
- attr_accessor :actors
3
+ attr_accessor :actors, :update_slots
4
+
5
+ def initialize
6
+ @update_slots = [ :pre_update, :update, :post_update ]
7
+ clear_subscriptions
8
+ end
9
+
10
+ def clear_subscriptions
11
+ @subscriptions = Hash[@update_slots.map { |slot| [slot, []] }]
12
+ end
6
13
 
7
14
  def pause
8
15
  @paused_subscriptions = @subscriptions
9
- @subscriptions = {}
16
+ clear_subscriptions
10
17
  end
11
18
 
12
19
  def unpause
@@ -16,8 +23,28 @@ class Director
16
23
  end
17
24
  end
18
25
 
26
+ def when(event=:update, &callback)
27
+ @subscriptions[event] ||= []
28
+ @subscriptions[event] << callback
29
+ end
30
+
19
31
  def update(time)
20
32
  time_in_seconds = time / 1000.to_f
21
- fire :update, time, time_in_seconds
33
+ @update_slots.each do |slot|
34
+ @subscriptions[slot].each do |callback|
35
+ callback.call time, time_in_seconds
36
+ end
37
+ end
22
38
  end
39
+
40
+ def unsubscribe_all(listener)
41
+ if @subscriptions
42
+ for slot in @subscriptions.keys
43
+ @subscriptions[slot].delete_if do |block|
44
+ eval('self',block.binding).equal?(listener)
45
+ end
46
+ end
47
+ end
48
+ end
49
+
23
50
  end
@@ -0,0 +1,214 @@
1
+ KbRangeBegin = 0 unless defined?(KbRangeBegin)
2
+ KbRangeEnd = 0xffff unless defined?(KbRangeEnd)
3
+ MsRangeBegin = MsLeft unless defined?(MsRangeBegin)
4
+ MsRangeEnd = MsWheelDown unless defined?(MsRangeEnd)
5
+ GpRangeBegin = GpLeft unless defined?(GpRangeBegin)
6
+ GpRangeEnd = Gp3Button15 unless defined?(GpRangeEnd)
7
+
8
+ BUTTON_ID_TO_SYM = {
9
+ KbRangeBegin => :keyboard_begin,
10
+ KbEscape => :escape,
11
+ KbF1 => :f1,
12
+ KbF2 => :f2,
13
+ KbF3 => :f3,
14
+ KbF4 => :f4,
15
+ KbF5 => :f5,
16
+ KbF6 => :f6,
17
+ KbF7 => :f7,
18
+ KbF8 => :f8,
19
+ KbF9 => :f9,
20
+ KbF10 => :f10,
21
+ KbF11 => :f11,
22
+ KbF12 => :f12,
23
+ Kb1 => :one,
24
+ Kb2 => :two,
25
+ Kb3 => :three,
26
+ Kb4 => :four,
27
+ Kb5 => :five,
28
+ Kb6 => :six,
29
+ Kb7 => :seven,
30
+ Kb8 => :eight,
31
+ Kb9 => :nine,
32
+ Kb0 => :zero,
33
+ KbA => :a,
34
+ KbB => :b,
35
+ KbC => :c,
36
+ KbD => :d,
37
+ KbE => :e,
38
+ KbF => :f,
39
+ KbG => :g,
40
+ KbH => :h,
41
+ KbI => :i,
42
+ KbJ => :j,
43
+ KbK => :k,
44
+ KbL => :l,
45
+ KbM => :m,
46
+ KbN => :n,
47
+ KbO => :o,
48
+ KbP => :p,
49
+ KbQ => :q,
50
+ KbR => :r,
51
+ KbS => :s,
52
+ KbT => :t,
53
+ KbU => :u,
54
+ KbV => :v,
55
+ KbW => :w,
56
+ KbX => :x,
57
+ KbY => :y,
58
+ KbZ => :z,
59
+ KbTab => :tab,
60
+ KbReturn => :return,
61
+ KbSpace => :space,
62
+ KbLeftShift => :left_shift,
63
+ KbRightShift => :right_shift,
64
+ KbLeftControl => :left_control,
65
+ KbRightControl => :right_control,
66
+ KbLeftAlt => :left_alt,
67
+ KbRightAlt => :right_alt,
68
+ KbLeftMeta => :left_meta,
69
+ KbRightMeta => :right_meta,
70
+ KbBackspace => :backspace,
71
+ KbLeft => :left,
72
+ KbRight => :right,
73
+ KbUp => :up,
74
+ KbDown => :down,
75
+ KbHome => :home,
76
+ KbEnd => :end,
77
+ KbInsert => :insert,
78
+ KbDelete => :delete,
79
+ KbPageUp => :page_up,
80
+ KbPageDown => :page_down,
81
+ KbEnter => :enter,
82
+ KbNumpad1 => :numpad_1,
83
+ KbNumpad2 => :numpad_2,
84
+ KbNumpad3 => :numpad_3,
85
+ KbNumpad4 => :numpad_4,
86
+ KbNumpad5 => :numpad_5,
87
+ KbNumpad6 => :numpad_6,
88
+ KbNumpad7 => :numpad_7,
89
+ KbNumpad8 => :numpad_8,
90
+ KbNumpad9 => :numpad_9,
91
+ KbNumpad0 => :numpad_0,
92
+ KbNumpadAdd => :numpad_add,
93
+ KbNumpadSubtract => :numpad_subtract,
94
+ KbNumpadMultiply => :numpad_multiply,
95
+ KbNumpadDivide => :numpad_divide,
96
+ KbRangeEnd => :keyboard_end,
97
+ MsRangeBegin => :mouse_begin,
98
+ MsLeft => :mouse_left,
99
+ MsRight => :mouse_right,
100
+ MsMiddle => :mouse_middle,
101
+ MsWheelUp => :mouse_wheel_up,
102
+ MsWheelDown => :mouse_wheel_down,
103
+ MsRangeEnd => :mouse_end,
104
+ GpRangeBegin => :gp_begin,
105
+ GpLeft => :gp_left,
106
+ GpRight => :gp_right,
107
+ GpUp => :gp_up,
108
+ GpDown => :gp_down,
109
+ GpButton0 => :gp_button_0,
110
+ GpButton1 => :gp_button_1,
111
+ GpButton2 => :gp_button_2,
112
+ GpButton3 => :gp_button_3,
113
+ GpButton4 => :gp_button_4,
114
+ GpButton5 => :gp_button_5,
115
+ GpButton6 => :gp_button_6,
116
+ GpButton7 => :gp_button_7,
117
+ GpButton8 => :gp_button_8,
118
+ GpButton9 => :gp_button_9,
119
+ GpButton10 => :gp_button_10,
120
+ GpButton11 => :gp_button_11,
121
+ GpButton12 => :gp_button_12,
122
+ GpButton13 => :gp_button_13,
123
+ GpButton14 => :gp_button_14,
124
+ GpButton15 => :gp_button_15,
125
+ GpRangeEnd => :gp_end,
126
+ }
127
+
128
+ BUTTON_ID_TO_SYM.merge!({
129
+ Gp0Left => :gp0_left,
130
+ Gp0Right => :gp0_right,
131
+ Gp0Up => :gp0_up,
132
+ Gp0Down => :gp0_down,
133
+ Gp0Button0 => :gp0_button_0,
134
+ Gp0Button1 => :gp0_button_1,
135
+ Gp0Button2 => :gp0_button_2,
136
+ Gp0Button3 => :gp0_button_3,
137
+ Gp0Button4 => :gp0_button_4,
138
+ Gp0Button5 => :gp0_button_5,
139
+ Gp0Button6 => :gp0_button_6,
140
+ Gp0Button7 => :gp0_button_7,
141
+ Gp0Button8 => :gp0_button_8,
142
+ Gp0Button9 => :gp0_button_9,
143
+ Gp0Button10 => :gp0_button_10,
144
+ Gp0Button11 => :gp0_button_11,
145
+ Gp0Button12 => :gp0_button_12,
146
+ Gp0Button13 => :gp0_button_13,
147
+ Gp0Button14 => :gp0_button_14,
148
+ Gp0Button15 => :gp0_button_15,
149
+
150
+ Gp1Left => :gp1_left,
151
+ Gp1Right => :gp1_right,
152
+ Gp1Up => :gp1_up,
153
+ Gp1Down => :gp1_down,
154
+ Gp1Button0 => :gp1_button_0,
155
+ Gp1Button1 => :gp1_button_1,
156
+ Gp1Button2 => :gp1_button_2,
157
+ Gp1Button3 => :gp1_button_3,
158
+ Gp1Button4 => :gp1_button_4,
159
+ Gp1Button5 => :gp1_button_5,
160
+ Gp1Button6 => :gp1_button_6,
161
+ Gp1Button7 => :gp1_button_7,
162
+ Gp1Button8 => :gp1_button_8,
163
+ Gp1Button9 => :gp1_button_9,
164
+ Gp1Button10 => :gp1_button_10,
165
+ Gp1Button11 => :gp1_button_11,
166
+ Gp1Button12 => :gp1_button_12,
167
+ Gp1Button13 => :gp1_button_13,
168
+ Gp1Button14 => :gp1_button_14,
169
+ Gp1Button15 => :gp1_button_15,
170
+
171
+ Gp2Left => :gp2_left,
172
+ Gp2Right => :gp2_right,
173
+ Gp2Up => :gp2_up,
174
+ Gp2Down => :gp2_down,
175
+ Gp2Button0 => :gp2_button_0,
176
+ Gp2Button1 => :gp2_button_1,
177
+ Gp2Button2 => :gp2_button_2,
178
+ Gp2Button3 => :gp2_button_3,
179
+ Gp2Button4 => :gp2_button_4,
180
+ Gp2Button5 => :gp2_button_5,
181
+ Gp2Button6 => :gp2_button_6,
182
+ Gp2Button7 => :gp2_button_7,
183
+ Gp2Button8 => :gp2_button_8,
184
+ Gp2Button9 => :gp2_button_9,
185
+ Gp2Button10 => :gp2_button_10,
186
+ Gp2Button11 => :gp2_button_11,
187
+ Gp2Button12 => :gp2_button_12,
188
+ Gp2Button13 => :gp2_button_13,
189
+ Gp2Button14 => :gp2_button_14,
190
+ Gp2Button15 => :gp2_button_15,
191
+
192
+ Gp3Left => :gp3_left,
193
+ Gp3Right => :gp3_right,
194
+ Gp3Up => :gp3_up,
195
+ Gp3Down => :gp3_down,
196
+ Gp3Button0 => :gp3_button_0,
197
+ Gp3Button1 => :gp3_button_1,
198
+ Gp3Button2 => :gp3_button_2,
199
+ Gp3Button3 => :gp3_button_3,
200
+ Gp3Button4 => :gp3_button_4,
201
+ Gp3Button5 => :gp3_button_5,
202
+ Gp3Button6 => :gp3_button_6,
203
+ Gp3Button7 => :gp3_button_7,
204
+ Gp3Button8 => :gp3_button_8,
205
+ Gp3Button9 => :gp3_button_9,
206
+ Gp3Button10 => :gp3_button_10,
207
+ Gp3Button11 => :gp3_button_11,
208
+ Gp3Button12 => :gp3_button_12,
209
+ Gp3Button13 => :gp3_button_13,
210
+ Gp3Button14 => :gp3_button_14,
211
+ Gp3Button15 => :gp3_button_15,
212
+ }) if defined?(Gp0Left) # if multi gp support
213
+
214
+ BUTTON_SYM_TO_ID = BUTTON_ID_TO_SYM.invert