gosu 0.7.22 → 0.7.23

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. data/Gosu/Audio.hpp +2 -0
  2. data/Gosu/Fwd.hpp +0 -1
  3. data/Gosu/Gosu.hpp +1 -1
  4. data/Gosu/Graphics.hpp +12 -11
  5. data/Gosu/GraphicsBase.hpp +5 -0
  6. data/Gosu/Image.hpp +0 -14
  7. data/Gosu/Input.hpp +32 -18
  8. data/Gosu/Text.hpp +3 -2
  9. data/Gosu/Version.hpp +2 -2
  10. data/Gosu/Window.hpp +21 -8
  11. data/GosuImpl/Audio/AudioOpenAL.mm +74 -8
  12. data/GosuImpl/Graphics/Common.hpp +25 -1
  13. data/GosuImpl/Graphics/DrawOp.hpp +54 -222
  14. data/GosuImpl/Graphics/DrawOpQueue.hpp +127 -0
  15. data/GosuImpl/Graphics/FormattedString.hpp +63 -20
  16. data/GosuImpl/Graphics/GosuView.hpp +5 -8
  17. data/GosuImpl/Graphics/GosuView.mm +36 -65
  18. data/GosuImpl/Graphics/Graphics.cpp +121 -110
  19. data/GosuImpl/Graphics/Image.cpp +0 -51
  20. data/GosuImpl/Graphics/Macro.hpp +1 -0
  21. data/GosuImpl/Graphics/RenderState.hpp +107 -0
  22. data/GosuImpl/Graphics/TexChunk.cpp +1 -10
  23. data/GosuImpl/Graphics/Text.cpp +22 -10
  24. data/GosuImpl/Graphics/TextMac.cpp +2 -4
  25. data/GosuImpl/Graphics/TextTouch.mm +14 -21
  26. data/GosuImpl/Graphics/TextWin.cpp +5 -2
  27. data/GosuImpl/Graphics/Texture.cpp +11 -10
  28. data/GosuImpl/Graphics/Transform.cpp +3 -1
  29. data/GosuImpl/Input/AccelerometerReader.hpp +10 -0
  30. data/GosuImpl/Input/AccelerometerReader.mm +31 -0
  31. data/GosuImpl/InputMac.mm +51 -24
  32. data/GosuImpl/InputTouch.mm +112 -1
  33. data/GosuImpl/InputWin.cpp +27 -3
  34. data/GosuImpl/InputX.cpp +21 -0
  35. data/GosuImpl/MacUtility.hpp +33 -0
  36. data/GosuImpl/Orientation.hpp +15 -0
  37. data/GosuImpl/Orientation.mm +34 -0
  38. data/GosuImpl/RubyGosu.swg +7 -9
  39. data/GosuImpl/RubyGosu_wrap.cxx +328 -82
  40. data/GosuImpl/RubyGosu_wrap.h +3 -0
  41. data/GosuImpl/TextInputWin.cpp +2 -0
  42. data/GosuImpl/Utility.cpp +2 -0
  43. data/GosuImpl/WindowMac.mm +13 -19
  44. data/GosuImpl/WindowTouch.mm +44 -32
  45. data/GosuImpl/WindowWin.cpp +20 -12
  46. data/GosuImpl/WindowX.cpp +33 -23
  47. data/examples/CptnRuby.rb +8 -9
  48. data/lib/gosu.rb +0 -0
  49. data/lib/gosu/swig_patches.rb +0 -12
  50. data/linux/extconf.rb +2 -2
  51. metadata +11 -7
  52. data/Gosu/RotFlip.hpp +0 -125
  53. data/GosuImpl/Graphics/RotFlip.cpp +0 -184
@@ -6,7 +6,9 @@
6
6
  #include <Gosu/Platform.hpp>
7
7
 
8
8
  #if defined(GOSU_IS_WIN)
9
+ #ifndef NOMINMAX
9
10
  #define NOMINMAX
11
+ #endif
10
12
  #include <windows.h>
11
13
  #include <GL/gl.h>
12
14
  #elif defined(GOSU_IS_IPHONE)
@@ -26,19 +28,23 @@ namespace Gosu
26
28
  {
27
29
  class Texture;
28
30
  class TexChunk;
31
+ class RenderState;
29
32
  struct DrawOp;
30
33
  class DrawOpQueue;
31
34
  typedef std::list<Transform> Transforms;
32
35
  typedef std::vector<DrawOpQueue> DrawOpQueueStack;
33
36
  class Macro;
34
37
 
38
+ const GLuint NO_TEXTURE = static_cast<GLuint>(-1);
39
+ const unsigned NO_CLIPPING = 0xffffffff;
40
+
35
41
  template<typename T>
36
42
  bool isPToTheLeftOfAB(T xa, T ya,
37
43
  T xb, T yb, T xp, T yp)
38
44
  {
39
45
  return (xb - xa) * (yp - ya) - (xp - xa) * (yb - ya) > 0;
40
46
  }
41
-
47
+
42
48
  template<typename T, typename C>
43
49
  void reorderCoordinatesIfNecessary(T& x1, T& y1,
44
50
  T& x2, T& y2, T& x3, T& y3, C& c3, T& x4, T& y4, C& c4)
@@ -62,6 +68,17 @@ namespace Gosu
62
68
  return result;
63
69
  }
64
70
 
71
+ inline void applyTransform(const Transform& transform, double& x, double& y)
72
+ {
73
+ double in[4] = { x, y, 0, 1 };
74
+ double out[4] = { 0, 0, 0, 0 };
75
+ for (int i = 0; i < 4; ++i)
76
+ for (int j = 0; j < 4; ++j)
77
+ out[i] += in[j] * transform[j * 4 + i];
78
+ x = out[0] / out[3];
79
+ y = out[1] / out[3];
80
+ }
81
+
65
82
  inline void multiplyBitmapAlpha(Bitmap& bmp, Color::Channel alpha)
66
83
  {
67
84
  for (int y = 0; y < bmp.height(); ++y)
@@ -73,6 +90,13 @@ namespace Gosu
73
90
  }
74
91
  }
75
92
 
93
+ #ifdef GOSU_IS_IPHONE
94
+ int clipRectBaseFactor();
95
+ #else
96
+ inline int clipRectBaseFactor() { return 1; }
97
+ #endif
98
+
99
+ bool isEntity(const std::wstring& name);
76
100
  const Bitmap& entityBitmap(const std::wstring& name);
77
101
  }
78
102
 
@@ -5,15 +5,11 @@
5
5
  #include <Gosu/Color.hpp>
6
6
  #include <GosuImpl/Graphics/Common.hpp>
7
7
  #include <GosuImpl/Graphics/TexChunk.hpp>
8
- #include <boost/bind.hpp>
8
+ #include <GosuImpl/Graphics/RenderState.hpp>
9
9
  #include <boost/cstdint.hpp>
10
- #include <algorithm>
11
- #include <set>
12
10
 
13
11
  namespace Gosu
14
12
  {
15
- const GLuint NO_TEXTURE = static_cast<GLuint>(-1);
16
-
17
13
  struct ArrayVertex
18
14
  {
19
15
  GLfloat texCoords[2];
@@ -42,90 +38,15 @@ namespace Gosu
42
38
  const TexChunk* chunk;
43
39
  AlphaMode mode;
44
40
 
45
- DrawOp(Gosu::Transform& transform) : transform(&transform) { clipWidth = 0xffffffff; usedVertices = 0; chunk = 0; }
46
-
47
- #ifndef GOSU_IS_IPHONE
48
- void perform(GLuint& currentTexName, Transform*& currentTransform, const void*) const
41
+ DrawOp(Gosu::Transform& transform)
42
+ : transform(&transform), clipWidth(NO_CLIPPING),
43
+ usedVertices(0), chunk(0)
49
44
  {
50
- if (clipWidth != 0xffffffff)
51
- {
52
- glEnable(GL_SCISSOR_TEST);
53
- glScissor(clipX, clipY, clipWidth, clipHeight);
54
- }
55
-
56
- if (transform != currentTransform) {
57
- glPopMatrix();
58
- glPushMatrix();
59
- glMultMatrixd(transform->data());
60
- currentTransform = transform;
61
- }
62
-
63
- if (mode == amAdditive)
64
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
65
- else if (mode == amMultiply)
66
- glBlendFunc(GL_DST_COLOR, GL_ZERO);
67
- else
68
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
69
-
70
- if (chunk)
71
- {
72
- if (currentTexName == NO_TEXTURE)
73
- glEnable(GL_TEXTURE_2D);
74
- if (chunk->texName() != currentTexName)
75
- glBindTexture(GL_TEXTURE_2D, chunk->texName());
76
- currentTexName = chunk->texName();
77
- }
78
- else if (currentTexName != NO_TEXTURE)
79
- {
80
- glDisable(GL_TEXTURE_2D);
81
- currentTexName = NO_TEXTURE;
82
- }
83
-
84
- if (usedVertices == 2)
85
- glBegin(GL_LINES);
86
- else if (usedVertices == 3)
87
- glBegin(GL_TRIANGLES);
88
- else if (usedVertices == 4)
89
- glBegin(GL_QUADS);
90
-
91
- double left, top, right, bottom;
92
- if (chunk)
93
- chunk->getCoords(left, top, right, bottom);
94
-
95
- for (unsigned i = 0; i < usedVertices; i++)
96
- {
97
- glColor4f(vertices[i].c.red() / 255.0, vertices[i].c.green() / 255.0,
98
- vertices[i].c.blue() / 255.0, vertices[i].c.alpha() / 255.0);
99
- if (chunk)
100
- switch (i)
101
- {
102
- case 0:
103
- glTexCoord2d(left, top);
104
- break;
105
- case 1:
106
- glTexCoord2d(right, top);
107
- break;
108
- case 2:
109
- glTexCoord2d(right, bottom);
110
- break;
111
- case 3:
112
- glTexCoord2d(left, bottom);
113
- break;
114
- }
115
- glVertex2d(vertices[i].x, vertices[i].y);
116
- }
117
-
118
- glEnd();
119
-
120
- if (clipWidth != 0xffffffff)
121
- glDisable(GL_SCISSOR_TEST);
122
45
  }
123
- #else
124
- void perform(unsigned& currentTexName, Transform*& currentTransform, const DrawOp* next) const
46
+
47
+ void perform(RenderState& current, const DrawOp* next) const
125
48
  {
126
- if (usedVertices != 4)
127
- return; // No triangles, no lines on iPhone
128
-
49
+ #ifdef GOSU_IS_IPHONE
129
50
  static const unsigned MAX_AUTOGROUP = 24;
130
51
 
131
52
  static int spriteCounter = 0;
@@ -147,36 +68,17 @@ namespace Gosu
147
68
 
148
69
  isSetup = true;
149
70
  }
71
+ #endif
150
72
 
151
- if (transform != currentTransform) {
152
- glPopMatrix();
153
- glPushMatrix();
154
- glMultMatrixd(transform->data());
155
- currentTransform = transform;
156
- }
157
-
158
- if (clipWidth != 0xffffffff)
159
- {
160
- glEnable(GL_SCISSOR_TEST);
161
- glScissor(clipX, clipY, clipWidth, clipHeight);
162
- }
163
-
164
- if (mode == amAdditive)
165
- glBlendFunc(GL_SRC_ALPHA, GL_ONE);
166
- else if (mode == amMultiply)
167
- glBlendFunc(GL_DST_COLOR, GL_ZERO);
168
- else
169
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
73
+ current.setClipRect(clipX, clipY, clipWidth, clipHeight);
74
+ current.setTransform(transform);
75
+ current.setAlphaMode(mode);
170
76
 
171
77
  if (chunk)
172
78
  {
173
- if (currentTexName == NO_TEXTURE)
174
- glEnable(GL_TEXTURE_2D);
175
- if (chunk->texName() != currentTexName)
176
- {
177
- glBindTexture(GL_TEXTURE_2D, chunk->texName());
178
- }
79
+ current.setTexName(chunk->texName());
179
80
 
81
+ #ifdef GOSU_IS_IPHONE
180
82
  double left, top, right, bottom;
181
83
  chunk->getCoords(left, top, right, bottom);
182
84
  spriteTexcoords[spriteCounter*12 + 0] = left;
@@ -192,15 +94,48 @@ namespace Gosu
192
94
  spriteTexcoords[spriteCounter*12 + 9] = bottom;
193
95
  spriteTexcoords[spriteCounter*12 + 10] = right;
194
96
  spriteTexcoords[spriteCounter*12 + 11] = bottom;
195
-
196
- currentTexName = chunk->texName();
97
+ #endif
197
98
  }
198
- else if (currentTexName != NO_TEXTURE)
99
+ else
100
+ current.setTexName(NO_TEXTURE);
101
+
102
+ #ifndef GOSU_IS_IPHONE
103
+ if (usedVertices == 2)
104
+ glBegin(GL_LINES);
105
+ else if (usedVertices == 3)
106
+ glBegin(GL_TRIANGLES);
107
+ else if (usedVertices == 4)
108
+ glBegin(GL_QUADS);
109
+
110
+ double left, top, right, bottom;
111
+ if (chunk)
112
+ chunk->getCoords(left, top, right, bottom);
113
+
114
+ for (unsigned i = 0; i < usedVertices; i++)
199
115
  {
200
- glDisable(GL_TEXTURE_2D);
201
- currentTexName = NO_TEXTURE;
116
+ glColor4f(vertices[i].c.red() / 255.0, vertices[i].c.green() / 255.0,
117
+ vertices[i].c.blue() / 255.0, vertices[i].c.alpha() / 255.0);
118
+ if (chunk)
119
+ switch (i)
120
+ {
121
+ case 0:
122
+ glTexCoord2d(left, top);
123
+ break;
124
+ case 1:
125
+ glTexCoord2d(right, top);
126
+ break;
127
+ case 2:
128
+ glTexCoord2d(right, bottom);
129
+ break;
130
+ case 3:
131
+ glTexCoord2d(left, bottom);
132
+ break;
133
+ }
134
+ glVertex2d(vertices[i].x, vertices[i].y);
202
135
  }
203
136
 
137
+ glEnd();
138
+ #else
204
139
  for (int i = 0; i < 3; ++i)
205
140
  {
206
141
  spriteVertices[spriteCounter*12 + i*2] = vertices[i].x;
@@ -216,26 +151,18 @@ namespace Gosu
216
151
 
217
152
  ++spriteCounter;
218
153
  if (spriteCounter == MAX_AUTOGROUP or next == 0 or
219
- chunk == 0 or next->chunk == 0 or
154
+ chunk == 0 or next->chunk == 0 or next->transform != transform or
220
155
  next->chunk->texName() != chunk->texName() or next->mode != mode or
221
- clipWidth != 0xffffffff or next->clipWidth != 0xffffffff)
156
+ clipWidth != NO_CLIPPING or next->clipWidth != NO_CLIPPING)
222
157
  {
223
158
  glDrawArrays(GL_TRIANGLES, 0, 6 * spriteCounter);
224
159
  //if (spriteCounter > 1)
225
160
  // printf("grouped %d quads\n", spriteCounter);
226
161
  spriteCounter = 0;
227
162
  }
228
-
229
- if (clipWidth != 0xffffffff)
230
- glDisable(GL_SCISSOR_TEST);
163
+ #endif
231
164
  }
232
165
 
233
- unsigned texName() const
234
- {
235
- return chunk ? chunk->texName() : NO_TEXTURE;
236
- }
237
- #endif
238
-
239
166
  void compileTo(VertexArray& va) const
240
167
  {
241
168
  ArrayVertex result[4];
@@ -263,101 +190,6 @@ namespace Gosu
263
190
  return z < other.z;
264
191
  }
265
192
  };
266
-
267
- class DrawOpQueue
268
- {
269
- int clipX, clipY;
270
- unsigned clipWidth, clipHeight;
271
- std::multiset<DrawOp> set;
272
-
273
- public:
274
- DrawOpQueue()
275
- : clipWidth(0xffffffff)
276
- {
277
- }
278
-
279
- void swap(DrawOpQueue& other)
280
- {
281
- std::swap(clipX, other.clipX);
282
- std::swap(clipY, other.clipY);
283
- std::swap(clipWidth, other.clipWidth);
284
- std::swap(clipHeight, other.clipHeight);
285
- set.swap(other.set);
286
- }
287
-
288
- void addDrawOp(DrawOp op, ZPos z)
289
- {
290
- if (clipWidth != 0xffffffff)
291
- {
292
- op.clipX = clipX;
293
- op.clipY = clipY;
294
- op.clipWidth = clipWidth;
295
- op.clipHeight = clipHeight;
296
- }
297
-
298
- if (z == zImmediate)
299
- {
300
- GLuint currentTexName = NO_TEXTURE;
301
- Transform* currentTransform = 0;
302
- glMatrixMode(GL_MODELVIEW);
303
- glPushMatrix();
304
- op.perform(currentTexName, currentTransform, 0);
305
- glPopMatrix();
306
- if (currentTexName != NO_TEXTURE)
307
- glDisable(GL_TEXTURE_2D);
308
- }
309
-
310
- op.z = z;
311
- set.insert(op);
312
- }
313
-
314
- void beginClipping(int x, int y, unsigned width, unsigned height)
315
- {
316
- clipX = x;
317
- clipY = y;
318
- clipWidth = width;
319
- clipHeight = height;
320
- }
321
-
322
- void endClipping()
323
- {
324
- clipWidth = 0xffffffff;
325
- }
326
-
327
- void performDrawOps() const
328
- {
329
- GLuint currentTexName = NO_TEXTURE;
330
- Transform* currentTransform = 0;
331
-
332
- glMatrixMode(GL_MODELVIEW);
333
- glPushMatrix();
334
-
335
- std::multiset<DrawOp>::const_iterator last, cur = set.begin(), end = set.end();
336
- while (cur != end)
337
- {
338
- last = cur;
339
- ++cur;
340
- last->perform(currentTexName, currentTransform, cur == end ? 0 : &*cur);
341
- }
342
-
343
- glPopMatrix();
344
-
345
- if (currentTexName != NO_TEXTURE)
346
- glDisable(GL_TEXTURE_2D);
347
- }
348
-
349
- void clear()
350
- {
351
- set.clear();
352
- }
353
-
354
- void compileTo(VertexArray& va) const
355
- {
356
- va.resize(set.size());
357
- std::for_each(set.begin(), set.end(),
358
- boost::bind(&DrawOp::compileTo, _1, boost::ref(va)));
359
- }
360
- };
361
193
  }
362
194
 
363
195
  #endif
@@ -0,0 +1,127 @@
1
+ #ifndef GOSUIMPL_GRAPHICS_DRAWOPQUEUE_HPP
2
+ #define GOSUIMPL_GRAPHICS_DRAWOPQUEUE_HPP
3
+
4
+ #include <GosuImpl/Graphics/Common.hpp>
5
+ #include <GosuImpl/Graphics/DrawOp.hpp>
6
+ #include <boost/foreach.hpp>
7
+ #include <boost/optional.hpp>
8
+ #include <algorithm>
9
+ #include <set>
10
+ #include <vector>
11
+
12
+ class Gosu::DrawOpQueue
13
+ {
14
+ std::multiset<DrawOp> set;
15
+
16
+ struct ClipRect
17
+ {
18
+ int x, y;
19
+ unsigned width, height;
20
+ };
21
+ std::vector<ClipRect> clipRectStack;
22
+ boost::optional<ClipRect> effectiveRect;
23
+ void updateEffectiveRect()
24
+ {
25
+ if (clipRectStack.empty())
26
+ return effectiveRect.reset();
27
+
28
+ ClipRect result = { 0, 0, 0x7fffffff, 0x7fffffff };
29
+ BOOST_FOREACH (const ClipRect& rect, clipRectStack)
30
+ {
31
+ int right = std::min<int>(result.x + result.width, rect.x + rect.width);
32
+ int bottom = std::min<int>(result.y + result.height, rect.y + rect.height);
33
+ result.x = std::max<int>(result.x, rect.x);
34
+ result.y = std::max<int>(result.y, rect.y);
35
+
36
+ if (result.x >= right || result.y >= bottom)
37
+ {
38
+ effectiveRect.reset();
39
+ return;
40
+ }
41
+
42
+ result.width = right - result.x;
43
+ result.height = bottom - result.y;
44
+ }
45
+
46
+ int fac = clipRectBaseFactor();
47
+ result.x *= fac, result.y *= fac, result.width *= fac, result.height *= fac;
48
+
49
+ effectiveRect = result;
50
+ }
51
+
52
+ public:
53
+ // I really wish I would trust ADL. :|
54
+ void swap(DrawOpQueue& other)
55
+ {
56
+ clipRectStack.swap(other.clipRectStack);
57
+ std::swap(effectiveRect, other.effectiveRect);
58
+ set.swap(other.set);
59
+ }
60
+
61
+ void addDrawOp(DrawOp op, ZPos z)
62
+ {
63
+ #ifdef GOSU_IS_IPHONE
64
+ // No triangles, no lines supported
65
+ assert(op.usedVertices == 4);
66
+ #endif
67
+
68
+ if (effectiveRect)
69
+ {
70
+ const ClipRect& rect = *effectiveRect;
71
+ op.clipX = rect.x;
72
+ op.clipY = rect.y;
73
+ op.clipWidth = rect.width;
74
+ op.clipHeight = rect.height;
75
+ }
76
+ else if (!clipRectStack.empty())
77
+ // When we have no effect rect but the stack is not empty, we have clipped
78
+ // the whole world away and don't need to render things.
79
+ return;
80
+
81
+ op.z = z;
82
+ set.insert(op);
83
+ }
84
+
85
+ void beginClipping(int x, int y, unsigned width, unsigned height)
86
+ {
87
+ ClipRect rect = { x, y, width, height };
88
+ clipRectStack.push_back(rect);
89
+ updateEffectiveRect();
90
+ }
91
+
92
+ void endClipping()
93
+ {
94
+ clipRectStack.pop_back();
95
+ updateEffectiveRect();
96
+ }
97
+
98
+ void performDrawOps() const
99
+ {
100
+ RenderState current;
101
+
102
+ std::multiset<DrawOp>::const_iterator last, cur = set.begin(), end = set.end();
103
+ while (cur != end)
104
+ {
105
+ last = cur;
106
+ ++cur;
107
+ last->perform(current, cur == end ? 0 : &*cur);
108
+ }
109
+ }
110
+
111
+ void clear()
112
+ {
113
+ // Not sure if Graphics::begin() should implicitly do that.
114
+ //clipRectStack.clear();
115
+ //effectiveRect.reset();
116
+ set.clear();
117
+ }
118
+
119
+ void compileTo(VertexArray& va) const
120
+ {
121
+ va.reserve(set.size());
122
+ BOOST_FOREACH (const DrawOp& op, set)
123
+ op.compileTo(va);
124
+ }
125
+ };
126
+
127
+ #endif