rubygame 2.3.0-x86-mswin32-60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. data/CREDITS +60 -0
  2. data/LICENSE +504 -0
  3. data/NEWS +252 -0
  4. data/README +123 -0
  5. data/ROADMAP +109 -0
  6. data/Rakefile +440 -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 +123 -0
  11. data/ext/rubygame/rubygame_core.so +0 -0
  12. data/ext/rubygame/rubygame_event.c +644 -0
  13. data/ext/rubygame/rubygame_event.h +48 -0
  14. data/ext/rubygame/rubygame_event.obj +0 -0
  15. data/ext/rubygame/rubygame_gfx.c +942 -0
  16. data/ext/rubygame/rubygame_gfx.h +101 -0
  17. data/ext/rubygame/rubygame_gfx.obj +0 -0
  18. data/ext/rubygame/rubygame_gfx.so +0 -0
  19. data/ext/rubygame/rubygame_gl.c +154 -0
  20. data/ext/rubygame/rubygame_gl.h +32 -0
  21. data/ext/rubygame/rubygame_gl.obj +0 -0
  22. data/ext/rubygame/rubygame_image.c +252 -0
  23. data/ext/rubygame/rubygame_image.h +41 -0
  24. data/ext/rubygame/rubygame_image.obj +0 -0
  25. data/ext/rubygame/rubygame_image.so +0 -0
  26. data/ext/rubygame/rubygame_joystick.c +247 -0
  27. data/ext/rubygame/rubygame_joystick.h +41 -0
  28. data/ext/rubygame/rubygame_joystick.obj +0 -0
  29. data/ext/rubygame/rubygame_main.c +155 -0
  30. data/ext/rubygame/rubygame_main.h +36 -0
  31. data/ext/rubygame/rubygame_main.obj +0 -0
  32. data/ext/rubygame/rubygame_mixer.c +1024 -0
  33. data/ext/rubygame/rubygame_mixer.h +36 -0
  34. data/ext/rubygame/rubygame_mixer.obj +0 -0
  35. data/ext/rubygame/rubygame_mixer.so +0 -0
  36. data/ext/rubygame/rubygame_music.c +1017 -0
  37. data/ext/rubygame/rubygame_music.h +29 -0
  38. data/ext/rubygame/rubygame_music.obj +0 -0
  39. data/ext/rubygame/rubygame_screen.c +448 -0
  40. data/ext/rubygame/rubygame_screen.h +43 -0
  41. data/ext/rubygame/rubygame_screen.obj +0 -0
  42. data/ext/rubygame/rubygame_shared.c +272 -0
  43. data/ext/rubygame/rubygame_shared.h +68 -0
  44. data/ext/rubygame/rubygame_shared.obj +0 -0
  45. data/ext/rubygame/rubygame_sound.c +863 -0
  46. data/ext/rubygame/rubygame_sound.h +29 -0
  47. data/ext/rubygame/rubygame_sound.obj +0 -0
  48. data/ext/rubygame/rubygame_surface.c +1151 -0
  49. data/ext/rubygame/rubygame_surface.h +62 -0
  50. data/ext/rubygame/rubygame_surface.obj +0 -0
  51. data/ext/rubygame/rubygame_time.c +183 -0
  52. data/ext/rubygame/rubygame_time.h +32 -0
  53. data/ext/rubygame/rubygame_time.obj +0 -0
  54. data/ext/rubygame/rubygame_ttf.c +599 -0
  55. data/ext/rubygame/rubygame_ttf.h +69 -0
  56. data/ext/rubygame/rubygame_ttf.obj +0 -0
  57. data/ext/rubygame/rubygame_ttf.so +0 -0
  58. data/lib/rubygame.rb +41 -0
  59. data/lib/rubygame/clock.rb +128 -0
  60. data/lib/rubygame/color.rb +79 -0
  61. data/lib/rubygame/color/models/base.rb +111 -0
  62. data/lib/rubygame/color/models/hsl.rb +153 -0
  63. data/lib/rubygame/color/models/hsv.rb +149 -0
  64. data/lib/rubygame/color/models/rgb.rb +78 -0
  65. data/lib/rubygame/color/palettes/css.rb +49 -0
  66. data/lib/rubygame/color/palettes/palette.rb +100 -0
  67. data/lib/rubygame/color/palettes/x11.rb +177 -0
  68. data/lib/rubygame/constants.rb +238 -0
  69. data/lib/rubygame/event.rb +313 -0
  70. data/lib/rubygame/ftor.rb +370 -0
  71. data/lib/rubygame/hotspot.rb +265 -0
  72. data/lib/rubygame/keyconstants.rb +237 -0
  73. data/lib/rubygame/mediabag.rb +94 -0
  74. data/lib/rubygame/named_resource.rb +254 -0
  75. data/lib/rubygame/queue.rb +288 -0
  76. data/lib/rubygame/rect.rb +612 -0
  77. data/lib/rubygame/sfont.rb +223 -0
  78. data/lib/rubygame/sprite.rb +511 -0
  79. data/samples/FreeSans.ttf +0 -0
  80. data/samples/GPL.txt +340 -0
  81. data/samples/README +40 -0
  82. data/samples/chimp.bmp +0 -0
  83. data/samples/chimp.rb +302 -0
  84. data/samples/demo_gl.rb +151 -0
  85. data/samples/demo_gl_tex.rb +197 -0
  86. data/samples/demo_music.rb +77 -0
  87. data/samples/demo_rubygame.rb +296 -0
  88. data/samples/demo_sfont.rb +52 -0
  89. data/samples/demo_ttf.rb +193 -0
  90. data/samples/demo_utf8.rb +53 -0
  91. data/samples/fist.bmp +0 -0
  92. data/samples/load_and_blit.rb +22 -0
  93. data/samples/panda.png +0 -0
  94. data/samples/punch.wav +0 -0
  95. data/samples/ruby.png +0 -0
  96. data/samples/song.ogg +0 -0
  97. data/samples/term16.png +0 -0
  98. data/samples/whiff.wav +0 -0
  99. metadata +164 -0
@@ -0,0 +1,69 @@
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
+
21
+ #ifndef _RUBYGAME_TTF_H
22
+ #define _RUBYGAME_TTF_H
23
+
24
+ #include "SDL_ttf.h"
25
+
26
+ #ifndef SDL_TTF_MAJOR_VERSION
27
+ #define SDL_TTF_MAJOR_VERSION 0
28
+ #endif
29
+
30
+ #ifndef SDL_TTF_MINOR_VERSION
31
+ #define SDL_TTF_MINOR_VERSION 0
32
+ #endif
33
+
34
+ #ifndef SDL_TTF_PATCHLEVEL
35
+ #define SDL_TTF_PATCHLEVEL 0
36
+ #endif
37
+
38
+ extern void Init_rubygame_ttf();
39
+
40
+ extern VALUE cTTF;
41
+
42
+ extern VALUE rbgm_ttf_setup(VALUE);
43
+ extern VALUE rbgm_ttf_quit(VALUE);
44
+ extern VALUE rbgm_ttf_new(VALUE, VALUE, VALUE);
45
+ extern VALUE rbgm_ttf_initialize(int, VALUE*, VALUE);
46
+
47
+ extern VALUE rbgm_ttf_getbold(VALUE);
48
+ extern VALUE rbgm_ttf_setbold(VALUE, VALUE);
49
+
50
+ extern VALUE rbgm_ttf_getitalic(VALUE);
51
+ extern VALUE rbgm_ttf_setitalic(VALUE, VALUE);
52
+
53
+ extern VALUE rbgm_ttf_getunderline(VALUE);
54
+ extern VALUE rbgm_ttf_setunderline(VALUE, VALUE);
55
+
56
+ extern VALUE rbgm_ttf_height(VALUE);
57
+ extern VALUE rbgm_ttf_ascent(VALUE);
58
+ extern VALUE rbgm_ttf_descent(VALUE);
59
+ extern VALUE rbgm_ttf_lineskip(VALUE);
60
+
61
+ extern VALUE rbgm_ttf_sizetext(VALUE, VALUE);
62
+ extern VALUE rbgm_ttf_size_utf8(VALUE, VALUE);
63
+ extern VALUE rbgm_ttf_size_unicode(VALUE, VALUE);
64
+
65
+ extern VALUE rbgm_ttf_render(int, VALUE*, VALUE);
66
+ extern VALUE rbgm_ttf_render_utf8(int , VALUE*, VALUE);
67
+ extern VALUE rbgm_ttf_render_unicode(int , VALUE*, VALUE);
68
+
69
+ #endif
Binary file
Binary file
data/lib/rubygame.rb ADDED
@@ -0,0 +1,41 @@
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
+ # This is the file that should be imported, it in turn imports rubygame.so
21
+ # (which has all of the C code for rubygame) and all the other rubygame modules
22
+
23
+ require "rbconfig"
24
+
25
+ require "rubygame_core"
26
+
27
+ %W{ rubygame_gfx rubygame_image rubygame_ttf rubygame_mixer }.each do |mod|
28
+ begin
29
+ require mod
30
+ rescue LoadError
31
+ warn( "Warning: Unable to require optional module: #{mod}.") if $VERBOSE
32
+ end
33
+ end
34
+
35
+ require "rubygame/color"
36
+ require "rubygame/constants"
37
+ require "rubygame/event"
38
+ require "rubygame/queue"
39
+ require "rubygame/rect"
40
+ require "rubygame/sprite"
41
+ require "rubygame/clock"
@@ -0,0 +1,128 @@
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
+ module Rubygame
21
+ # Clock provides class methods for tracking running time and delaying
22
+ # execution of the program for specified time periods. This is used to
23
+ # provide a consistent framerate, prevent the program from using
24
+ # all the processor time, etc.
25
+ #
26
+ # Clock also provides instance methods to make it convenient to
27
+ # monitor and limit application framerate. See #tick.
28
+ class Clock
29
+ # The runtime when the Clock was initialized.
30
+ attr_reader :start
31
+ # The number of times #tick has been called.
32
+ attr_reader :ticks
33
+
34
+ # Create a new Clock instance.
35
+ def initialize()
36
+ @start = Clock.runtime()
37
+ @last_tick = @start
38
+ @ticks = 0
39
+ @target_frametime = nil
40
+ yield self if block_given?
41
+ end
42
+
43
+ # The target frametime (milliseconds/frame). See #tick
44
+ attr_accessor :target_frametime
45
+
46
+ # Returns the current target framerate (frames/second).
47
+ # This is an alternate way to access @target_frametime.
48
+ # Same as: 1000.0 / #target_frametime
49
+ def target_framerate
50
+ if @target_frametime
51
+ 1000.0 / @target_frametime
52
+ else
53
+ nil
54
+ end
55
+ rescue ZeroDivisionError
56
+ return nil
57
+ end
58
+
59
+ # Sets the target number of frames per second to +framerate+.
60
+ # This is an alternate way to access @target_frametime.
61
+ # Same as: #target_frametime = 1000.0 / framerate
62
+ def target_framerate=( framerate )
63
+ if framerate
64
+ @target_frametime = 1000.0 / framerate
65
+ else
66
+ @target_frametime = nil
67
+ end
68
+ rescue ZeroDivisionError
69
+ @target_frametime = nil
70
+ end
71
+
72
+ # call-seq: lifetime() -> Numeric
73
+ #
74
+ # Returns time in milliseconds since this Clock instance was created.
75
+ def lifetime
76
+ Clock.runtime() - @start
77
+ end
78
+
79
+ # call-seq: framerate() -> Numeric
80
+ #
81
+ # Return the actual framerate (frames per second) recorded by the Clock.
82
+ # See #tick.
83
+ #
84
+ # TODO: sample only a few seconds in the past, instead of the
85
+ # entire lifetime of the Clock.
86
+ def framerate
87
+ # below is same as: return @ticks / (lifetime / 1000.0)
88
+ return 1000.0 * @ticks / lifetime()
89
+ rescue ZeroDivisionError
90
+ return 0
91
+ end
92
+
93
+ # Returns the number of milliseconds since you last called this method.
94
+ #
95
+ # You must call this method once per frame (i.e. per iteration of
96
+ # your main loop) if you want to use the framerate monitoring and/or
97
+ # framerate limiting features.
98
+ #
99
+ # Framerate monitoring allows you to check the framerate (frames per
100
+ # second) with the #framerate method.
101
+ #
102
+ # Framerate limiting allows you to prevent the application from running
103
+ # too fast (and using 100% of processor time) by pausing the program
104
+ # very briefly each frame. The pause duration is calculated each frame
105
+ # to maintain a constant framerate.
106
+ #
107
+ # Framerate limiting is only enabled if you have set the
108
+ # #target_framerate= or #target_frametime=.
109
+ # If you have done that, this method will automatically perform the
110
+ # delay each time you call it.
111
+ #
112
+ # (Please note that no effort is made to correct a framerate
113
+ # which is *slower* than the target framerate. Clock can't
114
+ # make your code run faster, only slow it down if it is
115
+ # running too fast.)
116
+ def tick()
117
+ passed = Clock.runtime() - @last_tick # how long since the last tick?
118
+ if @target_frametime
119
+ return Clock.delay(@target_frametime - passed) + passed
120
+ end
121
+ return passed
122
+ ensure
123
+ @last_tick = Clock.runtime()
124
+ @ticks += 1
125
+ end
126
+
127
+ end # class Clock
128
+ end #module Rubygame
@@ -0,0 +1,79 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 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/color/models/base'
21
+ require 'rubygame/color/models/rgb'
22
+ require 'rubygame/color/models/hsv'
23
+ require 'rubygame/color/models/hsl'
24
+
25
+ require 'rubygame/color/palettes/palette'
26
+ require 'rubygame/color/palettes/x11'
27
+ require 'rubygame/color/palettes/css'
28
+
29
+ module Rubygame
30
+
31
+ # The Color module contains classes related to colors.
32
+ #
33
+ # Available color representations:
34
+ #
35
+ # ColorRGB:: color class with red, green, and blue components.
36
+ # ColorHSV:: color class with hue, saturation, and value components.
37
+ # ColorHSL:: color class with hue, saturation, and luminosity components.
38
+ #
39
+ # The Palette class allows you to conveniently store and access a
40
+ # collection of many different colors, with inheritance from
41
+ # included Palettes.
42
+ #
43
+ # The available predefined palettes are:
44
+ #
45
+ # X11:: palette with the default X11 colors
46
+ # CSS:: palette used with HTML and CSS, very similar to X11
47
+ # GLOBAL:: special palette used for automatic lookup (see below)
48
+ #
49
+ # The GLOBAL palette is special; it is used for automatic color lookup
50
+ # in functions like Surface#draw_circle and TTF#render.It includes the
51
+ # CSS palette by default; you can include other palettes or define new
52
+ # custom colors in GLOBAL to make them available for automatic lookup.
53
+ #
54
+ # For convenience, you can access the GLOBAL palette through the
55
+ # #[] and #[]= methods:
56
+ #
57
+ # include Rubygame
58
+ # player_color = Color[:red]
59
+ # Color[:favorite] = Color[:azure]
60
+ #
61
+ module Color
62
+
63
+ (GLOBAL = Palette.new()).include(CSS) # :nodoc:
64
+
65
+ # Retrieve a color from the GLOBAL palette.
66
+ # See Palette#[]
67
+ def self.[]( name )
68
+ GLOBAL[name]
69
+ end
70
+
71
+ # Store a color in the GLOBAL palette.
72
+ # See Palette#[]=
73
+ def self.[]=( name, color )
74
+ GLOBAL[name] = color
75
+ end
76
+
77
+ end
78
+ end
79
+
@@ -0,0 +1,111 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 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
+ module Rubygame
21
+ module Color
22
+
23
+ # A mix-in module defining color arithmetic operations.
24
+ module ColorBase
25
+
26
+ # Perform color addition with another color of any type.
27
+ # The alpha of the new color will be equal to the alpha
28
+ # of the receiver.
29
+ def +(other)
30
+ wrap( simple_op(other) { |a,b| a + b } )
31
+ end
32
+
33
+ # Perform color subtraction with another color of any type.
34
+ # The alpha of the new color will be equal to the alpha
35
+ # of the receiver.
36
+ def -(other)
37
+ wrap( simple_op(other) { |a,b| a - b } )
38
+ end
39
+
40
+ # Perform color multiplication with another color of any type.
41
+ # The alpha of the new color will be equal to the alpha
42
+ # of the receiver.
43
+ def *(other)
44
+ wrap( simple_op(other) { |a,b| a * b } )
45
+ end
46
+
47
+ # Perform color division with another color of any type.
48
+ # The alpha of the new color will be equal to the alpha
49
+ # of the receiver.
50
+ def /(other)
51
+ wrap( simple_op(other) { |a,b| a / b } )
52
+ end
53
+
54
+ # Layer this color over another color.
55
+ def over(other)
56
+ c1, c2 = self.to_rgba_ary, other.to_rgba_ary
57
+ a1, a2 = c1[3], c2[3]
58
+
59
+ rgba = [0,1,2].collect do |i|
60
+ clamp( a1*c1.at(i) + a2*c2.at(i)*(1-a1) )
61
+ end
62
+
63
+ rgba << ( a1 + a2*(1-a1) )
64
+
65
+ wrap( rgba )
66
+ end
67
+
68
+ # Average this color with another color. (Linear weighted average)
69
+ #
70
+ # A weight of 0.0 means 0% of this color, 100% of the other.
71
+ # A weight of 1.0 means 100% of this color, 0% of the other.
72
+ # A weight of 0.5 means 50% of each color.
73
+ #
74
+ def average(other, weight=0.5)
75
+ c1, c2 = self.to_rgba_ary, other.to_rgba_ary
76
+
77
+ rgba = [0,1,2,3].collect do |i|
78
+ clamp( c1.at(i)*weight + c2.at(i)*(1-weight) )
79
+ end
80
+
81
+ wrap( rgba )
82
+ end
83
+
84
+ private
85
+
86
+ def wrap( rgba )
87
+ self.class.new_from_rgba( rgba )
88
+ end
89
+
90
+ def simple_op(other, &block)
91
+ c1, c2 = self.to_rgba_ary, other.to_rgba_ary
92
+ a1, a2 = c1[3], c2[3]
93
+
94
+ rgba = [0,1,2].collect do |i|
95
+ clamp( block.call( a1*c1.at(i), a2*c2.at(i) ) )
96
+ end
97
+
98
+ rgba << a1
99
+
100
+ return rgba
101
+ end
102
+
103
+ def clamp(v, min=0.0, max=1.0)
104
+ v = min if v < min
105
+ v = max if v > max
106
+ return v
107
+ end
108
+ end
109
+
110
+ end
111
+ end
@@ -0,0 +1,153 @@
1
+ #--
2
+ # Rubygame -- Ruby code and bindings to SDL to facilitate game creation
3
+ # Copyright (C) 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/color/models/base'
21
+
22
+ module Rubygame
23
+ module Color
24
+
25
+ # Represents color in the HSL (Hue, Saturation, Luminosity) color space.
26
+ class ColorHSL
27
+ include ColorBase
28
+
29
+ attr_reader :h, :s, :l, :a
30
+
31
+ # call-seq:
32
+ # new( [h,s,l,a] ) -> ColorHSL
33
+ # new( [h,s,l] ) -> ColorHSL
34
+ # new( color ) -> ColorHSL
35
+ #
36
+ # Create a new instance from an Array or an existing color
37
+ # (of any type). If the alpha (opacity) component is omitted
38
+ # from the array, full opacity will be used.
39
+ #
40
+ # All color components range from 0.0 to 1.0.
41
+ #
42
+ def initialize( color )
43
+ if color.kind_of?(Array)
44
+ @h, @s, @l, @a = color.collect { |i| i.to_f }
45
+ @a = 1.0 unless @a
46
+ elsif color.respond_to?(:to_rgba_ary)
47
+ @h, @s, @l, @a = self.class.rgba_to_hsla( *color.to_rgba_ary )
48
+ end
49
+ end
50
+
51
+ # Return an Array with the red, green, blue, and alpha components
52
+ # of the color (converting the color to the RGBA model first).
53
+ def to_rgba_ary
54
+ return self.class.hsla_to_rgba( @h, @s, @l, @a )
55
+ end
56
+
57
+ def to_s
58
+ "#<#{self.class} [#{@h}, #{@s}, #{@l}, #{@a}]>"
59
+ end
60
+ alias :inspect :to_s
61
+
62
+ class << self
63
+
64
+ def new_from_rgba( rgba )
65
+ new( rgba_to_hsla(*rgba) )
66
+ end
67
+
68
+ def new_from_sdl_rgba( rgba )
69
+ new_from_rgba( rgba.collect { |i| i / 255.0 } )
70
+ end
71
+
72
+ # Convert the red, green, blue, and alpha to the
73
+ # equivalent hue, saturation, luminosity, and alpha.
74
+ def rgba_to_hsla( r, g, b, a ) # :nodoc:
75
+ rgb_arr = [r, g, b]
76
+ max = rgb_arr.max
77
+ min = rgb_arr.min
78
+
79
+ # Calculate lightness.
80
+ l = (max + min) / 2.0
81
+
82
+ # Calculate saturation.
83
+ if l == 0.0 or max == min
84
+ s = 0
85
+ elsif 0 < l and l <= 0.5
86
+ s = (max - min) / (max + min)
87
+ else # l > 0.5
88
+ s = (max - min) / (2 - (max + min))
89
+ end
90
+
91
+ # Calculate hue.
92
+ if min == max
93
+ h = 0
94
+ # Undefined in this case, but set it to zero
95
+ elsif max == r and g >= b
96
+ h = (1.quo(6) * (g - b) / (max - min)) + 0
97
+ elsif max == r and g < b
98
+ h = (1.quo(6) * (g - b) / (max - min)) + 1.0
99
+ elsif max == g
100
+ h = (1.quo(6) * (b - r) / (max - min)) + 1.quo(3)
101
+ elsif max == b
102
+ h = (1.quo(6) * (r - g) / (max - min)) + 2.quo(3)
103
+ else
104
+ raise "Should never happen"
105
+ end
106
+
107
+ return [h,s,l,a]
108
+ end
109
+
110
+ # Convert the hue, saturation, luminosity, and alpha
111
+ # to the equivalent red, green, blue, and alpha.
112
+ def hsla_to_rgba( h, s, l, a ) # :nodoc:
113
+ # If the color is achromatic, return already with the lightness value for all components
114
+ if s == 0.0
115
+ return [l, l, l, a]
116
+ end
117
+
118
+ # Otherwise, we have to do the long, hard calculation
119
+
120
+ # q helper value
121
+ q = (l < 0.5) ? (l * (1.0 + s)) : (l + s - l * s)
122
+
123
+ # p helper value
124
+ p = (2.0 * l) - q
125
+
126
+ r = calculate_component( p, q, h + 1.quo(3) )
127
+ g = calculate_component( p, q, h )
128
+ b = calculate_component( p, q, h - 1.quo(3) )
129
+
130
+ return [r,g,b,a]
131
+ end
132
+
133
+ private
134
+
135
+ # Perform some arcane math to calculate a color component.
136
+ def calculate_component(p, q, tc) # :nodoc:
137
+ tc %= 1.0
138
+ if tc < 1.quo(6)
139
+ p + (q - p) * tc * 6.0
140
+ elsif tc < 0.5
141
+ q
142
+ elsif tc < 2.quo(3)
143
+ p + (q - p) * (2.quo(3) - tc) * 6.0
144
+ else
145
+ p
146
+ end
147
+ end
148
+
149
+ end
150
+
151
+ end
152
+ end
153
+ end