jemini 2009.10.27

Sign up to get free protection for your applications and to get access to all the features.
Files changed (127) hide show
  1. data/README.txt +9 -0
  2. data/bin/jemini +26 -0
  3. data/lib/ibxm.jar +0 -0
  4. data/lib/jinput.jar +0 -0
  5. data/lib/jogg-0.0.7.jar +0 -0
  6. data/lib/jorbis-0.0.15.jar +0 -0
  7. data/lib/jruby-complete.jar +0 -0
  8. data/lib/lwjgl.jar +0 -0
  9. data/lib/lwjgl_util_applet.jar +0 -0
  10. data/lib/native_files/OpenAL32.dll +0 -0
  11. data/lib/native_files/jinput-dx8.dll +0 -0
  12. data/lib/native_files/jinput-dx8_64.dll +0 -0
  13. data/lib/native_files/jinput-raw.dll +0 -0
  14. data/lib/native_files/jinput-raw_64.dll +0 -0
  15. data/lib/native_files/jinput-wintab.dll +0 -0
  16. data/lib/native_files/libjinput-linux.so +0 -0
  17. data/lib/native_files/libjinput-linux64.so +0 -0
  18. data/lib/native_files/libjinput-osx.jnilib +0 -0
  19. data/lib/native_files/liblwjgl.jnilib +0 -0
  20. data/lib/native_files/liblwjgl.so +0 -0
  21. data/lib/native_files/liblwjgl64.so +0 -0
  22. data/lib/native_files/libopenal.so +0 -0
  23. data/lib/native_files/lwjgl.dll +0 -0
  24. data/lib/native_files/openal.dylib +0 -0
  25. data/lib/natives-linux.jar +0 -0
  26. data/lib/natives-mac.jar +0 -0
  27. data/lib/natives-win32.jar +0 -0
  28. data/lib/phys2d.jar +0 -0
  29. data/lib/slick.jar +0 -0
  30. data/package/jar/jemini.jar +0 -0
  31. data/src/behavior.rb +248 -0
  32. data/src/behavior_event.rb +23 -0
  33. data/src/behaviors/animated_image.rb +88 -0
  34. data/src/behaviors/audible.rb +16 -0
  35. data/src/behaviors/axis_stateful.rb +35 -0
  36. data/src/behaviors/bounding_box_collidable.rb +27 -0
  37. data/src/behaviors/cardinal_movable.rb +121 -0
  38. data/src/behaviors/clickable.rb +19 -0
  39. data/src/behaviors/countable.rb +32 -0
  40. data/src/behaviors/debug_physical.rb +43 -0
  41. data/src/behaviors/debug_tangible.rb +31 -0
  42. data/src/behaviors/drawable.rb +7 -0
  43. data/src/behaviors/drawable_image.rb +111 -0
  44. data/src/behaviors/drawable_line.rb +32 -0
  45. data/src/behaviors/drawable_shape.rb +48 -0
  46. data/src/behaviors/fading_image_trail_emittable.rb +32 -0
  47. data/src/behaviors/game_object_emittable.rb +13 -0
  48. data/src/behaviors/grid_bound.rb +108 -0
  49. data/src/behaviors/handles_events.rb +33 -0
  50. data/src/behaviors/inertial.rb +14 -0
  51. data/src/behaviors/magnetic.rb +34 -0
  52. data/src/behaviors/metered.rb +3 -0
  53. data/src/behaviors/movable.rb +81 -0
  54. data/src/behaviors/particle_emitter.rb +27 -0
  55. data/src/behaviors/physical.rb +384 -0
  56. data/src/behaviors/physical_cardinal_movable.rb +111 -0
  57. data/src/behaviors/physical_image.rb +45 -0
  58. data/src/behaviors/pointer.rb +30 -0
  59. data/src/behaviors/pressable.rb +17 -0
  60. data/src/behaviors/regional.rb +76 -0
  61. data/src/behaviors/rotates_to_point.rb +19 -0
  62. data/src/behaviors/spatial.rb +43 -0
  63. data/src/behaviors/stateful.rb +33 -0
  64. data/src/behaviors/taggable.rb +28 -0
  65. data/src/behaviors/tangible.rb +59 -0
  66. data/src/behaviors/timeable.rb +88 -0
  67. data/src/behaviors/top_down_vehicle.rb +42 -0
  68. data/src/behaviors/triangle_trail_emittable.rb +46 -0
  69. data/src/behaviors/unique.rb +0 -0
  70. data/src/behaviors/updates.rb +8 -0
  71. data/src/behaviors/updates_at_consistant_rate.rb +28 -0
  72. data/src/behaviors/vectored_movement.rb +48 -0
  73. data/src/behaviors/world_collidable.rb +9 -0
  74. data/src/color.rb +70 -0
  75. data/src/events/grid_changed_event.rb +8 -0
  76. data/src/events/physical_message.rb +9 -0
  77. data/src/events/tangible_collision_event.rb +8 -0
  78. data/src/file_system.rb +17 -0
  79. data/src/game.rb +110 -0
  80. data/src/game_object.rb +176 -0
  81. data/src/game_objects/background.rb +10 -0
  82. data/src/game_objects/fading_image.rb +23 -0
  83. data/src/game_objects/tangible_object.rb +4 -0
  84. data/src/game_objects/text.rb +71 -0
  85. data/src/game_objects/triangle_trail.rb +85 -0
  86. data/src/game_state.rb +164 -0
  87. data/src/inflector.rb +68 -0
  88. data/src/input_helpers/joystick_dead_zone_filter.rb +9 -0
  89. data/src/jemini.rb +31 -0
  90. data/src/jemini_version.rb +4 -0
  91. data/src/listenable_mixin.rb +15 -0
  92. data/src/logger_mixin.rb +11 -0
  93. data/src/managers/basic_game_object_manager.rb +95 -0
  94. data/src/managers/basic_physics_manager.rb +95 -0
  95. data/src/managers/basic_render_manager.rb +49 -0
  96. data/src/managers/basic_tile_manager.rb +3 -0
  97. data/src/managers/basic_update_manager.rb +30 -0
  98. data/src/managers/diagnostic/diagnostic_input_manager.rb +0 -0
  99. data/src/managers/input_manager.rb +161 -0
  100. data/src/managers/input_support/input_binding.rb +77 -0
  101. data/src/managers/input_support/input_builder.rb +44 -0
  102. data/src/managers/input_support/input_listener.rb +74 -0
  103. data/src/managers/input_support/input_message.rb +5 -0
  104. data/src/managers/input_support/joystick_listener.rb +53 -0
  105. data/src/managers/input_support/key_listener.rb +27 -0
  106. data/src/managers/input_support/mouse_listener.rb +38 -0
  107. data/src/managers/input_support/slick_input_listener.rb +20 -0
  108. data/src/managers/input_support/slick_input_message.rb +11 -0
  109. data/src/managers/input_support/slick_input_translator.rb +15 -0
  110. data/src/managers/message_queue.rb +60 -0
  111. data/src/managers/network_manager.rb +41 -0
  112. data/src/managers/render_support/hardware_cursor.rb +13 -0
  113. data/src/managers/resource_manager.rb +167 -0
  114. data/src/managers/sound_manager.rb +47 -0
  115. data/src/managers/tag_manager.rb +47 -0
  116. data/src/managers/tangible_manager.rb +36 -0
  117. data/src/math.rb +23 -0
  118. data/src/org/rubyforge/rawr/Main.java +67 -0
  119. data/src/platform.rb +28 -0
  120. data/src/proc_enhancement.rb +5 -0
  121. data/src/project_generator.rb +138 -0
  122. data/src/resource.rb +31 -0
  123. data/src/spline.rb +13 -0
  124. data/src/states/input_diagnostic_state.rb +53 -0
  125. data/src/vector.rb +143 -0
  126. data/test/test_state.rb +3 -0
  127. metadata +188 -0
@@ -0,0 +1,77 @@
1
+ require 'managers/input_support/input_listener'
2
+
3
+ module Jemini
4
+ class InputBinding
5
+ MOUSE_BUTTON_NAMES = [:mouse_left, :mouse_right, :mouse_middle].freeze
6
+ attr_reader :action_name, :listeners
7
+
8
+ def initialize(action_name)
9
+ @action_name = action_name
10
+ @listeners = []
11
+ end
12
+
13
+ # type can be one of :hold, :release, :press, and :move
14
+ def add_input_listener(type, button_id, options={})
15
+ device = detect_device(button_id, type)
16
+ real_button = detect_button(button_id, device)
17
+ value = options[:value]
18
+ to = options[:to]
19
+ listener = InputListener.create(action_name, type, device, real_button)
20
+ listener.default_value = value
21
+ listener.message_to = to
22
+ InputManager.loading_input_manager.listeners << listener
23
+ end
24
+
25
+ def detect_device(button_id, type)
26
+ if mouse_button?(button_id, type)
27
+ :mouse
28
+ else
29
+ :key
30
+ end
31
+ end
32
+
33
+ def detect_button(button_id, device)
34
+ case device
35
+ when :mouse
36
+ detect_mouse_button(button_id)
37
+ when :key
38
+ case button_id.to_s
39
+ when /(left|right)_alt/
40
+ "Input::KEY_#{$1[0].chr.upcase}ALT".constantize
41
+ when /(left|right)_ctrl/
42
+ "Input::KEY_#{$1[0].chr.upcase}CONTROL".constantize
43
+ when /(left|right)_bracket/
44
+ "Input::KEY_#{$1[0].chr.upcase}BRACKET".constantize
45
+ when /(up|down|left|right)_arrow/
46
+ "Input::KEY_#{$1.upcase}".constantize
47
+ when /(left|right)_shift/
48
+ "Input::KEY_#{$1[0].chr.upcase}SHIFT".constantize
49
+ else
50
+ "Input::KEY_#{button_id.to_s.underscore.upcase}".constantize
51
+ end
52
+ end
53
+ end
54
+
55
+ def mouse_button?(button_id, type)
56
+ return true if type == :move && button_id == :mouse
57
+ return true if MOUSE_BUTTON_NAMES.include? button_id
58
+ return false unless button_id.respond_to? :has_key?
59
+ return true if button_id.has_key? :mouse_button
60
+ end
61
+
62
+ def detect_mouse_button(button_id)
63
+ case button_id
64
+ when :mouse_left
65
+ 0
66
+ when :mouse_right
67
+ 1
68
+ when :mouse_middle
69
+ 2
70
+ when :mouse
71
+ nil
72
+ else
73
+ button_id[:mouse_button]
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,44 @@
1
+ require 'managers/input_support/input_binding'
2
+ require 'logger_mixin'
3
+
4
+ module Jemini
5
+ class InputBuilder
6
+
7
+ include LoggerMixin
8
+
9
+ def self.declare
10
+ yield new
11
+ end
12
+
13
+ def in_order_to(action_name)
14
+ log.debug "in_order_to: #{action_name}"
15
+ @current_binding = create_binding(action_name)
16
+ yield self
17
+ @current_binding = nil
18
+ end
19
+
20
+ def create_binding(action_name)
21
+ InputBinding.new(action_name)
22
+ end
23
+
24
+ def hold(button, options={})
25
+ log.debug "hold: #{button}, #{options}"
26
+ @current_binding.add_input_listener(:hold, button, options)
27
+ end
28
+
29
+ def press(button, options={})
30
+ log.debug "press: #{button}, #{options}"
31
+ @current_binding.add_input_listener(:press, button, options)
32
+ end
33
+
34
+ def release(button, options={})
35
+ log.debug "release: #{button}, #{options}"
36
+ @current_binding.add_input_listener(:release, button, options)
37
+ end
38
+
39
+ def move(button, options={})
40
+ log.debug "move: #{button}, #{options}"
41
+ @current_binding.add_input_listener(:move, button, options)
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,74 @@
1
+ require 'managers/input_support/input_message'
2
+
3
+ module Jemini
4
+ class InputListener
5
+ attr_accessor :device,
6
+ :input_type,
7
+ :input_button_or_axis,
8
+ :joystick_id,
9
+ :destination_type,
10
+ :destination_value,
11
+ :input_callback,
12
+ :game_state,
13
+ :default_value,
14
+ :message_to
15
+
16
+ def self.create(message, type, device, button_id, options={}, &callback)
17
+ options[:input_callback] = callback
18
+ device_type = case device
19
+ when :key
20
+ KeyListener
21
+ when :mouse
22
+ MouseListener
23
+ when :joystick
24
+ JoystickListener
25
+ end
26
+ device_type.new(message, type, button_id, options)
27
+ end
28
+
29
+ # TODO: Indicate whether or not a joystick mapping is active if a joystick is not installed
30
+ def initialize(message, button_type, button_id, options)
31
+ @input_type = button_type
32
+ @input_button_or_axis = button_id
33
+ @game_message = message
34
+ # TODO: There has to be a better, threadsafe way to do this.
35
+ # Maybe threadsafety isn't a huge concern here?
36
+ @game_state = Jemini::InputManager::loading_input_manager.game_state
37
+ end
38
+
39
+ def poll(raw_input)
40
+ @poll_result = poll_value(raw_input)
41
+ if post_canceled?
42
+ @cancel_post = false
43
+ nil
44
+ else
45
+ to_game_message(raw_input, @poll_result)
46
+ end
47
+ end
48
+
49
+ def cancel_post!
50
+ @cancel_post = true
51
+ end
52
+
53
+ def post_canceled?
54
+ @cancel_post
55
+ end
56
+
57
+ def key
58
+ "#{@device}_#{@input_type}_#{@input_button_or_axis}_#{@joystick_id || 'any'}"
59
+ end
60
+
61
+ def to_s
62
+ key
63
+ end
64
+
65
+ # eventually, raw_input will need to be wrapped
66
+ def to_game_message(raw_input, game_value)
67
+ game_message = InputMessage.new(@game_message, default_value || game_value)
68
+ game_message.player = @player
69
+ @input_callback.call(game_message, raw_input) unless @input_callback.nil?
70
+ game_message.to = message_to
71
+ game_message
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,5 @@
1
+ module Jemini
2
+ class InputMessage < Message
3
+ attr_accessor :player
4
+ end
5
+ end
@@ -0,0 +1,53 @@
1
+ require 'managers/input_support/input_listener'
2
+
3
+ module Jemini
4
+ class JoystickListener < Jemini::InputListener
5
+ def device
6
+ :joystick
7
+ end
8
+
9
+ def find_axis_id_by_axis_name(raw_input, axis_name)
10
+ (0..raw_input.get_axis_count(@joystick_id)).find {|axis_id| raw_input.get_axis_name(@joystick_id, axis_id) == axis_name}
11
+ end
12
+
13
+ def poll_value(raw_input)
14
+ if @joystick_id && @joystick_id >= raw_input.controller_count
15
+ cancel_post!
16
+ return
17
+ end
18
+
19
+ case @input_type
20
+ when :axis_update
21
+ @axis_id ||= find_axis_id_by_axis_name(raw_input, @input_button_or_axis)
22
+ axis_value = raw_input.get_axis_value(@joystick_id, @axis_id)
23
+ axis_value
24
+ when :pressed
25
+ if @joystick_id.nil?
26
+ result = (0..raw_input.controller_count).any? {|i| raw_input.is_button_pressed(@input_button_or_axis, i)} unless raw_input.controller_count.zero?
27
+ else
28
+ result = raw_input.is_button_pressed(@input_button_or_axis, @joystick_id)
29
+ end
30
+ pressed = !@key_down_on_last_poll && result
31
+ @key_down_on_last_poll = result
32
+ cancel_post! unless pressed
33
+ pressed
34
+ when :held
35
+ if @joystick_id.nil?
36
+ result = (0..raw_input.controller_count).any? {|i| raw_input.is_button_pressed(@input_button_or_axis, i)} unless raw_input.controller_count.zero?
37
+ else
38
+ result = raw_input.is_button_pressed(@input_button_or_axis, @joystick_id)
39
+ end
40
+ cancel_post! unless result
41
+ result
42
+ when :released
43
+ button_down = raw_input.is_button_pressed(@input_button_or_axis, @joystick_id)
44
+ result = (@key_down_on_last_poll && !button_down) ? true : false
45
+ @key_down_on_last_poll = button_down
46
+ cancel_post! unless result
47
+ result
48
+ else
49
+ cancel_post!
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,27 @@
1
+ require 'managers/input_support/input_listener'
2
+
3
+ module Jemini
4
+ class KeyListener < Jemini::InputListener
5
+ def device
6
+ :key
7
+ end
8
+
9
+ def poll_value(raw_input)
10
+ case @input_type
11
+ when :press
12
+ cancel_post! unless raw_input.is_key_pressed(@input_button_or_axis)
13
+ when :hold
14
+ cancel_post! unless raw_input.is_key_down(@input_button_or_axis)
15
+ when :release
16
+ key_down = raw_input.is_key_down(@input_button_or_axis)
17
+ result = (@key_down_on_last_poll && !key_down) ? true : false
18
+ @key_down_on_last_poll = key_down
19
+ cancel_post! unless result
20
+ else
21
+ cancel_post!
22
+ raise "Input type of #{@input_type.inspect} is not supported!"
23
+ end
24
+ @game_value unless post_canceled?
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,38 @@
1
+ require 'managers/input_support/input_listener'
2
+
3
+ module Jemini
4
+ class MouseListener < Jemini::InputListener
5
+ def device
6
+ :mouse
7
+ end
8
+
9
+ def poll_value(raw_input)
10
+ value = MouseValue.new
11
+ value.position = percent_on_screen(raw_input)
12
+ value.screen_position = Vector.new(raw_input.mouse_x, raw_input.mouse_y)
13
+ case @input_type
14
+ when :move, :axis_update
15
+
16
+ when :press
17
+ cancel_post! unless raw_input.mouse_pressed?(@input_button_or_axis)
18
+ when :hold
19
+ cancel_post! unless raw_input.mouse_button_down?(@input_button_or_axis)
20
+ when :release
21
+ button_down = raw_input.mouse_button_down?(@input_button_or_axis)
22
+ result = (@button_down_on_last_poll && !button_down)
23
+ @button_down_on_last_poll = button_down
24
+ cancel_post! unless result
25
+ end
26
+
27
+ value
28
+ end
29
+
30
+ def percent_on_screen(raw_input)
31
+ Vector.new(raw_input.mouse_x.to_f / game_state.screen_size.x.to_f, raw_input.mouse_y.to_f / game_state.screen_size.y.to_f)
32
+ end
33
+ end
34
+
35
+ class MouseValue
36
+ attr_accessor :position, :screen_position, :position_delta, :screen_position_delta
37
+ end
38
+ end
@@ -0,0 +1,20 @@
1
+ module Jemini
2
+ class SlickInputListener
3
+ java_import 'org.newdawn.slick.InputListener'
4
+ include InputListener
5
+
6
+ def initialize(state)
7
+ @state = state
8
+ end
9
+
10
+ def isAcceptingInput
11
+ #@state == GameState.active_state
12
+ true
13
+ end
14
+
15
+ def method_missing(method, *args)
16
+ return if (method == :inputEnded) || @state != GameState.active_state
17
+ @state.manager(:message_queue).post_message SlickInputMessage.new(method, args)
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,11 @@
1
+ module Jemini
2
+ class SlickInputMessage < Message
3
+ attr_accessor :event_name, :data
4
+
5
+ def initialize(event_name, data)
6
+ self.name = :slick_input
7
+ @event_name = event_name
8
+ @data = data
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,15 @@
1
+ module Jemini
2
+ class SlickInputTranslator
3
+ SLICK_INPUT_TYPE_TRANSLATION = {
4
+ :keyPressed => [:key, :pressed], # which key?
5
+ :keyReleased => [:key, :released],
6
+ :mouseMoved => [:mouse, :moved],
7
+ :mousePressed => [:mouse, :pressed], # which button?
8
+ :mouseReleased => [:mouse, :released],
9
+ :mouseClicked => [:mouse, :clicked],
10
+ :mouseWheelMoved => [:mouse, :wheel_moved],
11
+ :controllerLeftPressed => [:controller, :pressed]
12
+
13
+ }
14
+ end
15
+ end
@@ -0,0 +1,60 @@
1
+ require 'thread'
2
+ module Jemini
3
+
4
+ # Message object that is posted to the MessageQueue.
5
+ class Message
6
+ attr_accessor :name, :value, :delta, :to
7
+
8
+ def initialize(name, value, delta=nil, to=nil)
9
+ @name = name
10
+ @value = value
11
+ @delta = delta
12
+ @to = to
13
+ end
14
+ end
15
+
16
+ class MessageQueue < Jemini::GameObject
17
+ def load
18
+ @listeners = Hash.new {|h,k| h[k] = []}
19
+ @messages = Queue.new
20
+ end
21
+
22
+ def process_messages(delta)
23
+ until @messages.empty?
24
+ message = @messages.shift
25
+ message.delta = delta
26
+
27
+ @listeners[message.name].each do |listener|
28
+ begin
29
+ if message.to.nil?
30
+ listener[1].call(message)
31
+ else
32
+ listener[1].call(message) if listener[0].respond_to?(:handles_events_for?) && listener[0].handles_events_for?(message.to)
33
+ end
34
+ rescue Exception => e
35
+ # Replace this with a logger
36
+ $stderr << "Error in callback #{listener[1]} for key: #{listener[0]}\n#{e.class} - #{e.message}\n#{e.backtrace.join("\n")}"
37
+ java.lang.System.exit(1)
38
+ end
39
+ end
40
+ end
41
+ end
42
+
43
+ def post_message(message)
44
+ @messages << message
45
+ end
46
+
47
+ # Listeners are registered on a certain type of message. This type is arbitrary
48
+ # and can be any symbol. The second parameter is a key that is used to identify
49
+ # the callback when it is removed. The third parameter is the callback object
50
+ # which must be a proc. Alternatively, the second parameter may be omitted and a
51
+ # block passed in its place.
52
+ def add_listener(type, key, callback=nil, &block)
53
+ @listeners[type.to_sym] << [key, callback || block]
54
+ end
55
+
56
+ def remove_listener(type, key)
57
+ @listeners[type.to_sym].delete_if {|listener| listener.first == key}
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,41 @@
1
+ module Jemini
2
+
3
+ class NetworkManager < Jemini::GameObject
4
+
5
+ attr_accessor :socket
6
+
7
+ class Peer
8
+ attr_accessor :address, :port
9
+ def initialize(address, port)
10
+ @address, @port = address, port
11
+ end
12
+ end
13
+
14
+ has_behavior :HandlesEvents
15
+
16
+ #An array of all network peers.
17
+ attr_accessor :peers
18
+
19
+ def load
20
+ @peers = []
21
+ @socket = UDPSocket.new
22
+ end
23
+
24
+ # def unload
25
+ # end
26
+
27
+ #Add an address and port to the list of network peers.
28
+ def add_peer(address, port = 5364)
29
+ @peers << Peer.new(address, port)
30
+ end
31
+
32
+ #Send event to each registered peer.
33
+ def notify_peers(event)
34
+ @peers.each do |peer|
35
+ @socket.send(event, 0, peer.address, peer.port)
36
+ end
37
+ end
38
+
39
+ end
40
+
41
+ end