gosu 0.12.1 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- 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);
|