gosu 1.0.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING +1 -1
- data/ext/gosu/extconf.rb +5 -1
- data/include/Gosu/Font.hpp +7 -9
- data/include/Gosu/Graphics.hpp +6 -4
- data/include/Gosu/GraphicsBase.hpp +6 -6
- data/include/Gosu/Image.hpp +3 -3
- data/include/Gosu/ImageData.hpp +1 -1
- data/include/Gosu/Text.hpp +4 -4
- data/include/Gosu/Utility.hpp +10 -8
- data/include/Gosu/Version.hpp +1 -1
- data/include/Gosu/Window.hpp +23 -9
- data/lib/gosu/compat.rb +4 -0
- data/lib/gosu/swig_patches.rb +11 -10
- data/rdoc/gosu.rb +14 -1
- data/src/EmptyImageData.hpp +1 -1
- data/src/Font.cpp +4 -4
- data/src/Graphics.cpp +4 -4
- data/src/Image.cpp +4 -3
- data/src/Input.cpp +1 -10
- data/src/LargeImageData.cpp +1 -1
- data/src/LargeImageData.hpp +1 -1
- data/src/Macro.cpp +100 -143
- data/src/Macro.hpp +1 -1
- data/src/RenderState.hpp +5 -5
- data/src/Resolution.cpp +111 -63
- data/src/RubyGosu.cxx +222 -124
- data/src/RubyGosu.h +2 -2
- data/src/TexChunk.cpp +1 -1
- data/src/TexChunk.hpp +1 -1
- data/src/TrueTypeFontApple.cpp +10 -2
- data/src/TrueTypeFontWin.cpp +3 -3
- data/src/Utility.cpp +52 -23
- data/src/Window.cpp +60 -31
- data/src/WindowUIKit.cpp +21 -9
- metadata +3 -25
- data/include/Gosu/Channel.h +0 -25
- data/include/Gosu/Color.h +0 -38
- data/include/Gosu/Font.h +0 -36
- data/include/Gosu/Gosu.h +0 -82
- data/include/Gosu/Image.h +0 -54
- data/include/Gosu/Sample.h +0 -19
- data/include/Gosu/Song.h +0 -24
- data/include/Gosu/TextInput.h +0 -30
- data/include/Gosu/Window.h +0 -63
- data/src/ChannelWrapper.cpp +0 -50
- data/src/ColorWrapper.cpp +0 -126
- data/src/Constants.cpp +0 -338
- data/src/FontWrapper.cpp +0 -74
- data/src/GosuWrapper.cpp +0 -251
- data/src/ImageWrapper.cpp +0 -168
- data/src/MPEGFile.hpp +0 -90
- data/src/SampleWrapper.cpp +0 -30
- data/src/SongWrapper.cpp +0 -52
- data/src/TextInputWrapper.cpp +0 -101
- data/src/UtilityApple.cpp +0 -16
- data/src/UtilityWin.cpp +0 -17
- data/src/WindowWrapper.cpp +0 -317
data/src/Image.cpp
CHANGED
@@ -57,7 +57,7 @@ unsigned Gosu::Image::height() const
|
|
57
57
|
}
|
58
58
|
|
59
59
|
void Gosu::Image::draw(double x, double y, ZPos z, double scale_x, double scale_y, Color c,
|
60
|
-
|
60
|
+
BlendMode mode) const
|
61
61
|
{
|
62
62
|
double x2 = x + width() * scale_x;
|
63
63
|
double y2 = y + height() * scale_y;
|
@@ -66,7 +66,7 @@ void Gosu::Image::draw(double x, double y, ZPos z, double scale_x, double scale_
|
|
66
66
|
}
|
67
67
|
|
68
68
|
void Gosu::Image::draw_mod(double x, double y, ZPos z, double scale_x, double scale_y, Color c1,
|
69
|
-
Color c2, Color c3, Color c4,
|
69
|
+
Color c2, Color c3, Color c4, BlendMode mode) const
|
70
70
|
{
|
71
71
|
double x2 = x + width() * scale_x;
|
72
72
|
double y2 = y + height() * scale_y;
|
@@ -75,7 +75,8 @@ void Gosu::Image::draw_mod(double x, double y, ZPos z, double scale_x, double sc
|
|
75
75
|
}
|
76
76
|
|
77
77
|
void Gosu::Image::draw_rot(double x, double y, ZPos z, double angle,
|
78
|
-
double center_x, double center_y, double scale_x, double scale_y, Color c,
|
78
|
+
double center_x, double center_y, double scale_x, double scale_y, Color c,
|
79
|
+
BlendMode mode) const
|
79
80
|
{
|
80
81
|
double size_x = width() * scale_x;
|
81
82
|
double size_y = height() * scale_y;
|
data/src/Input.cpp
CHANGED
@@ -78,20 +78,11 @@ struct Gosu::Input::Impl
|
|
78
78
|
|
79
79
|
void update_mouse_position()
|
80
80
|
{
|
81
|
-
#if SDL_VERSION_ATLEAST(2, 0, 5)
|
82
|
-
// SDL_GetGlobalMouseState was added in SDL 2.0.4, but it only started using the same
|
83
|
-
// coordinate system as SDL_GetWindowPosition on X11 in 2.0.5.
|
84
81
|
int x, y, window_x, window_y;
|
85
82
|
SDL_GetWindowPosition(window, &window_x, &window_y);
|
86
83
|
SDL_GetGlobalMouseState(&x, &y);
|
87
84
|
mouse_x = x - window_x;
|
88
85
|
mouse_y = y - window_y;
|
89
|
-
#else
|
90
|
-
int x, y;
|
91
|
-
SDL_GetMouseState(&x, &y);
|
92
|
-
mouse_x = x;
|
93
|
-
mouse_y = y;
|
94
|
-
#endif
|
95
86
|
}
|
96
87
|
|
97
88
|
void set_mouse_position(double x, double y)
|
@@ -100,7 +91,7 @@ struct Gosu::Input::Impl
|
|
100
91
|
static_cast<int>((x - mouse_offset_x) / mouse_scale_x),
|
101
92
|
static_cast<int>((y - mouse_offset_y) / mouse_scale_y));
|
102
93
|
|
103
|
-
#if
|
94
|
+
#if !defined(GOSU_IS_X)
|
104
95
|
// On systems where we have a working GetGlobalMouseState, we can warp the mouse and
|
105
96
|
// retrieve its position directly afterwards.
|
106
97
|
update_mouse_position();
|
data/src/LargeImageData.cpp
CHANGED
@@ -69,7 +69,7 @@ void Gosu::LargeImageData::draw(double x1, double y1, Color c1,
|
|
69
69
|
double x2, double y2, Color c2,
|
70
70
|
double x3, double y3, Color c3,
|
71
71
|
double x4, double y4, Color c4,
|
72
|
-
ZPos z,
|
72
|
+
ZPos z, BlendMode mode) const
|
73
73
|
{
|
74
74
|
normalize_coordinates(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
|
75
75
|
|
data/src/LargeImageData.hpp
CHANGED
@@ -25,7 +25,7 @@ public:
|
|
25
25
|
double x2, double y2, Color c2,
|
26
26
|
double x3, double y3, Color c3,
|
27
27
|
double x4, double y4, Color c4,
|
28
|
-
ZPos z,
|
28
|
+
ZPos z, BlendMode mode) const override;
|
29
29
|
|
30
30
|
const GLTexInfo* gl_tex_info() const override { return nullptr; }
|
31
31
|
|
data/src/Macro.cpp
CHANGED
@@ -1,168 +1,125 @@
|
|
1
1
|
#include "Macro.hpp"
|
2
2
|
#include "DrawOpQueue.hpp"
|
3
3
|
#include <Gosu/Image.hpp>
|
4
|
-
#include <cmath>
|
5
|
-
#include <algorithm>
|
6
|
-
#include <functional>
|
7
|
-
#include <memory>
|
8
4
|
#include <stdexcept>
|
9
5
|
using namespace std;
|
10
6
|
|
11
7
|
struct Gosu::Macro::Impl
|
12
8
|
{
|
13
|
-
typedef double Float;
|
14
|
-
|
15
9
|
VertexArrays vertex_arrays;
|
16
10
|
int width, height;
|
17
|
-
|
18
|
-
|
19
|
-
|
11
|
+
|
12
|
+
// Solves the 2x2 linear system for x:
|
13
|
+
// (a11 a12) (x1) = (b1)
|
14
|
+
// (a21 a22) (x2) = (b2)
|
15
|
+
// x1, x2 are output parameters. Returns false if the matrix is singular.
|
16
|
+
static bool solve_2x2(double a11, double a12, double a21, double a22, double b1, double b2,
|
17
|
+
double& x1, double& x2)
|
18
|
+
{
|
19
|
+
const double det = a11 * a22 - a21 * a12;
|
20
|
+
if (det == 0) return false;
|
21
|
+
x1 = (a22 * b1 - a12 * b2) / det;
|
22
|
+
x2 = (a11 * b2 - a21 * b1) / det;
|
23
|
+
return true;
|
24
|
+
}
|
25
|
+
|
26
|
+
Transform find_transform_for_target(double x1, double y1, double x2, double y2,
|
27
|
+
double x3, double y3, double x4, double y4) const
|
20
28
|
{
|
21
29
|
// Transformation logic follows a discussion on the ImageMagick mailing
|
22
30
|
// list (on which ImageMagick's perspective_transform.pl is based).
|
23
|
-
|
31
|
+
|
24
32
|
// To draw a macro at an arbitrary position, we solve the following system:
|
25
|
-
|
26
|
-
// 0, 0, 1, 0, 0, 0,
|
27
|
-
// 0, 0, 0, 0, 0, 1,
|
28
|
-
// w, 0, 1, 0, 0, 0, -
|
29
|
-
// 0, 0, 0, w, 0, 1, -
|
30
|
-
// 0, h, 1, 0, 0, 0,
|
31
|
-
// 0, 0, 0, 0, h, 1,
|
32
|
-
// w, h, 1, 0, 0, 0, -
|
33
|
-
// 0, 0, 0, w, h, 1, -
|
34
|
-
|
33
|
+
|
34
|
+
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
35
|
+
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
36
|
+
// w, 0, 1, 0, 0, 0, -x2 w, 0 | x2
|
37
|
+
// 0, 0, 0, w, 0, 1, -y2 w, 0 | y2
|
38
|
+
// 0, h, 1, 0, 0, 0, 0, -x3 h | x3
|
39
|
+
// 0, 0, 0, 0, h, 1, 0, -y3 h | y3
|
40
|
+
// w, h, 1, 0, 0, 0, -x4 w, -x4 h | x4
|
41
|
+
// 0, 0, 0, w, h, 1, -y4 w, -y4 h | y4
|
42
|
+
|
35
43
|
// Equivalent:
|
36
|
-
|
37
|
-
// 0, 0, 1, 0, 0, 0,
|
38
|
-
// 0, 0, 0, 0, 0, 1,
|
39
|
-
// w, 0, 0, 0, 0, 0, -
|
40
|
-
// 0, 0, 0, w, 0, 0, -
|
41
|
-
// 0, h, 0, 0, 0, 0,
|
42
|
-
// 0, 0, 0, 0, h, 0,
|
43
|
-
// 0, 0, 0, 0, 0, 0, (x2-x4)w, (x3-x4)h | x1-x2-x3+x4
|
44
|
-
// 0, 0, 0, 0, 0, 0, (y2-y4)w, (y3-y4)h | y1-y2-y3+y4
|
45
|
-
|
46
|
-
//
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
//
|
44
|
+
|
45
|
+
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
46
|
+
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
47
|
+
// w, 0, 0, 0, 0, 0, -x2 w, 0 | x2-x1
|
48
|
+
// 0, 0, 0, w, 0, 0, -y2 w, 0 | y2-y1
|
49
|
+
// 0, h, 0, 0, 0, 0, 0, -x3 h | x3-x1
|
50
|
+
// 0, 0, 0, 0, h, 0, 0, -y3 h | y3-y1
|
51
|
+
// 0, 0, 0, 0, 0, 0, (x2-x4) w, (x3-x4) h | x1-x2-x3+x4
|
52
|
+
// 0, 0, 0, 0, 0, 0, (y2-y4) w, (y3-y4) h | y1-y2-y3+y4
|
53
|
+
|
54
|
+
// The last two rows only involve the last two variables.
|
55
|
+
// We can directly solve this as a separate 2x2 linear system.
|
56
|
+
|
57
|
+
// Set up 2x2 linear system of the lower right corner entries.
|
58
|
+
const double a11 = (x2 - x4) * width;
|
59
|
+
const double a12 = (x3 - x4) * height;
|
60
|
+
const double a21 = (y2 - y4) * width;
|
61
|
+
const double a22 = (y3 - y4) * height;
|
62
|
+
const double b1 = x1 - x2 - x3 + x4;
|
63
|
+
const double b2 = y1 - y2 - y3 + y4;
|
64
|
+
|
65
|
+
// Solve:
|
66
|
+
double qx, qy;
|
67
|
+
if (!solve_2x2(a11, a12, a21, a22, b1, b2, qx, qy)) return Transform{{0}};
|
68
|
+
|
69
|
+
// Updating the last two rows with the computed solution yields
|
70
|
+
|
71
|
+
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
72
|
+
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
73
|
+
// w, 0, 0, 0, 0, 0, -x2 w, 0 | x2-x1
|
74
|
+
// 0, 0, 0, w, 0, 0, -y2 w, 0 | y2-y1
|
75
|
+
// 0, h, 0, 0, 0, 0, 0, -x3 h | x3-x1
|
76
|
+
// 0, 0, 0, 0, h, 0, 0, -y3 h | y3-y1
|
77
|
+
// 0, 0, 0, 0, 0, 0, 1, 0 | qx
|
78
|
+
// 0, 0, 0, 0, 0, 0, 0, 1 | qy
|
79
|
+
|
80
|
+
// We can use the last two rows to eliminate entries in rows 3, 4, 5, and 6:
|
81
|
+
|
82
|
+
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
83
|
+
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
84
|
+
// w, 0, 0, 0, 0, 0, 0, 0 | x2-x1 + qx x2 w
|
85
|
+
// 0, 0, 0, w, 0, 0, 0, 0 | y2-y1 + qx y2 w
|
86
|
+
// 0, h, 0, 0, 0, 0, 0, 0 | x3-x1 + qy x3 h
|
87
|
+
// 0, 0, 0, 0, h, 0, 0, 0 | y3-y1 + qy y3 h
|
88
|
+
// 0, 0, 0, 0, 0, 0, 1, 0 | qx
|
89
|
+
// 0, 0, 0, 0, 0, 0, 0, 1 | qy
|
90
|
+
|
91
|
+
// Normalize and reorder rows so we can read off the solution:
|
92
|
+
|
93
|
+
// 1, 0, 0, 0, 0, 0, 0, 0 | (x2-x1) / w + qx x2
|
94
|
+
// 0, 1, 0, 0, 0, 0, 0, 0 | (x3-x1) / h + qy x3
|
95
|
+
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
96
|
+
// 0, 0, 0, 1, 0, 0, 0, 0 | (y2-y1) / w + qx y2
|
97
|
+
// 0, 0, 0, 0, 1, 0, 0, 0 | (y3-y1) / h + qy y3
|
98
|
+
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
99
|
+
// 0, 0, 0, 0, 0, 0, 1, 0 | qx
|
100
|
+
// 0, 0, 0, 0, 0, 0, 0, 1 | qy
|
101
|
+
|
102
|
+
double c[8];
|
103
|
+
c[0] = (x2 - x1) / width + qx * x2;
|
104
|
+
c[1] = (x3 - x1) / height + qy * x3;
|
62
105
|
c[2] = x1;
|
106
|
+
c[3] = (y2 - y1) / width + qx * y2;
|
107
|
+
c[4] = (y3 - y1) / height + qy * y3;
|
63
108
|
c[5] = y1;
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
// If x2 == x4, we need to exchange rows 7 and 8.
|
68
|
-
|
69
|
-
// TODO: x2==x4 is the normal case where an image is
|
70
|
-
// drawn upright; the code should rather swap in the rare case that x3==x4!
|
71
|
-
|
72
|
-
Float left_cell7 = (x2 - x4) * width;
|
73
|
-
Float right_cell7 = (x3 - x4) * height;
|
74
|
-
Float orig_right_side7 = (x1 - x2 - x3 + x4);
|
75
|
-
Float left_cell8 = (y2 - y4) * width;
|
76
|
-
Float right_cell8 = (y3 - y4) * height;
|
77
|
-
Float orig_right_side8 = (y1 - y2 - y3 + y4);
|
78
|
-
|
79
|
-
bool swap_rows78 = x2 == x4;
|
80
|
-
if (swap_rows78) {
|
81
|
-
swap(left_cell7, left_cell8);
|
82
|
-
swap(right_cell7, right_cell8);
|
83
|
-
swap(orig_right_side7, orig_right_side8);
|
84
|
-
}
|
85
|
-
|
86
|
-
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
87
|
-
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
88
|
-
// w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
|
89
|
-
// 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
|
90
|
-
// 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
|
91
|
-
// 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
|
92
|
-
// 0, 0, 0, 0, 0, 0, left_cell7, right_cell7 | orig_right_side7
|
93
|
-
// 0, 0, 0, 0, 0, 0, left_cell8, right_cell8 | orig_right_side8
|
94
|
-
|
95
|
-
// Use row 7 to eliminate the left cell in row 8
|
96
|
-
// Row8 = Row8 - factor78 * Row7
|
97
|
-
Float factor78 = left_cell8 / left_cell7;
|
98
|
-
Float rem_cell8 = right_cell8 - right_cell7 * factor78;
|
99
|
-
Float right_side8 = orig_right_side8 - orig_right_side7 * factor78;
|
100
|
-
c[7] = right_side8 / rem_cell8;
|
101
|
-
|
102
|
-
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
103
|
-
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
104
|
-
// w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
|
105
|
-
// 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
|
106
|
-
// 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
|
107
|
-
// 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
|
108
|
-
// 0, 0, 0, 0, 0, 0, left_cell7, right_cell7 | orig_right_side7
|
109
|
-
// 0, 0, 0, 0, 0, 0, 0, rem_cell8 | right_side8
|
110
|
-
|
111
|
-
// Use the remaining value in row 8 to eliminate the right value in row 7.
|
112
|
-
// Row7 = Row7 - factor87 * Row8
|
113
|
-
Float factor87 = right_cell7 / rem_cell8;
|
114
|
-
Float rem_cell7 = left_cell7;
|
115
|
-
Float right_side7 = orig_right_side7 - right_side8 * factor87;
|
116
|
-
c[6] = right_side7 / rem_cell7;
|
117
|
-
|
118
|
-
// 0, 0, 1, 0, 0, 0, 0, 0 | x1
|
119
|
-
// 0, 0, 0, 0, 0, 1, 0, 0 | y1
|
120
|
-
// w, 0, 0, 0, 0, 0, -x2w, 0 | x2-x1
|
121
|
-
// 0, 0, 0, w, 0, 0, -y2w, 0 | y2-y1
|
122
|
-
// 0, h, 0, 0, 0, 0, 0, -x3h | x3-x1
|
123
|
-
// 0, 0, 0, 0, h, 0, 0, -y3h | y3-y1
|
124
|
-
// 0, 0, 0, 0, 0, 0, rem_cell7, 0 | right_side7
|
125
|
-
// 0, 0, 0, 0, 0, 0, 0, rem_cell8 | right_side8
|
126
|
-
|
127
|
-
// Use the new rows 7 and 8 to calculate c0, c1, c3 & c4.
|
128
|
-
// Row3 = Row3 - factor73 * Row7
|
129
|
-
Float factor73 = -x2 * width / rem_cell7;
|
130
|
-
Float rem_cell3 = width;
|
131
|
-
Float right_side3 = (x2 - x1) - right_side7 * factor73;
|
132
|
-
c[0] = right_side3 / rem_cell3;
|
133
|
-
// Row4 = Row4 - factor74 * Row7
|
134
|
-
Float factor74 = -y2 * width / rem_cell7;
|
135
|
-
Float rem_cell4 = width;
|
136
|
-
Float right_side4 = (y2 - y1) - right_side7 * factor74;
|
137
|
-
c[3] = right_side4 / rem_cell4;
|
138
|
-
// Row5 = Row5 - factor85 * Row7
|
139
|
-
Float factor85 = -x3 * height / rem_cell8;
|
140
|
-
Float rem_cell5 = height;
|
141
|
-
Float right_side5 = (x3 - x1) - right_side8 * factor85;
|
142
|
-
c[1] = right_side5 / rem_cell5;
|
143
|
-
// Row6 = Row6 - factor86 * Row8
|
144
|
-
Float factor86 = -y3 * height / rem_cell8;
|
145
|
-
Float rem_cell6 = height;
|
146
|
-
Float right_side6 = (y3 - y1) - right_side8 * factor86;
|
147
|
-
c[4] = right_side6 / rem_cell6;
|
148
|
-
|
149
|
-
if (swap_rows78) {
|
150
|
-
swap(c[6], c[7]);
|
151
|
-
}
|
152
|
-
|
153
|
-
// Let's hope I never have to debug/understand this again! :D
|
154
|
-
|
109
|
+
c[6] = qx;
|
110
|
+
c[7] = qy;
|
111
|
+
|
155
112
|
Transform result = {{
|
156
113
|
c[0], c[3], 0, c[6],
|
157
114
|
c[1], c[4], 0, c[7],
|
158
|
-
0,
|
115
|
+
0, 0, 1, 0,
|
159
116
|
c[2], c[5], 0, 1
|
160
117
|
}};
|
161
118
|
return result;
|
162
119
|
}
|
163
|
-
|
164
|
-
void draw_vertex_arrays(
|
165
|
-
|
120
|
+
|
121
|
+
void draw_vertex_arrays(double x1, double y1, double x2, double y2, double x3, double y3,
|
122
|
+
double x4, double y4) const
|
166
123
|
{
|
167
124
|
// TODO: Macros should not be split up just because they have different transforms.
|
168
125
|
// They should be premultiplied and have the same transform by definition. Then the
|
@@ -205,7 +162,7 @@ int Gosu::Macro::height() const
|
|
205
162
|
}
|
206
163
|
|
207
164
|
void Gosu::Macro::draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
|
208
|
-
double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z,
|
165
|
+
double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z, BlendMode mode) const
|
209
166
|
{
|
210
167
|
if (c1 != Color::WHITE || c2 != Color::WHITE || c3 != Color::WHITE || c4 != Color::WHITE) {
|
211
168
|
throw invalid_argument("Macros cannot be tinted with colors");
|
@@ -228,7 +185,7 @@ Gosu::Bitmap Gosu::Macro::to_bitmap() const
|
|
228
185
|
pimpl->width, 0, Color::WHITE,
|
229
186
|
0, pimpl->height, Color::WHITE,
|
230
187
|
pimpl->width, pimpl->height, Color::WHITE,
|
231
|
-
0,
|
188
|
+
0, BM_DEFAULT);
|
232
189
|
}).data().to_bitmap();
|
233
190
|
}
|
234
191
|
|
data/src/Macro.hpp
CHANGED
@@ -18,7 +18,7 @@ public:
|
|
18
18
|
|
19
19
|
void draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
|
20
20
|
double x3, double y3, Color c3, double x4, double y4, Color c4, ZPos z,
|
21
|
-
|
21
|
+
BlendMode mode) const override;
|
22
22
|
|
23
23
|
const Gosu::GLTexInfo* gl_tex_info() const override;
|
24
24
|
|
data/src/RenderState.hpp
CHANGED
@@ -10,10 +10,10 @@ struct Gosu::RenderState
|
|
10
10
|
std::shared_ptr<Texture> texture;
|
11
11
|
const Transform* transform;
|
12
12
|
ClipRect clip_rect;
|
13
|
-
|
13
|
+
BlendMode mode;
|
14
14
|
|
15
15
|
RenderState()
|
16
|
-
: transform(0), mode(
|
16
|
+
: transform(0), mode(BM_DEFAULT)
|
17
17
|
{
|
18
18
|
clip_rect.width = NO_CLIPPING;
|
19
19
|
}
|
@@ -39,10 +39,10 @@ struct Gosu::RenderState
|
|
39
39
|
|
40
40
|
void apply_alpha_mode() const
|
41
41
|
{
|
42
|
-
if (mode ==
|
42
|
+
if (mode == BM_ADD) {
|
43
43
|
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
44
44
|
}
|
45
|
-
else if (mode ==
|
45
|
+
else if (mode == BM_MULTIPLY) {
|
46
46
|
glBlendFunc(GL_DST_COLOR, GL_ZERO);
|
47
47
|
}
|
48
48
|
else {
|
@@ -174,7 +174,7 @@ public:
|
|
174
174
|
}
|
175
175
|
}
|
176
176
|
|
177
|
-
void set_alpha_mode(
|
177
|
+
void set_alpha_mode(BlendMode new_mode)
|
178
178
|
{
|
179
179
|
if (new_mode == mode) return;
|
180
180
|
|
data/src/Resolution.cpp
CHANGED
@@ -11,19 +11,19 @@ static SDL_DisplayMode display_mode(Gosu::Window* window)
|
|
11
11
|
VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
|
12
12
|
~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
|
13
13
|
} subsystem;
|
14
|
-
|
14
|
+
|
15
15
|
int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
|
16
16
|
SDL_DisplayMode result;
|
17
17
|
SDL_GetDesktopDisplayMode(index, &result);
|
18
18
|
return result;
|
19
19
|
}
|
20
20
|
|
21
|
-
|
21
|
+
int Gosu::screen_width(Window* window)
|
22
22
|
{
|
23
23
|
return display_mode(window).w;
|
24
24
|
}
|
25
25
|
|
26
|
-
|
26
|
+
int Gosu::screen_height(Window* window)
|
27
27
|
{
|
28
28
|
return display_mode(window).h;
|
29
29
|
}
|
@@ -31,88 +31,136 @@ unsigned Gosu::screen_height(Window* window)
|
|
31
31
|
#ifdef GOSU_IS_MAC
|
32
32
|
#import <AppKit/AppKit.h>
|
33
33
|
|
34
|
-
static
|
34
|
+
static SDL_Rect max_window_size(Gosu::Window* window)
|
35
35
|
{
|
36
|
-
//
|
37
|
-
|
36
|
+
// The extra size that a window needs depends on its style.
|
37
|
+
// This logic must be kept in sync with SDL_cocoawindow.m to be 100% accurate.
|
38
|
+
NSUInteger style;
|
39
|
+
if (window && window->borderless()) {
|
40
|
+
style = NSWindowStyleMaskBorderless;
|
41
|
+
}
|
42
|
+
else {
|
43
|
+
style = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable;
|
44
|
+
}
|
45
|
+
if (window && window->resizable()) {
|
46
|
+
style |= NSWindowStyleMaskResizable;
|
47
|
+
}
|
38
48
|
|
39
49
|
auto index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
unsigned Gosu::available_height(Window* window)
|
50
|
-
{
|
51
|
-
return max_window_size(window).height;
|
50
|
+
NSRect screen_frame = NSScreen.screens[index].visibleFrame;
|
51
|
+
NSRect content_rect = [NSWindow contentRectForFrameRect:screen_frame styleMask:style];
|
52
|
+
|
53
|
+
SDL_Rect result;
|
54
|
+
result.x = 0;
|
55
|
+
result.y = 0;
|
56
|
+
result.w = content_rect.size.width;
|
57
|
+
result.h = content_rect.size.height;
|
58
|
+
return result;
|
52
59
|
}
|
53
60
|
#endif
|
54
61
|
|
62
|
+
// TODO: Remove this implementation and remove ifdef for GOSU_IS_X once WIN_GetWindowBordersSize is patched
|
55
63
|
#ifdef GOSU_IS_WIN
|
56
64
|
#include <windows.h>
|
57
65
|
#include <SDL_syswm.h>
|
66
|
+
#include <dwmapi.h>
|
67
|
+
#pragma comment (lib, "Dwmapi.lib")
|
58
68
|
|
59
|
-
static
|
69
|
+
static SDL_Rect max_window_size(Gosu::Window* window)
|
60
70
|
{
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
71
|
+
// Replicate SDL's WIN_GetWindowBordersSize implementation (https://github.com/libsdl-org/SDL/blob/9f71a809e9bd6fbb5fa401a45c1537fc26abc1b4/src/video/windows/SDL_windowswindow.c#L514-L554)
|
72
|
+
// until it's patched to ignore the window drop shadow (window border is 1px but with drop shadow it's reported as 8px)
|
73
|
+
// REF: https://github.com/libsdl-org/SDL/issues/3835
|
74
|
+
|
75
|
+
static struct VideoSubsystem {
|
76
|
+
VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
|
77
|
+
~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
|
78
|
+
} subsystem;
|
79
|
+
|
80
|
+
int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
|
81
|
+
SDL_Rect rect;
|
82
|
+
SDL_GetDisplayUsableBounds(index, &rect);
|
83
|
+
|
84
|
+
if (window) {
|
85
|
+
SDL_SysWMinfo info;
|
86
|
+
SDL_VERSION(&info.version);
|
87
|
+
SDL_GetWindowWMInfo(Gosu::shared_window(), &info);
|
88
|
+
HWND hwnd = info.info.win.window;
|
89
|
+
|
90
|
+
RECT rcClient, rcWindow;
|
91
|
+
POINT ptDiff;
|
92
|
+
int top = 0, left = 0, bottom = 0, right = 0;
|
93
|
+
|
94
|
+
/* rcClient stores the size of the inner window, while rcWindow stores the outer size relative to the top-left
|
95
|
+
* screen position; so the top/left values of rcClient are always {0,0} and bottom/right are {height,width} */
|
96
|
+
GetClientRect(hwnd, &rcClient);
|
97
|
+
DwmGetWindowAttribute(hwnd, DWMWA_EXTENDED_FRAME_BOUNDS, &rcWindow, sizeof(rcWindow));
|
98
|
+
|
99
|
+
/* convert the top/left values to make them relative to
|
100
|
+
* the window; they will end up being slightly negative */
|
101
|
+
ptDiff.y = rcWindow.top;
|
102
|
+
ptDiff.x = rcWindow.left;
|
103
|
+
|
104
|
+
ScreenToClient(hwnd, &ptDiff);
|
105
|
+
|
106
|
+
rcWindow.top = ptDiff.y;
|
107
|
+
rcWindow.left = ptDiff.x;
|
108
|
+
|
109
|
+
/* convert the bottom/right values to make them relative to the window,
|
110
|
+
* these will be slightly bigger than the inner width/height */
|
111
|
+
ptDiff.y = rcWindow.bottom;
|
112
|
+
ptDiff.x = rcWindow.right;
|
113
|
+
|
114
|
+
ScreenToClient(hwnd, &ptDiff);
|
115
|
+
|
116
|
+
rcWindow.bottom = ptDiff.y;
|
117
|
+
rcWindow.right = ptDiff.x;
|
118
|
+
|
119
|
+
/* Now that both the inner and outer rects use the same coordinate system we can substract them to get the border size.
|
120
|
+
* Keep in mind that the top/left coordinates of rcWindow are negative because the border lies slightly before {0,0},
|
121
|
+
* so switch them around because SDL2 wants them in positive. */
|
122
|
+
top = rcClient.top - rcWindow.top;
|
123
|
+
left = rcClient.left - rcWindow.left;
|
124
|
+
bottom = rcWindow.bottom - rcClient.bottom;
|
125
|
+
right = rcWindow.right - rcClient.right;
|
126
|
+
|
127
|
+
rect.w -= left + right;
|
128
|
+
rect.h -= top + bottom;
|
78
129
|
}
|
79
|
-
|
80
|
-
RECT window_size = work_area;
|
81
|
-
// Keep in sync with STYLE_NORMAL in SDL_windowswindow.c.
|
82
|
-
DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
83
|
-
AdjustWindowRectEx(&window_size, style, FALSE, 0);
|
84
|
-
|
85
|
-
// Because AdjustWindowRectEx will make our rect larger, not smaller, we need to perform some
|
86
|
-
// unintuitive math here.
|
87
|
-
SIZE size;
|
88
|
-
size.cx = 2 * (work_area.right - work_area.left) - (window_size.right - window_size.left);
|
89
|
-
size.cy = 2 * (work_area.bottom - work_area.top) - (window_size.bottom - window_size.top);
|
90
|
-
return size;
|
91
|
-
}
|
92
130
|
|
93
|
-
|
94
|
-
|
95
|
-
return max_window_size(window).cx;
|
131
|
+
// Return a rect to have one less Gosu::available_width/height implementation.
|
132
|
+
return rect;
|
96
133
|
}
|
134
|
+
#endif
|
97
135
|
|
98
|
-
|
136
|
+
#ifdef GOSU_IS_X
|
137
|
+
static SDL_Rect max_window_size(Gosu::Window* window)
|
99
138
|
{
|
100
|
-
|
139
|
+
static struct VideoSubsystem {
|
140
|
+
VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
|
141
|
+
~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
|
142
|
+
} subsystem;
|
143
|
+
|
144
|
+
int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
|
145
|
+
SDL_Rect rect;
|
146
|
+
int top, left, bottom, right;
|
147
|
+
SDL_GetDisplayUsableBounds(index, &rect);
|
148
|
+
SDL_GetWindowBordersSize(Gosu::shared_window(), &top, &left, &bottom, &right);
|
149
|
+
|
150
|
+
rect.w -= left + right;
|
151
|
+
rect.h -= top + bottom;
|
152
|
+
|
153
|
+
return rect;
|
101
154
|
}
|
102
155
|
#endif
|
103
156
|
|
104
|
-
|
105
|
-
// Pessimistic fallback implementation for available_width / available_height.
|
106
|
-
// TODO: Look at this NET_WORKAREA based implementation: https://github.com/glfw/glfw/pull/989/files
|
107
|
-
unsigned Gosu::available_width(Window* window)
|
157
|
+
int Gosu::available_width(Window* window)
|
108
158
|
{
|
109
|
-
return
|
159
|
+
return max_window_size(window).w;
|
110
160
|
}
|
111
161
|
|
112
|
-
|
162
|
+
int Gosu::available_height(Window* window)
|
113
163
|
{
|
114
|
-
return
|
164
|
+
return max_window_size(window).h;
|
115
165
|
}
|
116
166
|
#endif
|
117
|
-
|
118
|
-
#endif
|