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/BlockAllocator.cpp
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
#include "BlockAllocator.hpp"
|
2
2
|
#include <stdexcept>
|
3
3
|
#include <vector>
|
4
|
+
using namespace std;
|
4
5
|
|
5
6
|
struct Gosu::BlockAllocator::Impl
|
6
7
|
{
|
7
8
|
unsigned width, height;
|
8
9
|
|
9
|
-
|
10
|
+
vector<Block> blocks;
|
10
11
|
unsigned first_x, first_y;
|
11
12
|
unsigned max_w, max_h;
|
12
13
|
|
@@ -31,8 +32,8 @@ struct Gosu::BlockAllocator::Impl
|
|
31
32
|
|
32
33
|
// Test if the block collides with any existing rects.
|
33
34
|
for (auto b : blocks) {
|
34
|
-
if (b.left < right && block.left < b.left + b.width &&
|
35
|
-
|
35
|
+
if (b.left < right && block.left < b.left + b.width &&
|
36
|
+
b.top < bottom && block.top < b.top + b.height) {
|
36
37
|
return false;
|
37
38
|
}
|
38
39
|
}
|
@@ -71,14 +72,10 @@ unsigned Gosu::BlockAllocator::height() const
|
|
71
72
|
bool Gosu::BlockAllocator::alloc(unsigned a_width, unsigned a_height, Block& b)
|
72
73
|
{
|
73
74
|
// The rect wouldn't even fit onto the texture!
|
74
|
-
if (a_width > width() || a_height > height())
|
75
|
-
return false;
|
76
|
-
}
|
75
|
+
if (a_width > width() || a_height > height()) return false;
|
77
76
|
|
78
77
|
// We know there's no space left.
|
79
|
-
if (a_width > pimpl->max_w && a_height > pimpl->max_h)
|
80
|
-
return false;
|
81
|
-
}
|
78
|
+
if (a_width > pimpl->max_w && a_height > pimpl->max_h) return false;
|
82
79
|
|
83
80
|
// Start to look for a place next to the last returned rect. Chances are
|
84
81
|
// good we'll find a place there.
|
@@ -129,5 +126,5 @@ void Gosu::BlockAllocator::free(unsigned left, unsigned top, unsigned width, uns
|
|
129
126
|
}
|
130
127
|
}
|
131
128
|
|
132
|
-
throw
|
129
|
+
throw logic_error("Tried to free an invalid block");
|
133
130
|
}
|
data/src/BlockAllocator.hpp
CHANGED
@@ -15,10 +15,8 @@ namespace Gosu
|
|
15
15
|
{
|
16
16
|
unsigned left, top, width, height;
|
17
17
|
Block() {}
|
18
|
-
Block(unsigned
|
19
|
-
: left(
|
20
|
-
{
|
21
|
-
}
|
18
|
+
Block(unsigned left, unsigned top, unsigned width, unsigned height)
|
19
|
+
: left(left), top(top), width(width), height(height) {}
|
22
20
|
};
|
23
21
|
|
24
22
|
BlockAllocator(unsigned width, unsigned height);
|
data/src/Channel.cpp
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
#include <Gosu/Audio.hpp>
|
2
|
+
#include "AudioImpl.hpp"
|
3
|
+
using namespace std;
|
4
|
+
|
5
|
+
// Returns the current state of a source
|
6
|
+
static ALint state(int& channel) {
|
7
|
+
ALint state;
|
8
|
+
alGetSourcei(Gosu::al_source_for_channel(channel), AL_SOURCE_STATE, &state);
|
9
|
+
if (state != AL_PLAYING && state != AL_PAUSED) {
|
10
|
+
channel = Gosu::NO_CHANNEL;
|
11
|
+
}
|
12
|
+
return state;
|
13
|
+
}
|
14
|
+
|
15
|
+
Gosu::Channel::Channel(int channel, int token)
|
16
|
+
: channel(channel), token(token)
|
17
|
+
{
|
18
|
+
}
|
19
|
+
|
20
|
+
int Gosu::Channel::current_channel() const
|
21
|
+
{
|
22
|
+
if (channel != NO_CHANNEL && channel_expired(channel, token)) {
|
23
|
+
channel = NO_CHANNEL;
|
24
|
+
}
|
25
|
+
return channel;
|
26
|
+
}
|
27
|
+
|
28
|
+
bool Gosu::Channel::playing() const
|
29
|
+
{
|
30
|
+
if (current_channel() == NO_CHANNEL) return false;
|
31
|
+
|
32
|
+
return state(channel) == AL_PLAYING;
|
33
|
+
}
|
34
|
+
|
35
|
+
bool Gosu::Channel::paused() const
|
36
|
+
{
|
37
|
+
if (current_channel() == NO_CHANNEL) return false;
|
38
|
+
|
39
|
+
return state(channel) == AL_PAUSED;
|
40
|
+
}
|
41
|
+
|
42
|
+
void Gosu::Channel::pause()
|
43
|
+
{
|
44
|
+
if (playing()) {
|
45
|
+
ALuint source = al_source_for_channel(channel);
|
46
|
+
alSourcePause(source);
|
47
|
+
}
|
48
|
+
}
|
49
|
+
|
50
|
+
void Gosu::Channel::resume()
|
51
|
+
{
|
52
|
+
if (paused()) {
|
53
|
+
ALuint source = al_source_for_channel(channel);
|
54
|
+
alSourcePlay(source);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
|
58
|
+
void Gosu::Channel::stop()
|
59
|
+
{
|
60
|
+
if (current_channel() == NO_CHANNEL) return;
|
61
|
+
|
62
|
+
ALuint source = al_source_for_channel(channel);
|
63
|
+
alSourceStop(source);
|
64
|
+
channel = NO_CHANNEL;
|
65
|
+
}
|
66
|
+
|
67
|
+
void Gosu::Channel::set_volume(double volume)
|
68
|
+
{
|
69
|
+
if (current_channel() == NO_CHANNEL) return;
|
70
|
+
|
71
|
+
ALuint source = al_source_for_channel(channel);
|
72
|
+
alSourcef(source, AL_GAIN, max(volume, 0.0));
|
73
|
+
}
|
74
|
+
|
75
|
+
void Gosu::Channel::set_pan(double pan)
|
76
|
+
{
|
77
|
+
if (current_channel() == NO_CHANNEL) return;
|
78
|
+
|
79
|
+
ALuint source = al_source_for_channel(channel);
|
80
|
+
alSource3f(source, AL_POSITION, pan * 10, 0, 0);
|
81
|
+
}
|
82
|
+
|
83
|
+
void Gosu::Channel::set_speed(double speed)
|
84
|
+
{
|
85
|
+
if (current_channel() == NO_CHANNEL) return;
|
86
|
+
|
87
|
+
ALuint source = al_source_for_channel(channel);
|
88
|
+
alSourcef(source, AL_PITCH, speed);
|
89
|
+
}
|
data/src/Color.cpp
CHANGED
@@ -55,11 +55,6 @@ Gosu::Color Gosu::Color::from_hsv(double h, double s, double v)
|
|
55
55
|
|
56
56
|
Gosu::Color Gosu::Color::from_ahsv(Channel alpha, double h, double s, double v)
|
57
57
|
{
|
58
|
-
if (s == 0) {
|
59
|
-
// Grey.
|
60
|
-
return Color(alpha, v * 255, v * 255, v * 255);
|
61
|
-
}
|
62
|
-
|
63
58
|
// Normalize hue so that is always in the [0, 360) range and wraps around.
|
64
59
|
h = normalize_angle(h);
|
65
60
|
// Clamp s and v for consistency with the Ruby/Gosu ARGB getters/setters.
|
@@ -121,10 +116,10 @@ void Gosu::Color::set_value(double v)
|
|
121
116
|
|
122
117
|
Gosu::Color Gosu::interpolate(Color a, Color b, double weight)
|
123
118
|
{
|
124
|
-
return Color(clamp<long>(round(
|
125
|
-
clamp<long>(round(
|
126
|
-
clamp<long>(round(
|
127
|
-
clamp<long>(round(
|
119
|
+
return Color(clamp<long>(round(interpolate(a.alpha(), b.alpha(), weight)), 0, 255),
|
120
|
+
clamp<long>(round(interpolate(a.red(), b.red(), weight)), 0, 255),
|
121
|
+
clamp<long>(round(interpolate(a.green(), b.green(), weight)), 0, 255),
|
122
|
+
clamp<long>(round(interpolate(a.blue(), b.blue(), weight)), 0, 255));
|
128
123
|
}
|
129
124
|
|
130
125
|
Gosu::Color Gosu::multiply(Color a, Color b)
|
data/src/DirectoriesApple.cpp
CHANGED
@@ -4,61 +4,61 @@
|
|
4
4
|
#import <Gosu/Directories.hpp>
|
5
5
|
#import <Foundation/Foundation.h>
|
6
6
|
#import <unistd.h>
|
7
|
-
|
7
|
+
using namespace std;
|
8
8
|
|
9
9
|
void Gosu::use_resource_directory()
|
10
10
|
{
|
11
11
|
chdir(resource_prefix().c_str());
|
12
12
|
}
|
13
13
|
|
14
|
-
|
14
|
+
string Gosu::user_settings_prefix()
|
15
15
|
{
|
16
|
-
static
|
16
|
+
static string result = [] {
|
17
17
|
@autoreleasepool {
|
18
18
|
NSString* library =
|
19
19
|
NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];
|
20
20
|
NSString* preferences = [library stringByAppendingPathComponent:@"Preferences"];
|
21
21
|
|
22
|
-
return
|
22
|
+
return string(preferences.UTF8String ?: ".") + "/";
|
23
23
|
}
|
24
24
|
}();
|
25
25
|
return result;
|
26
26
|
}
|
27
27
|
|
28
|
-
|
28
|
+
string Gosu::user_documents_prefix()
|
29
29
|
{
|
30
|
-
static
|
30
|
+
static string result = [] {
|
31
31
|
@autoreleasepool {
|
32
32
|
NSString* documents =
|
33
33
|
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
|
34
34
|
|
35
|
-
return
|
35
|
+
return string(documents.UTF8String ?: ".") + "/";
|
36
36
|
}
|
37
37
|
}();
|
38
38
|
return result;
|
39
39
|
}
|
40
40
|
|
41
|
-
|
41
|
+
string Gosu::resource_prefix()
|
42
42
|
{
|
43
|
-
static
|
43
|
+
static string result = [] {
|
44
44
|
@autoreleasepool {
|
45
45
|
NSString* resources = [NSBundle mainBundle].resourcePath;
|
46
|
-
return
|
46
|
+
return string(resources.UTF8String ?: ".") + "/";
|
47
47
|
}
|
48
48
|
}();
|
49
49
|
return result;
|
50
50
|
}
|
51
51
|
|
52
|
-
|
52
|
+
string Gosu::shared_resource_prefix()
|
53
53
|
{
|
54
54
|
#ifdef GOSU_IS_IPHONE
|
55
55
|
return resource_prefix();
|
56
56
|
#else
|
57
|
-
static
|
57
|
+
static string result = [] {
|
58
58
|
@autoreleasepool {
|
59
59
|
NSString* bundle_path = [NSBundle mainBundle].bundlePath;
|
60
60
|
NSString* containing_path = [bundle_path stringByDeletingLastPathComponent];
|
61
|
-
return
|
61
|
+
return string(containing_path.UTF8String ?: ".");
|
62
62
|
}
|
63
63
|
}();
|
64
64
|
return result;
|
data/src/DirectoriesUnix.cpp
CHANGED
@@ -7,8 +7,9 @@
|
|
7
7
|
#include <pwd.h>
|
8
8
|
#include <sys/types.h>
|
9
9
|
#include <unistd.h>
|
10
|
+
using namespace std;
|
10
11
|
|
11
|
-
static
|
12
|
+
static string home_dir()
|
12
13
|
{
|
13
14
|
passwd* pwd = getpwuid(geteuid());
|
14
15
|
assert (pwd && pwd->pw_dir);
|
@@ -20,22 +21,22 @@ void Gosu::use_resource_directory()
|
|
20
21
|
// Do nothing, we expect the user to have the correct cwd on Linux.
|
21
22
|
}
|
22
23
|
|
23
|
-
|
24
|
+
string Gosu::resource_prefix()
|
24
25
|
{
|
25
|
-
return
|
26
|
+
return string();
|
26
27
|
}
|
27
28
|
|
28
|
-
|
29
|
+
string Gosu::shared_resource_prefix()
|
29
30
|
{
|
30
|
-
return
|
31
|
+
return string();
|
31
32
|
}
|
32
33
|
|
33
|
-
|
34
|
+
string Gosu::user_settings_prefix()
|
34
35
|
{
|
35
36
|
return home_dir() + "/.";
|
36
37
|
}
|
37
38
|
|
38
|
-
|
39
|
+
string Gosu::user_documents_prefix()
|
39
40
|
{
|
40
41
|
return home_dir() + "/";
|
41
42
|
}
|
data/src/DirectoriesWin.cpp
CHANGED
@@ -6,15 +6,16 @@
|
|
6
6
|
#include <Gosu/Utility.hpp>
|
7
7
|
#include <cwchar>
|
8
8
|
#include <stdexcept>
|
9
|
-
#include <shlobj.h>
|
9
|
+
#include <shlobj.h>
|
10
|
+
using namespace std;
|
10
11
|
|
11
|
-
static
|
12
|
+
static string special_folder_path(int csidl)
|
12
13
|
{
|
13
14
|
WCHAR buf[MAX_PATH + 2];
|
14
15
|
if (FAILED(SHGetFolderPathW(nullptr, csidl | CSIDL_FLAG_CREATE, nullptr, 0, buf))) {
|
15
|
-
throw
|
16
|
+
throw runtime_error("Error getting special folder path");
|
16
17
|
}
|
17
|
-
|
18
|
+
size_t len = wcslen(buf);
|
18
19
|
if (buf[len - 1] != L'\\') {
|
19
20
|
buf[len] = L'\\';
|
20
21
|
buf[len + 1] = 0;
|
@@ -22,9 +23,9 @@ static std::string special_folder_path(int csidl)
|
|
22
23
|
return Gosu::wstring_to_utf8(buf);
|
23
24
|
}
|
24
25
|
|
25
|
-
static
|
26
|
+
static string exe_filename()
|
26
27
|
{
|
27
|
-
static
|
28
|
+
static string result;
|
28
29
|
if (result.empty()) {
|
29
30
|
WCHAR buffer[MAX_PATH * 2];
|
30
31
|
Gosu::winapi_check(GetModuleFileNameW(nullptr, buffer, MAX_PATH * 2),
|
@@ -39,9 +40,9 @@ void Gosu::use_resource_directory()
|
|
39
40
|
SetCurrentDirectory(utf8_to_wstring(resource_prefix()).c_str());
|
40
41
|
}
|
41
42
|
|
42
|
-
|
43
|
+
string Gosu::resource_prefix()
|
43
44
|
{
|
44
|
-
static
|
45
|
+
static string result;
|
45
46
|
if (result.empty()) {
|
46
47
|
result = exe_filename();
|
47
48
|
auto last_delim = result.find_last_of("\\/");
|
@@ -50,17 +51,17 @@ std::string Gosu::resource_prefix()
|
|
50
51
|
return result;
|
51
52
|
}
|
52
53
|
|
53
|
-
|
54
|
+
string Gosu::shared_resource_prefix()
|
54
55
|
{
|
55
56
|
return resource_prefix();
|
56
57
|
}
|
57
58
|
|
58
|
-
|
59
|
+
string Gosu::user_settings_prefix()
|
59
60
|
{
|
60
61
|
return special_folder_path(CSIDL_APPDATA);
|
61
62
|
}
|
62
63
|
|
63
|
-
|
64
|
+
string Gosu::user_documents_prefix()
|
64
65
|
{
|
65
66
|
return special_folder_path(CSIDL_PERSONAL);
|
66
67
|
}
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <Gosu/ImageData.hpp>
|
4
|
+
#include <memory>
|
5
|
+
|
6
|
+
namespace Gosu
|
7
|
+
{
|
8
|
+
class EmptyImageData : public ImageData
|
9
|
+
{
|
10
|
+
public:
|
11
|
+
int width() const override
|
12
|
+
{
|
13
|
+
return 0;
|
14
|
+
}
|
15
|
+
|
16
|
+
int height() const override
|
17
|
+
{
|
18
|
+
return 0;
|
19
|
+
}
|
20
|
+
|
21
|
+
void draw(double, double, Color,
|
22
|
+
double, double, Color,
|
23
|
+
double, double, Color,
|
24
|
+
double, double, Color,
|
25
|
+
ZPos, AlphaMode) const override
|
26
|
+
{
|
27
|
+
}
|
28
|
+
|
29
|
+
GLTexInfo* gl_tex_info() const override
|
30
|
+
{
|
31
|
+
return nullptr;
|
32
|
+
}
|
33
|
+
|
34
|
+
Bitmap to_bitmap() const override
|
35
|
+
{
|
36
|
+
return Bitmap();
|
37
|
+
}
|
38
|
+
|
39
|
+
virtual std::unique_ptr<ImageData> subimage(int, int, int, int) const override
|
40
|
+
{
|
41
|
+
return nullptr;
|
42
|
+
}
|
43
|
+
|
44
|
+
virtual void insert(const Bitmap&, int x, int y) override
|
45
|
+
{
|
46
|
+
}
|
47
|
+
|
48
|
+
static const std::shared_ptr<EmptyImageData>& instance_ptr()
|
49
|
+
{
|
50
|
+
static std::shared_ptr<EmptyImageData> instance = std::make_shared<EmptyImageData>();
|
51
|
+
return instance;
|
52
|
+
}
|
53
|
+
};
|
54
|
+
}
|
data/src/FileUnix.cpp
CHANGED
@@ -14,6 +14,8 @@
|
|
14
14
|
#include <sys/stat.h>
|
15
15
|
#endif
|
16
16
|
|
17
|
+
using namespace std;
|
18
|
+
|
17
19
|
struct Gosu::File::Impl
|
18
20
|
{
|
19
21
|
int fd = -1;
|
@@ -27,7 +29,7 @@ struct Gosu::File::Impl
|
|
27
29
|
}
|
28
30
|
};
|
29
31
|
|
30
|
-
Gosu::File::File(const
|
32
|
+
Gosu::File::File(const string& filename, FileMode mode)
|
31
33
|
: pimpl(new Impl)
|
32
34
|
{
|
33
35
|
int flags;
|
@@ -47,9 +49,7 @@ Gosu::File::File(const std::string& filename, FileMode mode)
|
|
47
49
|
// TODO: Locking flags?
|
48
50
|
|
49
51
|
pimpl->fd = open(filename.c_str(), flags, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
50
|
-
if (pimpl->fd < 0)
|
51
|
-
throw std::runtime_error("Cannot open file " + filename);
|
52
|
-
}
|
52
|
+
if (pimpl->fd < 0) throw runtime_error("Cannot open file " + filename);
|
53
53
|
|
54
54
|
if (mode == FM_READ && size() > 0) {
|
55
55
|
pimpl->mapping = mmap(nullptr, size(), PROT_READ, 0, pimpl->fd, 0);
|
@@ -63,19 +63,22 @@ Gosu::File::~File()
|
|
63
63
|
}
|
64
64
|
}
|
65
65
|
|
66
|
-
|
66
|
+
size_t Gosu::File::size() const
|
67
67
|
{
|
68
68
|
// TODO: Error checking?
|
69
69
|
return lseek(pimpl->fd, 0, SEEK_END);
|
70
70
|
}
|
71
71
|
|
72
|
-
void Gosu::File::resize(
|
72
|
+
void Gosu::File::resize(size_t new_size)
|
73
|
+
{
|
74
|
+
ftruncate(pimpl->fd, new_size);
|
75
|
+
}
|
73
76
|
|
74
|
-
void Gosu::File::read(
|
77
|
+
void Gosu::File::read(size_t offset, size_t length, void* dest_buffer) const
|
75
78
|
{
|
76
79
|
// TODO: Bounds checks?
|
77
80
|
if (pimpl->mapping != MAP_FAILED) {
|
78
|
-
|
81
|
+
memcpy(dest_buffer, static_cast<const char*>(pimpl->mapping) + offset, length);
|
79
82
|
}
|
80
83
|
else {
|
81
84
|
// TODO: Error checking?
|
@@ -84,7 +87,7 @@ void Gosu::File::read(std::size_t offset, std::size_t length, void* dest_buffer)
|
|
84
87
|
}
|
85
88
|
}
|
86
89
|
|
87
|
-
void Gosu::File::write(
|
90
|
+
void Gosu::File::write(size_t offset, size_t length, const void* source_buffer)
|
88
91
|
{
|
89
92
|
// TODO: Error checking?
|
90
93
|
lseek(pimpl->fd, offset, SEEK_SET);
|