gosu 0.12.1 → 0.13.0
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.
- checksums.yaml +4 -4
- data/Gosu/Audio.hpp +23 -25
- data/Gosu/Graphics.hpp +16 -12
- data/Gosu/Image.hpp +3 -0
- data/Gosu/Version.hpp +2 -2
- data/lib/gosu.rb +2 -2
- data/lib/gosu/compat.rb +1 -1
- data/lib/gosu/patches.rb +5 -0
- data/lib/gosu/swig_patches.rb +1 -1
- data/rdoc/gosu.rb +10 -10
- data/src/Audio.cpp +93 -228
- data/src/AudioImpl.cpp +94 -0
- data/src/AudioImpl.hpp +33 -0
- data/src/AudioToolboxFile.hpp +14 -18
- data/src/Bitmap.cpp +36 -30
- data/src/BitmapIO.cpp +14 -23
- data/src/BlockAllocator.cpp +7 -10
- data/src/BlockAllocator.hpp +2 -4
- data/src/Channel.cpp +89 -0
- data/src/Color.cpp +4 -9
- data/src/DirectoriesApple.cpp +13 -13
- data/src/DirectoriesUnix.cpp +8 -7
- data/src/DirectoriesWin.cpp +12 -11
- data/src/EmptyImageData.hpp +54 -0
- data/src/FileUnix.cpp +12 -9
- data/src/FileWin.cpp +8 -7
- data/src/Font.cpp +12 -13
- data/src/FormattedString.cpp +237 -0
- data/src/FormattedString.hpp +14 -265
- data/src/GosuViewController.cpp +2 -5
- data/src/Graphics.cpp +38 -39
- data/src/IO.cpp +11 -10
- data/src/Image.cpp +16 -9
- data/src/Input.cpp +16 -15
- data/src/InputUIKit.cpp +8 -7
- data/src/Macro.cpp +11 -11
- data/src/Math.cpp +9 -8
- data/src/RubyGosu.cxx +129 -99
- data/src/TextApple.cpp +19 -13
- data/src/TextInput.cpp +23 -22
- data/src/TextWin.cpp +17 -19
- data/src/Texture.cpp +15 -10
- data/src/Transform.cpp +13 -17
- data/src/Utility.cpp +3 -2
- data/src/UtilityApple.cpp +10 -11
- data/src/UtilityWin.cpp +2 -1
- data/src/Version.cpp +5 -4
- data/src/WinMain.cpp +3 -3
- data/src/WinUtility.cpp +7 -6
- data/src/Window.cpp +11 -10
- data/src/WindowUIKit.cpp +9 -8
- data/src/stb_image.h +782 -480
- data/src/stb_image_write.h +425 -15
- data/src/stb_vorbis.c +82 -32
- metadata +8 -4
- data/src/ALChannelManagement.hpp +0 -119
data/src/TextApple.cpp
CHANGED
@@ -17,16 +17,18 @@ typedef UIFont AppleFont;
|
|
17
17
|
typedef NSFont AppleFont;
|
18
18
|
#endif
|
19
19
|
|
20
|
+
using namespace std;
|
21
|
+
|
20
22
|
// If a font is a filename, loads the font and returns its family name that can be used
|
21
23
|
// like any system font. Otherwise, just returns the family name.
|
22
|
-
static
|
24
|
+
static string normalize_font(const string& font_name)
|
23
25
|
{
|
24
26
|
#ifdef GOSU_IS_IPHONE
|
25
27
|
// On iOS, we have no support for loading font files yet. However, if you register your fonts
|
26
28
|
// via your app's Info.plist, you should be able to reference them by name.
|
27
29
|
return font_name;
|
28
30
|
#else
|
29
|
-
static
|
31
|
+
static map<string, string> family_of_files;
|
30
32
|
|
31
33
|
// Not a path name: It is already a family name.
|
32
34
|
if (font_name.find("/") == font_name.npos) {
|
@@ -58,13 +60,13 @@ static std::string normalize_font(const std::string& font_name)
|
|
58
60
|
#endif
|
59
61
|
}
|
60
62
|
|
61
|
-
static AppleFont* get_font(
|
63
|
+
static AppleFont* get_font(string font_name, unsigned font_flags, double height)
|
62
64
|
{
|
63
65
|
font_name = normalize_font(font_name);
|
64
66
|
|
65
|
-
static
|
67
|
+
static map<pair<string, pair<unsigned, double>>, AppleFont*> used_fonts;
|
66
68
|
|
67
|
-
auto key =
|
69
|
+
auto key = make_pair(font_name, make_pair(font_flags, height));
|
68
70
|
|
69
71
|
AppleFont* result = used_fonts[key];
|
70
72
|
if (!result) {
|
@@ -89,7 +91,7 @@ static AppleFont* get_font(std::string font_name, unsigned font_flags, double he
|
|
89
91
|
result = get_font(Gosu::default_font_name(), 0, height);
|
90
92
|
}
|
91
93
|
else {
|
92
|
-
throw
|
94
|
+
throw runtime_error("Cannot load default font");
|
93
95
|
}
|
94
96
|
}
|
95
97
|
used_fonts[key] = result;
|
@@ -97,9 +99,13 @@ static AppleFont* get_font(std::string font_name, unsigned font_flags, double he
|
|
97
99
|
return result;
|
98
100
|
}
|
99
101
|
|
100
|
-
|
102
|
+
string Gosu::default_font_name()
|
101
103
|
{
|
104
|
+
#ifdef GOSU_IS_IPHONE
|
102
105
|
return "Arial";
|
106
|
+
#else
|
107
|
+
return "Arial Unicode MS";
|
108
|
+
#endif
|
103
109
|
}
|
104
110
|
|
105
111
|
#ifndef GOSU_IS_IPHONE
|
@@ -115,11 +121,11 @@ static NSDictionary* attribute_dictionary(NSFont* font, unsigned font_flags)
|
|
115
121
|
}
|
116
122
|
#endif
|
117
123
|
|
118
|
-
unsigned Gosu::text_width(const
|
119
|
-
|
124
|
+
unsigned Gosu::text_width(const string& text, const string& font_name,
|
125
|
+
unsigned font_height, unsigned font_flags)
|
120
126
|
{
|
121
127
|
if (text.find_first_of("\r\n") != text.npos) {
|
122
|
-
throw
|
128
|
+
throw invalid_argument("text_width cannot handle line breaks");
|
123
129
|
}
|
124
130
|
|
125
131
|
AppleFont* font = get_font(font_name, font_flags, font_height);
|
@@ -138,11 +144,11 @@ unsigned Gosu::text_width(const std::string& text, const std::string& font_name,
|
|
138
144
|
return ceil(size.width / size.height * font_height);
|
139
145
|
}
|
140
146
|
|
141
|
-
void Gosu::draw_text(Bitmap& bitmap, const
|
142
|
-
|
147
|
+
void Gosu::draw_text(Bitmap& bitmap, const string& text, int x, int y, Color c,
|
148
|
+
const string& font_name, unsigned font_height, unsigned font_flags)
|
143
149
|
{
|
144
150
|
if (text.find_first_of("\r\n") != text.npos) {
|
145
|
-
throw
|
151
|
+
throw invalid_argument("the argument to draw_text cannot contain line breaks");
|
146
152
|
}
|
147
153
|
|
148
154
|
AppleFont* font = get_font(font_name, font_flags, font_height);
|
data/src/TextInput.cpp
CHANGED
@@ -6,14 +6,15 @@
|
|
6
6
|
#include <Gosu/Platform.hpp>
|
7
7
|
#include <SDL.h>
|
8
8
|
#include <cctype>
|
9
|
+
using namespace std;
|
9
10
|
|
10
11
|
struct Gosu::TextInput::Impl
|
11
12
|
{
|
12
|
-
|
13
|
+
string text;
|
13
14
|
|
14
15
|
// This is the current IME composition.
|
15
16
|
// http://wiki.libsdl.org/Tutorials/TextInput#CandidateList
|
16
|
-
|
17
|
+
string composition;
|
17
18
|
|
18
19
|
// Indices into the UTF-8 encoded text.
|
19
20
|
unsigned caret_pos = 0, selection_start = 0;
|
@@ -25,17 +26,17 @@ struct Gosu::TextInput::Impl
|
|
25
26
|
return (static_cast<unsigned char>(ch) & 0xc0) == 0x80;
|
26
27
|
}
|
27
28
|
|
28
|
-
void insert_text(const
|
29
|
+
void insert_text(const string& new_text)
|
29
30
|
{
|
30
31
|
// Stop IME composition.
|
31
32
|
composition.clear();
|
32
33
|
|
33
34
|
// Delete (overwrite) previous selection.
|
34
35
|
if (caret_pos != selection_start) {
|
35
|
-
unsigned
|
36
|
-
unsigned
|
37
|
-
text.erase(text.begin() +
|
38
|
-
caret_pos = selection_start =
|
36
|
+
unsigned from = min(caret_pos, selection_start);
|
37
|
+
unsigned to = max(caret_pos, selection_start);
|
38
|
+
text.erase(text.begin() + from, text.begin() + to);
|
39
|
+
caret_pos = selection_start = from;
|
39
40
|
}
|
40
41
|
|
41
42
|
text.insert(text.begin() + caret_pos, new_text.begin(), new_text.end());
|
@@ -77,20 +78,20 @@ struct Gosu::TextInput::Impl
|
|
77
78
|
|
78
79
|
void move_word_left(bool modify_selection)
|
79
80
|
{
|
80
|
-
while (caret_pos > 0 &&
|
81
|
+
while (caret_pos > 0 && isspace(text[caret_pos - 1])) {
|
81
82
|
move_left(modify_selection);
|
82
83
|
}
|
83
|
-
while (caret_pos > 0 && !
|
84
|
+
while (caret_pos > 0 && !isspace(text[caret_pos - 1])) {
|
84
85
|
move_left(modify_selection);
|
85
86
|
}
|
86
87
|
}
|
87
88
|
|
88
89
|
void move_word_right(bool modify_selection)
|
89
90
|
{
|
90
|
-
while (caret_pos < text.length() &&
|
91
|
+
while (caret_pos < text.length() && isspace(text.at(caret_pos))) {
|
91
92
|
move_right(modify_selection);
|
92
93
|
}
|
93
|
-
while (caret_pos < text.length() && !
|
94
|
+
while (caret_pos < text.length() && !isspace(text.at(caret_pos))) {
|
94
95
|
move_right(modify_selection);
|
95
96
|
}
|
96
97
|
}
|
@@ -116,10 +117,10 @@ struct Gosu::TextInput::Impl
|
|
116
117
|
void delete_backward()
|
117
118
|
{
|
118
119
|
if (selection_start != caret_pos) {
|
119
|
-
unsigned
|
120
|
-
unsigned
|
121
|
-
text.erase(text.begin() +
|
122
|
-
selection_start = caret_pos =
|
120
|
+
unsigned from = min(caret_pos, selection_start);
|
121
|
+
unsigned to = max(caret_pos, selection_start);
|
122
|
+
text.erase(text.begin() + from, text.begin() + to);
|
123
|
+
selection_start = caret_pos = from;
|
123
124
|
}
|
124
125
|
else if (caret_pos > 0) {
|
125
126
|
move_left(false);
|
@@ -131,10 +132,10 @@ struct Gosu::TextInput::Impl
|
|
131
132
|
void delete_forward()
|
132
133
|
{
|
133
134
|
if (selection_start != caret_pos) {
|
134
|
-
unsigned
|
135
|
-
unsigned
|
136
|
-
text.erase(text.begin() +
|
137
|
-
selection_start = caret_pos =
|
135
|
+
unsigned from = min(caret_pos, selection_start);
|
136
|
+
unsigned to = max(caret_pos, selection_start);
|
137
|
+
text.erase(text.begin() + from, text.begin() + to);
|
138
|
+
selection_start = caret_pos = from;
|
138
139
|
}
|
139
140
|
else if (caret_pos < text.length()) {
|
140
141
|
move_right(false);
|
@@ -153,16 +154,16 @@ Gosu::TextInput::~TextInput()
|
|
153
154
|
{
|
154
155
|
}
|
155
156
|
|
156
|
-
|
157
|
+
string Gosu::TextInput::text() const
|
157
158
|
{
|
158
|
-
|
159
|
+
string composed_text = pimpl->text;
|
159
160
|
if (!pimpl->composition.empty()) {
|
160
161
|
composed_text.insert(pimpl->caret_pos, pimpl->composition);
|
161
162
|
}
|
162
163
|
return composed_text;
|
163
164
|
}
|
164
165
|
|
165
|
-
void Gosu::TextInput::set_text(const
|
166
|
+
void Gosu::TextInput::set_text(const string& text)
|
166
167
|
{
|
167
168
|
pimpl->text = text;
|
168
169
|
pimpl->composition.clear();
|
data/src/TextWin.cpp
CHANGED
@@ -13,16 +13,17 @@
|
|
13
13
|
#include <algorithm>
|
14
14
|
#include <map>
|
15
15
|
#include <set>
|
16
|
-
#include <stdexcept>
|
16
|
+
#include <stdexcept>
|
17
|
+
using namespace std;
|
17
18
|
|
18
|
-
|
19
|
+
string Gosu::default_font_name()
|
19
20
|
{
|
20
21
|
return "Arial";
|
21
22
|
}
|
22
23
|
|
23
24
|
namespace Gosu
|
24
25
|
{
|
25
|
-
|
26
|
+
string get_name_from_ttf_file(const string& filename);
|
26
27
|
|
27
28
|
namespace
|
28
29
|
{
|
@@ -79,7 +80,7 @@ namespace Gosu
|
|
79
80
|
return bitmap;
|
80
81
|
}
|
81
82
|
|
82
|
-
void select_font(
|
83
|
+
void select_font(string font_name, unsigned font_height, unsigned font_flags) const
|
83
84
|
{
|
84
85
|
// TODO for ASYNC support:
|
85
86
|
// Use a lock on both maps.
|
@@ -89,7 +90,7 @@ namespace Gosu
|
|
89
90
|
// performance on my test system.
|
90
91
|
// In case of trouble, it can be taken out without worrying too much.
|
91
92
|
|
92
|
-
static
|
93
|
+
static map<string, string> custom_fonts;
|
93
94
|
|
94
95
|
if (font_name.find("/") != font_name.npos) {
|
95
96
|
if (custom_fonts.count(font_name) == 0) {
|
@@ -101,11 +102,10 @@ namespace Gosu
|
|
101
102
|
}
|
102
103
|
}
|
103
104
|
|
104
|
-
static
|
105
|
+
static map<pair<string, unsigned>, HFONT> loaded_fonts;
|
105
106
|
|
106
107
|
HFONT font;
|
107
|
-
|
108
|
-
std::make_pair(font_name, font_height | font_flags << 16);
|
108
|
+
pair<string, unsigned> key = make_pair(font_name, font_height | font_flags << 16);
|
109
109
|
|
110
110
|
if (loaded_fonts.count(key) == 0) {
|
111
111
|
LOGFONT logfont = {
|
@@ -117,9 +117,7 @@ namespace Gosu
|
|
117
117
|
DEFAULT_PITCH | FF_DONTCARE
|
118
118
|
};
|
119
119
|
|
120
|
-
|
121
|
-
// Don't rely on wcsncpy being in std::...
|
122
|
-
using namespace std;
|
120
|
+
wstring wfont_name = utf8_to_wstring(font_name);
|
123
121
|
wcsncpy(logfont.lfFaceName, wfont_name.c_str(), LF_FACESIZE);
|
124
122
|
logfont.lfFaceName[LF_FACESIZE - 1] = 0;
|
125
123
|
|
@@ -136,17 +134,17 @@ namespace Gosu
|
|
136
134
|
}
|
137
135
|
};
|
138
136
|
|
139
|
-
unsigned Gosu::text_width(const
|
140
|
-
|
137
|
+
unsigned Gosu::text_width(const string& text, const string& font_name,
|
138
|
+
unsigned font_height, unsigned font_flags)
|
141
139
|
{
|
142
140
|
if (text.find_first_of("\r\n") != text.npos) {
|
143
|
-
throw
|
141
|
+
throw invalid_argument("the argument to text_width cannot contain line breaks");
|
144
142
|
}
|
145
143
|
|
146
144
|
WinBitmap helper(1, 1);
|
147
145
|
helper.select_font(font_name, font_height, font_flags);
|
148
146
|
|
149
|
-
|
147
|
+
wstring wtext = utf8_to_wstring(text);
|
150
148
|
SIZE size;
|
151
149
|
winapi_check(GetTextExtentPoint32W(helper.context(), wtext.c_str(), wtext.length(), &size),
|
152
150
|
"calculating the width of a text");
|
@@ -154,11 +152,11 @@ unsigned Gosu::text_width(const std::string& text, const std::string& font_name,
|
|
154
152
|
return size.cx;
|
155
153
|
}
|
156
154
|
|
157
|
-
void Gosu::draw_text(Bitmap& bitmap, const
|
158
|
-
|
155
|
+
void Gosu::draw_text(Bitmap& bitmap, const string& text, int x, int y, Color c,
|
156
|
+
const string& font_name, unsigned font_height, unsigned font_flags)
|
159
157
|
{
|
160
158
|
if (text.find_first_of("\r\n") != text.npos) {
|
161
|
-
throw
|
159
|
+
throw invalid_argument("the argument to draw_text cannot contain line breaks");
|
162
160
|
}
|
163
161
|
|
164
162
|
unsigned width = text_width(text, font_name, font_height, font_flags);
|
@@ -172,7 +170,7 @@ void Gosu::draw_text(Bitmap& bitmap, const std::string& text, int x, int y, Colo
|
|
172
170
|
winapi_check(SetBkMode(helper.context(), TRANSPARENT),
|
173
171
|
"setting a bitmap's background mode to TRANSPARENT");
|
174
172
|
|
175
|
-
|
173
|
+
wstring wtext = utf8_to_wstring(text);
|
176
174
|
ExtTextOutW(helper.context(), 0, 0, 0, 0, wtext.c_str(), wtext.length(), 0);
|
177
175
|
|
178
176
|
for (unsigned rel_y = 0; rel_y < font_height; ++rel_y)
|
data/src/Texture.cpp
CHANGED
@@ -4,6 +4,7 @@
|
|
4
4
|
#include <Gosu/Graphics.hpp>
|
5
5
|
#include <Gosu/Platform.hpp>
|
6
6
|
#include <stdexcept>
|
7
|
+
using namespace std;
|
7
8
|
|
8
9
|
namespace Gosu
|
9
10
|
{
|
@@ -18,17 +19,17 @@ Gosu::Texture::Texture(unsigned size, bool retro)
|
|
18
19
|
// Create texture name.
|
19
20
|
glGenTextures(1, &tex_name_);
|
20
21
|
if (tex_name_ == static_cast<GLuint>(-1)) {
|
21
|
-
throw
|
22
|
+
throw runtime_error("Couldn't create OpenGL texture");
|
22
23
|
}
|
23
24
|
|
24
25
|
// Create empty texture.
|
25
26
|
glBindTexture(GL_TEXTURE_2D, tex_name_);
|
26
27
|
#ifdef GOSU_IS_OPENGLES
|
27
28
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, allocator_.width(), allocator_.height(), 0, GL_RGBA,
|
28
|
-
|
29
|
+
GL_UNSIGNED_BYTE, nullptr);
|
29
30
|
#else
|
30
31
|
glTexImage2D(GL_TEXTURE_2D, 0, 4, allocator_.width(), allocator_.height(), 0, GL_RGBA,
|
31
|
-
|
32
|
+
GL_UNSIGNED_BYTE, nullptr);
|
32
33
|
#endif
|
33
34
|
|
34
35
|
if (retro || undocumented_retrofication) {
|
@@ -71,23 +72,27 @@ bool Gosu::Texture::retro() const
|
|
71
72
|
return retro_;
|
72
73
|
}
|
73
74
|
|
74
|
-
|
75
|
-
|
75
|
+
unique_ptr<Gosu::TexChunk> Gosu::Texture::try_alloc(shared_ptr<Texture> ptr, const Bitmap& bmp,
|
76
|
+
unsigned padding)
|
76
77
|
{
|
77
78
|
BlockAllocator::Block block;
|
78
79
|
|
79
80
|
if (!allocator_.alloc(bmp.width(), bmp.height(), block)) return nullptr;
|
80
81
|
|
81
|
-
|
82
|
-
|
82
|
+
unique_ptr<Gosu::TexChunk> result(new TexChunk(ptr,
|
83
|
+
block.left + padding,
|
84
|
+
block.top + padding,
|
85
|
+
block.width - 2 * padding,
|
86
|
+
block.height - 2 * padding,
|
87
|
+
padding));
|
83
88
|
|
84
89
|
ensure_current_context();
|
85
90
|
|
86
91
|
glBindTexture(GL_TEXTURE_2D, tex_name_);
|
87
92
|
glTexSubImage2D(GL_TEXTURE_2D, 0, block.left, block.top, block.width, block.height,
|
88
|
-
|
93
|
+
Color::GL_FORMAT, GL_UNSIGNED_BYTE, bmp.data());
|
89
94
|
|
90
|
-
return
|
95
|
+
return result;
|
91
96
|
}
|
92
97
|
|
93
98
|
void Gosu::Texture::block(unsigned x, unsigned y, unsigned width, unsigned height)
|
@@ -103,7 +108,7 @@ void Gosu::Texture::free(unsigned x, unsigned y, unsigned width, unsigned height
|
|
103
108
|
Gosu::Bitmap Gosu::Texture::to_bitmap(unsigned x, unsigned y, unsigned width, unsigned height) const
|
104
109
|
{
|
105
110
|
#ifdef GOSU_IS_OPENGLES
|
106
|
-
throw
|
111
|
+
throw logic_error("Texture::to_bitmap not supported on iOS");
|
107
112
|
#else
|
108
113
|
ensure_current_context();
|
109
114
|
|
data/src/Transform.cpp
CHANGED
@@ -5,13 +5,13 @@
|
|
5
5
|
#include <Gosu/GraphicsBase.hpp>
|
6
6
|
#include <Gosu/Math.hpp>
|
7
7
|
#include <cmath>
|
8
|
+
using namespace std;
|
8
9
|
|
9
|
-
Gosu::Transform
|
10
|
-
Gosu::rotate(double angle, double around_x, double around_y)
|
10
|
+
Gosu::Transform Gosu::rotate(double angle, double around_x, double around_y)
|
11
11
|
{
|
12
|
-
double c =
|
13
|
-
double s =
|
14
|
-
|
12
|
+
double c = cos(degrees_to_radians(angle));
|
13
|
+
double s = sin(degrees_to_radians(angle));
|
14
|
+
Transform result = {
|
15
15
|
+c, +s, 0, 0,
|
16
16
|
-s, +c, 0, 0,
|
17
17
|
0, 0, 1, 0,
|
@@ -24,10 +24,9 @@ Gosu::rotate(double angle, double around_x, double around_y)
|
|
24
24
|
return result;
|
25
25
|
}
|
26
26
|
|
27
|
-
Gosu::Transform
|
28
|
-
Gosu::translate(double x, double y)
|
27
|
+
Gosu::Transform Gosu::translate(double x, double y)
|
29
28
|
{
|
30
|
-
|
29
|
+
Transform result = {
|
31
30
|
1, 0, 0, 0,
|
32
31
|
0, 1, 0, 0,
|
33
32
|
0, 0, 1, 0,
|
@@ -36,10 +35,9 @@ Gosu::translate(double x, double y)
|
|
36
35
|
return result;
|
37
36
|
}
|
38
37
|
|
39
|
-
Gosu::Transform
|
40
|
-
Gosu::scale(double factor)
|
38
|
+
Gosu::Transform Gosu::scale(double factor)
|
41
39
|
{
|
42
|
-
|
40
|
+
Transform result = {
|
43
41
|
factor, 0, 0, 0,
|
44
42
|
0, factor, 0, 0,
|
45
43
|
0, 0, 1, 0,
|
@@ -48,10 +46,9 @@ Gosu::scale(double factor)
|
|
48
46
|
return result;
|
49
47
|
}
|
50
48
|
|
51
|
-
Gosu::Transform
|
52
|
-
Gosu::scale(double scale_x, double scale_y, double around_x, double around_y)
|
49
|
+
Gosu::Transform Gosu::scale(double scale_x, double scale_y, double around_x, double around_y)
|
53
50
|
{
|
54
|
-
|
51
|
+
Transform result = {
|
55
52
|
scale_x, 0, 0, 0,
|
56
53
|
0, scale_y, 0, 0,
|
57
54
|
0, 0, 1, 0,
|
@@ -64,10 +61,9 @@ Gosu::scale(double scale_x, double scale_y, double around_x, double around_y)
|
|
64
61
|
return result;
|
65
62
|
}
|
66
63
|
|
67
|
-
Gosu::Transform
|
68
|
-
Gosu::concat(const Transform& left, const Transform& right)
|
64
|
+
Gosu::Transform Gosu::concat(const Transform& left, const Transform& right)
|
69
65
|
{
|
70
|
-
|
66
|
+
Transform result;
|
71
67
|
for (int i = 0; i < 16; ++i) {
|
72
68
|
result[i] = 0;
|
73
69
|
for (int j = 0; j < 4; ++j) {
|