gosu 2.0.0.pre6 → 2.0.0.pre8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/dependencies/SDL/include/SDL.h +1 -1
  3. data/dependencies/SDL/include/SDL_assert.h +3 -1
  4. data/dependencies/SDL/include/SDL_atomic.h +2 -2
  5. data/dependencies/SDL/include/SDL_audio.h +1 -1
  6. data/dependencies/SDL/include/SDL_bits.h +1 -1
  7. data/dependencies/SDL/include/SDL_blendmode.h +3 -3
  8. data/dependencies/SDL/include/SDL_clipboard.h +1 -1
  9. data/dependencies/SDL/include/SDL_config.h +1 -1
  10. data/dependencies/SDL/include/SDL_cpuinfo.h +1 -1
  11. data/dependencies/SDL/include/SDL_egl.h +1 -1
  12. data/dependencies/SDL/include/SDL_endian.h +1 -1
  13. data/dependencies/SDL/include/SDL_error.h +1 -1
  14. data/dependencies/SDL/include/SDL_events.h +4 -11
  15. data/dependencies/SDL/include/SDL_filesystem.h +3 -3
  16. data/dependencies/SDL/include/SDL_gamecontroller.h +27 -5
  17. data/dependencies/SDL/include/SDL_gesture.h +1 -1
  18. data/dependencies/SDL/include/SDL_guid.h +1 -1
  19. data/dependencies/SDL/include/SDL_haptic.h +1 -1
  20. data/dependencies/SDL/include/SDL_hidapi.h +1 -1
  21. data/dependencies/SDL/include/SDL_hints.h +268 -1
  22. data/dependencies/SDL/include/SDL_joystick.h +1 -1
  23. data/dependencies/SDL/include/SDL_keyboard.h +5 -3
  24. data/dependencies/SDL/include/SDL_keycode.h +1 -1
  25. data/dependencies/SDL/include/SDL_loadso.h +1 -1
  26. data/dependencies/SDL/include/SDL_locale.h +1 -1
  27. data/dependencies/SDL/include/SDL_log.h +3 -3
  28. data/dependencies/SDL/include/SDL_main.h +1 -1
  29. data/dependencies/SDL/include/SDL_messagebox.h +1 -1
  30. data/dependencies/SDL/include/SDL_metal.h +1 -1
  31. data/dependencies/SDL/include/SDL_misc.h +1 -1
  32. data/dependencies/SDL/include/SDL_mouse.h +1 -1
  33. data/dependencies/SDL/include/SDL_mutex.h +1 -1
  34. data/dependencies/SDL/include/SDL_name.h +1 -1
  35. data/dependencies/SDL/include/SDL_opengl.h +1 -1
  36. data/dependencies/SDL/include/SDL_opengles.h +1 -1
  37. data/dependencies/SDL/include/SDL_opengles2.h +1 -1
  38. data/dependencies/SDL/include/SDL_pixels.h +20 -2
  39. data/dependencies/SDL/include/SDL_platform.h +7 -1
  40. data/dependencies/SDL/include/SDL_power.h +1 -1
  41. data/dependencies/SDL/include/SDL_quit.h +1 -1
  42. data/dependencies/SDL/include/SDL_rect.h +1 -1
  43. data/dependencies/SDL/include/SDL_render.h +3 -3
  44. data/dependencies/SDL/include/SDL_revision.h +2 -2
  45. data/dependencies/SDL/include/SDL_rwops.h +1 -1
  46. data/dependencies/SDL/include/SDL_scancode.h +1 -1
  47. data/dependencies/SDL/include/SDL_sensor.h +1 -1
  48. data/dependencies/SDL/include/SDL_shape.h +1 -1
  49. data/dependencies/SDL/include/SDL_stdinc.h +18 -12
  50. data/dependencies/SDL/include/SDL_surface.h +1 -1
  51. data/dependencies/SDL/include/SDL_system.h +17 -2
  52. data/dependencies/SDL/include/SDL_syswm.h +1 -1
  53. data/dependencies/SDL/include/SDL_test.h +1 -1
  54. data/dependencies/SDL/include/SDL_test_assert.h +1 -1
  55. data/dependencies/SDL/include/SDL_test_common.h +1 -1
  56. data/dependencies/SDL/include/SDL_test_compare.h +1 -1
  57. data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
  58. data/dependencies/SDL/include/SDL_test_font.h +1 -1
  59. data/dependencies/SDL/include/SDL_test_fuzzer.h +1 -1
  60. data/dependencies/SDL/include/SDL_test_harness.h +1 -1
  61. data/dependencies/SDL/include/SDL_test_images.h +1 -1
  62. data/dependencies/SDL/include/SDL_test_log.h +1 -1
  63. data/dependencies/SDL/include/SDL_test_md5.h +1 -1
  64. data/dependencies/SDL/include/SDL_test_memory.h +1 -1
  65. data/dependencies/SDL/include/SDL_test_random.h +1 -1
  66. data/dependencies/SDL/include/SDL_thread.h +1 -1
  67. data/dependencies/SDL/include/SDL_timer.h +1 -1
  68. data/dependencies/SDL/include/SDL_touch.h +1 -1
  69. data/dependencies/SDL/include/SDL_types.h +1 -1
  70. data/dependencies/SDL/include/SDL_version.h +3 -3
  71. data/dependencies/SDL/include/SDL_video.h +8 -2
  72. data/dependencies/SDL/include/begin_code.h +3 -1
  73. data/dependencies/SDL/include/close_code.h +1 -1
  74. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  75. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  76. data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -3
  77. data/dependencies/SDL_sound/dr_flac.h +9 -5
  78. data/dependencies/SDL_sound/dr_mp3.h +14 -3
  79. data/dependencies/SDL_sound/stb_vorbis.h +66 -20
  80. data/dependencies/stb/stb_image.h +173 -175
  81. data/ext/gosu-ffi/gosu-ffi.def +1 -0
  82. data/ffi/Gosu_FFI_internal.h +2 -2
  83. data/ffi/Gosu_Image.cpp +26 -14
  84. data/ffi/Gosu_Image.h +8 -2
  85. data/include/Gosu/Image.hpp +1 -1
  86. data/lib/SDL2.dll +0 -0
  87. data/lib/gosu/ffi.rb +2 -1
  88. data/lib/gosu/image.rb +33 -20
  89. data/lib64/SDL2.dll +0 -0
  90. data/src/BinPacker.cpp +1 -1
  91. data/src/ClipRectStack.cpp +38 -0
  92. data/src/ClipRectStack.hpp +17 -83
  93. data/src/DrawOp.hpp +0 -5
  94. data/src/DrawOpQueue.hpp +24 -30
  95. data/src/GosuGLView.cpp +1 -7
  96. data/src/Graphics.cpp +8 -5
  97. data/src/GraphicsImpl.hpp +0 -23
  98. data/src/RenderState.hpp +25 -38
  99. metadata +6 -5
data/lib/gosu/image.rb CHANGED
@@ -1,9 +1,8 @@
1
1
  module Gosu
2
2
  class Image
3
- BlobHelper = Struct.new(:columns, :rows, :to_blob)
4
-
5
3
  def self.from_blob(width, height, rgba = "\0\0\0\0" * (width * height), retro: false, tileable: false)
6
- self.new(BlobHelper.new(width, height, rgba), retro: retro, tileable: tileable)
4
+ @struct ||= Struct.new(:columns, :rows, :to_blob)
5
+ self.new(@struct.new(width, height, rgba), retro: retro, tileable: tileable)
7
6
  end
8
7
 
9
8
  def self.from_text(markup, line_height, font: Gosu.default_font_name, width: -1, spacing: 0, align: :left,
@@ -48,25 +47,38 @@ module Gosu
48
47
  return images
49
48
  end
50
49
 
51
- def initialize(object, retro: false, tileable: false)
50
+ def initialize(object, retro: false, tileable: false, rect: nil)
51
+ if rect and rect.size != 4
52
+ raise ArgumentError, "Expected 4-element array as rect"
53
+ end
54
+
55
+ flags = GosuFFI.image_flags(retro: retro, tileable: tileable)
56
+
52
57
  if object.is_a? String
53
- __image = GosuFFI.Gosu_Image_create(object, GosuFFI.image_flags(retro: retro, tileable: tileable))
58
+ if rect
59
+ __image = GosuFFI.Gosu_Image_create_from_rect(object, *rect, flags)
60
+ else
61
+ __image = GosuFFI.Gosu_Image_create(object, flags)
62
+ end
54
63
  GosuFFI.check_last_error
55
64
  elsif object.is_a?(FFI::Pointer)
56
65
  __image = object
57
- elsif object.respond_to?(:to_blob) &&
58
- object.respond_to?(:columns) &&
66
+ elsif object.respond_to?(:to_blob) and
67
+ object.respond_to?(:columns) and
59
68
  object.respond_to?(:rows)
60
- blob_bytes = object.to_blob { self.format = "RGBA"; self.depth = 8 }.bytes
61
- FFI::MemoryPointer.new(:uchar, blob_bytes.size) do |blob|
62
- blob.write_array_of_type(:uchar, :put_uchar, blob_bytes)
63
- __image = GosuFFI.Gosu_Image_create_from_blob(blob, blob_bytes.size, object.columns, object.rows, GosuFFI.image_flags(retro: retro, tileable: tileable))
64
- GosuFFI.check_last_error
65
- end
69
+
70
+ blob = object.to_blob { self.format = "RGBA"; self.depth = 8 }
66
71
 
67
- raise "Failed to load image from blob" if __image.null?
72
+ # This creates a copy of the Ruby string data, which shouldn't be necessary with CRuby.
73
+ ptr = FFI::MemoryPointer.from_string(blob)
74
+ rect ||= [0, 0, object.columns, object.rows]
75
+ # Do not consider the terminating null byte part of the ptr length.
76
+ __image = GosuFFI.Gosu_Image_create_from_blob(ptr, ptr.size - 1, object.columns, object.rows, *rect, flags)
77
+ ptr.free
78
+
79
+ GosuFFI.check_last_error
68
80
  else
69
- raise ArgumentError
81
+ raise ArgumentError, "Expected String or RMagick::Image (or a type compatible with it)"
70
82
  end
71
83
 
72
84
  @managed_pointer = FFI::AutoPointer.new(__image, GosuFFI.method(:Gosu_Image_destroy))
@@ -95,7 +107,8 @@ module Gosu
95
107
  end
96
108
 
97
109
  def draw_as_quad(x1, y1, color1, x2, y2, color2, x3, y3, color3, x4, y4, color4, z = 0, mode = :default)
98
- GosuFFI.Gosu_Image_draw_as_quad(x1, y1, GosuFFI.color_to_uint32(color1), x2, y2, GosuFFI.color_to_uint32(color2),
110
+ GosuFFI.Gosu_Image_draw_as_quad(__pointer,
111
+ x1, y1, GosuFFI.color_to_uint32(color1), x2, y2, GosuFFI.color_to_uint32(color2),
99
112
  x3, y3, GosuFFI.color_to_uint32(color3), x4, y4, GosuFFI.color_to_uint32(color4),
100
113
  z, GosuFFI.blend_mode(mode))
101
114
  GosuFFI.check_last_error
@@ -112,17 +125,17 @@ module Gosu
112
125
  end
113
126
 
114
127
  def subimage(left, top, width, height)
115
- __pointer = GosuFFI.Gosu_Image_create_from_subimage(__pointer, left, top, width, height)
128
+ __subimage = GosuFFI.Gosu_Image_create_from_subimage(__pointer, left, top, width, height)
116
129
  GosuFFI.check_last_error
117
- Gosu::Image.new(__pointer)
130
+ Gosu::Image.new(__subimage)
118
131
  end
119
132
 
120
133
  def insert(image, x, y)
121
134
  image_ = nil
122
135
  if image.is_a?(Gosu::Image)
123
136
  image_ = image.__pointer
124
- elsif image.respond_to?(:to_blob) &&
125
- image.respond_to?(:rows) &&
137
+ elsif image.respond_to?(:to_blob) and
138
+ image.respond_to?(:rows) and
126
139
  image.respond_to?(:columns)
127
140
  image_ = Gosu::Image.new(image).__pointer
128
141
  else
data/lib64/SDL2.dll CHANGED
Binary file
data/src/BinPacker.cpp CHANGED
@@ -136,7 +136,7 @@ void Gosu::BinPacker::merge_neighbors(int index)
136
136
  // ┃ ┣━━┻━┫
137
137
  // ┗━┻━━━━┛
138
138
  // In this case, the texture gets stuck in this fragmented state. We assume that this is not an
139
- // issue in practice, just like memory
139
+ // issue in practice, just like RAM fragmentation has never been problematic for us.
140
140
 
141
141
  // Merge any of the other rectangles in the list into the one with the given index if they share
142
142
  // any of their four sides.
@@ -0,0 +1,38 @@
1
+ #include "ClipRectStack.hpp"
2
+ #include <stdexcept>
3
+
4
+ void Gosu::ClipRectStack::clear()
5
+ {
6
+ m_stack.clear();
7
+ m_effective_rect = std::nullopt;
8
+ }
9
+
10
+ void Gosu::ClipRectStack::push(const Rect& rect)
11
+ {
12
+ m_stack.push_back(rect);
13
+ if (m_effective_rect) {
14
+ m_effective_rect->clip_to(rect);
15
+ }
16
+ else {
17
+ m_effective_rect = rect;
18
+ }
19
+ }
20
+
21
+ void Gosu::ClipRectStack::pop()
22
+ {
23
+ if (m_stack.empty()) {
24
+ throw std::logic_error("ClipRectStack is empty");
25
+ }
26
+ m_stack.pop_back();
27
+
28
+ // The clip rect is the intersection of all active clip rects (if any).
29
+ m_effective_rect = std::nullopt;
30
+ for (const auto& rect : m_stack) {
31
+ if (m_effective_rect) {
32
+ m_effective_rect->clip_to(rect);
33
+ }
34
+ else {
35
+ m_effective_rect = rect;
36
+ }
37
+ }
38
+ }
@@ -1,90 +1,24 @@
1
1
  #pragma once
2
2
 
3
+ #include <Gosu/Utility.hpp>
3
4
  #include "GraphicsImpl.hpp"
4
- #include <cassert>
5
+ #include <limits>
6
+ #include <optional>
7
+ #include <stdexcept>
5
8
  #include <vector>
6
9
 
7
- class Gosu::ClipRectStack
10
+ namespace Gosu
8
11
  {
9
- std::vector<ClipRect> stack;
10
- bool has_effective_rect; // is effective_rect valid?
11
- ClipRect effective_rect;
12
-
13
- void update_effective_rect()
12
+ class ClipRectStack
14
13
  {
15
- // Nothing to do, no clipping in place.
16
- if (stack.empty()) {
17
- has_effective_rect = false;
18
- return;
19
- }
20
-
21
- ClipRect result = { 0.0, 0.0, 1e10, 1e10 };
22
- for (std::size_t i = 0, end = stack.size(); i < end; ++i) {
23
- const ClipRect& rect = stack[i];
24
- int result_right = std::min(result.x + result.width, rect.x + rect.width);
25
- int result_bottom = std::min(result.y + result.height, rect.y + rect.height);
26
- result.x = std::max(result.x, rect.x);
27
- result.y = std::max(result.y, rect.y);
28
-
29
- if (result.x >= result_right || result.y >= result_bottom) {
30
- // We have clipped the world away!
31
- has_effective_rect = false;
32
- return;
33
- }
34
-
35
- result.width = result_right - result.x;
36
- result.height = result_bottom - result.y;
37
- }
38
-
39
- // On the iPhone, we may have to multiply everything by 2 for Retina displays.
40
- // TODO: Doesn't this affect Retina Macs as well?
41
- // TODO: This should be handled by a global transform.
42
- int fac = clip_rect_base_factor();
43
- result.x *= fac;
44
- result.y *= fac;
45
- result.width *= fac;
46
- result.height *= fac;
47
-
48
- // Normal clipping.
49
- effective_rect = result;
50
- has_effective_rect = true;
51
- }
52
-
53
- public:
54
- ClipRectStack()
55
- : has_effective_rect(false)
56
- {
57
- }
58
-
59
- void clear()
60
- {
61
- stack.clear();
62
- has_effective_rect = false;
63
- }
64
-
65
- void begin_clipping(double x, double y, double width, double height)
66
- {
67
- ClipRect rect = { x, y, width, height };
68
- stack.push_back(rect);
69
- update_effective_rect();
70
- }
71
-
72
- void end_clipping()
73
- {
74
- assert (!stack.empty());
75
- stack.pop_back();
76
- update_effective_rect();
77
- }
78
-
79
- const ClipRect* maybe_effective_rect() const
80
- {
81
- return has_effective_rect ? &effective_rect : 0;
82
- }
83
-
84
- bool clipped_world_away() const
85
- {
86
- // When we have no effective rect but the stack is not empty, we have clipped
87
- // the whole world away and don't need to render things.
88
- return !has_effective_rect && !stack.empty();
89
- }
90
- };
14
+ std::vector<Rect> m_stack;
15
+ std::optional<Rect> m_effective_rect;
16
+
17
+ public:
18
+ void clear();
19
+ void push(const Rect& rect);
20
+ void pop();
21
+
22
+ const std::optional<Rect>& effective_rect() const { return m_effective_rect; }
23
+ };
24
+ }
data/src/DrawOp.hpp CHANGED
@@ -168,10 +168,5 @@ namespace Gosu
168
168
 
169
169
  vas.back().vertices.insert(vas.back().vertices.end(), result, result + 4);
170
170
  }
171
-
172
- bool operator<(const DrawOp& other) const
173
- {
174
- return z < other.z;
175
- }
176
171
  };
177
172
  }
data/src/DrawOpQueue.hpp CHANGED
@@ -9,6 +9,7 @@
9
9
  #include <cmath>
10
10
  #include <functional>
11
11
  #include <map>
12
+ #include <utility>
12
13
  #include <vector>
13
14
 
14
15
  class Gosu::DrawOpQueue
@@ -22,7 +23,7 @@ class Gosu::DrawOpQueue
22
23
  std::vector<std::function<void ()>> gl_blocks;
23
24
 
24
25
  public:
25
- DrawOpQueue(QueueMode mode)
26
+ explicit DrawOpQueue(QueueMode mode)
26
27
  : queue_mode(mode)
27
28
  {
28
29
  }
@@ -34,39 +35,31 @@ public:
34
35
 
35
36
  void schedule_draw_op(DrawOp op)
36
37
  {
37
- if (clip_rect_stack.clipped_world_away()) return;
38
-
39
- #ifdef GOSU_IS_OPENGLES
38
+ #ifdef GOSU_IS_OPENGLES
40
39
  // No triangles, no lines supported
41
- assert (op.vertices_or_block_index == 4);
42
- #endif
40
+ assert(op.vertices_or_block_index == 4);
41
+ #endif
43
42
 
44
43
  op.render_state.transform = &transform_stack.current();
45
- if (const ClipRect* cr = clip_rect_stack.maybe_effective_rect()) {
46
- op.render_state.clip_rect = *cr;
47
- }
44
+ op.render_state.clip_rect = clip_rect_stack.effective_rect();
48
45
  ops.push_back(op);
49
46
  }
50
47
 
51
48
  void gl(std::function<void ()> gl_block, ZPos z)
52
49
  {
53
- // TODO: Document this case: Clipped-away GL blocks are *not* being run.
54
- if (clip_rect_stack.clipped_world_away()) return;
55
-
56
50
  int complement_of_block_index = ~(int)gl_blocks.size();
57
- gl_blocks.push_back(gl_block);
51
+ gl_blocks.push_back(std::move(gl_block));
58
52
 
59
53
  DrawOp op;
60
54
  op.vertices_or_block_index = complement_of_block_index;
61
55
  op.render_state.transform = &transform_stack.current();
62
- if (const ClipRect* cr = clip_rect_stack.maybe_effective_rect()) {
63
- op.render_state.clip_rect = *cr;
64
- }
56
+ op.render_state.clip_rect = clip_rect_stack.effective_rect();
65
57
  op.z = z;
66
58
  ops.push_back(op);
67
59
  }
68
60
 
69
- void begin_clipping(double x, double y, double width, double height, double screen_height)
61
+ void begin_clipping(double x, double y, double width, double height,
62
+ std::optional<int> viewport_height)
70
63
  {
71
64
  if (mode() == QM_RECORD_MACRO) {
72
65
  throw std::logic_error("Clipping is not allowed while creating a macro");
@@ -80,21 +73,21 @@ public:
80
73
  transform_stack.current().apply(left, top);
81
74
  transform_stack.current().apply(right, bottom);
82
75
 
83
- double phys_x = std::min(left, right);
84
- double phys_y = std::min(top, bottom);
85
- double phys_width = std::abs(left - right);
86
- double phys_height = std::abs(top - bottom);
87
-
76
+ Rect clip_rect {
77
+ .x = static_cast<int>(std::min(left, right)),
78
+ .y = static_cast<int>(std::min(top, bottom)),
79
+ .width = static_cast<int>(std::abs(left - right)),
80
+ .height = static_cast<int>(std::abs(top - bottom)),
81
+ };
88
82
  // Adjust for OpenGL having the wrong idea of where y=0 is.
89
- phys_y = screen_height - phys_y - phys_height;
83
+ if (viewport_height && mode() == QM_RENDER_TO_SCREEN) {
84
+ clip_rect.y = *viewport_height - clip_rect.y - clip_rect.height;
85
+ }
90
86
 
91
- clip_rect_stack.begin_clipping(phys_x, phys_y, phys_width, phys_height);
87
+ clip_rect_stack.push(clip_rect);
92
88
  }
93
89
 
94
- void end_clipping()
95
- {
96
- clip_rect_stack.end_clipping();
97
- }
90
+ void end_clipping() { clip_rect_stack.pop(); }
98
91
 
99
92
  void set_base_transform(const Transform& base_transform)
100
93
  {
@@ -118,7 +111,8 @@ public:
118
111
  }
119
112
 
120
113
  // Apply Z-Ordering.
121
- std::stable_sort(ops.begin(), ops.end());
114
+ std::stable_sort(ops.begin(), ops.end(),
115
+ [](const DrawOp& lhs, const DrawOp& rhs) { return lhs.z < rhs.z; });
122
116
 
123
117
  RenderStateManager manager;
124
118
 
@@ -156,7 +150,7 @@ public:
156
150
  throw std::logic_error("Custom OpenGL code cannot be recorded as a macro");
157
151
  }
158
152
 
159
- std::stable_sort(ops.begin(), ops.end());
153
+ std::stable_sort(ops.begin(), ops.end(), [](const DrawOp& lhs, const DrawOp& rhs) { return lhs.z < rhs.z; });
160
154
  for (const auto& op : ops) {
161
155
  op.compile_to(vas);
162
156
  }
data/src/GosuGLView.cpp CHANGED
@@ -28,12 +28,6 @@ namespace Gosu
28
28
  {
29
29
  // Don't bother unsetting anything.
30
30
  }
31
-
32
- int clip_rect_base_factor()
33
- {
34
- static int result = [UIScreen mainScreen].scale;
35
- return result;
36
- }
37
31
  }
38
32
 
39
33
  @implementation GosuGLView
@@ -97,7 +91,7 @@ namespace Gosu
97
91
  [EAGLContext setCurrentContext:_context];
98
92
  [self destroyFramebuffer];
99
93
  [self createFramebuffer];
100
- self.contentScaleFactor = Gosu::clip_rect_base_factor();
94
+ self.contentScaleFactor = [UIScreen mainScreen].scale;
101
95
  }
102
96
 
103
97
  - (BOOL)createFramebuffer
data/src/Graphics.cpp CHANGED
@@ -247,17 +247,20 @@ void Gosu::gl(Gosu::ZPos z, const std::function<void()>& f)
247
247
  #endif
248
248
  }
249
249
 
250
- void Gosu::clip_to(double x, double y, double width, double height,
251
- const std::function<void()>& f)
250
+ void Gosu::clip_to(double x, double y, double width, double height, const std::function<void()>& f)
252
251
  {
253
- double screen_height = current_viewport().m_impl->phys_height;
254
- current_queue().begin_clipping(x, y, width, height, screen_height);
252
+ std::optional<int> viewport_height;
253
+ if (current_viewport_pointer) {
254
+ viewport_height = current_viewport_pointer->m_impl->phys_height;
255
+ }
256
+
257
+ current_queue().begin_clipping(x, y, width, height, viewport_height);
255
258
  f();
256
259
  current_queue().end_clipping();
257
260
  }
258
261
 
259
262
  Gosu::Image Gosu::render(int width, int height, const std::function<void()>& f,
260
- unsigned image_flags)
263
+ unsigned image_flags)
261
264
  {
262
265
  const OpenGLContext current_context;
263
266
 
data/src/GraphicsImpl.hpp CHANGED
@@ -13,23 +13,6 @@ namespace Gosu
13
13
  struct RenderState;
14
14
  class RenderStateManager;
15
15
 
16
- const unsigned NO_CLIPPING = 0xffffffff;
17
-
18
- // In various places in Gosu, width==NO_CLIPPING by convention means
19
- // that no clipping should happen.
20
- struct ClipRect
21
- {
22
- double x, y, width, height;
23
-
24
- bool operator==(const ClipRect& other) const
25
- {
26
- // No clipping
27
- return (width == NO_CLIPPING && other.width == NO_CLIPPING) ||
28
- // Clipping, but same
29
- (x == other.x && y == other.y && width == other.width && height == other.height);
30
- }
31
- };
32
-
33
16
  enum QueueMode
34
17
  {
35
18
  QM_RENDER_TO_SCREEN,
@@ -71,12 +54,6 @@ namespace Gosu
71
54
 
72
55
  void schedule_draw_op(const DrawOp& op);
73
56
 
74
- #ifdef GOSU_IS_IPHONE
75
- int clip_rect_base_factor();
76
- #else
77
- inline int clip_rect_base_factor() { return 1; }
78
- #endif
79
-
80
57
  void register_frame();
81
58
 
82
59
  inline std::string escape_markup(const std::string& text) {
data/src/RenderState.hpp CHANGED
@@ -1,9 +1,11 @@
1
1
  #pragma once
2
2
 
3
3
  #include <Gosu/Transform.hpp>
4
+ #include "ClipRectStack.hpp"
4
5
  #include "GraphicsImpl.hpp"
5
6
  #include "OpenGLContext.hpp"
6
7
  #include "Texture.hpp"
8
+ #include <optional>
7
9
 
8
10
  // Properties that potentially need to be changed between each draw operation.
9
11
  // This does not include the color or vertex data of the actual quads.
@@ -11,13 +13,12 @@ struct Gosu::RenderState
11
13
  {
12
14
  std::shared_ptr<Texture> texture;
13
15
  const Transform* transform;
14
- ClipRect clip_rect;
16
+ std::optional<Rect> clip_rect;
15
17
  BlendMode mode;
16
18
 
17
19
  RenderState()
18
20
  : transform(0), mode(BM_DEFAULT)
19
21
  {
20
- clip_rect.width = NO_CLIPPING;
21
22
  }
22
23
 
23
24
  bool operator==(const RenderState& rhs) const
@@ -54,12 +55,12 @@ struct Gosu::RenderState
54
55
 
55
56
  void apply_clip_rect() const
56
57
  {
57
- if (clip_rect.width == NO_CLIPPING) {
58
- glDisable(GL_SCISSOR_TEST);
58
+ if (clip_rect.has_value()) {
59
+ glEnable(GL_SCISSOR_TEST);
60
+ glScissor(clip_rect->x, clip_rect->y, clip_rect->width, clip_rect->height);
59
61
  }
60
62
  else {
61
- glEnable(GL_SCISSOR_TEST);
62
- glScissor(clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
63
+ glDisable(GL_SCISSOR_TEST);
63
64
  }
64
65
  }
65
66
 
@@ -76,12 +77,8 @@ struct Gosu::RenderState
76
77
 
77
78
  // Manages the OpenGL rendering state. It caches the current state, only forwarding the
78
79
  // changes to OpenGL if the new state is really different.
79
- class Gosu::RenderStateManager : private Gosu::RenderState
80
+ class Gosu::RenderStateManager : private Gosu::RenderState, private Gosu::Noncopyable
80
81
  {
81
- // Not copyable
82
- RenderStateManager(const RenderStateManager&);
83
- RenderStateManager& operator=(const RenderStateManager&);
84
-
85
82
  void apply_transform() const
86
83
  {
87
84
  glMatrixMode(GL_MODELVIEW);
@@ -110,9 +107,7 @@ public:
110
107
 
111
108
  ~RenderStateManager()
112
109
  {
113
- ClipRect no_clipping;
114
- no_clipping.width = NO_CLIPPING;
115
- set_clip_rect(no_clipping);
110
+ set_clip_rect(std::nullopt);
116
111
  set_texture(std::shared_ptr<Texture>());
117
112
  // Return to previous MV matrix
118
113
  glMatrixMode(GL_MODELVIEW);
@@ -127,9 +122,11 @@ public:
127
122
  set_alpha_mode(rs.mode);
128
123
  }
129
124
 
130
- void set_texture(std::shared_ptr<Texture> new_texture)
125
+ void set_texture(const std::shared_ptr<Texture>& new_texture)
131
126
  {
132
- if (new_texture == texture) return;
127
+ if (new_texture == texture) {
128
+ return;
129
+ }
133
130
 
134
131
  if (new_texture) {
135
132
  if (!texture) {
@@ -146,39 +143,29 @@ public:
146
143
 
147
144
  void set_transform(const Transform* new_transform)
148
145
  {
149
- if (new_transform == transform) return;
146
+ if (new_transform == transform) {
147
+ return;
148
+ }
150
149
 
151
150
  transform = new_transform;
152
151
  apply_transform();
153
152
  }
154
153
 
155
- void set_clip_rect(const ClipRect& new_clip_rect)
154
+ void set_clip_rect(const std::optional<Rect>& new_clip_rect)
156
155
  {
157
- if (new_clip_rect.width == NO_CLIPPING) {
158
- // Disable clipping
159
- if (clip_rect.width != NO_CLIPPING) {
160
- glDisable(GL_SCISSOR_TEST);
161
- clip_rect.width = NO_CLIPPING;
162
- }
163
- }
164
- else {
165
- // Enable clipping if off
166
- if (clip_rect.width == NO_CLIPPING) {
167
- glEnable(GL_SCISSOR_TEST);
168
- clip_rect = new_clip_rect;
169
- glScissor(clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
170
- }
171
- // Adjust clipping if necessary
172
- else if (!(clip_rect == new_clip_rect)) {
173
- clip_rect = new_clip_rect;
174
- glScissor(clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
175
- }
156
+ if (clip_rect == new_clip_rect) {
157
+ return;
176
158
  }
159
+
160
+ clip_rect = new_clip_rect;
161
+ apply_clip_rect();
177
162
  }
178
163
 
179
164
  void set_alpha_mode(BlendMode new_mode)
180
165
  {
181
- if (new_mode == mode) return;
166
+ if (new_mode == mode) {
167
+ return;
168
+ }
182
169
 
183
170
  mode = new_mode;
184
171
  apply_alpha_mode();
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: 2.0.0.pre6
4
+ version: 2.0.0.pre8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julian Raschke
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-09-02 00:00:00.000000000 Z
11
+ date: 2024-02-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -258,6 +258,7 @@ files:
258
258
  - src/BitmapIO.cpp
259
259
  - src/Buffer.cpp
260
260
  - src/Channel.cpp
261
+ - src/ClipRectStack.cpp
261
262
  - src/ClipRectStack.hpp
262
263
  - src/Color.cpp
263
264
  - src/Directories.cpp
@@ -332,11 +333,11 @@ required_ruby_version: !ruby/object:Gem::Requirement
332
333
  version: 2.5.0
333
334
  required_rubygems_version: !ruby/object:Gem::Requirement
334
335
  requirements:
335
- - - ">"
336
+ - - ">="
336
337
  - !ruby/object:Gem::Version
337
- version: 1.3.1
338
+ version: '0'
338
339
  requirements: []
339
- rubygems_version: 3.4.3
340
+ rubygems_version: 3.5.4
340
341
  signing_key:
341
342
  specification_version: 4
342
343
  summary: 2D game development library.