gosu 0.7.39 → 0.7.40
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/.yardopts +1 -0
- data/Gosu/Version.hpp +2 -2
- data/GosuImpl/Graphics/ClipRectStack.hpp +11 -0
- data/GosuImpl/Graphics/Common.hpp +4 -3
- data/GosuImpl/Graphics/DrawOp.hpp +13 -6
- data/GosuImpl/Graphics/DrawOpQueue.hpp +89 -20
- data/GosuImpl/Graphics/Graphics.cpp +36 -96
- data/GosuImpl/Graphics/Macro.hpp +0 -17
- data/GosuImpl/Graphics/RenderState.hpp +6 -6
- data/GosuImpl/Graphics/TexChunk.cpp +3 -5
- data/GosuImpl/Graphics/TexChunk.hpp +3 -4
- data/GosuImpl/Graphics/Texture.cpp +3 -4
- data/GosuImpl/Graphics/Texture.hpp +1 -1
- data/GosuImpl/RubyGosu_wrap.cxx +2 -2
- data/GosuImpl/WindowX.cpp +64 -83
- data/linux/extconf.rb +1 -0
- metadata +4 -3
data/.yardopts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
reference/gosu.rb - README.txt COPYING reference/*.rdoc --output reference/rdoc
|
data/Gosu/Version.hpp
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
#ifndef GOSUIMPL_GRAPHICS_CLIPRECTSTACK_HPP
|
|
2
2
|
#define GOSUIMPL_GRAPHICS_CLIPRECTSTACK_HPP
|
|
3
3
|
|
|
4
|
+
#include <GosuImpl/Graphics/Common.hpp>
|
|
5
|
+
#include <cassert>
|
|
6
|
+
#include <vector>
|
|
7
|
+
|
|
4
8
|
class Gosu::ClipRectStack
|
|
5
9
|
{
|
|
6
10
|
std::vector<ClipRect> stack;
|
|
@@ -52,6 +56,12 @@ public:
|
|
|
52
56
|
{
|
|
53
57
|
}
|
|
54
58
|
|
|
59
|
+
void clear()
|
|
60
|
+
{
|
|
61
|
+
stack.clear();
|
|
62
|
+
hasEffectiveRect = false;
|
|
63
|
+
}
|
|
64
|
+
|
|
55
65
|
void beginClipping(int x, int y, int width, int height)
|
|
56
66
|
{
|
|
57
67
|
ClipRect rect = { x, y, width, height };
|
|
@@ -61,6 +71,7 @@ public:
|
|
|
61
71
|
|
|
62
72
|
void endClipping()
|
|
63
73
|
{
|
|
74
|
+
assert (!stack.empty());
|
|
64
75
|
stack.pop_back();
|
|
65
76
|
updateEffectiveRect();
|
|
66
77
|
}
|
|
@@ -104,10 +104,11 @@ namespace Gosu
|
|
|
104
104
|
return result;
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
|
|
107
|
+
template<typename Float>
|
|
108
|
+
void applyTransform(const Transform& transform, Float& x, Float& y)
|
|
108
109
|
{
|
|
109
|
-
|
|
110
|
-
|
|
110
|
+
Float in[4] = { x, y, 0, 1 };
|
|
111
|
+
Float out[4] = { 0, 0, 0, 0 };
|
|
111
112
|
for (int i = 0; i < 4; ++i)
|
|
112
113
|
for (int j = 0; j < 4; ++j)
|
|
113
114
|
out[i] += in[j] * transform[j * 4 + i];
|
|
@@ -139,12 +139,9 @@ namespace Gosu
|
|
|
139
139
|
|
|
140
140
|
void compileTo(VertexArrays& vas) const
|
|
141
141
|
{
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
vas.back().renderState = renderState;
|
|
146
|
-
}
|
|
147
|
-
|
|
142
|
+
// Copy vertex data and apply & forget about the transform.
|
|
143
|
+
// This is important because the pointed-to transform will be gone by the next
|
|
144
|
+
// frame anyway.
|
|
148
145
|
ArrayVertex result[4];
|
|
149
146
|
for (int i = 0; i < 4; ++i)
|
|
150
147
|
{
|
|
@@ -152,12 +149,22 @@ namespace Gosu
|
|
|
152
149
|
result[i].vertices[1] = vertices[i].y;
|
|
153
150
|
result[i].vertices[2] = 0;
|
|
154
151
|
result[i].color = vertices[i].c.abgr();
|
|
152
|
+
applyTransform(*renderState.transform, result[i].vertices[0], result[i].vertices[1]);
|
|
155
153
|
}
|
|
154
|
+
RenderState vaRenderState = renderState;
|
|
155
|
+
vaRenderState.transform = 0;
|
|
156
|
+
|
|
156
157
|
result[0].texCoords[0] = left, result[0].texCoords[1] = top;
|
|
157
158
|
result[1].texCoords[0] = right, result[1].texCoords[1] = top;
|
|
158
159
|
result[2].texCoords[0] = right, result[2].texCoords[1] = bottom;
|
|
159
160
|
result[3].texCoords[0] = left, result[3].texCoords[1] = bottom;
|
|
160
161
|
|
|
162
|
+
if (vas.empty() || !(vas.back().renderState == vaRenderState))
|
|
163
|
+
{
|
|
164
|
+
vas.push_back(VertexArray());
|
|
165
|
+
vas.back().renderState = vaRenderState;
|
|
166
|
+
}
|
|
167
|
+
|
|
161
168
|
vas.back().vertices.insert(vas.back().vertices.end(), result, result + 4);
|
|
162
169
|
}
|
|
163
170
|
|
|
@@ -12,6 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
class Gosu::DrawOpQueue
|
|
14
14
|
{
|
|
15
|
+
Transforms individualTransforms;
|
|
16
|
+
Transforms absoluteTransforms;
|
|
15
17
|
ClipRectStack clipRectStack;
|
|
16
18
|
|
|
17
19
|
typedef std::vector<DrawOp> DrawOps;
|
|
@@ -19,13 +21,29 @@ class Gosu::DrawOpQueue
|
|
|
19
21
|
typedef std::vector<std::tr1::function<void()> > GLBlocks;
|
|
20
22
|
GLBlocks glBlocks;
|
|
21
23
|
|
|
24
|
+
void makeCurrentTransform(const Transform& transform)
|
|
25
|
+
{
|
|
26
|
+
Transforms::iterator oldPosition =
|
|
27
|
+
std::find(absoluteTransforms.begin(), absoluteTransforms.end(), transform);
|
|
28
|
+
if (oldPosition == absoluteTransforms.end())
|
|
29
|
+
absoluteTransforms.push_back(transform);
|
|
30
|
+
else
|
|
31
|
+
absoluteTransforms.splice(absoluteTransforms.end(), absoluteTransforms, oldPosition);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
Transform& currentTransform()
|
|
35
|
+
{
|
|
36
|
+
return absoluteTransforms.back();
|
|
37
|
+
}
|
|
38
|
+
|
|
22
39
|
public:
|
|
23
|
-
|
|
24
|
-
void swap(DrawOpQueue& other)
|
|
40
|
+
DrawOpQueue()
|
|
25
41
|
{
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
42
|
+
// Every queue has a base transform that is always the current transform.
|
|
43
|
+
// This keeps the code a bit more uniform, and allows the window to
|
|
44
|
+
// set a base transform in the main rendering queue.
|
|
45
|
+
individualTransforms.push_back(scale(1));
|
|
46
|
+
absoluteTransforms.push_back(scale(1));
|
|
29
47
|
}
|
|
30
48
|
|
|
31
49
|
void scheduleDrawOp(DrawOp op)
|
|
@@ -38,12 +56,13 @@ public:
|
|
|
38
56
|
assert (op.verticesOrBlockIndex == 4);
|
|
39
57
|
#endif
|
|
40
58
|
|
|
59
|
+
op.renderState.transform = ¤tTransform();
|
|
41
60
|
if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
|
|
42
61
|
op.renderState.clipRect = *cr;
|
|
43
62
|
ops.push_back(op);
|
|
44
63
|
}
|
|
45
64
|
|
|
46
|
-
void scheduleGL(
|
|
65
|
+
void scheduleGL(std::tr1::function<void()> glBlock, ZPos z)
|
|
47
66
|
{
|
|
48
67
|
// TODO: Document this case: Clipped-away GL blocks are *not* being run.
|
|
49
68
|
if (clipRectStack.clippedWorldAway())
|
|
@@ -53,24 +72,71 @@ public:
|
|
|
53
72
|
glBlocks.push_back(glBlock);
|
|
54
73
|
|
|
55
74
|
DrawOp op;
|
|
56
|
-
op.renderState.transform = &transform;
|
|
57
75
|
op.verticesOrBlockIndex = complementOfBlockIndex;
|
|
76
|
+
op.renderState.transform = ¤tTransform();
|
|
58
77
|
if (const ClipRect* cr = clipRectStack.maybeEffectiveRect())
|
|
59
78
|
op.renderState.clipRect = *cr;
|
|
60
79
|
op.z = z;
|
|
61
80
|
ops.push_back(op);
|
|
62
81
|
}
|
|
63
82
|
|
|
64
|
-
void beginClipping(int x, int y, int width, int height)
|
|
83
|
+
void beginClipping(int x, int y, int width, int height, int screenHeight)
|
|
65
84
|
{
|
|
66
|
-
|
|
85
|
+
// Apply current transformation.
|
|
86
|
+
|
|
87
|
+
double left = x, right = x + width;
|
|
88
|
+
double top = y, bottom = y + height;
|
|
89
|
+
|
|
90
|
+
applyTransform(currentTransform(), left, top);
|
|
91
|
+
applyTransform(currentTransform(), right, bottom);
|
|
92
|
+
|
|
93
|
+
int physX = std::min(left, right);
|
|
94
|
+
int physY = std::min(top, bottom);
|
|
95
|
+
int physWidth = std::abs(int(left - right));
|
|
96
|
+
int physHeight = std::abs(int(top - bottom));
|
|
97
|
+
|
|
98
|
+
// Adjust for OpenGL having the wrong idea of where y=0 is.
|
|
99
|
+
// TODO: This should really happen *right before* setting up
|
|
100
|
+
// the glScissor.
|
|
101
|
+
physY = screenHeight - physY - physHeight;
|
|
102
|
+
|
|
103
|
+
clipRectStack.beginClipping(physX, physY, physWidth, physHeight);
|
|
67
104
|
}
|
|
68
105
|
|
|
69
106
|
void endClipping()
|
|
70
107
|
{
|
|
71
108
|
clipRectStack.endClipping();
|
|
72
109
|
}
|
|
73
|
-
|
|
110
|
+
|
|
111
|
+
void setBaseTransform(const Transform& baseTransform)
|
|
112
|
+
{
|
|
113
|
+
assert (individualTransforms.size() == 1);
|
|
114
|
+
assert (absoluteTransforms.size() == 1);
|
|
115
|
+
|
|
116
|
+
individualTransforms.front() = absoluteTransforms.front() = baseTransform;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
void pushTransform(const Transform& transform)
|
|
120
|
+
{
|
|
121
|
+
individualTransforms.push_back(transform);
|
|
122
|
+
Transform result = multiply(transform, currentTransform());
|
|
123
|
+
makeCurrentTransform(result);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
void popTransform()
|
|
127
|
+
{
|
|
128
|
+
assert (individualTransforms.size() > 1);
|
|
129
|
+
|
|
130
|
+
individualTransforms.pop_back();
|
|
131
|
+
// TODO: If currentTransform() wouldn't have to be .back(), then I think
|
|
132
|
+
// this could be optimized away and just be pop_back too. Or not?
|
|
133
|
+
Transform result = scale(1);
|
|
134
|
+
for (Transforms::reverse_iterator it = individualTransforms.rbegin(),
|
|
135
|
+
end = individualTransforms.rend(); it != end; ++it)
|
|
136
|
+
result = multiply(result, *it);
|
|
137
|
+
makeCurrentTransform(result);
|
|
138
|
+
}
|
|
139
|
+
|
|
74
140
|
void performDrawOpsAndCode()
|
|
75
141
|
{
|
|
76
142
|
// Apply Z-Ordering.
|
|
@@ -95,10 +161,7 @@ public:
|
|
|
95
161
|
{
|
|
96
162
|
manager.setRenderState(current->renderState);
|
|
97
163
|
if (current->verticesOrBlockIndex >= 0)
|
|
98
|
-
|
|
99
|
-
// Normal DrawOp, no GL code
|
|
100
|
-
current->perform(0); // next unused on desktop
|
|
101
|
-
}
|
|
164
|
+
current->perform(0);
|
|
102
165
|
else
|
|
103
166
|
{
|
|
104
167
|
// GL code
|
|
@@ -112,12 +175,6 @@ public:
|
|
|
112
175
|
#endif
|
|
113
176
|
}
|
|
114
177
|
|
|
115
|
-
void clear()
|
|
116
|
-
{
|
|
117
|
-
glBlocks.clear();
|
|
118
|
-
ops.clear();
|
|
119
|
-
}
|
|
120
|
-
|
|
121
178
|
void compileTo(VertexArrays& vas)
|
|
122
179
|
{
|
|
123
180
|
if (!glBlocks.empty())
|
|
@@ -127,6 +184,18 @@ public:
|
|
|
127
184
|
for (DrawOps::const_iterator op = ops.begin(), end = ops.end(); op != end; ++op)
|
|
128
185
|
op->compileTo(vas);
|
|
129
186
|
}
|
|
187
|
+
|
|
188
|
+
void clear()
|
|
189
|
+
{
|
|
190
|
+
absoluteTransforms.resize(1);
|
|
191
|
+
// Important!! Due to all the swapping, the first entry in the list is not necessarily
|
|
192
|
+
// the base matrix. We need to restore it.
|
|
193
|
+
absoluteTransforms.front() = scale(1);
|
|
194
|
+
individualTransforms.resize(1);
|
|
195
|
+
clipRectStack.clear();
|
|
196
|
+
glBlocks.clear();
|
|
197
|
+
ops.clear();
|
|
198
|
+
}
|
|
130
199
|
};
|
|
131
200
|
|
|
132
201
|
#endif
|
|
@@ -28,8 +28,6 @@ struct Gosu::Graphics::Impl
|
|
|
28
28
|
DrawOpQueueStack queues;
|
|
29
29
|
typedef std::vector<std::tr1::shared_ptr<Texture> > Textures;
|
|
30
30
|
Textures textures;
|
|
31
|
-
Transforms currentTransforms;
|
|
32
|
-
Transforms absoluteTransforms;
|
|
33
31
|
|
|
34
32
|
#if 0
|
|
35
33
|
std::mutex texMutex;
|
|
@@ -52,7 +50,7 @@ struct Gosu::Graphics::Impl
|
|
|
52
50
|
result = multiply(scale(1.0 * physHeight / virtWidth, 1.0 * physWidth / virtHeight), result);
|
|
53
51
|
return result;
|
|
54
52
|
}
|
|
55
|
-
}
|
|
53
|
+
}
|
|
56
54
|
|
|
57
55
|
Orientation orientation;
|
|
58
56
|
|
|
@@ -66,7 +64,7 @@ struct Gosu::Graphics::Impl
|
|
|
66
64
|
if (orientation != currentOrientation())
|
|
67
65
|
{
|
|
68
66
|
orientation = currentOrientation();
|
|
69
|
-
|
|
67
|
+
queues.front().setBaseTransform(transformForOrientation(orientation));
|
|
70
68
|
}
|
|
71
69
|
}
|
|
72
70
|
#endif
|
|
@@ -102,10 +100,6 @@ Gosu::Graphics::Graphics(unsigned physWidth, unsigned physHeight, bool fullscree
|
|
|
102
100
|
|
|
103
101
|
// Create default draw-op queue.
|
|
104
102
|
pimpl->queues.resize(1);
|
|
105
|
-
|
|
106
|
-
// Push one identity matrix as the default transform.
|
|
107
|
-
pimpl->currentTransforms.push_back(scale(1));
|
|
108
|
-
pimpl->absoluteTransforms.push_back(scale(1));
|
|
109
103
|
}
|
|
110
104
|
|
|
111
105
|
Gosu::Graphics::~Graphics()
|
|
@@ -114,14 +108,12 @@ Gosu::Graphics::~Graphics()
|
|
|
114
108
|
|
|
115
109
|
unsigned Gosu::Graphics::width() const
|
|
116
110
|
{
|
|
117
|
-
|
|
118
|
-
return size[0];
|
|
111
|
+
return pimpl->virtWidth;
|
|
119
112
|
}
|
|
120
113
|
|
|
121
114
|
unsigned Gosu::Graphics::height() const
|
|
122
115
|
{
|
|
123
|
-
|
|
124
|
-
return size[1];
|
|
116
|
+
return pimpl->virtHeight;
|
|
125
117
|
}
|
|
126
118
|
|
|
127
119
|
bool Gosu::Graphics::fullscreen() const
|
|
@@ -136,33 +128,28 @@ void Gosu::Graphics::setResolution(unsigned virtualWidth, unsigned virtualHeight
|
|
|
136
128
|
|
|
137
129
|
pimpl->virtWidth = virtualWidth, pimpl->virtHeight = virtualHeight;
|
|
138
130
|
#ifdef GOSU_IS_IPHONE
|
|
139
|
-
pimpl->orientation = static_cast<
|
|
131
|
+
pimpl->orientation = static_cast<Orientation>(-1);
|
|
140
132
|
#else
|
|
141
133
|
Transform baseTransform;
|
|
142
134
|
baseTransform = scale(1.0 / virtualWidth * pimpl->physWidth,
|
|
143
135
|
1.0 / virtualHeight * pimpl->physHeight);
|
|
144
|
-
pimpl->
|
|
136
|
+
pimpl->queues.front().setBaseTransform(baseTransform);
|
|
145
137
|
#endif
|
|
146
138
|
}
|
|
147
139
|
|
|
148
140
|
bool Gosu::Graphics::begin(Gosu::Color clearWithColor)
|
|
149
141
|
{
|
|
150
|
-
// If
|
|
151
|
-
|
|
142
|
+
// If recording is in process, cancel it.
|
|
143
|
+
assert (pimpl->queues.size() == 1);
|
|
152
144
|
pimpl->queues.resize(1);
|
|
153
145
|
// Clear leftover clippings.
|
|
154
146
|
pimpl->queues.front().clear();
|
|
155
147
|
|
|
156
|
-
pimpl->currentTransforms.resize(1);
|
|
157
148
|
#ifdef GOSU_IS_IPHONE
|
|
158
149
|
pimpl->updateBaseTransform();
|
|
159
150
|
#endif
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
glClearColor(clearWithColor.red()/255.0,
|
|
163
|
-
clearWithColor.green()/255.0,
|
|
164
|
-
clearWithColor.blue()/255.0,
|
|
165
|
-
clearWithColor.alpha()/255.0);
|
|
151
|
+
glClearColor(clearWithColor.red() / 255.f, clearWithColor.green() / 255.f,
|
|
152
|
+
clearWithColor.blue() / 255.f, clearWithColor.alpha() / 255.f);
|
|
166
153
|
glClear(GL_COLOR_BUFFER_BIT);
|
|
167
154
|
|
|
168
155
|
return true;
|
|
@@ -170,18 +157,22 @@ bool Gosu::Graphics::begin(Gosu::Color clearWithColor)
|
|
|
170
157
|
|
|
171
158
|
void Gosu::Graphics::end()
|
|
172
159
|
{
|
|
160
|
+
// If recording is in process, cancel it.
|
|
161
|
+
assert (pimpl->queues.size() == 1);
|
|
162
|
+
pimpl->queues.resize(1);
|
|
163
|
+
|
|
173
164
|
flush();
|
|
174
|
-
|
|
165
|
+
|
|
175
166
|
glFlush();
|
|
176
167
|
}
|
|
177
168
|
|
|
178
169
|
void Gosu::Graphics::flush()
|
|
179
170
|
{
|
|
180
|
-
|
|
181
|
-
|
|
171
|
+
if (pimpl->queues.size() != 1)
|
|
172
|
+
throw std::logic_error("Flushing to screen is not allowed while creating a macro");
|
|
182
173
|
|
|
183
|
-
pimpl->queues.
|
|
184
|
-
pimpl->queues.
|
|
174
|
+
pimpl->queues.front().performDrawOpsAndCode();
|
|
175
|
+
pimpl->queues.front().clear();
|
|
185
176
|
}
|
|
186
177
|
|
|
187
178
|
void Gosu::Graphics::beginGL()
|
|
@@ -225,14 +216,14 @@ void Gosu::Graphics::scheduleGL(const std::tr1::function<void()>& functor, Gosu:
|
|
|
225
216
|
throw std::logic_error("Custom OpenGL is unsupported on the iPhone");
|
|
226
217
|
}
|
|
227
218
|
#else
|
|
228
|
-
namespace
|
|
219
|
+
namespace Gosu
|
|
229
220
|
{
|
|
230
221
|
struct RunGLFunctor
|
|
231
222
|
{
|
|
232
|
-
|
|
223
|
+
Graphics& graphics;
|
|
233
224
|
std::tr1::function<void()> functor;
|
|
234
225
|
|
|
235
|
-
RunGLFunctor(
|
|
226
|
+
RunGLFunctor(Graphics& graphics, const std::tr1::function<void()>& functor)
|
|
236
227
|
: graphics(graphics), functor(functor)
|
|
237
228
|
{
|
|
238
229
|
}
|
|
@@ -243,7 +234,7 @@ namespace
|
|
|
243
234
|
glPushAttrib(GL_ALL_ATTRIB_BITS);
|
|
244
235
|
glDisable(GL_BLEND);
|
|
245
236
|
while (glGetError() != GL_NO_ERROR);
|
|
246
|
-
|
|
237
|
+
|
|
247
238
|
functor();
|
|
248
239
|
|
|
249
240
|
// Does not have to be inlined.
|
|
@@ -254,39 +245,20 @@ namespace
|
|
|
254
245
|
|
|
255
246
|
void Gosu::Graphics::scheduleGL(const std::tr1::function<void()>& functor, Gosu::ZPos z)
|
|
256
247
|
{
|
|
257
|
-
pimpl->queues.back().scheduleGL(
|
|
248
|
+
pimpl->queues.back().scheduleGL(RunGLFunctor(*this, functor), z);
|
|
258
249
|
}
|
|
259
250
|
#endif
|
|
260
251
|
|
|
261
252
|
void Gosu::Graphics::beginClipping(double x, double y, double width, double height)
|
|
262
253
|
{
|
|
263
254
|
if (pimpl->queues.size() > 1)
|
|
264
|
-
throw std::logic_error("Clipping not allowed while creating a macro yet");
|
|
265
|
-
|
|
266
|
-
// Apply current transformation.
|
|
267
|
-
|
|
268
|
-
double left = x, right = x + width;
|
|
269
|
-
double top = y, bottom = y + height;
|
|
270
|
-
|
|
271
|
-
applyTransform(pimpl->absoluteTransforms.back(), left, top);
|
|
272
|
-
applyTransform(pimpl->absoluteTransforms.back(), right, bottom);
|
|
273
|
-
|
|
274
|
-
int physX = std::min(left, right);
|
|
275
|
-
int physY = std::min(top, bottom);
|
|
276
|
-
int physWidth = std::abs(left - right);
|
|
277
|
-
int physHeight = std::abs(top - bottom);
|
|
255
|
+
throw std::logic_error("Clipping is not allowed while creating a macro yet");
|
|
278
256
|
|
|
279
|
-
|
|
280
|
-
physY = pimpl->physHeight - physY - physHeight;
|
|
281
|
-
|
|
282
|
-
pimpl->queues.back().beginClipping(physX, physY, physWidth, physHeight);
|
|
257
|
+
pimpl->queues.back().beginClipping(x, y, width, height, pimpl->physHeight);
|
|
283
258
|
}
|
|
284
259
|
|
|
285
260
|
void Gosu::Graphics::endClipping()
|
|
286
261
|
{
|
|
287
|
-
if (pimpl->queues.size() > 1)
|
|
288
|
-
throw std::logic_error("Clipping is not allowed while creating a macro");
|
|
289
|
-
|
|
290
262
|
pimpl->queues.back().endClipping();
|
|
291
263
|
}
|
|
292
264
|
|
|
@@ -305,47 +277,20 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::endRecording(int width, int heigh
|
|
|
305
277
|
return result;
|
|
306
278
|
}
|
|
307
279
|
|
|
308
|
-
namespace
|
|
309
|
-
{
|
|
310
|
-
void ensureBackOfList(Gosu::Transforms& list, const Gosu::Transform& transform)
|
|
311
|
-
{
|
|
312
|
-
Gosu::Transforms::iterator oldPosition =
|
|
313
|
-
std::find(list.begin(), list.end(), transform);
|
|
314
|
-
if (oldPosition == list.end())
|
|
315
|
-
list.push_back(transform);
|
|
316
|
-
else
|
|
317
|
-
list.splice(list.end(), list, oldPosition);
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
|
|
321
280
|
void Gosu::Graphics::pushTransform(const Gosu::Transform& transform)
|
|
322
281
|
{
|
|
323
|
-
|
|
324
|
-
throw std::logic_error("Transforms not allowed while creating a macro yet");
|
|
325
|
-
|
|
326
|
-
pimpl->currentTransforms.push_back(transform);
|
|
327
|
-
Transform result = multiply(transform, pimpl->absoluteTransforms.back());
|
|
328
|
-
ensureBackOfList(pimpl->absoluteTransforms, result);
|
|
282
|
+
pimpl->queues.back().pushTransform(transform);
|
|
329
283
|
}
|
|
330
284
|
|
|
331
285
|
void Gosu::Graphics::popTransform()
|
|
332
286
|
{
|
|
333
|
-
pimpl->
|
|
334
|
-
Transform result = scale(1);
|
|
335
|
-
|
|
336
|
-
for (Transforms::reverse_iterator it = pimpl->currentTransforms.rbegin(),
|
|
337
|
-
end = pimpl->currentTransforms.rend(); it != end; ++it)
|
|
338
|
-
result = multiply(result, *it);
|
|
339
|
-
|
|
340
|
-
ensureBackOfList(pimpl->absoluteTransforms, result);
|
|
287
|
+
pimpl->queues.back().popTransform();
|
|
341
288
|
}
|
|
342
289
|
|
|
343
290
|
void Gosu::Graphics::drawLine(double x1, double y1, Color c1,
|
|
344
|
-
double x2, double y2, Color c2,
|
|
345
|
-
ZPos z, AlphaMode mode)
|
|
291
|
+
double x2, double y2, Color c2, ZPos z, AlphaMode mode)
|
|
346
292
|
{
|
|
347
293
|
DrawOp op;
|
|
348
|
-
op.renderState.transform = &pimpl->absoluteTransforms.back();
|
|
349
294
|
op.renderState.mode = mode;
|
|
350
295
|
op.verticesOrBlockIndex = 2;
|
|
351
296
|
op.vertices[0] = DrawOp::Vertex(x1, y1, c1);
|
|
@@ -355,12 +300,10 @@ void Gosu::Graphics::drawLine(double x1, double y1, Color c1,
|
|
|
355
300
|
}
|
|
356
301
|
|
|
357
302
|
void Gosu::Graphics::drawTriangle(double x1, double y1, Color c1,
|
|
358
|
-
double x2, double y2, Color c2,
|
|
359
|
-
double x3, double y3, Color c3,
|
|
303
|
+
double x2, double y2, Color c2, double x3, double y3, Color c3,
|
|
360
304
|
ZPos z, AlphaMode mode)
|
|
361
305
|
{
|
|
362
306
|
DrawOp op;
|
|
363
|
-
op.renderState.transform = &pimpl->absoluteTransforms.back();
|
|
364
307
|
op.renderState.mode = mode;
|
|
365
308
|
op.verticesOrBlockIndex = 3;
|
|
366
309
|
op.vertices[0] = DrawOp::Vertex(x1, y1, c1);
|
|
@@ -375,15 +318,12 @@ void Gosu::Graphics::drawTriangle(double x1, double y1, Color c1,
|
|
|
375
318
|
}
|
|
376
319
|
|
|
377
320
|
void Gosu::Graphics::drawQuad(double x1, double y1, Color c1,
|
|
378
|
-
double x2, double y2, Color c2,
|
|
379
|
-
double
|
|
380
|
-
double x4, double y4, Color c4,
|
|
381
|
-
ZPos z, AlphaMode mode)
|
|
321
|
+
double x2, double y2, Color c2, double x3, double y3, Color c3,
|
|
322
|
+
double x4, double y4, Color c4, ZPos z, AlphaMode mode)
|
|
382
323
|
{
|
|
383
324
|
reorderCoordinatesIfNecessary(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
|
|
384
325
|
|
|
385
326
|
DrawOp op;
|
|
386
|
-
op.renderState.transform = &pimpl->absoluteTransforms.back();
|
|
387
327
|
op.renderState.mode = mode;
|
|
388
328
|
op.verticesOrBlockIndex = 4;
|
|
389
329
|
op.vertices[0] = DrawOp::Vertex(x1, y1, c1);
|
|
@@ -422,14 +362,14 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
|
|
|
422
362
|
if (srcX == 0 && srcWidth == src.width() &&
|
|
423
363
|
srcY == 0 && srcHeight == src.height())
|
|
424
364
|
{
|
|
425
|
-
data = texture->tryAlloc(*this, pimpl->
|
|
365
|
+
data = texture->tryAlloc(*this, pimpl->queues, texture, src, 0);
|
|
426
366
|
}
|
|
427
367
|
else
|
|
428
368
|
{
|
|
429
369
|
Bitmap trimmedSrc;
|
|
430
370
|
trimmedSrc.resize(srcWidth, srcHeight);
|
|
431
371
|
trimmedSrc.insert(src, 0, 0, srcX, srcY, srcWidth, srcHeight);
|
|
432
|
-
data = texture->tryAlloc(*this, pimpl->
|
|
372
|
+
data = texture->tryAlloc(*this, pimpl->queues, texture, trimmedSrc, 0);
|
|
433
373
|
}
|
|
434
374
|
|
|
435
375
|
if (!data.get())
|
|
@@ -460,7 +400,7 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
|
|
|
460
400
|
std::tr1::shared_ptr<Texture> texture(*i);
|
|
461
401
|
|
|
462
402
|
std::auto_ptr<ImageData> data;
|
|
463
|
-
data = texture->tryAlloc(*this, pimpl->
|
|
403
|
+
data = texture->tryAlloc(*this, pimpl->queues, texture, bmp, 1);
|
|
464
404
|
if (data.get())
|
|
465
405
|
return data;
|
|
466
406
|
}
|
|
@@ -472,7 +412,7 @@ std::auto_ptr<Gosu::ImageData> Gosu::Graphics::createImage(
|
|
|
472
412
|
pimpl->textures.push_back(texture);
|
|
473
413
|
|
|
474
414
|
std::auto_ptr<ImageData> data;
|
|
475
|
-
data = texture->tryAlloc(*this, pimpl->
|
|
415
|
+
data = texture->tryAlloc(*this, pimpl->queues, texture, bmp, 1);
|
|
476
416
|
if (!data.get())
|
|
477
417
|
throw std::logic_error("Internal texture block allocation error");
|
|
478
418
|
|
data/GosuImpl/Graphics/Macro.hpp
CHANGED
|
@@ -15,7 +15,6 @@ class Gosu::Macro : public Gosu::ImageData
|
|
|
15
15
|
{
|
|
16
16
|
Graphics& graphics;
|
|
17
17
|
VertexArrays vertexArrays;
|
|
18
|
-
std::vector<Transform> embeddedTransforms;
|
|
19
18
|
int givenWidth, givenHeight;
|
|
20
19
|
|
|
21
20
|
void realDraw(double x1, double y1, double x2, double y3) const
|
|
@@ -48,22 +47,6 @@ public:
|
|
|
48
47
|
: graphics(graphics), givenWidth(width), givenHeight(height)
|
|
49
48
|
{
|
|
50
49
|
queue.compileTo(vertexArrays);
|
|
51
|
-
|
|
52
|
-
// Very important fix: RenderState only contains a (non-owned) pointer to a Transform.
|
|
53
|
-
// If we want to use this Macro in more than a single frame, the pointer would be
|
|
54
|
-
// invalidated. Hence, we copy the transform into this macro and just let the
|
|
55
|
-
// RenderState refer to that one.
|
|
56
|
-
|
|
57
|
-
// TODO: As the next step, we should flatten all the transforms into a single one. But
|
|
58
|
-
// maybe not here, as the VertexArrays are already split up, possibly because their
|
|
59
|
-
// transforms differed.
|
|
60
|
-
|
|
61
|
-
embeddedTransforms.reserve(vertexArrays.size());
|
|
62
|
-
for (VertexArrays::iterator it = vertexArrays.begin(), end = vertexArrays.end(); it != end; ++it)
|
|
63
|
-
{
|
|
64
|
-
embeddedTransforms.push_back(*it->renderState.transform);
|
|
65
|
-
it->renderState.transform = &embeddedTransforms.back();
|
|
66
|
-
}
|
|
67
50
|
}
|
|
68
51
|
|
|
69
52
|
int width() const
|
|
@@ -61,8 +61,7 @@ struct Gosu::RenderState
|
|
|
61
61
|
void apply() const
|
|
62
62
|
{
|
|
63
63
|
applyTexture();
|
|
64
|
-
|
|
65
|
-
// cliprect from the outside is okay
|
|
64
|
+
// TODO: No inner clipRect yet - how would this work?!
|
|
66
65
|
applyAlphaMode();
|
|
67
66
|
}
|
|
68
67
|
#endif
|
|
@@ -79,8 +78,7 @@ class Gosu::RenderStateManager : private Gosu::RenderState
|
|
|
79
78
|
void applyTransform() const
|
|
80
79
|
{
|
|
81
80
|
glMatrixMode(GL_MODELVIEW);
|
|
82
|
-
|
|
83
|
-
glPushMatrix();
|
|
81
|
+
glLoadIdentity();
|
|
84
82
|
|
|
85
83
|
#ifndef GOSU_IS_IPHONE
|
|
86
84
|
glMultMatrixd(&(*transform)[0]);
|
|
@@ -96,9 +94,10 @@ class Gosu::RenderStateManager : private Gosu::RenderState
|
|
|
96
94
|
public:
|
|
97
95
|
RenderStateManager()
|
|
98
96
|
{
|
|
97
|
+
applyAlphaMode();
|
|
98
|
+
// Preserve previous MV matrix
|
|
99
99
|
glMatrixMode(GL_MODELVIEW);
|
|
100
100
|
glPushMatrix();
|
|
101
|
-
applyAlphaMode();
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
~RenderStateManager()
|
|
@@ -107,6 +106,8 @@ public:
|
|
|
107
106
|
noClipping.width = NO_CLIPPING;
|
|
108
107
|
setClipRect(noClipping);
|
|
109
108
|
setTexName(NO_TEXTURE);
|
|
109
|
+
// Return to previous MV matrix
|
|
110
|
+
glMatrixMode(GL_MODELVIEW);
|
|
110
111
|
glPopMatrix();
|
|
111
112
|
}
|
|
112
113
|
|
|
@@ -139,7 +140,6 @@ public:
|
|
|
139
140
|
if (newTransform == transform)
|
|
140
141
|
return;
|
|
141
142
|
transform = newTransform;
|
|
142
|
-
|
|
143
143
|
applyTransform();
|
|
144
144
|
}
|
|
145
145
|
|
|
@@ -4,10 +4,9 @@
|
|
|
4
4
|
#include <Gosu/Bitmap.hpp>
|
|
5
5
|
#include <Gosu/Graphics.hpp>
|
|
6
6
|
|
|
7
|
-
Gosu::TexChunk::TexChunk(Graphics& graphics,
|
|
7
|
+
Gosu::TexChunk::TexChunk(Graphics& graphics, DrawOpQueueStack& queues,
|
|
8
8
|
std::tr1::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding)
|
|
9
|
-
:
|
|
10
|
-
texture(texture), x(x), y(y), w(w), h(h), padding(padding)
|
|
9
|
+
: graphics(graphics), queues(queues), texture(texture), x(x), y(y), w(w), h(h), padding(padding)
|
|
11
10
|
{
|
|
12
11
|
info.texName = texture->texName();
|
|
13
12
|
float textureSize = texture->size();
|
|
@@ -30,7 +29,6 @@ void Gosu::TexChunk::draw(double x1, double y1, Color c1,
|
|
|
30
29
|
{
|
|
31
30
|
DrawOp op;
|
|
32
31
|
op.renderState.texName = texName();
|
|
33
|
-
op.renderState.transform = &transforms->back();
|
|
34
32
|
op.renderState.mode = mode;
|
|
35
33
|
|
|
36
34
|
reorderCoordinatesIfNecessary(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
|
|
@@ -52,7 +50,7 @@ void Gosu::TexChunk::draw(double x1, double y1, Color c1,
|
|
|
52
50
|
op.bottom = info.bottom;
|
|
53
51
|
|
|
54
52
|
op.z = z;
|
|
55
|
-
queues
|
|
53
|
+
queues.back().scheduleDrawOp(op);
|
|
56
54
|
}
|
|
57
55
|
|
|
58
56
|
const Gosu::GLTexInfo* Gosu::TexChunk::glTexInfo() const
|
|
@@ -11,9 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
class Gosu::TexChunk : public Gosu::ImageData
|
|
13
13
|
{
|
|
14
|
-
Graphics
|
|
15
|
-
|
|
16
|
-
DrawOpQueueStack* queues;
|
|
14
|
+
Graphics& graphics;
|
|
15
|
+
DrawOpQueueStack& queues;
|
|
17
16
|
std::tr1::shared_ptr<Texture> texture;
|
|
18
17
|
int x, y, w, h, padding;
|
|
19
18
|
|
|
@@ -21,7 +20,7 @@ class Gosu::TexChunk : public Gosu::ImageData
|
|
|
21
20
|
GLTexInfo info;
|
|
22
21
|
|
|
23
22
|
public:
|
|
24
|
-
TexChunk(Graphics& graphics,
|
|
23
|
+
TexChunk(Graphics& graphics, DrawOpQueueStack& queues,
|
|
25
24
|
std::tr1::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding);
|
|
26
25
|
~TexChunk();
|
|
27
26
|
|
|
@@ -61,9 +61,8 @@ GLuint Gosu::Texture::texName() const
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
std::auto_ptr<Gosu::TexChunk>
|
|
64
|
-
Gosu::Texture::tryAlloc(Graphics& graphics,
|
|
65
|
-
|
|
66
|
-
const Bitmap& bmp, unsigned padding)
|
|
64
|
+
Gosu::Texture::tryAlloc(Graphics& graphics, DrawOpQueueStack& queues,
|
|
65
|
+
std::tr1::shared_ptr<Texture> ptr, const Bitmap& bmp, unsigned padding)
|
|
67
66
|
{
|
|
68
67
|
std::auto_ptr<Gosu::TexChunk> result;
|
|
69
68
|
|
|
@@ -71,7 +70,7 @@ std::auto_ptr<Gosu::TexChunk>
|
|
|
71
70
|
if (!allocator.alloc(bmp.width(), bmp.height(), block))
|
|
72
71
|
return result;
|
|
73
72
|
|
|
74
|
-
result.reset(new TexChunk(graphics,
|
|
73
|
+
result.reset(new TexChunk(graphics, queues, ptr, block.left + padding, block.top + padding,
|
|
75
74
|
block.width - 2 * padding, block.height - 2 * padding, padding));
|
|
76
75
|
|
|
77
76
|
glBindTexture(GL_TEXTURE_2D, name);
|
|
@@ -23,7 +23,7 @@ namespace Gosu
|
|
|
23
23
|
unsigned size() const;
|
|
24
24
|
GLuint texName() const;
|
|
25
25
|
std::auto_ptr<TexChunk>
|
|
26
|
-
tryAlloc(Graphics& graphics,
|
|
26
|
+
tryAlloc(Graphics& graphics, DrawOpQueueStack& queues,
|
|
27
27
|
std::tr1::shared_ptr<Texture> ptr, const Bitmap& bmp, unsigned padding);
|
|
28
28
|
void free(unsigned x, unsigned y);
|
|
29
29
|
Gosu::Bitmap toBitmap(unsigned x, unsigned y, unsigned width, unsigned height) const;
|
data/GosuImpl/RubyGosu_wrap.cxx
CHANGED
|
@@ -11243,8 +11243,8 @@ SWIGEXPORT void Init_gosu(void) {
|
|
|
11243
11243
|
SWIG_RubyInitializeTrackings();
|
|
11244
11244
|
rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(0)));
|
|
11245
11245
|
rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(7)));
|
|
11246
|
-
rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(
|
|
11247
|
-
rb_define_const(mGosu, "VERSION", SWIG_FromCharPtr("0.7.
|
|
11246
|
+
rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(40)));
|
|
11247
|
+
rb_define_const(mGosu, "VERSION", SWIG_FromCharPtr("0.7.40"));
|
|
11248
11248
|
rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
|
|
11249
11249
|
rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
|
|
11250
11250
|
rb_define_module_function(mGosu, "degrees_to_radians", VALUEFUNC(_wrap_degrees_to_radians), -1);
|
data/GosuImpl/WindowX.cpp
CHANGED
|
@@ -26,62 +26,68 @@
|
|
|
26
26
|
|
|
27
27
|
using namespace std::tr1::placeholders;
|
|
28
28
|
|
|
29
|
-
namespace
|
|
29
|
+
namespace Gosu
|
|
30
30
|
{
|
|
31
|
-
|
|
32
|
-
class scoped_resource
|
|
31
|
+
namespace FPS
|
|
33
32
|
{
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
33
|
+
void registerFrame();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
void screenMetrics(int *x_org, int *y_org, int *width, int *height){
|
|
37
|
+
// Open the X Display; passing NULL returns the default display.
|
|
38
|
+
Display* display = XOpenDisplay(NULL);
|
|
37
39
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
: pointer(pointer), deleter(deleter)
|
|
41
|
-
{
|
|
42
|
-
}
|
|
40
|
+
// Raw screen information from the X server.
|
|
41
|
+
Screen* screen = XScreenOfDisplay(display, DefaultScreen(display));
|
|
43
42
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
43
|
+
// Xinerama screen information; if available, this info is more accurate.
|
|
44
|
+
// This is especially important for multi-monitor configurations.
|
|
45
|
+
int screen_count = 0;
|
|
46
|
+
XineramaScreenInfo *screen_info = XineramaQueryScreens(display, &screen_count);
|
|
47
|
+
|
|
48
|
+
// If screen_info is not NULL, we got preferred measurements from Xinerama,
|
|
49
|
+
// otherwise we use the measurements from the X server.
|
|
50
|
+
if(screen_info != NULL){
|
|
51
|
+
// screen_info is an array of length screen_count
|
|
52
|
+
// Index zero should hold the "default" or "primary"
|
|
53
|
+
// screen as configured by the user.
|
|
54
|
+
*x_org = screen_info[0].x_org;
|
|
55
|
+
*y_org = screen_info[0].y_org;
|
|
56
|
+
*width = screen_info[0].width;
|
|
57
|
+
*height = screen_info[0].height;
|
|
58
|
+
}else{
|
|
59
|
+
// screen is a reference to the default X Server screen
|
|
60
|
+
// Since we know Xinerama isn't running, this screen
|
|
61
|
+
// should correspond to exactly one physical display.
|
|
62
|
+
*x_org = 0;
|
|
63
|
+
*y_org = 0;
|
|
64
|
+
*width = screen->width;
|
|
65
|
+
*height = screen->height;
|
|
49
66
|
}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
{
|
|
53
|
-
|
|
67
|
+
|
|
68
|
+
// Release the Xinerama screen info, if we have it.
|
|
69
|
+
if(screen_info != NULL){
|
|
70
|
+
XFree(screen_info);
|
|
54
71
|
}
|
|
55
72
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
return get();
|
|
59
|
-
}
|
|
73
|
+
// Release the connection to the X Display
|
|
74
|
+
XCloseDisplay(display);
|
|
60
75
|
|
|
61
|
-
|
|
62
|
-
{
|
|
63
|
-
reset(0);
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
namespace Gosu
|
|
69
|
-
{
|
|
70
|
-
namespace FPS
|
|
71
|
-
{
|
|
72
|
-
void registerFrame();
|
|
76
|
+
return;
|
|
73
77
|
}
|
|
74
78
|
|
|
75
79
|
unsigned screenWidth()
|
|
76
80
|
{
|
|
77
|
-
|
|
78
|
-
|
|
81
|
+
int x_org, y_org, width, height;
|
|
82
|
+
screenMetrics(&x_org, &y_org, &width, &height);
|
|
83
|
+
return width;
|
|
79
84
|
}
|
|
80
85
|
|
|
81
86
|
unsigned screenHeight()
|
|
82
87
|
{
|
|
83
|
-
|
|
84
|
-
|
|
88
|
+
int x_org, y_org, width, height;
|
|
89
|
+
screenMetrics(&x_org, &y_org, &width, &height);
|
|
90
|
+
return height;
|
|
85
91
|
}
|
|
86
92
|
}
|
|
87
93
|
|
|
@@ -238,63 +244,38 @@ Gosu::Window::Window(unsigned width, unsigned height, bool fullscreen,
|
|
|
238
244
|
Atom atoms[] = { XInternAtom(pimpl->display, "WM_DELETE_WINDOW", false) };
|
|
239
245
|
XSetWMProtocols(pimpl->display, pimpl->window, atoms, 1);
|
|
240
246
|
|
|
241
|
-
// Get xinerama screen info
|
|
242
|
-
int screen_count = 0;
|
|
243
|
-
XineramaScreenInfo *screen_info = XineramaQueryScreens(pimpl->display, &screen_count);
|
|
244
247
|
|
|
245
|
-
//
|
|
246
|
-
int screen_origin_x = 0;
|
|
247
|
-
int screen_origin_y = 0;
|
|
248
|
-
int screen_width = 0;
|
|
249
|
-
int screen_height = 0;
|
|
250
|
-
|
|
251
|
-
// Literal X screen, different from Xinerama screens
|
|
248
|
+
// Get reference to X Screen
|
|
252
249
|
Screen* screen = XScreenOfDisplay(pimpl->display,
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
// Get origin/size from first xinerama screen if it
|
|
256
|
-
// exists; convention seems to be that the first
|
|
257
|
-
// screen is always the default screen with xinerama.
|
|
258
|
-
if(screen_info != NULL){
|
|
259
|
-
screen_origin_x = screen_info[0].x_org;
|
|
260
|
-
screen_origin_y = screen_info[0].y_org;
|
|
261
|
-
screen_width = screen_info[0].width;
|
|
262
|
-
screen_height = screen_info[0].height;
|
|
263
|
-
|
|
264
|
-
// ... or just use the whole X screen if we don't
|
|
265
|
-
// seem to have any xinerama information.
|
|
266
|
-
}else{
|
|
267
|
-
screen_width = screen->width;
|
|
268
|
-
screen_height = screen->height;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
// Free the screen info, cause I guess we don't
|
|
272
|
-
// need it after this?
|
|
273
|
-
XFree(screen_info);
|
|
250
|
+
DefaultScreen(pimpl->display));
|
|
274
251
|
|
|
275
|
-
if (fullscreen)
|
|
276
|
-
|
|
252
|
+
if (fullscreen){
|
|
253
|
+
// If we're going fullscreen, replace the window
|
|
254
|
+
// position and size with our screen metrics.
|
|
255
|
+
int screen_x_org, screen_y_org, screen_width, screen_height;
|
|
256
|
+
Gosu::screenMetrics(&screen_x_org, &screen_y_org, &screen_width, &screen_height);
|
|
277
257
|
pimpl->width = screen_width;
|
|
278
258
|
pimpl->height = screen_height;
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
259
|
+
pimpl->x = screen_x_org;
|
|
260
|
+
pimpl->y = screen_y_org;
|
|
261
|
+
|
|
262
|
+
// Override Redirect (JohnColburn says: I don't actually know what this is for.)
|
|
282
263
|
XSetWindowAttributes windowAttributes;
|
|
283
264
|
windowAttributes.override_redirect = true;
|
|
284
265
|
unsigned mask = CWOverrideRedirect;
|
|
285
266
|
XChangeWindowAttributes(pimpl->display, pimpl->window, mask, &windowAttributes);
|
|
286
|
-
|
|
287
267
|
}
|
|
288
|
-
|
|
289
|
-
|
|
268
|
+
|
|
269
|
+
// Move and resize the window to its current position and size.
|
|
270
|
+
XMoveResizeWindow(pimpl->display, pimpl->window, pimpl->x, pimpl->y, pimpl->width, pimpl->height);
|
|
290
271
|
|
|
291
|
-
// Set window to be non
|
|
292
|
-
|
|
272
|
+
// Set window to be non-resizable
|
|
273
|
+
XSizeHints *sizeHints = XAllocSizeHints();
|
|
293
274
|
sizeHints->flags = PMinSize | PMaxSize;
|
|
294
275
|
sizeHints->min_width = sizeHints->max_width = pimpl->width;
|
|
295
276
|
sizeHints->min_height = sizeHints->max_height = pimpl->height;
|
|
296
|
-
XSetWMNormalHints(pimpl->display, pimpl->window, sizeHints
|
|
297
|
-
sizeHints
|
|
277
|
+
XSetWMNormalHints(pimpl->display, pimpl->window, sizeHints);
|
|
278
|
+
XFree(sizeHints);
|
|
298
279
|
|
|
299
280
|
// TODO: Window style (_MOTIF_WM_HINTS)?
|
|
300
281
|
|
data/linux/extconf.rb
CHANGED
|
@@ -96,6 +96,7 @@ else
|
|
|
96
96
|
have_header('vorbisfile.h') if have_library('vorbisfile', 'ov_open_callbacks')
|
|
97
97
|
have_header('AL/al.h') if have_library('openal')
|
|
98
98
|
have_header('sndfile.h') if have_library('sndfile')
|
|
99
|
+
have_header('X11/extensions/Xinerama.h') if have_library('Xinerama', 'XineramaQueryScreens')
|
|
99
100
|
end
|
|
100
101
|
|
|
101
102
|
# Copy all relevant C++ files into the current directory
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: gosu
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
hash:
|
|
4
|
+
hash: 83
|
|
5
5
|
prerelease:
|
|
6
6
|
segments:
|
|
7
7
|
- 0
|
|
8
8
|
- 7
|
|
9
|
-
-
|
|
10
|
-
version: 0.7.
|
|
9
|
+
- 40
|
|
10
|
+
version: 0.7.40
|
|
11
11
|
platform: ruby
|
|
12
12
|
authors:
|
|
13
13
|
- Julian Raschke
|
|
@@ -27,6 +27,7 @@ extensions:
|
|
|
27
27
|
extra_rdoc_files: []
|
|
28
28
|
|
|
29
29
|
files:
|
|
30
|
+
- .yardopts
|
|
30
31
|
- COPYING
|
|
31
32
|
- README.txt
|
|
32
33
|
- Gosu/Async.hpp
|