rubygame 2.2.0-mswin32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (94) hide show
  1. data/CREDITS +60 -0
  2. data/LICENSE +504 -0
  3. data/NEWS +201 -0
  4. data/README +139 -0
  5. data/ROADMAP +43 -0
  6. data/Rakefile +409 -0
  7. data/doc/extended_readme.rdoc +49 -0
  8. data/doc/getting_started.rdoc +47 -0
  9. data/doc/macosx_install.rdoc +70 -0
  10. data/doc/windows_install.rdoc +127 -0
  11. data/ext/rubygame/MANIFEST +25 -0
  12. data/ext/rubygame/rubygame_core.so +0 -0
  13. data/ext/rubygame/rubygame_event.c +644 -0
  14. data/ext/rubygame/rubygame_event.h +48 -0
  15. data/ext/rubygame/rubygame_event.obj +0 -0
  16. data/ext/rubygame/rubygame_gfx.c +942 -0
  17. data/ext/rubygame/rubygame_gfx.h +101 -0
  18. data/ext/rubygame/rubygame_gfx.obj +0 -0
  19. data/ext/rubygame/rubygame_gfx.so +0 -0
  20. data/ext/rubygame/rubygame_gl.c +154 -0
  21. data/ext/rubygame/rubygame_gl.h +32 -0
  22. data/ext/rubygame/rubygame_gl.obj +0 -0
  23. data/ext/rubygame/rubygame_image.c +108 -0
  24. data/ext/rubygame/rubygame_image.h +41 -0
  25. data/ext/rubygame/rubygame_image.obj +0 -0
  26. data/ext/rubygame/rubygame_image.so +0 -0
  27. data/ext/rubygame/rubygame_joystick.c +247 -0
  28. data/ext/rubygame/rubygame_joystick.h +41 -0
  29. data/ext/rubygame/rubygame_joystick.obj +0 -0
  30. data/ext/rubygame/rubygame_main.c +155 -0
  31. data/ext/rubygame/rubygame_main.h +33 -0
  32. data/ext/rubygame/rubygame_main.obj +0 -0
  33. data/ext/rubygame/rubygame_mixer.c +764 -0
  34. data/ext/rubygame/rubygame_mixer.h +62 -0
  35. data/ext/rubygame/rubygame_mixer.obj +0 -0
  36. data/ext/rubygame/rubygame_mixer.so +0 -0
  37. data/ext/rubygame/rubygame_screen.c +448 -0
  38. data/ext/rubygame/rubygame_screen.h +43 -0
  39. data/ext/rubygame/rubygame_screen.obj +0 -0
  40. data/ext/rubygame/rubygame_shared.c +209 -0
  41. data/ext/rubygame/rubygame_shared.h +60 -0
  42. data/ext/rubygame/rubygame_shared.obj +0 -0
  43. data/ext/rubygame/rubygame_surface.c +1147 -0
  44. data/ext/rubygame/rubygame_surface.h +62 -0
  45. data/ext/rubygame/rubygame_surface.obj +0 -0
  46. data/ext/rubygame/rubygame_time.c +183 -0
  47. data/ext/rubygame/rubygame_time.h +32 -0
  48. data/ext/rubygame/rubygame_time.obj +0 -0
  49. data/ext/rubygame/rubygame_ttf.c +599 -0
  50. data/ext/rubygame/rubygame_ttf.h +69 -0
  51. data/ext/rubygame/rubygame_ttf.obj +0 -0
  52. data/ext/rubygame/rubygame_ttf.so +0 -0
  53. data/lib/rubygame.rb +41 -0
  54. data/lib/rubygame/MANIFEST +12 -0
  55. data/lib/rubygame/clock.rb +128 -0
  56. data/lib/rubygame/color.rb +79 -0
  57. data/lib/rubygame/color/models/base.rb +106 -0
  58. data/lib/rubygame/color/models/hsl.rb +153 -0
  59. data/lib/rubygame/color/models/hsv.rb +149 -0
  60. data/lib/rubygame/color/models/rgb.rb +78 -0
  61. data/lib/rubygame/color/palettes/css.rb +49 -0
  62. data/lib/rubygame/color/palettes/palette.rb +100 -0
  63. data/lib/rubygame/color/palettes/x11.rb +177 -0
  64. data/lib/rubygame/constants.rb +238 -0
  65. data/lib/rubygame/event.rb +313 -0
  66. data/lib/rubygame/ftor.rb +370 -0
  67. data/lib/rubygame/hotspot.rb +265 -0
  68. data/lib/rubygame/keyconstants.rb +237 -0
  69. data/lib/rubygame/mediabag.rb +94 -0
  70. data/lib/rubygame/queue.rb +288 -0
  71. data/lib/rubygame/rect.rb +612 -0
  72. data/lib/rubygame/sfont.rb +223 -0
  73. data/lib/rubygame/sprite.rb +511 -0
  74. data/samples/FreeSans.ttf +0 -0
  75. data/samples/GPL.txt +340 -0
  76. data/samples/README +40 -0
  77. data/samples/chimp.bmp +0 -0
  78. data/samples/chimp.rb +313 -0
  79. data/samples/demo_gl.rb +151 -0
  80. data/samples/demo_gl_tex.rb +197 -0
  81. data/samples/demo_music.rb +75 -0
  82. data/samples/demo_rubygame.rb +284 -0
  83. data/samples/demo_sfont.rb +52 -0
  84. data/samples/demo_ttf.rb +193 -0
  85. data/samples/demo_utf8.rb +53 -0
  86. data/samples/fist.bmp +0 -0
  87. data/samples/load_and_blit.rb +22 -0
  88. data/samples/panda.png +0 -0
  89. data/samples/punch.wav +0 -0
  90. data/samples/ruby.png +0 -0
  91. data/samples/song.ogg +0 -0
  92. data/samples/term16.png +0 -0
  93. data/samples/whiff.wav +0 -0
  94. metadata +152 -0
@@ -0,0 +1,237 @@
1
+ # :enddoc:
2
+ module Rubygame
3
+ ALL_KEYS = {\
4
+ K_BACKSPACE => ["\b", "backspace"],\
5
+ K_TAB => ["\t", "tab"],\
6
+ K_CLEAR => [nil, "clear"],\
7
+ K_RETURN => ["\n", "return", "enter"],\
8
+ K_PAUSE => [nil, "pause"],\
9
+ K_ESCAPE => ["^[", "escape"],\
10
+ K_SPACE => [" ", "space"],\
11
+ K_EXCLAIM => ["!", "exclamation_mark", "exclaim"],\
12
+ K_QUOTEDBL => ["\"", "double_quote"],\
13
+ K_HASH => ["#", "hash", "pound", "bang"],\
14
+ K_DOLLAR => ["$", "dollar"],\
15
+ K_AMPERSAND => ["&", "ampersand", "and"],\
16
+ K_QUOTE => ["'", "quote"],\
17
+ K_LEFTPAREN => ["(", "left_parenthesis", "lparen"],\
18
+ K_RIGHTPAREN => [")", "right_parenthesis","rparen"],\
19
+ K_ASTERISK => ["*", "asterisk"],\
20
+ K_PLUS => ["+", "plus"],\
21
+ K_COMMA => [",", "comma"],\
22
+ K_MINUS => ["-", "minus"],\
23
+ K_PERIOD => [".", "period"],\
24
+ K_SLASH => ["/", "slash"],\
25
+ K_0 => ["0", "numberline_0"],\
26
+ K_1 => ["1", "numberline_1"],\
27
+ K_2 => ["2", "numberline_2"],\
28
+ K_3 => ["3", "numberline_3"],\
29
+ K_4 => ["4", "numberline_4"],\
30
+ K_5 => ["5", "numberline_5"],\
31
+ K_6 => ["6", "numberline_6"],\
32
+ K_7 => ["7", "numberline_7"],\
33
+ K_8 => ["8", "numberline_8"],\
34
+ K_9 => ["9", "numberline_9"],\
35
+ K_COLON => [":", "colon"],\
36
+ K_SEMICOLON => [";", "semicolon"],\
37
+ K_LESS => ["<", "less_than"],\
38
+ K_EQUALS => ["=", "equals"],\
39
+ K_GREATER => [">", "greater_than"],\
40
+ K_QUESTION => ["?", "question_mark", "question"],\
41
+ K_AT => ["@", "at"],\
42
+ K_LEFTBRACKET => ["[", "left_bracket", "lbracket"],\
43
+ K_BACKSLASH => ["\\", "backslash"],\
44
+ K_RIGHTBRACKET => ["]", "right_bracket", "rbracket"],\
45
+ K_CARET => ["^", "caret"],\
46
+ K_UNDERSCORE => ["_", "underscore"],\
47
+ K_BACKQUOTE => ["`", "backquote", "grave"],\
48
+ K_A => ["a"],\
49
+ K_B => ["b"],\
50
+ K_C => ["c"],\
51
+ K_D => ["d"],\
52
+ K_E => ["e"],\
53
+ K_F => ["f"],\
54
+ K_G => ["g"],\
55
+ K_H => ["h"],\
56
+ K_I => ["i"],\
57
+ K_J => ["j"],\
58
+ K_K => ["k"],\
59
+ K_L => ["l"],\
60
+ K_M => ["m"],\
61
+ K_N => ["n"],\
62
+ K_O => ["o"],\
63
+ K_P => ["p"],\
64
+ K_Q => ["q"],\
65
+ K_R => ["r"],\
66
+ K_S => ["s"],\
67
+ K_T => ["t"],\
68
+ K_U => ["u"],\
69
+ K_V => ["v"],\
70
+ K_W => ["w"],\
71
+ K_X => ["x"],\
72
+ K_Y => ["y"],\
73
+ K_Z => ["z"],\
74
+ K_DELETE => [nil, "delete", "del"],\
75
+ K_KP0 => ["0", "kp0", "keypad_0"],\
76
+ K_KP1 => ["1", "kp1", "keypad_1"],\
77
+ K_KP2 => ["2", "kp2", "keypad_2"],\
78
+ K_KP3 => ["3", "kp3", "keypad_3"],\
79
+ K_KP4 => ["4", "kp4", "keypad_4"],\
80
+ K_KP5 => ["5", "kp5", "keypad_5"],\
81
+ K_KP6 => ["6", "kp6", "keypad_6"],\
82
+ K_KP7 => ["7", "kp7", "keypad_7"],\
83
+ K_KP8 => ["8", "kp8", "keypad_8"],\
84
+ K_KP9 => ["9", "kp9", "keypad_9"],\
85
+ K_KP_PERIOD => [".", "period", "keypad_period"],\
86
+ K_KP_DIVIDE => ["/", "divide", "keypad_divide"],\
87
+ K_KP_MULTIPLY => ["*", "multiply", "keypad_multiply"],\
88
+ K_KP_MINUS => ["-", "minus", "keypad_minus"],\
89
+ K_KP_PLUS => ["+", "plus", "keypad_plus"],\
90
+ K_KP_ENTER => ["\n", "enter", "keypad_enter"],\
91
+ K_KP_EQUALS => ["=", "equals", "keypad_equals"],\
92
+ K_UP => [nil, "up"],\
93
+ K_DOWN => [nil, "down"],\
94
+ K_RIGHT => [nil, "right"],\
95
+ K_LEFT => [nil, "left"],\
96
+ K_INSERT => [nil, "insert", "ins"],\
97
+ K_HOME => [nil, "home"],\
98
+ K_END => [nil, "end"],\
99
+ K_PAGEUP => [nil, "page_up", "pgup"],\
100
+ K_PAGEDOWN => [nil, "page_down", "pgdn"],\
101
+ K_F1 => [nil, "f1", "function_1"],\
102
+ K_F2 => [nil, "f2", "function_2"],\
103
+ K_F3 => [nil, "f3", "function_3"],\
104
+ K_F4 => [nil, "f4", "function_4"],\
105
+ K_F5 => [nil, "f5", "function_5"],\
106
+ K_F6 => [nil, "f6", "function_6"],\
107
+ K_F7 => [nil, "f7", "function_7"],\
108
+ K_F8 => [nil, "f8", "function_8"],\
109
+ K_F9 => [nil, "f9", "function_9"],\
110
+ K_F10 => [nil, "f10", "function_10"],\
111
+ K_F11 => [nil, "f11", "function_11"],\
112
+ K_F12 => [nil, "f12", "function_12"],\
113
+ K_F13 => [nil, "f13", "function_13"],\
114
+ K_F14 => [nil, "f14", "function_14"],\
115
+ K_F15 => [nil, "f15", "function_15"],\
116
+ K_NUMLOCK => [nil, "numlock"],\
117
+ K_CAPSLOCK => [nil, "capslock", "caplock"],\
118
+ K_SCROLLOCK => [nil, "scroll_lock", "scrollock", "scrolllock"],\
119
+ K_LSHIFT => [nil, "left_shift", "lshift"],\
120
+ K_RSHIFT => [nil, "right_shift", "rshift"],\
121
+ K_LCTRL => [nil, "left_control", "lctrl"],\
122
+ K_RCTRL => [nil, "right_control", "rctrl"],\
123
+ K_LALT => [nil, "left_alt", "lalt"],\
124
+ K_RALT => [nil, "right_alt", "ralt"],\
125
+ K_LMETA => [nil, "left_meta", "lmeta"],\
126
+ K_RMETA => [nil, "right_meta", "rmeta"],\
127
+ K_LSUPER => [nil, "left_super", "lsuper"],\
128
+ K_RSUPER => [nil, "right_super", "rsuper"],\
129
+ K_MODE => [nil, "mode"],\
130
+ K_HELP => [nil, "help"],\
131
+ K_PRINT => [nil, "print_screen","prt_scr","print"],\
132
+ K_SYSREQ => [nil, "sysrq", "sysreq", "system_request"],\
133
+ K_BREAK => [nil, "break"],\
134
+ K_MENU => [nil, "menu"],\
135
+ K_POWER => [nil, "power"],\
136
+ # I have no idea how to get a Euro symbol here!
137
+ K_EURO => ["\u20ac", "euro"],\
138
+ # just K_WORLD_0 to K_WORLD_95 after this
139
+ K_WORLD_0 => [nil, "world_0"],\
140
+ K_WORLD_1 => [nil, "world_1"],\
141
+ K_WORLD_2 => [nil, "world_2"],\
142
+ K_WORLD_3 => [nil, "world_3"],\
143
+ K_WORLD_4 => [nil, "world_4"],\
144
+ K_WORLD_5 => [nil, "world_5"],\
145
+ K_WORLD_6 => [nil, "world_6"],\
146
+ K_WORLD_7 => [nil, "world_7"],\
147
+ K_WORLD_8 => [nil, "world_8"],\
148
+ K_WORLD_9 => [nil, "world_9"],\
149
+ K_WORLD_10 => [nil, "world_10"],\
150
+ K_WORLD_11 => [nil, "world_11"],\
151
+ K_WORLD_12 => [nil, "world_12"],\
152
+ K_WORLD_13 => [nil, "world_13"],\
153
+ K_WORLD_14 => [nil, "world_14"],\
154
+ K_WORLD_15 => [nil, "world_15"],\
155
+ K_WORLD_16 => [nil, "world_16"],\
156
+ K_WORLD_17 => [nil, "world_17"],\
157
+ K_WORLD_18 => [nil, "world_18"],\
158
+ K_WORLD_19 => [nil, "world_19"],\
159
+ K_WORLD_20 => [nil, "world_20"],\
160
+ K_WORLD_21 => [nil, "world_21"],\
161
+ K_WORLD_22 => [nil, "world_22"],\
162
+ K_WORLD_23 => [nil, "world_23"],\
163
+ K_WORLD_24 => [nil, "world_24"],\
164
+ K_WORLD_25 => [nil, "world_25"],\
165
+ K_WORLD_26 => [nil, "world_26"],\
166
+ K_WORLD_27 => [nil, "world_27"],\
167
+ K_WORLD_28 => [nil, "world_28"],\
168
+ K_WORLD_29 => [nil, "world_29"],\
169
+ K_WORLD_30 => [nil, "world_30"],\
170
+ K_WORLD_31 => [nil, "world_31"],\
171
+ K_WORLD_32 => [nil, "world_32"],\
172
+ K_WORLD_33 => [nil, "world_33"],\
173
+ K_WORLD_34 => [nil, "world_34"],\
174
+ K_WORLD_35 => [nil, "world_35"],\
175
+ K_WORLD_36 => [nil, "world_36"],\
176
+ K_WORLD_37 => [nil, "world_37"],\
177
+ K_WORLD_38 => [nil, "world_38"],\
178
+ K_WORLD_39 => [nil, "world_39"],\
179
+ K_WORLD_40 => [nil, "world_40"],\
180
+ K_WORLD_41 => [nil, "world_41"],\
181
+ K_WORLD_41 => [nil, "world_41"],\
182
+ K_WORLD_42 => [nil, "world_42"],\
183
+ K_WORLD_43 => [nil, "world_43"],\
184
+ K_WORLD_44 => [nil, "world_44"],\
185
+ K_WORLD_45 => [nil, "world_45"],\
186
+ K_WORLD_46 => [nil, "world_46"],\
187
+ K_WORLD_47 => [nil, "world_47"],\
188
+ K_WORLD_48 => [nil, "world_48"],\
189
+ K_WORLD_49 => [nil, "world_49"],\
190
+ K_WORLD_50 => [nil, "world_50"],\
191
+ K_WORLD_51 => [nil, "world_51"],\
192
+ K_WORLD_52 => [nil, "world_52"],\
193
+ K_WORLD_53 => [nil, "world_53"],\
194
+ K_WORLD_54 => [nil, "world_54"],\
195
+ K_WORLD_55 => [nil, "world_55"],\
196
+ K_WORLD_56 => [nil, "world_56"],\
197
+ K_WORLD_57 => [nil, "world_57"],\
198
+ K_WORLD_58 => [nil, "world_58"],\
199
+ K_WORLD_59 => [nil, "world_59"],\
200
+ K_WORLD_60 => [nil, "world_60"],\
201
+ K_WORLD_61 => [nil, "world_61"],\
202
+ K_WORLD_62 => [nil, "world_62"],\
203
+ K_WORLD_63 => [nil, "world_63"],\
204
+ K_WORLD_64 => [nil, "world_64"],\
205
+ K_WORLD_65 => [nil, "world_65"],\
206
+ K_WORLD_66 => [nil, "world_66"],\
207
+ K_WORLD_67 => [nil, "world_67"],\
208
+ K_WORLD_68 => [nil, "world_68"],\
209
+ K_WORLD_69 => [nil, "world_69"],\
210
+ K_WORLD_70 => [nil, "world_70"],\
211
+ K_WORLD_71 => [nil, "world_71"],\
212
+ K_WORLD_72 => [nil, "world_72"],\
213
+ K_WORLD_73 => [nil, "world_73"],\
214
+ K_WORLD_74 => [nil, "world_74"],\
215
+ K_WORLD_75 => [nil, "world_75"],\
216
+ K_WORLD_76 => [nil, "world_76"],\
217
+ K_WORLD_77 => [nil, "world_77"],\
218
+ K_WORLD_78 => [nil, "world_78"],\
219
+ K_WORLD_79 => [nil, "world_79"],\
220
+ K_WORLD_80 => [nil, "world_80"],\
221
+ K_WORLD_81 => [nil, "world_81"],\
222
+ K_WORLD_82 => [nil, "world_82"],\
223
+ K_WORLD_83 => [nil, "world_83"],\
224
+ K_WORLD_84 => [nil, "world_84"],\
225
+ K_WORLD_85 => [nil, "world_85"],\
226
+ K_WORLD_86 => [nil, "world_86"],\
227
+ K_WORLD_87 => [nil, "world_87"],\
228
+ K_WORLD_88 => [nil, "world_88"],\
229
+ K_WORLD_89 => [nil, "world_89"],\
230
+ K_WORLD_90 => [nil, "world_90"],\
231
+ K_WORLD_91 => [nil, "world_91"],\
232
+ K_WORLD_92 => [nil, "world_92"],\
233
+ K_WORLD_93 => [nil, "world_93"],\
234
+ K_WORLD_94 => [nil, "world_94"],\
235
+ K_WORLD_95 => [nil, "world_95"],\
236
+ }
237
+ end
@@ -0,0 +1,94 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2007 John Croisant
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #++
19
+
20
+ require "rubygame"
21
+
22
+ module Rubygame
23
+
24
+ # *NOTE*: you must require 'rubygame/mediabag' manually to gain access to
25
+ # Rubygame::MediaBag. It is not imported with Rubygame by default!
26
+ #
27
+ # A Hash-like class which will load and retain media files (images and
28
+ # sounds), so that the file can be loaded once, but used many times.
29
+ #
30
+ # The first time a file is requested with the #[] method,that file will be
31
+ # loaded into memory. All subsequent requests for the same file will return
32
+ # a reference to the already-loaded version. Ideally, objects should not
33
+ # have to know whether or not the image has been loaded or not.
34
+ class MediaBag
35
+ @@image_ext = %W{bmp gif jpg lbm pcx png pnm ppm pgm pbm tga tif xcf xpm}
36
+ @@sound_ext = %W{wav}
37
+
38
+ def initialize()
39
+ @media = Hash.new
40
+ end
41
+
42
+ # Return a reference to the stored value for key.
43
+ # If there is no value for key, automatically attempt to load key
44
+ # as a filename (guessing the file type based on its extension)
45
+ #
46
+ def [](key)
47
+ @media[key] or load(key)
48
+ rescue Rubygame::SDLError
49
+ nil
50
+ end
51
+
52
+ # Load the file, but only if it has not been previously loaded.
53
+ def load(filename)
54
+ @media[filename] or store( filename, load_file(filename) )
55
+ end
56
+
57
+ # Store value as key, but only if there is no previous value.
58
+ def store(key,value)
59
+ @media[key] ||= value
60
+ end
61
+
62
+ # Forcibly (re)load the file, replacing the previous version in memory
63
+ # (if any).
64
+ def force_load(filename)
65
+ force_store( filename, load_file(filename) )
66
+ end
67
+
68
+ # Forcibly store value as key, replacing the previous value (if any).
69
+ def force_store(key,value)
70
+ @media[key] = value
71
+ end
72
+
73
+ def load_file(filename)
74
+ case File::extname(filename).downcase[1..-1]
75
+ when *(@@image_ext)
76
+ return load_image(filename)
77
+ when *(@@sound_ext)
78
+ return load_sound(filename)
79
+ else
80
+ raise(ArgumentError,"Unrecognized file extension `%s': %s"%
81
+ [File::extname(filename), filename])
82
+ end
83
+ end
84
+
85
+ def load_image(filename)
86
+ return Rubygame::Surface.load_image(filename)
87
+ end
88
+
89
+ def load_sound(filename)
90
+ return Rubygame::Mixer::Sample.load_audio(filename)
91
+ end
92
+ end
93
+
94
+ end
@@ -0,0 +1,288 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 2004-2007 John Croisant
4
+ #
5
+ # This library is free software; you can redistribute it and/or
6
+ # modify it under the terms of the GNU Lesser General Public
7
+ # License as published by the Free Software Foundation; either
8
+ # version 2.1 of the License, or (at your option) any later version.
9
+ #
10
+ # This library is distributed in the hope that it will be useful,
11
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # Lesser General Public License for more details.
14
+ #
15
+ # You should have received a copy of the GNU Lesser General Public
16
+ # License along with this library; if not, write to the Free Software
17
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
+ #++
19
+
20
+ require "rubygame/event"
21
+
22
+ module Rubygame
23
+
24
+ # EventQueue provides a simple way to manage SDL's events, allowing the
25
+ # application to detect keyboard presses, mouse movements and clicks,
26
+ # joystick movement, etc. You can also post custom events to the
27
+ # EventQueue to help manage the game state.
28
+ #
29
+ # This class replaces the old Rubygame::Queue class, which is no longer
30
+ # available. While EventQueue class serves the same purpose as the old
31
+ # class, they are somewhat different in behavior. Please note that while
32
+ # the old class was a Singleton, this class is not; you may have as many
33
+ # separate instances of EventQueue as you wish (although it is strongly
34
+ # recommended that only one be used to #fetch_sdl_events).
35
+ #
36
+ # For basic usage, create a #new EventQueue with autofetch, then call the
37
+ # #each method once per game loop, passing a block which handles events.
38
+ # See the sample applications for examples of this.
39
+ #
40
+ # If you wish to ignore all events of a certain class, append those classes
41
+ # the instance variable @ignore (accessors are provided). You can ignore as
42
+ # many classes of events as you want, but make sure you don't ignore ALL
43
+ # event classes, or the user won't be able to control the game!
44
+ #
45
+ # If the program has to pause and wait for an event (for example, if the
46
+ # player must press a button to begin playing), you might find the #wait
47
+ # method to be convenient.
48
+ #
49
+ # For reference, the full list of SDL events is:
50
+ # - Event (base class, not used by itself)
51
+ # - ActiveEvent
52
+ # - JoyAxisEvent
53
+ # - JoyBallEvent
54
+ # - JoyDownEvent
55
+ # - JoyHatEvent
56
+ # - JoyUpEvent
57
+ # - KeyDownEvent
58
+ # - KeyUpEvent
59
+ # - MouseDownEvent
60
+ # - MouseMotionEvent
61
+ # - MouseUpEvent
62
+ # - QuitEvent
63
+ # - ResizeEvent
64
+ #
65
+ class EventQueue < Array
66
+ # Array of classes to be ignored by #push.
67
+ attr_accessor :ignore
68
+
69
+ # Whether to fetch SDL events automatically when #each and #wait are used.
70
+ # Enabled by default.
71
+ attr_accessor :autofetch
72
+
73
+ # Create a new EventQueue.
74
+ def initialize()
75
+ @autofetch = true
76
+ @ignore = []
77
+ yield self if block_given?
78
+ end
79
+
80
+ # Append events to the EventQueue.
81
+ # Silently ignores events whose class is in @ignore.
82
+ def push(*events)
83
+ events = events.flatten.delete_if {|e| @ignore.include?(e.class)}
84
+ events.each do |e|
85
+ super( e )
86
+ end
87
+ end
88
+
89
+ alias post push
90
+
91
+ alias peek_each each # Iterate through all events without removing.
92
+
93
+ # Iterate through all events in the EventQueue, yielding them one at a time
94
+ # to the given block. The EventQueue is flushed after all events have been
95
+ # yielded. You can use #peek_each if you want to keep the events.
96
+ #
97
+ # If the internal variable @autofetch is true, this method will call
98
+ # #fetch_sdl_events once before iterating.
99
+ def each(&block)
100
+ fetch_sdl_events if @autofetch
101
+ super
102
+ self.clear
103
+ end
104
+
105
+ # Posts pending SDL hardware events to the EventQueue. Only one EventQueue
106
+ # should call this method per application, and only if you are not using
107
+ # Rubygame#fetch_sdl_events to manually process events! Otherwise, some
108
+ # events may be removed from SDL's event stack before they can be properly
109
+ # processed!
110
+ def fetch_sdl_events
111
+ self.push(Rubygame.fetch_sdl_events())
112
+ end
113
+
114
+ # Wait for an event to be posted, then return that event.
115
+ # If there is already an event in the queue, this method will immediately
116
+ # return that event.
117
+ # Events that are ignored will not trigger the return.
118
+ #
119
+ # This method takes this argument:
120
+ # time:: how long (in milliseconds) to delay between each check for
121
+ # new events. Defaults to 10 ms.
122
+ #
123
+ # If a block is given to this method, it will be run after each
124
+ # unsuccessful check for new events. This method will pass to the block the
125
+ # number of times it has checked for new events.
126
+ #
127
+ # If the internal variable @autofetch is true, this method will call
128
+ # #fetch_sdl_events before every check for new events.
129
+ #
130
+ # Please be cautious when using this method, as it is rather easy to
131
+ # cause an infinite loop. Two ways an infinite loop might occur are:
132
+ # 1. Waiting for an SDL event when @autofetch is disabled. (This is
133
+ # not a problem if the block will post an event.)
134
+ # 2. Waiting for any event when all possible event types are ignored.
135
+ #
136
+ def wait(delay=10, &block)
137
+ iterations = 0
138
+ if block_given?
139
+ loop do
140
+ fetch_sdl_events() if @autofetch
141
+ if self.length >= 1
142
+ s = self.shift
143
+ return s unless s == nil
144
+ end
145
+ yield iterations
146
+ iterations += 1
147
+ Rubygame::Clock.delay(delay)
148
+ end
149
+ else
150
+ loop do
151
+ fetch_sdl_events() if @autofetch
152
+ s = self.shift
153
+ return s unless s == nil
154
+ iterations += 1
155
+ Rubygame::Clock.delay(delay)
156
+ end
157
+ end
158
+ end
159
+
160
+ end # class EventQueue
161
+
162
+
163
+ # A mixin module to extend EventQueue with the ability to 'deliver' specific
164
+ # types of events to subscribed objects, a la a mailing list. Each object
165
+ # must subscribe for the classes of events it wishes to receive;
166
+ # when the MailQueue receives an event of that type, it will deliver
167
+ # it to the subscribers. See #subscribe for more information.
168
+ #
169
+ # Please note that if you extend an already-existing EventQueue object
170
+ # with this mixin module (rather than including it in a class), you must
171
+ # call #setup before using the object. This will create the necessary
172
+ # internal variables for the MailQueue to work.
173
+ #
174
+ module MailQueue
175
+ # Whether to automatically deliver events as they are received.
176
+ # Enabled by default.
177
+ attr_accessor :autodeliver
178
+
179
+ # Create a new MailQueue object.
180
+ # Like EventQueue.new, this method will yield self if a block is given.
181
+ def initialize()
182
+ setup()
183
+ super
184
+ end
185
+
186
+ # Create the necessary internal variables for the MailQueue.
187
+ def setup
188
+ @subscribe = Hash.new
189
+ @autodeliver = true
190
+ end
191
+
192
+ # Returns an Array of all event classes which have at least one subscriber.
193
+ def list
194
+ @subscribe.collect { |k, v|
195
+ (v.length > 0) ? k : nil rescue NoMethodError nil
196
+ }.compact
197
+ end
198
+
199
+ # Subscribe +client+ to receive events that match +klass+.
200
+ #
201
+ # After the client object has been subscribed, the MailQueue will
202
+ # push along any event for which "klass === event" is true. This usually
203
+ # means that the event is an instance of klass or one of klass's child
204
+ # classes; however, note that klass may have changed its own #=== operator
205
+ # to have different behavior, so this is not always the case.
206
+ #
207
+ # Important: the MailQueue uses the client's #push method to deliver
208
+ # events! If the client does not have such a method, MailQueue will
209
+ # silently catch the error and move on to the next client.
210
+ #
211
+ # A client object may be subscribed for many different types of events
212
+ # simultaneously, and more than one client object may be subscribed to
213
+ # any type of event (in which case each object will receive the event).
214
+ # A client may also be subscribed multiple times for the same type (in
215
+ # which case it will receive duplicate events). Likewise, the client will
216
+ # receive duplicates if it is subscribed to multiple classes which share
217
+ # ancestry, for example Numeric and Float.
218
+ #
219
+ # If a client wishes to receive ALL types of events, it can subscribe to
220
+ # Object, which is a parent class of all objects.
221
+ #
222
+ # If the queue's @autodeliver is true, it will deliver events to
223
+ # subscribers immediately after they are posted, rather than waiting for
224
+ # #deliver to be called.
225
+ def subscribe(client,klass)
226
+ @subscribe[klass] << client
227
+ rescue NoMethodError
228
+ @subscribe[klass] = [client] if @subscribe[klass].nil?
229
+ end
230
+
231
+ # Returns true if +client+ is currently subscribed to receive events
232
+ # of type +klass+.
233
+ def subscribed?(client,klass)
234
+ return true if @subscribe[klass].include?(client) rescue NoMethodError
235
+ return false
236
+ end
237
+
238
+ # Unsubscribes the client to stop receiving events of type +klass+.
239
+ # It is safe (has no effect) to unsubscribe for an event type you
240
+ # are not subscribed to receive.
241
+ def unsubscribe(client,klass)
242
+ @subscribe[klass] -= [client] rescue NoMethodError
243
+ ensure
244
+ return
245
+ end
246
+
247
+ # This private method is used by #deliver to do the real work.
248
+ def deliver_event(event)
249
+ @subscribe.each_pair { |klass,clients|
250
+ begin
251
+ if klass === event
252
+ clients.each do |client|
253
+ client.push(event) rescue NoMethodError
254
+ end
255
+ end
256
+ rescue NoMethodError
257
+ end
258
+ }
259
+ end
260
+ private :deliver_event
261
+
262
+ # Deliver each pending event to all objects which are subscribed to
263
+ # that event class. Every client object MUST have a #push method, or
264
+ # events can't be delivered to it, and it will become very lonely!
265
+ #
266
+ # The queue will be cleared of all events after all deliveries are done.
267
+ def deliver()
268
+ each() { |event| deliver_event(event) }
269
+ clear()
270
+ end
271
+
272
+ # Append events to the queue. If @autodeliver is enabled, all events
273
+ # on the queue will be delivered to subscribed client objects immediately.
274
+ def push(*args)
275
+ # Temporarily disable autofetch to avoid infinite loop
276
+ a, @autofetch = @autofetch, false
277
+ # Fetch once to emulate autofetch, if it was enabled before
278
+ fetch_sdl_events() if a
279
+
280
+ super
281
+ deliver() if @autodeliver
282
+
283
+ @autofetch = a
284
+ return
285
+ end
286
+ end
287
+
288
+ end # module Rubygame