gosu 0.11.4.pre3 → 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 94bfc8e22230e0613727dbc03a8bacbc3b39ccf2
4
- data.tar.gz: 9a4b29f27d6d2ade8191ef50940693904d88028a
3
+ metadata.gz: 0d1640e560328b803317616abde6c301648daffb
4
+ data.tar.gz: 419425be00ae9f09d1cc74702170f55f87ff563b
5
5
  SHA512:
6
- metadata.gz: 8fd062fda171cb3a06a31abf9dcf97da32e02b2a5de57d251b3ddf1c2bc799d57cfbab7346cd36dcab84be0c49ce8eff3315dd6183e8a51c8ba2ea842b50636c
7
- data.tar.gz: 403717d0b239a02e219328ef483884a72ce34841acc9c9c9f5e8b546109f35904ce2cae697ecda874c46803951d0bf209586212b196e50135f825041886d5606
6
+ metadata.gz: 6ba0ce007bc4fdddd98887d1594f2b106e150fb50282dc859e517f1122a4853c6d8f3ca69cb8d34cde51914e2310c53eba1ba9873dde736fbac58e6dc0bcef32
7
+ data.tar.gz: 2eb57895d03d4bfcbcc31c28ef79ef35fa5f78684dde4d1f7106b0914470bf2d70b27aa87b3df23e4432f367aa1bdbbd4883bb39e2915405b9b6aba79ed83775
@@ -37,46 +37,38 @@ namespace Gosu
37
37
  unsigned width() const;
38
38
  unsigned height() const;
39
39
 
40
- //! Prepares the graphics object for drawing. Nothing must be drawn
41
- //! without calling begin.
42
- bool begin(Color clear_with_color = Color::BLACK);
43
- //! Every call to begin must have a matching call to end.
44
- void end();
40
+ //! Prepares the graphics object for drawing and then runs the rendering code in f.
41
+ //! Nothing must be drawn outside of frame() and record().
42
+ void frame(const std::function<void()>& f);
45
43
 
46
44
  //! Flushes the Z queue to the screen and starts a new one.
47
- //! Useful for games that are *very* composite in nature (splitscreen).
45
+ //! This can be useful to separate the Z queues of two parts of the game, e.g. the two
46
+ //! halves of a game that runs in split-screen mode.
48
47
  static void flush();
49
48
 
50
- //! Finishes all pending Gosu drawing operations and executes
51
- //! the following OpenGL code in a clean environment.
52
- static void begin_gl();
53
- //! Resets Gosu into its default rendering state.
54
- static void end_gl();
49
+ //! Finishes all pending Gosu drawing operations and executes the code in f in a clean
50
+ //! OpenGL environment.
51
+ static void gl(const std::function<void()>& f);
52
+
55
53
  //! Schedules a custom GL functor to be executed at a certain Z level.
56
- //! The functor is called in a clean GL context (as given by begin_gl/end_gl).
57
- //! Gosu's rendering up to the Z level may not yet have been glFlush()ed.
54
+ //! The functor f is run in a clean GL context.
58
55
  //! Note: You may not call any Gosu rendering functions from within the
59
- //! functor, and you must schedule it from within Window::draw's call tree.
60
- static void gl(const std::function<void ()>& functor, ZPos z);
56
+ //! functor.
57
+ static void gl(ZPos z, const std::function<void()>& f);
61
58
 
62
- //! Enables clipping to a specified rectangle.
63
- static void begin_clipping(double x, double y, double width, double height);
64
- //! Disables clipping.
65
- static void end_clipping();
59
+ //! Renders everything drawn in f clipped to a rectangle on the screen.
60
+ static void clip_to(double x, double y, double width, double height,
61
+ const std::function<void()>& f);
66
62
 
67
- //! Starts recording a macro. Cannot be nested.
68
- static void begin_recording();
69
- //! Finishes building the macro and returns it as a drawable object.
70
- //! The width and height affect nothing about the recording process,
71
- //! the resulting macro will simply return these values when you ask
72
- //! it.
73
- //! Most usually, the return value is passed to Image::Image().
74
- static std::unique_ptr<Gosu::ImageData> end_recording(int width, int height);
63
+ //! Records a macro and returns it as an ImageData instance.
64
+ //! Usually, the return value is passed to Image::Image().
65
+ //! Cannot be nested.
66
+ static std::unique_ptr<Gosu::ImageData> record(int width, int height,
67
+ const std::function<void()>& f);
75
68
 
76
69
  //! Pushes one transformation onto the transformation stack.
77
- static void push_transform(const Transform& transform);
78
- //! Pops one transformation from the transformation stack.
79
- static void pop_transform();
70
+ static void transform(const Transform& transform,
71
+ const std::function<void()>& f);
80
72
 
81
73
  //! Draws a line from one point to another (last pixel exclusive).
82
74
  //! Note: OpenGL lines are not reliable at all and may have a missing pixel at the start
@@ -3,8 +3,8 @@
3
3
  #include <string>
4
4
 
5
5
  #define GOSU_MAJOR_VERSION 0
6
- #define GOSU_MINOR_VERSION 11
7
- #define GOSU_POINT_VERSION 4
6
+ #define GOSU_MINOR_VERSION 12
7
+ #define GOSU_POINT_VERSION 0
8
8
 
9
9
  namespace Gosu
10
10
  {
@@ -381,17 +381,10 @@ module Gosu
381
381
  ##
382
382
  # Returns an image that is a smaller, rectangular view of this {Image}.
383
383
  #
384
- # This is a very fast operation, and no new textures are allocated.
384
+ # This is a very fast operation, and no new textures will be allocated.
385
385
  # If you update this {Image} or the {#subimage} using {#insert}, the other {Image} will be affected as well.
386
386
  #
387
- # This method can be used to load texture atlases created with third-party tools.
388
- # The texture atlas must be a power of two (512x512 or 1024x1024) and loaded with :tileable => true.
389
- # The individual {Image}s can then be loaded efficiently with {#subimage}.
390
- # {#gl_tex_info} will work on a {#subimage}.
391
- #
392
387
  # Caveats:
393
- # * {#subimage} only works if the image lives on a single texture.
394
- # If the image was too large and had to be split up into several OpenGL textures, subimage will return nil (same as {#gl_tex_info}).
395
388
  # * If you stretch or rotate a {#subimage}, the pixels adjacent to it might bleed into it, as Gosu does not manage the 'tileability' of subimages.
396
389
  #
397
390
  # @return [Image?] an image that represents a portion of the containing image
@@ -202,13 +202,13 @@ Gosu::Sample::Sample(Reader reader)
202
202
  data.reset(new SampleData(audio_file));
203
203
  }
204
204
  catch (const std::runtime_error& ex) {
205
+ #ifndef GOSU_IS_MAC
205
206
  if (std::string(ex.what()).find("unknown format") != std::string::npos) {
206
207
  MPEGFile mpeg_file(reader);
207
208
  data.reset(new SampleData(mpeg_file));
208
- }
209
- else {
209
+ } else
210
+ #endif
210
211
  throw ex;
211
- }
212
212
  }
213
213
  }
214
214
 
@@ -374,10 +374,14 @@ public:
374
374
  file.reset(new WAVE_FILE(filename));
375
375
  }
376
376
  catch (const std::runtime_error& ex) {
377
+ #ifndef GOSU_IS_MAC
377
378
  if (std::string(ex.what()).find("unknown format") != std::string::npos) {
378
379
  Gosu::File source_file(filename);
379
380
  file.reset(new MPEGFile(source_file.front_reader()));
380
381
  }
382
+ else
383
+ #endif
384
+ throw ex;
381
385
  }
382
386
  }
383
387
  alGenBuffers(2, buffers);
@@ -393,9 +397,13 @@ public:
393
397
  file.reset(new WAVE_FILE(reader));
394
398
  }
395
399
  catch (const std::runtime_error& ex) {
400
+ #ifndef GOSU_IS_MAC
396
401
  if (std::string(ex.what()).find("unknown format") != std::string::npos) {
397
402
  file.reset(new MPEGFile(reader));
398
403
  }
404
+ else
405
+ #endif
406
+ throw ex;
399
407
  }
400
408
  }
401
409
  alGenBuffers(2, buffers);
@@ -34,7 +34,7 @@ namespace Gosu
34
34
 
35
35
  const std::vector<char>& decoded_data()
36
36
  {
37
- static const unsigned INCREMENT = 512 * 1024;
37
+ static const std::size_t INCREMENT = 512 * 1024;
38
38
 
39
39
  if (!data_.empty()) {
40
40
  return data_;
@@ -43,7 +43,7 @@ namespace Gosu
43
43
  for (;;) {
44
44
  data_.resize(data_.size() + INCREMENT);
45
45
 
46
- int read_bytes = read_data(&data_[data_.size() - INCREMENT], INCREMENT);
46
+ auto read_bytes = read_data(&data_[data_.size() - INCREMENT], INCREMENT);
47
47
 
48
48
  if (read_bytes < INCREMENT) {
49
49
  data_.resize(data_.size() - INCREMENT + read_bytes);
@@ -25,7 +25,7 @@ namespace
25
25
  std::size_t remaining = reader->resource().size() - reader->position();
26
26
  std::size_t actual_size = (size < remaining ? size : remaining);
27
27
  reader->read(data, actual_size);
28
- return actual_size;
28
+ return static_cast<int>(actual_size);
29
29
  }
30
30
 
31
31
  void skip_callback(void* user, int n)
@@ -159,7 +159,7 @@ void Gosu::Font::set_image(wchar_t wc, unsigned font_flags, const Image& image)
159
159
  void Gosu::Font::draw_rot(const string& text, double x, double y, ZPos z, double angle,
160
160
  double scale_x, double scale_y, Color c, AlphaMode mode) const
161
161
  {
162
- Gosu::Graphics::push_transform(rotate(angle, x, y));
163
- draw(text, x, y, z, scale_x, scale_y, c, mode);
164
- Gosu::Graphics::pop_transform();
162
+ Gosu::Graphics::transform(rotate(angle, x, y), [&] {
163
+ draw(text, x, y, z, scale_x, scale_y, c, mode);
164
+ });
165
165
  }
@@ -192,12 +192,10 @@ static void handle_audio_interruption(void* unused, UInt32 inInterruptionState)
192
192
 
193
193
  if (window.needs_redraw()) {
194
194
  [self.GLView redrawGL:^{
195
- if (window.graphics().begin()) {
195
+ window.graphics().frame([&window] {
196
196
  window.draw();
197
- window.graphics().end();
198
-
199
197
  Gosu::FPS::register_frame();
200
- }
198
+ });
201
199
  }];
202
200
  }
203
201
 
@@ -62,6 +62,35 @@ struct Gosu::Graphics::Impl
62
62
  Transform translate_transform = translate(black_width, black_height);
63
63
  base_transform = concat(translate_transform, scale_transform);
64
64
  }
65
+
66
+ #ifndef GOSU_IS_OPENGLES
67
+ void begin_gl()
68
+ {
69
+ glPushAttrib(GL_ALL_ATTRIB_BITS);
70
+ glDisable(GL_BLEND);
71
+ // Reset the colour to white to avoid surprises.
72
+ // https://www.libgosu.org/cgi-bin/mwf/topic_show.pl?pid=9115#pid9115
73
+ glColor4ubv(reinterpret_cast<const GLubyte*>(&Color::WHITE));
74
+ while (glGetError() != GL_NO_ERROR);
75
+ }
76
+
77
+ void end_gl()
78
+ {
79
+ glPopAttrib();
80
+
81
+ // Restore matrices.
82
+ // TODO: Should be merged into RenderState and removed from Graphics.
83
+
84
+ glMatrixMode(GL_PROJECTION);
85
+ glLoadIdentity();
86
+ glViewport(0, 0, phys_width, phys_height);
87
+ glOrtho(0, phys_width, phys_height, 0, -1, 1);
88
+
89
+ glMatrixMode(GL_MODELVIEW);
90
+ glLoadIdentity();
91
+ glEnable(GL_BLEND);
92
+ }
93
+ #endif
65
94
  };
66
95
 
67
96
  Gosu::Graphics::Graphics(unsigned phys_width, unsigned phys_height)
@@ -112,7 +141,7 @@ void Gosu::Graphics::set_resolution(unsigned virtual_width, unsigned virtual_hei
112
141
  pimpl->update_base_transform();
113
142
  }
114
143
 
115
- bool Gosu::Graphics::begin(Gosu::Color clear_with_color)
144
+ void Gosu::Graphics::frame(const std::function<void()>& f)
116
145
  {
117
146
  if (current_graphics_pointer != nullptr) {
118
147
  throw std::logic_error("Cannot nest calls to Gosu::Graphics::begin()");
@@ -135,17 +164,13 @@ bool Gosu::Graphics::begin(Gosu::Color clear_with_color)
135
164
 
136
165
  queues.back().set_base_transform(pimpl->base_transform);
137
166
 
138
- glClearColor(clear_with_color.red() / 255.f, clear_with_color.green() / 255.f,
139
- clear_with_color.blue() / 255.f, clear_with_color.alpha() / 255.f);
167
+ glClearColor(0, 0, 0, 1);
140
168
  glClear(GL_COLOR_BUFFER_BIT);
141
169
 
142
170
  current_graphics_pointer = this;
143
171
 
144
- return true;
145
- }
146
-
147
- void Gosu::Graphics::end()
148
- {
172
+ f();
173
+
149
174
  // If recording is in process, cancel it.
150
175
  while (current_queue().recording()) {
151
176
  queues.pop_back();
@@ -164,7 +189,7 @@ void Gosu::Graphics::end()
164
189
  0, height() + pimpl->black_height, Color::BLACK,
165
190
  width(), height() + pimpl->black_height, Color::BLACK, 0);
166
191
  }
167
- else if (pimpl->black_width) {
192
+ if (pimpl->black_width) {
168
193
  draw_quad(-pimpl->black_width, 0, Color::BLACK,
169
194
  0, 0, Color::BLACK,
170
195
  -pimpl->black_width, height(), Color::BLACK,
@@ -197,121 +222,68 @@ void Gosu::Graphics::flush()
197
222
  current_queue().clear_queue();
198
223
  }
199
224
 
200
- void Gosu::Graphics::begin_gl()
225
+ void Gosu::Graphics::gl(const std::function<void()>& f)
201
226
  {
202
227
  if (current_queue().recording()) {
203
228
  throw std::logic_error("Custom OpenGL is not allowed while creating a macro");
204
229
  }
205
230
 
206
- #ifdef GOSU_IS_OPENGLES
207
- throw std::logic_error("Custom OpenGL ES is not supported yet");
208
- #else
209
- flush();
210
- glPushAttrib(GL_ALL_ATTRIB_BITS);
211
- glDisable(GL_BLEND);
212
- while (glGetError() != GL_NO_ERROR);
213
- #endif
214
- }
215
-
216
- void Gosu::Graphics::end_gl()
217
- {
218
231
  #ifdef GOSU_IS_OPENGLES
219
232
  throw std::logic_error("Custom OpenGL ES is not supported yet");
220
233
  #else
221
234
  Graphics& cg = current_graphics();
222
-
223
- glPopAttrib();
224
235
 
225
- // Restore matrices.
226
- // TODO: Should be merged into RenderState and removed from Graphics.
236
+ flush();
237
+
238
+ cg.pimpl->begin_gl();
227
239
 
228
- glMatrixMode(GL_PROJECTION);
229
- glLoadIdentity();
230
- glViewport(0, 0, cg.pimpl->phys_width, cg.pimpl->phys_height);
231
- glOrtho(0, cg.pimpl->phys_width, cg.pimpl->phys_height, 0, -1, 1);
240
+ f();
232
241
 
233
- glMatrixMode(GL_MODELVIEW);
234
- glLoadIdentity();
235
- glEnable(GL_BLEND);
242
+ cg.pimpl->end_gl();
236
243
  #endif
237
244
  }
238
245
 
239
- #ifdef GOSU_IS_OPENGLES
240
- void Gosu::Graphics::gl(const std::function<void ()>& functor, Gosu::ZPos z)
246
+ void Gosu::Graphics::gl(Gosu::ZPos z, const std::function<void ()>& f)
241
247
  {
248
+ #ifdef GOSU_IS_OPENGLES
242
249
  throw std::logic_error("Custom OpenGL ES is not supported yet");
243
- }
244
250
  #else
245
- namespace Gosu
246
- {
247
- struct RunGLFunctor
248
- {
249
- Graphics& graphics;
250
- std::function<void ()> functor;
251
-
252
- RunGLFunctor(Graphics& graphics, const std::function<void ()>& functor)
253
- : graphics(graphics), functor(functor)
254
- {
255
- }
256
-
257
- void operator()() const
258
- {
259
- // Duplicated from begin_gl() (which we don't call, to avoid flushing).
260
- glPushAttrib(GL_ALL_ATTRIB_BITS);
261
- glDisable(GL_BLEND);
262
- // Reset the colour to white to avoid surprises.
263
- // https://www.libgosu.org/cgi-bin/mwf/topic_show.pl?pid=9115#pid9115
264
- glColor4ubv(reinterpret_cast<const GLubyte*>(&Color::WHITE));
265
- while (glGetError() != GL_NO_ERROR);
266
-
267
- functor();
268
-
269
- graphics.end_gl();
270
- }
271
- };
272
- }
273
-
274
- void Gosu::Graphics::gl(const std::function<void ()>& functor, Gosu::ZPos z)
275
- {
276
- current_queue().gl(RunGLFunctor(current_graphics(), functor), z);
277
- }
251
+ current_queue().gl([f] {
252
+ Graphics& cg = current_graphics();
253
+ cg.pimpl->begin_gl();
254
+ f();
255
+ cg.pimpl->end_gl();
256
+ }, z);
278
257
  #endif
258
+ }
279
259
 
280
- void Gosu::Graphics::begin_clipping(double x, double y, double width, double height)
260
+ void Gosu::Graphics::clip_to(double x, double y, double width, double height,
261
+ const std::function<void()>& f)
281
262
  {
282
263
  double screen_height = current_graphics().pimpl->phys_height;
283
264
  current_queue().begin_clipping(x, y, width, height, screen_height);
284
- }
285
-
286
- void Gosu::Graphics::end_clipping()
287
- {
265
+ f();
288
266
  current_queue().end_clipping();
289
267
  }
290
268
 
291
- void Gosu::Graphics::begin_recording()
269
+ std::unique_ptr<Gosu::ImageData> Gosu::Graphics::record(int width, int height,
270
+ const std::function<void()>& f)
292
271
  {
293
272
  queues.resize(queues.size() + 1);
294
273
  current_queue().set_recording();
295
- }
296
274
 
297
- std::unique_ptr<Gosu::ImageData> Gosu::Graphics::end_recording(int width, int height)
298
- {
299
- if (!current_queue().recording()) {
300
- throw std::logic_error("No macro recording in progress that can be captured");
301
- }
275
+ f();
302
276
 
303
277
  std::unique_ptr<ImageData> result(new Macro(current_queue(), width, height));
304
278
  queues.pop_back();
305
279
  return result;
306
280
  }
307
281
 
308
- void Gosu::Graphics::push_transform(const Gosu::Transform& transform)
282
+ void Gosu::Graphics::transform(const Gosu::Transform& transform,
283
+ const std::function<void()>& f)
309
284
  {
310
285
  current_queue().push_transform(transform);
311
- }
312
-
313
- void Gosu::Graphics::pop_transform()
314
- {
286
+ f();
315
287
  current_queue().pop_transform();
316
288
  }
317
289
 
@@ -58,6 +58,7 @@ namespace Gosu
58
58
  class DrawOpQueue;
59
59
  typedef std::list<Transform> Transforms;
60
60
  typedef std::list<DrawOpQueue> DrawOpQueueStack;
61
+ class LargeImageData;
61
62
  class Macro;
62
63
  struct ArrayVertex
63
64
  {
@@ -1,35 +1,37 @@
1
1
  #include "LargeImageData.hpp"
2
- #include "GraphicsImpl.hpp"
3
2
  #include <Gosu/Bitmap.hpp>
4
3
  #include <Gosu/Graphics.hpp>
5
4
  #include <Gosu/Math.hpp>
6
5
  #include <cmath>
7
6
  using namespace std;
8
7
 
9
- Gosu::LargeImageData::LargeImageData(const Bitmap& source,
10
- unsigned part_width, unsigned part_height, unsigned image_flags)
8
+ Gosu::LargeImageData::LargeImageData(const Bitmap& source, int tile_width, int tile_height,
9
+ unsigned image_flags)
11
10
  {
12
- full_width = source.width();
13
- full_height = source.height();
14
- parts_x = static_cast<unsigned>(trunc(ceil(1.0 * source.width() / part_width)));
15
- parts_y = static_cast<unsigned>(trunc(ceil(1.0 * source.height() / part_height)));
16
- this->part_width = part_width;
17
- this->part_height = part_height;
18
-
19
- parts.resize(parts_x * parts_y);
20
-
21
- for (unsigned y = 0; y < parts_y; ++y) {
22
- for (unsigned x = 0; x < parts_x; ++x) {
23
- // The right-most parts don't necessarily have the full width.
24
- unsigned src_width = part_width;
25
- if (x == parts_x - 1 && source.width() % part_width != 0) {
26
- src_width = source.width() % part_width;
11
+ w = source.width();
12
+ h = source.height();
13
+ tiles_x = static_cast<int>(ceil(1.0 * w / tile_width));
14
+ tiles_y = static_cast<int>(ceil(1.0 * h / tile_height));
15
+
16
+ // When there are no tiles, set both fields to 0 to avoid entering any for() loop in this class.
17
+ if (tiles_x == 0 || tiles_y == 0) {
18
+ tiles_x = tiles_y = 0;
19
+ }
20
+
21
+ tiles.reserve(tiles_x * tiles_y);
22
+
23
+ for (int y = 0; y < tiles_y; ++y) {
24
+ for (int x = 0; x < tiles_x; ++x) {
25
+ int src_width = tile_width;
26
+ if (x == tiles_x - 1 && w % tile_width != 0) {
27
+ // The right-most parts don't necessarily have the full width.
28
+ src_width = w % tile_width;
27
29
  }
28
30
 
29
- // Same for the parts on the bottom.
30
- unsigned src_height = part_height;
31
- if (y == parts_y - 1 && source.height() % part_height != 0) {
32
- src_height = source.height() % part_height;
31
+ int src_height = tile_height;
32
+ if (y == tiles_y - 1 && h % tile_height != 0) {
33
+ // Same for the parts on the bottom.
34
+ src_height = h % tile_height;
33
35
  }
34
36
 
35
37
  unsigned local_flags = IF_TILEABLE | image_flags;
@@ -40,7 +42,7 @@ Gosu::LargeImageData::LargeImageData(const Bitmap& source,
40
42
  local_flags |= (image_flags & IF_TILEABLE_LEFT);
41
43
  }
42
44
  // Right edge, only tileable if requested in image_flags.
43
- if (x == parts_x - 1) {
45
+ if (x == tiles_x - 1) {
44
46
  local_flags &= ~IF_TILEABLE_RIGHT;
45
47
  local_flags |= (image_flags & IF_TILEABLE_RIGHT);
46
48
  }
@@ -50,102 +52,156 @@ Gosu::LargeImageData::LargeImageData(const Bitmap& source,
50
52
  local_flags |= (image_flags & IF_TILEABLE_TOP);
51
53
  }
52
54
  // Bottom edge, only tileable if requested in image_flags.
53
- if (y == parts_y - 1) {
55
+ if (y == tiles_y - 1) {
54
56
  local_flags &= ~IF_TILEABLE_BOTTOM;
55
57
  local_flags |= (image_flags & IF_TILEABLE_BOTTOM);
56
58
  }
57
59
 
58
- parts[y * parts_x + x].reset(Graphics::create_image(source,
59
- x * part_width, y * part_height,
60
- src_width, src_height,
61
- local_flags).release());
60
+ tiles.emplace_back(Graphics::create_image(source,
61
+ x * tile_width, y * tile_height,
62
+ src_width, src_height, local_flags));
62
63
  }
63
64
  }
64
65
  }
65
66
 
66
- int Gosu::LargeImageData::width() const
67
- {
68
- return full_width;
69
- }
70
-
71
- int Gosu::LargeImageData::height() const
67
+ void Gosu::LargeImageData::draw(double x1, double y1, Color c1,
68
+ double x2, double y2, Color c2,
69
+ double x3, double y3, Color c3,
70
+ double x4, double y4, Color c4,
71
+ ZPos z, AlphaMode mode) const
72
72
  {
73
- return full_height;
73
+ normalize_coordinates(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
74
+
75
+ double y = 0;
76
+ for (int ty = 0; ty < tiles_y; ++ty) {
77
+ double x = 0;
78
+ for (int tx = 0; tx < tiles_x; ++tx) {
79
+ ImageData& tile = *tiles[ty * tiles_x + tx];
80
+
81
+ double rel_x_l = x / w;
82
+ double rel_x_r = (x + tile.width()) / w;
83
+ double rel_y_t = y / h;
84
+ double rel_y_b = (y + tile.height()) / h;
85
+
86
+ #define INTERPOLATE(what, x_weight, y_weight) \
87
+ interpolate(interpolate(what##1, what##3, y_weight), \
88
+ interpolate(what##2, what##4, y_weight), \
89
+ x_weight);
90
+
91
+ double x_t_l = INTERPOLATE(x, rel_x_l, rel_y_t);
92
+ double x_t_r = INTERPOLATE(x, rel_x_r, rel_y_t);
93
+ double x_b_l = INTERPOLATE(x, rel_x_l, rel_y_b);
94
+ double x_b_r = INTERPOLATE(x, rel_x_r, rel_y_b);
95
+
96
+ double y_t_l = INTERPOLATE(y, rel_x_l, rel_y_t);
97
+ double y_t_r = INTERPOLATE(y, rel_x_r, rel_y_t);
98
+ double y_b_l = INTERPOLATE(y, rel_x_l, rel_y_b);
99
+ double y_b_r = INTERPOLATE(y, rel_x_r, rel_y_b);
100
+
101
+ Color c_t_l = INTERPOLATE(c, rel_x_l, rel_y_t);
102
+ Color c_t_r = INTERPOLATE(c, rel_x_r, rel_y_t);
103
+ Color c_b_l = INTERPOLATE(c, rel_x_l, rel_y_b);
104
+ Color c_b_r = INTERPOLATE(c, rel_x_r, rel_y_b);
105
+
106
+ tile.draw(x_t_l, y_t_l, c_t_l,
107
+ x_t_r, y_t_r, c_t_r,
108
+ x_b_l, y_b_l, c_b_l,
109
+ x_b_r, y_b_r, c_b_r,
110
+ z, mode);
111
+
112
+ x += tile.width();
113
+ }
114
+ y += tiles[ty * tiles_x]->height();
115
+ }
74
116
  }
75
117
 
76
- namespace
118
+ unique_ptr<Gosu::ImageData>
119
+ Gosu::LargeImageData::subimage(int left, int top, int width, int height) const
77
120
  {
78
- // Local interpolation helper functions. - TODO why not from Math.hpp?
79
-
80
- double ipl(double a, double b, double ratio)
81
- {
82
- return a + (b - a) * ratio;
121
+ if (left < 0 || top < 0 || left + width > w || top + height > h) {
122
+ throw invalid_argument("subimage bounds exceed those of its parent");
83
123
  }
84
-
85
- Gosu::Color ipl(Gosu::Color a, Gosu::Color b, double ratio)
86
- {
87
- Gosu::Color result;
88
- result.set_alpha(Gosu::round(ipl(a.alpha(), b.alpha(), ratio)));
89
- result.set_red (Gosu::round(ipl(a.red(), b.red(), ratio)));
90
- result.set_green(Gosu::round(ipl(a.green(), b.green(), ratio)));
91
- result.set_blue (Gosu::round(ipl(a.blue(), b.blue(), ratio)));
92
- return result;
124
+ if (width <= 0 || height <= 0) {
125
+ throw invalid_argument("cannot create empty image");
93
126
  }
94
- }
95
-
96
- void Gosu::LargeImageData::draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
97
- double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z, AlphaMode mode) const
98
- {
99
- if (parts.empty()) return;
100
-
101
- normalize_coordinates(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
102
127
 
103
- for (unsigned py = 0; py < parts_y; ++py) {
104
- for (unsigned px = 0; px < parts_x; ++px) {
105
- ImageData& part = *parts[py * parts_x + px];
106
-
107
- double rel_x_l = static_cast<double>(px * part_width) / width();
108
- double rel_x_r = static_cast<double>(px * part_width + part.width()) / width();
109
- double rel_y_t = static_cast<double>(py * part_height) / height();
110
- double rel_y_b = static_cast<double>(py * part_height + part.height()) / height();
111
-
112
- double abs_x_t_l = ipl(ipl(x1, x3, rel_y_t), ipl(x2, x4, rel_y_t), rel_x_l);
113
- double abs_x_t_r = ipl(ipl(x1, x3, rel_y_t), ipl(x2, x4, rel_y_t), rel_x_r);
114
- double abs_x_b_l = ipl(ipl(x1, x3, rel_y_b), ipl(x2, x4, rel_y_b), rel_x_l);
115
- double abs_x_b_r = ipl(ipl(x1, x3, rel_y_b), ipl(x2, x4, rel_y_b), rel_x_r);
116
-
117
- double abs_y_t_l = ipl(ipl(y1, y3, rel_y_t), ipl(y2, y4, rel_y_t), rel_x_l);
118
- double abs_y_t_r = ipl(ipl(y1, y3, rel_y_t), ipl(y2, y4, rel_y_t), rel_x_r);
119
- double abs_y_b_l = ipl(ipl(y1, y3, rel_y_b), ipl(y2, y4, rel_y_b), rel_x_l);
120
- double abs_y_b_r = ipl(ipl(y1, y3, rel_y_b), ipl(y2, y4, rel_y_b), rel_x_r);
121
-
122
- Color abs_c_t_l = ipl(ipl(c1, c3, rel_y_t), ipl(c2, c4, rel_y_t), rel_x_l);
123
- Color abs_c_t_r = ipl(ipl(c1, c3, rel_y_t), ipl(c2, c4, rel_y_t), rel_x_r);
124
- Color abs_c_b_l = ipl(ipl(c1, c3, rel_y_b), ipl(c2, c4, rel_y_b), rel_x_l);
125
- Color abs_c_b_r = ipl(ipl(c1, c3, rel_y_b), ipl(c2, c4, rel_y_b), rel_x_r);
126
-
127
- part.draw(abs_x_t_l, abs_y_t_l, abs_c_t_l, abs_x_t_r, abs_y_t_r, abs_c_t_r,
128
- abs_x_b_l, abs_y_b_l, abs_c_b_l, abs_x_b_r, abs_y_b_r, abs_c_b_r, z, mode);
128
+ int sub_tiles_y = 0;
129
+ vector<unique_ptr<ImageData>> sub_tiles;
130
+
131
+ int y = 0;
132
+ for (int ty = 0; ty < tiles_y; ++ty) {
133
+ int row_height = tiles[ty * tiles_x]->height();
134
+
135
+ if (y + row_height <= top) {
136
+ y += tiles[ty * tiles_x]->height();
137
+ continue;
129
138
  }
139
+ if (y >= top + height) break;
140
+
141
+ sub_tiles_y += 1;
142
+
143
+ int x = 0;
144
+ for (int tx = 0; tx < tiles_x; ++tx) {
145
+ ImageData& tile = *tiles[ty * tiles_x + tx];
146
+
147
+ if (x + tile.width() <= left) {
148
+ x += tile.width();
149
+ continue;
150
+ }
151
+ if (x >= left + width) break;
152
+
153
+ int sub_left = max(0, left - x);
154
+ int sub_top = max(0, top - y);
155
+ int sub_right = min(tile.width(), left + width - x);
156
+ int sub_bottom = min(tile.height(), top + height - y);
157
+
158
+ sub_tiles.emplace_back(tile.subimage(sub_left, sub_top, sub_right - sub_left, sub_bottom - sub_top));
159
+
160
+ x += tile.width();
161
+ }
162
+ y += tiles[ty * tiles_x]->height();
163
+ }
164
+
165
+ if (sub_tiles.size() == 1) {
166
+ return move(sub_tiles[0]);
167
+ }
168
+ else {
169
+ unique_ptr<LargeImageData> result(new LargeImageData());
170
+ result->w = width;
171
+ result->h = height;
172
+ result->tiles_x = static_cast<int>(sub_tiles.size()) / sub_tiles_y;
173
+ result->tiles_y = sub_tiles_y;
174
+ result->tiles.swap(sub_tiles);
175
+ return move(result);
130
176
  }
131
177
  }
132
178
 
133
179
  Gosu::Bitmap Gosu::LargeImageData::to_bitmap() const
134
180
  {
135
181
  Bitmap bitmap(width(), height());
136
- for (int x = 0; x < parts_x; ++x) {
137
- for (int y = 0; y < parts_y; ++y) {
138
- bitmap.insert(parts[y * parts_x + x]->to_bitmap(), x * part_width, y * part_height);
182
+ int y = 0;
183
+ for (int ty = 0; ty < tiles_y; ++ty) {
184
+ int x = 0;
185
+ for (int tx = 0; tx < tiles_x; ++tx) {
186
+ ImageData& tile = *tiles[ty * tiles_x + tx];
187
+ bitmap.insert(tile.to_bitmap(), x, y);
188
+ x += tile.width();
139
189
  }
190
+ y += tiles[ty * tiles_x]->height();
140
191
  }
141
192
  return bitmap;
142
193
  }
143
194
 
144
195
  void Gosu::LargeImageData::insert(const Bitmap& bitmap, int at_x, int at_y)
145
196
  {
146
- for (int x = 0; x < parts_x; ++x) {
147
- for (int y = 0; y < parts_y; ++y) {
148
- parts[y * parts_x + x]->insert(bitmap, at_x - x * part_width, at_y - y * part_height);
197
+ int y = 0;
198
+ for (int ty = 0; ty < tiles_y; ++ty) {
199
+ int x = 0;
200
+ for (int tx = 0; tx < tiles_x; ++tx) {
201
+ ImageData& tile = *tiles[ty * tiles_x + tx];
202
+ tile.insert(bitmap, at_x - x, at_y - y);
203
+ x += tile.width();
149
204
  }
205
+ y += tiles[ty * tiles_x]->height();
150
206
  }
151
207
  }
@@ -1,43 +1,37 @@
1
1
  #pragma once
2
2
 
3
+ #include "GraphicsImpl.hpp"
3
4
  #include <Gosu/Fwd.hpp>
4
5
  #include <Gosu/ImageData.hpp>
5
6
  #include <Gosu/Platform.hpp>
6
7
  #include <memory>
7
8
  #include <vector>
8
9
 
9
- namespace Gosu
10
+ class Gosu::LargeImageData : public Gosu::ImageData
10
11
  {
11
- class LargeImageData : public ImageData
12
- {
13
- unsigned full_width, full_height;
14
- unsigned parts_x, parts_y;
15
- unsigned part_width, part_height;
16
- std::vector<std::shared_ptr<ImageData>> parts;
12
+ int w, h;
13
+ int tiles_x, tiles_y;
14
+ std::vector<std::unique_ptr<ImageData>> tiles;
15
+
16
+ LargeImageData() {}
17
17
 
18
- public:
19
- LargeImageData(const Bitmap& source, unsigned part_width, unsigned part_height,
20
- unsigned image_flags);
18
+ public:
19
+ LargeImageData(const Bitmap& source, int tile_width, int tile_height, unsigned image_flags);
21
20
 
22
- int width() const override;
23
- int height() const override;
21
+ int width() const override { return w; }
22
+ int height() const override { return h; }
24
23
 
25
- void draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
26
- double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z,
27
- AlphaMode mode) const override;
24
+ void draw(double x1, double y1, Color c1,
25
+ double x2, double y2, Color c2,
26
+ double x3, double y3, Color c3,
27
+ double x4, double y4, Color c4,
28
+ ZPos z, AlphaMode mode) const override;
28
29
 
29
- const GLTexInfo* gl_tex_info() const override
30
- {
31
- return nullptr;
32
- }
33
-
34
- std::unique_ptr<ImageData> subimage(int x, int y, int w, int h) const override
35
- {
36
- return std::unique_ptr<ImageData>();
37
- }
38
-
39
- Bitmap to_bitmap() const override;
40
-
41
- void insert(const Bitmap& bitmap, int x, int y) override;
42
- };
43
- }
30
+ const GLTexInfo* gl_tex_info() const override { return nullptr; }
31
+
32
+ std::unique_ptr<ImageData> subimage(int x, int y, int width, int height) const override;
33
+
34
+ Bitmap to_bitmap() const override;
35
+
36
+ void insert(const Bitmap& bitmap, int x, int y) override;
37
+ };
@@ -211,7 +211,7 @@ void Gosu::Macro::draw(double x1, double y1, Color c1, double x2, double y2, Col
211
211
  normalize_coordinates(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
212
212
 
213
213
  std::function<void ()> f = [=] { pimpl->draw_vertex_arrays(x1, y1, x2, y2, x3, y3, x4, y4); };
214
- Gosu::Graphics::gl(f, z);
214
+ Gosu::Graphics::gl(z, f);
215
215
  }
216
216
 
217
217
  const Gosu::GLTexInfo* Gosu::Macro::gl_tex_info() const
@@ -2400,30 +2400,24 @@ namespace Gosu
2400
2400
 
2401
2401
  void unsafe_gl()
2402
2402
  {
2403
- Gosu::Graphics::begin_gl();
2404
- rb_yield(Qnil);
2405
- Gosu::Graphics::end_gl();
2403
+ Gosu::Graphics::gl([] { rb_yield(Qnil); });
2406
2404
  }
2407
2405
 
2408
2406
  void unsafe_gl(Gosu::ZPos z)
2409
2407
  {
2410
2408
  VALUE block = rb_block_proc();
2411
- Gosu::Graphics::gl([block] {
2409
+ Gosu::Graphics::gl(z, [block] {
2412
2410
  Gosu::call_ruby_block(block);
2413
- }, z);
2411
+ });
2414
2412
  }
2415
2413
 
2416
2414
  void clip_to(double x, double y, double width, double height)
2417
2415
  {
2418
- Gosu::Graphics::begin_clipping(x, y, width, height);
2419
- rb_yield(Qnil);
2420
- Gosu::Graphics::end_clipping();
2416
+ Gosu::Graphics::clip_to(x, y, width, height, [] { rb_yield(Qnil); });
2421
2417
  }
2422
2418
 
2423
2419
  Gosu::Image* record(int width, int height) {
2424
- Gosu::Graphics::begin_recording();
2425
- rb_yield(Qnil);
2426
- return new Gosu::Image(Gosu::Graphics::end_recording(width, height));
2420
+ return new Gosu::Image(Gosu::Graphics::record(width, height, [] { rb_yield(Qnil); }));
2427
2421
  }
2428
2422
 
2429
2423
  // This method cannot be called "transform" because then it would be an ambiguous overload of
@@ -2437,44 +2431,38 @@ namespace Gosu
2437
2431
  Gosu::Transform transform = {
2438
2432
  m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15
2439
2433
  };
2440
- Gosu::Graphics::push_transform(transform);
2441
- rb_yield(Qnil);
2442
- Gosu::Graphics::pop_transform();
2434
+ Gosu::Graphics::transform(transform,
2435
+ [] { rb_yield(Qnil); });
2443
2436
  }
2444
2437
 
2445
2438
  void rotate_for_ruby(double angle, double around_x = 0, double around_y = 0)
2446
2439
  {
2447
- Gosu::Graphics::push_transform(Gosu::rotate(angle, around_x, around_y));
2448
- rb_yield(Qnil);
2449
- Gosu::Graphics::pop_transform();
2440
+ Gosu::Graphics::transform(Gosu::rotate(angle, around_x, around_y),
2441
+ [] { rb_yield(Qnil); });
2450
2442
  }
2451
2443
 
2452
2444
  void scale_for_ruby(double factor)
2453
2445
  {
2454
- Gosu::Graphics::push_transform(Gosu::scale(factor));
2455
- rb_yield(Qnil);
2456
- Gosu::Graphics::pop_transform();
2446
+ Gosu::Graphics::transform(Gosu::scale(factor),
2447
+ [] { rb_yield(Qnil); });
2457
2448
  }
2458
2449
 
2459
2450
  void scale_for_ruby(double scale_x, double scale_y)
2460
2451
  {
2461
- Gosu::Graphics::push_transform(Gosu::scale(scale_x, scale_y));
2462
- rb_yield(Qnil);
2463
- Gosu::Graphics::pop_transform();
2452
+ Gosu::Graphics::transform(Gosu::scale(scale_x, scale_y),
2453
+ [] { rb_yield(Qnil); });
2464
2454
  }
2465
2455
 
2466
2456
  void scale_for_ruby(double scale_x, double scale_y, double around_x, double around_y)
2467
2457
  {
2468
- Gosu::Graphics::push_transform(Gosu::scale(scale_x, scale_y, around_x, around_y));
2469
- rb_yield(Qnil);
2470
- Gosu::Graphics::pop_transform();
2458
+ Gosu::Graphics::transform(Gosu::scale(scale_x, scale_y, around_x, around_y),
2459
+ [] { rb_yield(Qnil); });
2471
2460
  }
2472
2461
 
2473
2462
  void translate_for_ruby(double x, double y)
2474
2463
  {
2475
- Gosu::Graphics::push_transform(Gosu::translate(x, y));
2476
- rb_yield(Qnil);
2477
- Gosu::Graphics::pop_transform();
2464
+ Gosu::Graphics::transform(Gosu::translate(x, y),
2465
+ [] { rb_yield(Qnil); });
2478
2466
  }
2479
2467
  }
2480
2468
 
@@ -11638,8 +11626,8 @@ SWIGEXPORT void Init_gosu(void) {
11638
11626
  rb_define_const(mGosu, "VERSION", SWIG_From_std_string(static_cast< std::string >(Gosu::VERSION)));
11639
11627
  rb_define_const(mGosu, "LICENSES", SWIG_From_std_string(static_cast< std::string >(Gosu::LICENSES)));
11640
11628
  rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(0)));
11641
- rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(11)));
11642
- rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(4)));
11629
+ rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(12)));
11630
+ rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(0)));
11643
11631
  rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
11644
11632
  rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
11645
11633
  rb_define_module_function(mGosu, "degrees_to_radians", VALUEFUNC(_wrap_degrees_to_radians), -1);
@@ -3,27 +3,35 @@
3
3
  #include "Texture.hpp"
4
4
  #include <Gosu/Bitmap.hpp>
5
5
  #include <Gosu/Graphics.hpp>
6
+ using namespace std;
6
7
 
7
8
  void Gosu::TexChunk::set_tex_info()
8
9
  {
10
+ double texture_size = texture->size();
11
+
9
12
  info.tex_name = texture->tex_name();
10
- float texture_size = texture->size();
11
- info.left = x / texture_size;
12
- info.top = y / texture_size;
13
- info.right = (x + w) / texture_size;
13
+ info.left = x / texture_size;
14
+ info.top = y / texture_size;
15
+ info.right = (x + w) / texture_size;
14
16
  info.bottom = (y + h) / texture_size;
15
17
  }
16
18
 
17
- Gosu::TexChunk::TexChunk(std::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding)
19
+ Gosu::TexChunk::TexChunk(shared_ptr<Texture> texture, int x, int y, int w, int h, int padding)
18
20
  : texture(texture), x(x), y(y), w(w), h(h), padding(padding)
19
21
  {
20
22
  set_tex_info();
21
23
  }
22
24
 
23
- Gosu::TexChunk::TexChunk(const TexChunk& parent_chunk, int x, int y, int w, int h)
24
- : texture(parent_chunk.texture), x(parent_chunk.x + x), y(parent_chunk.y + y), w(w), h(h),
25
- padding(0)
25
+ Gosu::TexChunk::TexChunk(const TexChunk& parent, int x, int y, int w, int h)
26
+ : texture(parent.texture), x(parent.x + x), y(parent.y + y), w(w), h(h), padding(0)
26
27
  {
28
+ if (x < 0 || y < 0 || x + w > parent.w || y + h > parent.h) {
29
+ throw invalid_argument("subimage bounds exceed those of its parent");
30
+ }
31
+ if (w <= 0 || h <= 0) {
32
+ throw invalid_argument("cannot create empty image");
33
+ }
34
+
27
35
  set_tex_info();
28
36
  texture->block(this->x, this->y, this->w, this->h);
29
37
  }
@@ -62,9 +70,9 @@ void Gosu::TexChunk::draw(double x1, double y1, Color c1, double x2, double y2,
62
70
  Graphics::schedule_draw_op(op);
63
71
  }
64
72
 
65
- const Gosu::GLTexInfo* Gosu::TexChunk::gl_tex_info() const
73
+ unique_ptr<Gosu::ImageData> Gosu::TexChunk::subimage(int x, int y, int width, int height) const
66
74
  {
67
- return &info;
75
+ return unique_ptr<Gosu::ImageData>(new TexChunk(*this, x, y, width, height));
68
76
  }
69
77
 
70
78
  Gosu::Bitmap Gosu::TexChunk::to_bitmap() const
@@ -72,15 +80,8 @@ Gosu::Bitmap Gosu::TexChunk::to_bitmap() const
72
80
  return texture->to_bitmap(x, y, w, h);
73
81
  }
74
82
 
75
- std::unique_ptr<Gosu::ImageData> Gosu::TexChunk::subimage(int x, int y, int width, int height) const
76
- {
77
- return std::unique_ptr<Gosu::ImageData>(new TexChunk(*this, x, y, width, height));
78
- }
79
-
80
83
  void Gosu::TexChunk::insert(const Bitmap& original, int x, int y)
81
84
  {
82
- // TODO: Should respect border_flags.
83
-
84
85
  Bitmap alternate;
85
86
  const Bitmap* bitmap = &original;
86
87
 
@@ -5,46 +5,37 @@
5
5
  #include <Gosu/ImageData.hpp>
6
6
  #include <memory>
7
7
  #include <stdexcept>
8
- #include <vector>
9
8
 
10
9
  class Gosu::TexChunk : public Gosu::ImageData
11
10
  {
12
11
  std::shared_ptr<Texture> texture;
13
12
  int x, y, w, h, padding;
14
13
 
15
- // Cached for faster access.
16
14
  GLTexInfo info;
17
15
 
18
16
  void set_tex_info();
19
17
 
20
18
  public:
21
19
  TexChunk(std::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding);
22
- TexChunk(const TexChunk& parent_chunk, int x, int y, int w, int h);
23
- ~TexChunk();
20
+ TexChunk(const TexChunk& parent, int x, int y, int w, int h);
21
+ ~TexChunk() override;
24
22
 
25
- int width() const
26
- {
27
- return w;
28
- }
23
+ int width() const override { return w; }
24
+ int height() const override { return h; }
29
25
 
30
- int height() const
31
- {
32
- return h;
33
- }
34
-
35
- GLuint tex_name() const
36
- {
37
- return info.tex_name;
38
- }
26
+ GLuint tex_name() const { return info.tex_name; }
39
27
 
40
28
  void draw(double x1, double y1, Color c1,
41
29
  double x2, double y2, Color c2,
42
30
  double x3, double y3, Color c3,
43
31
  double x4, double y4, Color c4,
44
- ZPos z, AlphaMode mode) const;
32
+ ZPos z, AlphaMode mode) const override;
45
33
 
46
- const GLTexInfo* gl_tex_info() const;
47
- Gosu::Bitmap to_bitmap() const;
48
- std::unique_ptr<ImageData> subimage(int x, int y, int width, int height) const;
49
- void insert(const Bitmap& bitmap, int x, int y);
34
+ const GLTexInfo* gl_tex_info() const override { return &info; }
35
+
36
+ std::unique_ptr<ImageData> subimage(int x, int y, int width, int height) const override;
37
+
38
+ Gosu::Bitmap to_bitmap() const override;
39
+
40
+ void insert(const Bitmap& bitmap, int x, int y) override;
50
41
  };
@@ -9,14 +9,16 @@ const std::string Gosu::VERSION = std::to_string(GOSU_MAJOR_VERSION) + '.' +
9
9
  const std::string Gosu::LICENSES =
10
10
  "This software may utilize code from the following third-party libraries:\n"
11
11
  "\n"
12
- "Gosu, https://www.libgosu.org, MIT License, http://opensource.org/licenses/MIT\n"
13
- "SDL 2, http://www.libsdl.org, MIT License, http://opensource.org/licenses/MIT\n"
12
+ "Gosu, https://www.libgosu.org, MIT License, https://opensource.org/licenses/MIT\n"
13
+ "SDL 2, https://www.libsdl.org, MIT License, https://opensource.org/licenses/MIT\n"
14
14
  #if defined(GOSU_IS_WIN) || defined(GOSU_IS_X)
15
15
  "libsndfile, http://www.mega-nerd.com/libsndfile, GNU LGPL 3, "
16
- "http://www.gnu.org/copyleft/lesser.html\n"
16
+ "https://www.gnu.org/copyleft/lesser.html\n"
17
+ "mpg123, https://mpg123.de, GNU LGPL 3, "
18
+ "https://www.gnu.org/copyleft/lesser.html\n"
17
19
  #endif
18
20
  #if defined(GOSU_IS_WIN)
19
21
  "OpenAL Soft, http://kcat.strangesoft.net/openal.html, GNU LGPL 2, "
20
- "http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html\n"
22
+ "https://www.gnu.org/licenses/old-licenses/lgpl-2.0.html\n"
21
23
  #endif
22
24
  ;
@@ -283,11 +283,10 @@ bool Gosu::Window::tick()
283
283
 
284
284
  if (needs_redraw()) {
285
285
  ensure_current_context();
286
- if (graphics().begin()) {
286
+ graphics().frame([&] {
287
287
  draw();
288
- graphics().end();
289
288
  FPS::register_frame();
290
- }
289
+ });
291
290
 
292
291
  SDL_GL_SwapWindow(shared_window());
293
292
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gosu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.11.4.pre3
4
+ version: 0.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Raschke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-04 00:00:00.000000000 Z
11
+ date: 2017-04-23 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |2
14
14
  2D game development library.
@@ -152,12 +152,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
152
152
  version: 1.8.2
153
153
  required_rubygems_version: !ruby/object:Gem::Requirement
154
154
  requirements:
155
- - - ">"
155
+ - - ">="
156
156
  - !ruby/object:Gem::Version
157
- version: 1.3.1
157
+ version: '0'
158
158
  requirements: []
159
159
  rubyforge_project:
160
- rubygems_version: 2.6.8
160
+ rubygems_version: 2.6.11
161
161
  signing_key:
162
162
  specification_version: 4
163
163
  summary: 2D game development library.