gosu 0.7.24 → 0.7.25

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.
data/Gosu/ButtonsMac.hpp CHANGED
@@ -3,8 +3,8 @@
3
3
 
4
4
  namespace Gosu
5
5
  {
6
- //! List of all the button ids that can be used with Gosu::Input.
7
- //! This enumeration contains ids for non-character keyboard keys (kb*),
6
+ //! List of button ids that can be used with Gosu::Input.
7
+ //! This enumeration contains ids for keyboard keys (kb*),
8
8
  //! mouse buttons and mouse wheel (ms*) and gamepad buttons (gp*).
9
9
  enum ButtonName
10
10
  {
data/Gosu/ButtonsWin.hpp CHANGED
@@ -3,7 +3,10 @@
3
3
 
4
4
  namespace Gosu
5
5
  {
6
- enum ButtonName
6
+ //! List of button ids that can be used with Gosu::Input.
7
+ //! This enumeration contains ids for keyboard keys (kb*),
8
+ //! mouse buttons and mouse wheel (ms*) and gamepad buttons (gp*).
9
+ enum ButtonName
7
10
  {
8
11
  kbRangeBegin = 1,
9
12
  kbEscape = 0x01,
data/Gosu/ButtonsX.hpp CHANGED
@@ -3,8 +3,8 @@
3
3
 
4
4
  namespace Gosu
5
5
  {
6
- //! Enumerates all the named button ids that can be used with Gosu::Input.
7
- //! This enumeration contains ids for non-character keyboard keys (kb*),
6
+ //! List of button ids that can be used with Gosu::Input.
7
+ //! This enumeration contains ids for keyboard keys (kb*),
8
8
  //! mouse buttons and mouse wheel (ms*) and gamepad buttons (gp*).
9
9
  enum ButtonName
10
10
  {
data/Gosu/Color.hpp CHANGED
@@ -5,39 +5,58 @@
5
5
  #define GOSU_COLOR_HPP
6
6
 
7
7
  #include <boost/cstdint.hpp>
8
+ #include <Gosu/Platform.hpp>
8
9
 
9
10
  namespace Gosu
10
11
  {
11
12
  //! Represents an ARGB color value with 8 bits for each channel. Can be
12
13
  //! implicitly constructed from literals of the form 0xaarrggbb. Has fast
13
14
  //! value semantics.
15
+ //! The four-byte layout in memory is RGBA. On Big-Endian machines the
16
+ //! unsigned int interpretation is 0xrrggbbaa, on Little-Endian machines
17
+ //! it is 0xaabbggrr.
14
18
  class Color
15
19
  {
16
20
  boost::uint32_t rep;
17
-
21
+ #ifdef GOSU_IS_LITTLE_ENDIAN
22
+ enum { RED_OFFSET = 0, GREEN_OFFSET = 8, BLUE_OFFSET = 16, ALPHA_OFFSET = 24 };
23
+ #else
24
+ enum { RED_OFFSET = 24, GREEN_OFFSET = 16, BLUE_OFFSET = 8, ALPHA_OFFSET = 0 };
25
+ #endif
26
+
18
27
  public:
19
28
  typedef boost::uint8_t Channel;
20
-
29
+ static const unsigned GL_FORMAT = 0x1908; // GL_RGBA
30
+
21
31
  //! The default constructor does not initialize the color to any value.
22
32
  Color()
23
33
  {
24
34
  }
25
-
35
+
26
36
  //! Conversion constructor for literals of the form 0xaarrggbb.
27
37
  //! (C++ only.)
28
38
  Color(boost::uint32_t argb)
29
- : rep(argb)
30
39
  {
40
+ *this = Color((argb >> 24) & 0xff, (argb >> 16) & 0xff,
41
+ (argb >> 8) & 0xff, (argb >> 0) & 0xff);
31
42
  }
32
-
43
+
33
44
  Color(Channel red, Channel green, Channel blue)
34
45
  {
35
- rep = (0xff << 24) | (red << 16) | (green << 8) | blue;
46
+ *this = Color(0xff, red, green, blue);
36
47
  }
37
-
48
+
38
49
  Color(Channel alpha, Channel red, Channel green, Channel blue)
39
50
  {
40
- rep = (alpha << 24) | (red << 16) | (green << 8) | blue;
51
+ rep = (alpha << ALPHA_OFFSET) | (red << RED_OFFSET) |
52
+ (green << GREEN_OFFSET) | (blue << BLUE_OFFSET);
53
+ }
54
+
55
+ static Color fromRGBA(boost::uint32_t rgba)
56
+ {
57
+ Color result;
58
+ result.rep = rgba;
59
+ return result;
41
60
  }
42
61
 
43
62
  //! Constructs a color from the given hue/saturation/value triple.
@@ -47,48 +66,48 @@ namespace Gosu
47
66
  static Color fromHSV(double h, double s, double v);
48
67
  static Color fromAHSV(Channel alpha, double h, double s, double v);
49
68
 
50
- Channel alpha() const
51
- {
52
- return static_cast<Channel>((rep >> 24) & 0xff);
53
- }
54
-
55
69
  Channel red() const
56
70
  {
57
- return static_cast<Channel>((rep >> 16) & 0xff);
71
+ return static_cast<Channel>(rep >> RED_OFFSET);
58
72
  }
59
73
 
60
74
  Channel green() const
61
75
  {
62
- return static_cast<Channel>((rep >> 8) & 0xff);
76
+ return static_cast<Channel>(rep >> GREEN_OFFSET);
63
77
  }
64
78
 
65
79
  Channel blue() const
66
80
  {
67
- return static_cast<Channel>(rep & 0xff);
81
+ return static_cast<Channel>(rep >> BLUE_OFFSET);
68
82
  }
69
83
 
70
- void setAlpha(Channel value)
84
+ Channel alpha() const
71
85
  {
72
- rep &= 0x00ffffff;
73
- rep |= value << 24;
86
+ return static_cast<Channel>(rep >> ALPHA_OFFSET);
74
87
  }
75
88
 
76
89
  void setRed(Channel value)
77
90
  {
78
- rep &= 0xff00ffff;
79
- rep |= value << 16;
91
+ rep &= ~(0xff << RED_OFFSET);
92
+ rep |= value << RED_OFFSET;
80
93
  }
81
94
 
82
95
  void setGreen(Channel value)
83
96
  {
84
- rep &= 0xffff00ff;
85
- rep |= value << 8;
97
+ rep &= ~(0xff << GREEN_OFFSET);
98
+ rep |= value << GREEN_OFFSET;
86
99
  }
87
100
 
88
101
  void setBlue(Channel value)
89
102
  {
90
- rep &= 0xffffff00;
91
- rep |= value;
103
+ rep &= ~(0xff << BLUE_OFFSET);
104
+ rep |= value << BLUE_OFFSET;
105
+ }
106
+
107
+ void setAlpha(Channel value)
108
+ {
109
+ rep &= ~(0xff << ALPHA_OFFSET);
110
+ rep |= value << ALPHA_OFFSET;
92
111
  }
93
112
 
94
113
  //! Returns the hue of the color, in the usual range of 0..360.
@@ -112,19 +131,19 @@ namespace Gosu
112
131
  //! Returns the color in 0xaarrggbb representation.
113
132
  boost::uint32_t argb() const
114
133
  {
115
- return rep;
134
+ return alpha() << 24 | red() << 16 | green() << 8 | blue();
116
135
  }
117
136
 
118
137
  //! Returns the color in 0x00bbggrr representation.
119
138
  boost::uint32_t bgr() const
120
139
  {
121
- return red() | (rep & 0x0000ff00) | blue() << 16;
140
+ return blue() << 16 | green() << 8 | red();
122
141
  }
123
142
 
124
143
  //! Returns the color in 0xaabbggrr representation.
125
144
  boost::uint32_t abgr() const
126
145
  {
127
- return alpha() << 24 | bgr();
146
+ return alpha() << 24 | blue() << 16 | green() << 8 | red();
128
147
  }
129
148
 
130
149
  static const Color NONE;
@@ -171,7 +190,6 @@ namespace Gosu
171
190
  //! and then multiplied with each other.
172
191
  Color multiply(Color a, Color b);
173
192
 
174
- // Deprecated
175
193
  namespace Colors
176
194
  {
177
195
  const Color none = 0x00000000;
data/Gosu/Graphics.hpp CHANGED
@@ -22,7 +22,7 @@ namespace Gosu
22
22
  //! Returns the maximum size of an texture that will be allocated
23
23
  //! internally by Gosu.
24
24
  //! Useful when extending Gosu using OpenGL.
25
- extern unsigned const MAX_TEXTURE_SIZE;
25
+ unsigned const MAX_TEXTURE_SIZE = 1024;
26
26
 
27
27
  typedef boost::array<double, 16> Transform;
28
28
  Transform translate(double x, double y);
data/Gosu/Version.hpp CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  #define GOSU_MAJOR_VERSION 0
5
5
  #define GOSU_MINOR_VERSION 7
6
- #define GOSU_POINT_VERSION 24
7
- #define GOSU_VERSION "0.7.24"
6
+ #define GOSU_POINT_VERSION 25
7
+ #define GOSU_VERSION "0.7.25"
8
8
 
9
9
  #endif
@@ -34,7 +34,7 @@ namespace Gosu
34
34
  }
35
35
 
36
36
  Gosu::Reader Gosu::loadFromPNG(Bitmap& out, Reader reader)
37
- {
37
+ {
38
38
  #if 0
39
39
  boost::mutex::scoped_lock lock(pngMutex);
40
40
  #endif
@@ -34,10 +34,6 @@ Gosu::Reader Gosu::loadFromBMP(Bitmap& bmp, Reader reader)
34
34
  CGContextDrawImage(context, CGRectMake(0.0, 0.0, bmp.width(), bmp.height()), imageRef);
35
35
  CGContextRelease(context);
36
36
 
37
- for (unsigned y = 0; y < bmp.height(); ++y)
38
- for (unsigned x = 0; x < bmp.width(); ++x)
39
- bmp.setPixel(x, y, bmp.getPixel(x, y).abgr());
40
-
41
37
  return reader;
42
38
  }
43
39
 
@@ -128,7 +128,7 @@ Gosu::Color Gosu::multiply(Color a, Color b)
128
128
  const Gosu::Color Gosu::Color::NONE = 0x00000000;
129
129
  const Gosu::Color Gosu::Color::BLACK = 0xff000000;
130
130
  const Gosu::Color Gosu::Color::GRAY = 0xff808080;
131
- const Gosu::Color Gosu::Color::WHITE = 0xffffffff;
131
+ const Gosu::Color Gosu::Color::WHITE = 0xffffffff;
132
132
  const Gosu::Color Gosu::Color::AQUA = 0xff00ffff;
133
133
  const Gosu::Color Gosu::Color::RED = 0xffff0000;
134
134
  const Gosu::Color Gosu::Color::GREEN = 0xff00ff00;
@@ -357,7 +357,7 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
357
357
  const Bitmap& src, unsigned srcX, unsigned srcY,
358
358
  unsigned srcWidth, unsigned srcHeight, unsigned borderFlags)
359
359
  {
360
- static const unsigned maxSize = Texture::maxTextureSize();
360
+ static const unsigned maxSize = MAX_TEXTURE_SIZE;
361
361
 
362
362
  // Special case: If the texture is supposed to have hard borders,
363
363
  // is quadratic, has a size that is at least 64 pixels but less than 256
@@ -5,43 +5,6 @@
5
5
  #include <Gosu/Platform.hpp>
6
6
  #include <stdexcept>
7
7
 
8
- #ifndef GL_BGRA
9
- #define GL_BGRA 0x80E1
10
- #endif
11
-
12
- // TODO: Move from Texture:: to local namespace and use MAX_TEXTURE_SIZE instead.
13
- unsigned Gosu::Texture::maxTextureSize()
14
- {
15
- #if defined(GOSU_IS_MAC)
16
- // Includes the iPhone
17
- return 1024;
18
- #elif defined(GOSU_IS_UNIX)
19
- // Since we cannot get the max. texture size until after context creation, we have to
20
- // just be pessimistic about it until Gosu is restructured to create the context
21
- // earlier. Otherwise, libGL will segfault left and right.
22
- return 512;
23
- #else
24
- const static unsigned MIN_SIZE = 256, MAX_SIZE = 1024;
25
-
26
- static unsigned size = 0;
27
- if (size == 0)
28
- {
29
- size = MIN_SIZE / 2;
30
- GLint width = 1;
31
- do
32
- {
33
- size *= 2;
34
- glTexImage2D(GL_PROXY_TEXTURE_2D, 0, 4, size * 2, size * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
35
- glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
36
- } while (width != 0 && size < MAX_SIZE);
37
- }
38
-
39
- return size;
40
- #endif
41
- }
42
-
43
- const unsigned Gosu::MAX_TEXTURE_SIZE = Gosu::Texture::maxTextureSize();
44
-
45
8
  namespace Gosu
46
9
  {
47
10
  bool undocumentedRetrofication = false;
@@ -113,32 +76,9 @@ std::auto_ptr<Gosu::TexChunk>
113
76
  result.reset(new TexChunk(graphics, transforms, queues, ptr, block->left + padding, block->top + padding,
114
77
  block->width - 2 * padding, block->height - 2 * padding, padding));
115
78
 
116
- #if defined(__BIG_ENDIAN__)
117
- std::vector<unsigned> pixelData(srcWidth * srcHeight);
118
- for (unsigned y = 0; y < srcHeight; ++y)
119
- for (unsigned x = 0; x < srcWidth; ++x)
120
- {
121
- boost::uint32_t pixVal = (bmp.getPixel(x, y).argb() & 0x00ffffff) << 8 | bmp.getPixel(x, y).alpha();
122
- pixVal = bigToNative(pixVal);
123
- pixelData[y * srcWidth + x] = pixVal;
124
- }
125
- const unsigned* texData = &pixelData[0];
126
- unsigned format = GL_RGBA;
127
- #elif defined(GOSU_IS_IPHONE)
128
- std::vector<unsigned> pixelData(srcWidth * srcHeight);
129
- for (unsigned y = 0; y < srcHeight; ++y)
130
- for (unsigned x = 0; x < srcWidth; ++x)
131
- pixelData[y * srcWidth + x] = bmp.getPixel(x, y).abgr();
132
- const unsigned* texData = &pixelData[0];
133
- unsigned format = GL_RGBA;
134
- #else
135
- const unsigned* texData = bmp.data();
136
- unsigned format = GL_BGRA;
137
- #endif
138
-
139
79
  glBindTexture(GL_TEXTURE_2D, name);
140
80
  glTexSubImage2D(GL_TEXTURE_2D, 0, block->left, block->top, block->width, block->height,
141
- format, GL_UNSIGNED_BYTE, texData);
81
+ Color::GL_FORMAT, GL_UNSIGNED_BYTE, bmp.data());
142
82
 
143
83
  num += 1;
144
84
  return result;
@@ -158,21 +98,11 @@ Gosu::Bitmap Gosu::Texture::toBitmap(unsigned x, unsigned y, unsigned width, uns
158
98
  Gosu::Bitmap fullTexture;
159
99
  fullTexture.resize(size(), size());
160
100
  glBindTexture(GL_TEXTURE_2D, name);
161
- glGetTexImage(GL_TEXTURE_2D, 0, GL_BGRA, GL_UNSIGNED_BYTE, fullTexture.data());
101
+ glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, fullTexture.data());
162
102
  Gosu::Bitmap bitmap;
163
103
  bitmap.resize(width, height);
164
104
  bitmap.insert(fullTexture, -int(x), -int(y));
165
105
 
166
- #if defined(__BIG_ENDIAN__)
167
- for (unsigned y = 0; y < height; ++y)
168
- for (unsigned x = 0; x < width; ++x)
169
- bitmap.setPixel(x, y, bigToNative(bitmap.getPixel(x, y).argb() & 0xffffff00 >> 8 | bitmap.getPixel(x, y).alpha() << 24));
170
- #elif defined(GOSU_IS_IPHONE)
171
- for (unsigned y = 0; y < height; ++y)
172
- for (unsigned x = 0; x < width; ++x)
173
- bitmap.setPixel(x, y, bitmap.getPixel(x, y).abgr());
174
- #endif
175
-
176
106
  return bitmap;
177
107
  #endif
178
108
  }
@@ -19,8 +19,6 @@ namespace Gosu
19
19
  unsigned num;
20
20
 
21
21
  public:
22
- static unsigned maxTextureSize();
23
-
24
22
  Texture(unsigned size);
25
23
  ~Texture();
26
24
  unsigned size() const;
data/GosuImpl/InputMac.mm CHANGED
@@ -441,11 +441,49 @@ namespace {
441
441
 
442
442
  idChars.assign(0);
443
443
 
444
- #ifndef __LP64__
444
+ #ifdef __LP64__
445
+ CFRef<TISInputSourceRef> is(TISCopyCurrentKeyboardLayoutInputSource());
446
+ CFRef<CFDataRef> UCHR(
447
+ static_cast<CFDataRef>(TISGetInputSourceProperty(is.obj(), kTISPropertyUnicodeKeyLayoutData)));
448
+ if (!UCHR.get())
449
+ return;
450
+
451
+ // Reverse for() to prefer lower IDs in charToId
452
+ for (int code = numScancodes - 1; code >= 0; --code)
453
+ {
454
+ UInt32 deadKeyState = 0;
455
+ UniChar value[8];
456
+ UniCharCount valueLength = 8;
457
+
458
+ if (code == kbLeftShift || code == kbRightShift ||
459
+ code == kbLeftAlt || code == kbRightAlt ||
460
+ code == kbLeftControl || code == kbRightControl ||
461
+ code == kbLeftMeta || code == kbRightMeta)
462
+ continue;
463
+
464
+ if (noErr != UCKeyTranslate(
465
+ reinterpret_cast<const UCKeyboardLayout*>(CFDataGetBytePtr(UCHR.obj())),
466
+ code, kUCKeyActionDown, 0, LMGetKbdType(),
467
+ kUCKeyTranslateNoDeadKeysMask, &deadKeyState,
468
+ valueLength, &valueLength, value))
469
+ continue;
470
+
471
+ // Ignore special characters except newline.
472
+ if (value[0] == 3)
473
+ value[0] = 13; // convert Enter to Return
474
+ if (value[0] < 32 && value[0] != 13)
475
+ continue;
476
+
477
+ idChars[code] = value[0];
478
+ charIds[value[0]] = code;
479
+ }
480
+ #else
481
+ // The very old-school way.
445
482
  const void* KCHR = reinterpret_cast<const void*>(GetScriptManagerVariable(smKCHRCache));
446
483
  if (!KCHR)
447
484
  return;
448
485
 
486
+ // Reverse for() to prefer lower IDs in charToId
449
487
  for (int code = numScancodes - 1; code >= 0; --code)
450
488
  {
451
489
  UInt32 deadKeyState = 0;
@@ -454,20 +492,12 @@ namespace {
454
492
  if (deadKeyState != 0)
455
493
  value = KeyTranslate(KCHR, code, &deadKeyState);
456
494
 
457
- // No character! Pity.
458
- if (value == 0)
459
- continue;
460
-
461
495
  // Ignore special characters except newline.
462
496
  if (value == 3)
463
497
  value = 13; // convert Enter to Return
464
498
  if (value < 32 && value != 13)
465
499
  continue;
466
500
 
467
- // Now we have a character which is *not* limited to the ASCII range. To correctly
468
- // translate this into a wchar_t, we need to convert it based on the current locale.
469
- // TODO: That locale stuff should be explicit. Locales always cause trouble.
470
-
471
501
  std::string str(1, char(value));
472
502
  wchar_t ch = Gosu::macRomanToWstring(str).at(0);
473
503
 
@@ -1,6 +1,6 @@
1
- // Mini Swig Style Improvement List:
2
- // - %predicate instead of %rename
3
- // - use Python names for op overloading
1
+ // Mini SWIG file TODO List:
2
+ // - %predicate instead of %rename where applicable
3
+ // - use Python names for op overloading for easier porting to other languages
4
4
 
5
5
  %trackobjects;
6
6
  %include exception.i
@@ -61,14 +61,16 @@
61
61
  $1 = Gosu::Button(NUM2LONG($input));
62
62
  }
63
63
  %typemap(out) Gosu::Button {
64
- $result = LONG2NUM($1.id());
65
- if ($result == -1)
64
+ if ($1 == Gosu::noButton)
66
65
  $result = Qnil;
66
+ else
67
+ $result = LONG2NUM($1.id());
67
68
  }
68
69
  %typemap(directorin) Gosu::Button {
69
- $input = LONG2NUM($1.id());
70
- if ($input == -1)
70
+ if ($1 == Gosu::noButton)
71
71
  $input = Qnil;
72
+ else
73
+ $input = LONG2NUM($1.id());
72
74
  }
73
75
 
74
76
  // Typemaps for enums that should be given in as symbols.
@@ -164,7 +166,9 @@ namespace Gosu {
164
166
  void register_entity(const std::wstring& name, Gosu::Image* image) { registerEntity(name, image->getData().toBitmap()); }
165
167
  }
166
168
 
169
+ #include <ctime>
167
170
  #include <sstream>
171
+ #include <boost/algorithm/string.hpp>
168
172
 
169
173
  // New Ruby 1.9 syntax (for compilation with Ruby 1.8)
170
174
  #ifndef RSTRING_LEN
@@ -219,14 +223,8 @@ namespace Gosu
219
223
  throw std::logic_error("Blob length mismatch!");
220
224
  Bitmap result;
221
225
  result.resize(width, height);
222
- const unsigned* rgbaIter = reinterpret_cast<const unsigned*>(RSTRING_PTR(blob));
223
- for (unsigned y = 0; y < height; ++y)
224
- for (unsigned x = 0; x < width; ++x)
225
- {
226
- unsigned rgba = *rgbaIter;
227
- result.setPixel(x, y, Gosu::Color(rgba).abgr()); // swap R and B
228
- ++rgbaIter;
229
- }
226
+ std::memcpy(result.data(),
227
+ reinterpret_cast<const boost::uint32_t*>(RSTRING_PTR(blob)), width * height * 4);
230
228
  return result;
231
229
  }
232
230
  }
@@ -434,6 +432,7 @@ namespace Gosu {
434
432
  }
435
433
  std::string toBlob() const
436
434
  {
435
+ // TODO: Optimize with direct copy into a Ruby string
437
436
  Gosu::Bitmap bmp = $self->getData().toBitmap();
438
437
  return std::string(reinterpret_cast<const char*>(bmp.data()),
439
438
  reinterpret_cast<const char*>(bmp.data()) + bmp.width() * bmp.height() * 4);
@@ -446,6 +445,16 @@ namespace Gosu {
446
445
  {
447
446
  return $self->height();
448
447
  }
448
+ void save(const std::wstring& filename) const
449
+ {
450
+ Gosu::Bitmap bmp = $self->getData().toBitmap();
451
+ Gosu::Buffer buf;
452
+ if (boost::iends_with(filename, L".bmp"))
453
+ Gosu::saveToBMP(bmp, buf.backWriter());
454
+ else
455
+ Gosu::saveToPNG(bmp, buf.backWriter());
456
+ Gosu::saveFile(buf, filename);
457
+ }
449
458
  }
450
459
 
451
460
  // Audio:
@@ -472,6 +481,9 @@ namespace Gosu {
472
481
  %include "../Gosu/ButtonsMac.hpp"
473
482
  %init %{
474
483
  GosusDarkSide::oncePerTick = GosusDarkSide::yieldToOtherRubyThreads;
484
+ // While we are at it, to some healthy srand() - otherwise unavailable to Ruby people
485
+ std::srand(static_cast<unsigned int>(std::time(0)));
486
+ std::rand(); // and flush the first value
475
487
  %}
476
488
 
477
489
  // TextInput
@@ -624,6 +636,11 @@ namespace Gosu {
624
636
  rb_yield(Qnil);
625
637
  $self->graphics().popTransform();
626
638
  }
639
+ void scale(double factorX, double factorY, double aroundX, double aroundY) {
640
+ $self->graphics().pushTransform(Gosu::scale(factorX, factorY, aroundX, aroundY));
641
+ rb_yield(Qnil);
642
+ $self->graphics().popTransform();
643
+ }
627
644
  void translate(double x, double y) {
628
645
  $self->graphics().pushTransform(Gosu::translate(x, y));
629
646
  rb_yield(Qnil);