gosu 0.9.2 → 0.10.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/Bitmap.hpp +3 -3
- data/Gosu/Directories.hpp +6 -3
- data/Gosu/Gosu.hpp +0 -1
- data/Gosu/GraphicsBase.hpp +12 -8
- data/Gosu/Input.hpp +5 -16
- data/Gosu/Platform.hpp +1 -0
- data/Gosu/Version.hpp +3 -5
- data/Gosu/Window.hpp +7 -8
- data/README.txt +3 -3
- data/ext/gosu/extconf.rb +17 -16
- data/ext/gosu/gosu_wrap.cxx +59 -58
- data/ext/gosu/gosu_wrap.h +1 -1
- data/rdoc/gosu.rb +285 -283
- data/src/{MacUtility.hpp → AppleUtility.hpp} +24 -42
- data/src/Audio/ALChannelManagement.hpp +1 -1
- data/src/Audio/{AudioOpenAL.cpp → Audio.cpp} +6 -7
- data/src/Audio/Audio.mm +1 -0
- data/src/Audio/AudioFile.hpp +2 -2
- data/src/Audio/AudioToolboxFile.hpp +5 -20
- data/src/Audio/OggFile.hpp +44 -56
- data/src/Audio/SndFile.hpp +2 -2
- data/src/Bitmap/Bitmap.cpp +98 -2
- data/src/Bitmap/BitmapIO.cpp +156 -0
- data/src/DirectoriesApple.mm +76 -0
- data/src/DirectoriesUnix.cpp +5 -12
- data/src/DirectoriesWin.cpp +5 -0
- data/src/Graphics/BlockAllocator.hpp +2 -2
- data/src/Graphics/ClipRectStack.hpp +2 -2
- data/src/Graphics/Common.hpp +2 -2
- data/src/Graphics/DrawOp.hpp +2 -2
- data/src/Graphics/DrawOpQueue.hpp +2 -2
- data/src/Graphics/Graphics.cpp +7 -2
- data/src/Graphics/LargeImageData.cpp +6 -6
- data/src/Graphics/LargeImageData.hpp +3 -3
- data/src/Graphics/Macro.hpp +2 -2
- data/src/Graphics/RenderState.hpp +2 -2
- data/src/Graphics/Resolution.cpp +1 -1
- data/src/Graphics/TexChunk.hpp +2 -2
- data/src/Graphics/Texture.cpp +21 -16
- data/src/Graphics/Texture.hpp +7 -5
- data/src/Graphics/TransformStack.hpp +2 -2
- data/src/Iconv.hpp +2 -2
- data/src/Input/Input.cpp +3 -1
- data/src/Input/{InputTouch.mm → InputUIKit.mm} +32 -26
- data/src/Input/TextInput.cpp +1 -1
- data/src/Text/FormattedString.hpp +2 -2
- data/src/Text/TextApple.mm +8 -8
- data/src/Text/TextMac.cpp +1 -1
- data/src/Text/TextUnix.cpp +1 -1
- data/src/UIKit/GosuAppDelegate.h +8 -0
- data/src/UIKit/GosuAppDelegate.mm +24 -0
- data/src/UIKit/GosuGLView.h +8 -0
- data/src/UIKit/GosuGLView.mm +130 -0
- data/src/UIKit/GosuViewController.h +13 -0
- data/src/UIKit/GosuViewController.mm +214 -0
- data/src/UtilityApple.mm +5 -18
- data/src/Window.cpp +1 -3
- data/src/WindowUIKit.mm +124 -0
- data/src/stb_image.h +6437 -0
- data/src/stb_image_write.h +730 -0
- data/src/stb_vorbis.c +5459 -0
- metadata +18 -26
- data/Gosu/Sockets.hpp +0 -156
- data/src/Audio/AudioOpenAL.mm +0 -1
- data/src/Bitmap/BitmapApple.mm +0 -226
- data/src/Bitmap/BitmapBMP.cpp +0 -79
- data/src/Bitmap/BitmapColorKey.cpp +0 -50
- data/src/Bitmap/BitmapFreeImage.cpp +0 -174
- data/src/Bitmap/BitmapGDIplus.cpp +0 -212
- data/src/Bitmap/BitmapUtils.cpp +0 -76
- data/src/DirectoriesMac.mm +0 -38
- data/src/DirectoriesTouch.mm +0 -38
- data/src/GosuView.hpp +0 -15
- data/src/GosuView.mm +0 -208
- data/src/Input/AccelerometerReader.hpp +0 -10
- data/src/Input/AccelerometerReader.mm +0 -31
- data/src/Sockets/CommSocket.cpp +0 -305
- data/src/Sockets/ListenerSocket.cpp +0 -59
- data/src/Sockets/MessageSocket.cpp +0 -128
- data/src/Sockets/Socket.cpp +0 -145
- data/src/Sockets/Socket.hpp +0 -66
- data/src/WindowTouch.mm +0 -243
- data/src/X11vroot.h +0 -118
@@ -1,75 +1,57 @@
|
|
1
|
-
#ifndef
|
2
|
-
#define
|
1
|
+
#ifndef GOSU_APPLEUTILITY_HPP
|
2
|
+
#define GOSU_APPLEUTILITY_HPP
|
3
3
|
|
4
4
|
#include <Gosu/Platform.hpp>
|
5
5
|
|
6
|
-
#
|
7
|
-
|
8
|
-
#ifndef GOSU_IS_IPHONE
|
9
|
-
#import <ApplicationServices/ApplicationServices.h>
|
10
|
-
|
11
|
-
// Not defined on 10.4 Tiger SDK which Gosu uses.
|
12
|
-
#if __LP64__ || NS_BUILD_32_LIKE_64
|
13
|
-
typedef long NSInteger;
|
14
|
-
typedef unsigned long NSUInteger;
|
15
|
-
#else
|
16
|
-
typedef int NSInteger;
|
17
|
-
typedef unsigned int NSUInteger;
|
18
|
-
#endif
|
19
|
-
#endif
|
6
|
+
#ifdef __OBJC__
|
20
7
|
|
21
8
|
#include <iostream>
|
22
9
|
#include <ostream>
|
23
10
|
#include <sstream>
|
24
11
|
#include <string>
|
25
12
|
#include <stdexcept>
|
13
|
+
#include <objc/objc.h>
|
14
|
+
#import <CoreFoundation/CoreFoundation.h>
|
15
|
+
#import <Foundation/Foundation.h>
|
26
16
|
|
27
17
|
namespace Gosu
|
28
18
|
{
|
29
19
|
inline void throwOSError(OSStatus status, unsigned line)
|
30
20
|
{
|
21
|
+
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
22
|
+
NSError *error = [NSError errorWithDomain:NSOSStatusErrorDomain code:status userInfo:nil];
|
31
23
|
std::ostringstream str;
|
32
|
-
#ifdef GOSU_IS_IPHONE
|
33
|
-
str << "Error on line " << line << " (Code " << status << ")";
|
34
|
-
#else
|
35
24
|
str << "Error on line " << line << " (Code " << status << "): "
|
36
|
-
|
37
|
-
|
38
|
-
|
25
|
+
<< [[error localizedDescription] UTF8String]
|
26
|
+
<< " (" << [[error description] UTF8String] << ")";
|
27
|
+
[pool release];
|
39
28
|
throw std::runtime_error(str.str());
|
40
29
|
}
|
41
30
|
|
42
31
|
#define CHECK_OS(status) if (!(status)) {} else Gosu::throwOSError(status, __LINE__)
|
43
|
-
}
|
44
32
|
|
45
|
-
#ifdef __OBJC__
|
46
|
-
#import <objc/objc.h>
|
47
|
-
#import <stdexcept>
|
48
|
-
namespace Gosu
|
49
|
-
{
|
50
33
|
template<typename T>
|
51
|
-
class
|
34
|
+
class ObjCRef
|
52
35
|
{
|
53
|
-
|
54
|
-
|
36
|
+
ObjCRef(const ObjCRef&);
|
37
|
+
ObjCRef& operator=(const ObjCRef&);
|
55
38
|
|
56
39
|
T* ptr;
|
40
|
+
|
57
41
|
public:
|
58
|
-
|
42
|
+
ObjCRef(T* ptr = nil)
|
59
43
|
: ptr(ptr)
|
60
44
|
{
|
61
45
|
}
|
62
46
|
|
63
|
-
~
|
47
|
+
~ObjCRef()
|
64
48
|
{
|
65
|
-
|
66
|
-
[ptr release];
|
49
|
+
[ptr release];
|
67
50
|
}
|
68
51
|
|
69
52
|
void reset(T* newPtr = nil)
|
70
53
|
{
|
71
|
-
|
72
|
-
[ptr release];
|
54
|
+
[ptr release];
|
73
55
|
ptr = newPtr;
|
74
56
|
}
|
75
57
|
|
@@ -81,7 +63,7 @@ namespace Gosu
|
|
81
63
|
T* obj() const
|
82
64
|
{
|
83
65
|
if (!ptr)
|
84
|
-
throw std::logic_error("
|
66
|
+
throw std::logic_error("Objective-C reference is nil");
|
85
67
|
return ptr;
|
86
68
|
}
|
87
69
|
};
|
@@ -104,21 +86,21 @@ namespace Gosu
|
|
104
86
|
{
|
105
87
|
}
|
106
88
|
|
107
|
-
CFRef()
|
89
|
+
~CFRef()
|
108
90
|
{
|
109
91
|
if (ref)
|
110
92
|
CFRelease(ref);
|
111
93
|
}
|
112
94
|
|
113
|
-
CFRefType get()
|
95
|
+
CFRefType get() const
|
114
96
|
{
|
115
97
|
return ref;
|
116
98
|
}
|
117
99
|
|
118
|
-
CFRefType obj()
|
100
|
+
CFRefType obj() const
|
119
101
|
{
|
120
102
|
if (!ref)
|
121
|
-
throw std::logic_error("
|
103
|
+
throw std::logic_error("CoreFoundation reference is NULL");
|
122
104
|
return ref;
|
123
105
|
}
|
124
106
|
};
|
@@ -57,9 +57,9 @@ namespace
|
|
57
57
|
|
58
58
|
// TODO: What is this NSAutoreleasePool good for?
|
59
59
|
#ifdef GOSU_IS_MAC
|
60
|
-
#include "../
|
60
|
+
#include "../AppleUtility.hpp"
|
61
61
|
#define CONSTRUCTOR_COMMON \
|
62
|
-
|
62
|
+
ObjCRef<NSAutoreleasePool> pool([NSAutoreleasePool new]); \
|
63
63
|
if (!alChannelManagement.get()) \
|
64
64
|
alChannelManagement.reset(new ALChannelManagement)
|
65
65
|
#else
|
@@ -133,7 +133,6 @@ void Gosu::SampleInstance::changePan(double pan)
|
|
133
133
|
ALuint source = alChannelManagement->sourceIfStillPlaying(handle, extra);
|
134
134
|
if (source == ALChannelManagement::NO_SOURCE)
|
135
135
|
return;
|
136
|
-
// TODO: This is not the old panning behavior!
|
137
136
|
alSource3f(source, AL_POSITION, pan * 10, 0, 0);
|
138
137
|
}
|
139
138
|
|
@@ -273,7 +272,7 @@ public:
|
|
273
272
|
// AVAudioPlayer impl
|
274
273
|
class Gosu::Song::ModuleData : public BaseData
|
275
274
|
{
|
276
|
-
|
275
|
+
ObjCRef<AVAudioPlayer> player;
|
277
276
|
|
278
277
|
void applyVolume()
|
279
278
|
{
|
@@ -284,9 +283,9 @@ public:
|
|
284
283
|
ModuleData(const std::wstring& filename)
|
285
284
|
{
|
286
285
|
std::string utf8Filename = Gosu::wstringToUTF8(filename);
|
287
|
-
|
288
|
-
|
289
|
-
player.reset([[AVAudioPlayer alloc] initWithContentsOfURL:
|
286
|
+
ObjCRef<NSString> nsFilename([[NSString alloc] initWithUTF8String:utf8Filename.c_str()]);
|
287
|
+
ObjCRef<NSURL> url([[NSURL alloc] initFileURLWithPath:nsFilename.obj()]);
|
288
|
+
player.reset([[AVAudioPlayer alloc] initWithContentsOfURL:url.obj() error:NULL]);
|
290
289
|
}
|
291
290
|
|
292
291
|
void play(bool looping)
|
data/src/Audio/Audio.mm
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
#include "Audio.cpp"
|
data/src/Audio/AudioFile.hpp
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
#ifndef
|
2
|
-
#define
|
1
|
+
#ifndef GOSU_SRC_AUDIO_AUDIOFILE_MAC_HPP
|
2
|
+
#define GOSU_SRC_AUDIO_AUDIOFILE_MAC_HPP
|
3
3
|
|
4
4
|
#include "AudioFile.hpp"
|
5
5
|
#include <AudioToolbox/AudioToolbox.h>
|
@@ -9,7 +9,7 @@
|
|
9
9
|
#include <Gosu/IO.hpp>
|
10
10
|
#include <Gosu/Utility.hpp>
|
11
11
|
#include <Gosu/Platform.hpp>
|
12
|
-
#include "../
|
12
|
+
#include "../AppleUtility.hpp"
|
13
13
|
#include <algorithm>
|
14
14
|
#include <vector>
|
15
15
|
#include <arpa/inet.h>
|
@@ -141,24 +141,9 @@ namespace Gosu
|
|
141
141
|
public:
|
142
142
|
AudioToolboxFile(const std::wstring& filename)
|
143
143
|
{
|
144
|
-
|
145
|
-
|
146
|
-
#ifdef GOSU_IS_IPHONE
|
144
|
+
ObjCRef<NSString> utf8Filename([[NSString alloc] initWithUTF8String:wstringToUTF8(filename).c_str()]);
|
145
|
+
ObjCRef<NSURL> url([[NSURL alloc] initFileURLWithPath:utf8Filename.get()]);
|
147
146
|
CHECK_OS(ExtAudioFileOpenURL((CFURLRef)url.get(), &file_));
|
148
|
-
#else
|
149
|
-
// Use FSRef for compatibility with 10.4 Tiger.
|
150
|
-
FSRef fsRef;
|
151
|
-
CFURLGetFSRef(reinterpret_cast<CFURLRef>(url.get()), &fsRef);
|
152
|
-
try
|
153
|
-
{
|
154
|
-
CHECK_OS(ExtAudioFileOpen(&fsRef, &file_));
|
155
|
-
}
|
156
|
-
catch (const std::runtime_error&)
|
157
|
-
{
|
158
|
-
throw std::runtime_error("Unsupported audio file type (" +
|
159
|
-
Gosu::wstringToUTF8(filename) + ")");
|
160
|
-
}
|
161
|
-
#endif
|
162
147
|
|
163
148
|
fileID_ = 0;
|
164
149
|
|
data/src/Audio/OggFile.hpp
CHANGED
@@ -1,11 +1,14 @@
|
|
1
|
-
#ifndef
|
2
|
-
#define
|
1
|
+
#ifndef GOSU_SRC_AUDIO_OGGFILE_HPP
|
2
|
+
#define GOSU_SRC_AUDIO_OGGFILE_HPP
|
3
3
|
|
4
4
|
#include "AudioFile.hpp"
|
5
5
|
#include <Gosu/IO.hpp>
|
6
|
-
#include <vorbis/vorbisfile.h>
|
7
6
|
#include <algorithm>
|
8
7
|
#include <stdexcept>
|
8
|
+
#include <sstream>
|
9
|
+
|
10
|
+
#define STB_VORBIS_HEADER_ONLY
|
11
|
+
#include "../stb_vorbis.c"
|
9
12
|
|
10
13
|
// Based on the Drama Sound Engine for D
|
11
14
|
|
@@ -13,58 +16,55 @@ namespace Gosu
|
|
13
16
|
{
|
14
17
|
class OggFile : public AudioFile
|
15
18
|
{
|
19
|
+
Gosu::Buffer contents_;
|
16
20
|
Gosu::Buffer buffer_;
|
17
|
-
|
18
|
-
ALenum format_;
|
21
|
+
int channels_;
|
19
22
|
ALenum sampleRate_;
|
20
|
-
|
23
|
+
stb_vorbis* stream_;
|
21
24
|
|
22
|
-
|
23
|
-
static std::size_t readCallback(void* ptr, std::size_t size, std::size_t nmemb, void* datasource)
|
24
|
-
{
|
25
|
-
OggFile* oggFile = static_cast<OggFile*>(datasource);
|
26
|
-
size = std::min(size * nmemb,
|
27
|
-
oggFile->buffer_.size() - oggFile->reader_.position());
|
28
|
-
oggFile->reader_.read(ptr, size);
|
29
|
-
return size;
|
30
|
-
}
|
31
|
-
|
32
|
-
void setup()
|
25
|
+
void open()
|
33
26
|
{
|
34
|
-
|
35
|
-
ov_open_callbacks(this, &file_, 0, 0, cbs);
|
27
|
+
int error = 0;
|
36
28
|
|
37
|
-
|
38
|
-
|
39
|
-
throw std::runtime_error("multi-stream vorbis files not supported");
|
29
|
+
const unsigned char *mem = static_cast<const unsigned char*>(contents_.data());
|
30
|
+
stream_ = stb_vorbis_open_memory(mem, contents_.size(), &error, 0);
|
40
31
|
|
41
|
-
|
42
|
-
|
32
|
+
if (stream_ == 0)
|
33
|
+
{
|
34
|
+
std::ostringstream message;
|
35
|
+
message << "Cannot open Ogg Vorbis file, error code: " << error;
|
36
|
+
throw std::runtime_error(message.str());
|
37
|
+
}
|
38
|
+
|
39
|
+
stb_vorbis_info info = stb_vorbis_get_info(stream_);
|
40
|
+
channels_ = info.channels;
|
41
|
+
sampleRate_ = info.sample_rate;
|
42
|
+
buffer_.resize(info.temp_memory_required);
|
43
43
|
}
|
44
44
|
|
45
|
-
void
|
45
|
+
void close()
|
46
46
|
{
|
47
|
-
|
47
|
+
stb_vorbis_close(stream_);
|
48
|
+
stream_ = 0;
|
48
49
|
}
|
49
50
|
|
50
51
|
public:
|
51
52
|
OggFile(Gosu::Reader reader)
|
52
|
-
: reader_(buffer_.frontReader())
|
53
53
|
{
|
54
|
-
|
55
|
-
reader.read(
|
54
|
+
contents_.resize(reader.resource().size() - reader.position());
|
55
|
+
reader.read(contents_.data(), contents_.size());
|
56
56
|
|
57
|
-
|
57
|
+
open();
|
58
58
|
}
|
59
59
|
|
60
60
|
~OggFile()
|
61
61
|
{
|
62
|
-
|
62
|
+
close();
|
63
63
|
}
|
64
64
|
|
65
65
|
ALenum format() const
|
66
66
|
{
|
67
|
-
return
|
67
|
+
return (channels_ == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16);
|
68
68
|
}
|
69
69
|
|
70
70
|
ALuint sampleRate() const
|
@@ -74,38 +74,26 @@ namespace Gosu
|
|
74
74
|
|
75
75
|
std::size_t readData(void* dest, std::size_t length)
|
76
76
|
{
|
77
|
-
|
78
|
-
|
79
|
-
1;
|
80
|
-
#else
|
81
|
-
0;
|
82
|
-
#endif
|
77
|
+
int samples = 0;
|
78
|
+
int maxSamples = length / sizeof(short);
|
83
79
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
result = ov_read(&file_, ptr + size, length - size,
|
91
|
-
OGG_ENDIANNESS, 2 /* 16-bit */,
|
92
|
-
1 /* signed */, §ion);
|
93
|
-
if (result > 0)
|
94
|
-
size += result;
|
95
|
-
else if (result < 0)
|
96
|
-
throw std::runtime_error("error reading vorbis stream");
|
97
|
-
else
|
80
|
+
while (samples < maxSamples) {
|
81
|
+
int samplesPerChannel =
|
82
|
+
stb_vorbis_get_samples_short_interleaved(stream_, channels_,
|
83
|
+
static_cast<short*>(dest) + samples, maxSamples - samples);
|
84
|
+
|
85
|
+
if (samplesPerChannel == 0)
|
98
86
|
break;
|
87
|
+
|
88
|
+
samples += samplesPerChannel * channels_;
|
99
89
|
}
|
100
90
|
|
101
|
-
return
|
91
|
+
return samples * sizeof(short);
|
102
92
|
}
|
103
93
|
|
104
94
|
void rewind()
|
105
95
|
{
|
106
|
-
|
107
|
-
reader_ = buffer_.frontReader();
|
108
|
-
setup();
|
96
|
+
stb_vorbis_seek_start(stream_);
|
109
97
|
}
|
110
98
|
};
|
111
99
|
}
|
data/src/Audio/SndFile.hpp
CHANGED
data/src/Bitmap/Bitmap.cpp
CHANGED
@@ -14,7 +14,7 @@ void Gosu::Bitmap::resize(unsigned width, unsigned height, Color c)
|
|
14
14
|
{
|
15
15
|
if (width == w && height == h)
|
16
16
|
return;
|
17
|
-
|
17
|
+
|
18
18
|
Bitmap temp(width, height, c);
|
19
19
|
temp.insert(*this, 0, 0);
|
20
20
|
swap(temp);
|
@@ -39,7 +39,7 @@ void Gosu::Bitmap::insert(const Bitmap& source, int x, int y, unsigned srcX,
|
|
39
39
|
unsigned srcY, unsigned srcWidth, unsigned srcHeight)
|
40
40
|
{
|
41
41
|
// TODO: This should use memcpy if possible (x == 0 && srcWidth == this->width())
|
42
|
-
|
42
|
+
|
43
43
|
if (x < 0)
|
44
44
|
{
|
45
45
|
unsigned clipLeft = -x;
|
@@ -85,3 +85,99 @@ void Gosu::Bitmap::insert(const Bitmap& source, int x, int y, unsigned srcX,
|
|
85
85
|
setPixel(x + relX, y + relY,
|
86
86
|
source.getPixel(srcX + relX, srcY + relY));
|
87
87
|
}
|
88
|
+
|
89
|
+
void Gosu::applyColorKey(Bitmap& bitmap, Color key)
|
90
|
+
{
|
91
|
+
std::vector<Color> surroundingColors;
|
92
|
+
surroundingColors.reserve(4);
|
93
|
+
|
94
|
+
for (unsigned y = 0; y < bitmap.height(); ++y)
|
95
|
+
for (unsigned x = 0; x < bitmap.width(); ++x)
|
96
|
+
if (bitmap.getPixel(x, y) == key)
|
97
|
+
{
|
98
|
+
surroundingColors.clear();
|
99
|
+
if (x > 0 && bitmap.getPixel(x - 1, y) != key)
|
100
|
+
surroundingColors.push_back(bitmap.getPixel(x - 1, y));
|
101
|
+
if (x < bitmap.width() - 1 && bitmap.getPixel(x + 1, y) != key)
|
102
|
+
surroundingColors.push_back(bitmap.getPixel(x + 1, y));
|
103
|
+
if (y > 0 && bitmap.getPixel(x, y - 1) != key)
|
104
|
+
surroundingColors.push_back(bitmap.getPixel(x, y - 1));
|
105
|
+
if (y < bitmap.height() - 1 && bitmap.getPixel(x, y + 1) != key)
|
106
|
+
surroundingColors.push_back(bitmap.getPixel(x, y + 1));
|
107
|
+
|
108
|
+
if (surroundingColors.empty())
|
109
|
+
{
|
110
|
+
bitmap.setPixel(x, y, Color::NONE);
|
111
|
+
continue;
|
112
|
+
}
|
113
|
+
|
114
|
+
unsigned red = 0, green = 0, blue = 0;
|
115
|
+
for (unsigned i = 0; i < surroundingColors.size(); ++i)
|
116
|
+
{
|
117
|
+
red += surroundingColors[i].red();
|
118
|
+
green += surroundingColors[i].green();
|
119
|
+
blue += surroundingColors[i].blue();
|
120
|
+
}
|
121
|
+
bitmap.setPixel(x, y, Color(0, red / surroundingColors.size(),
|
122
|
+
green / surroundingColors.size(), blue / surroundingColors.size()));
|
123
|
+
}
|
124
|
+
}
|
125
|
+
|
126
|
+
void Gosu::unapplyColorKey(Bitmap& bitmap, Color color)
|
127
|
+
{
|
128
|
+
Color* p = bitmap.data();
|
129
|
+
for (int i = bitmap.width() * bitmap.height(); i > 0; --i, ++p)
|
130
|
+
if (p->alpha() == 0)
|
131
|
+
*p = color;
|
132
|
+
else
|
133
|
+
p->setAlpha(255);
|
134
|
+
}
|
135
|
+
|
136
|
+
void Gosu::applyBorderFlags(Bitmap& dest, const Bitmap& source,
|
137
|
+
unsigned srcX, unsigned srcY, unsigned srcWidth, unsigned srcHeight,
|
138
|
+
unsigned imageFlags)
|
139
|
+
{
|
140
|
+
// Backwards compatibility: This used to be 'bool tileable'.
|
141
|
+
if (imageFlags == 1)
|
142
|
+
imageFlags = ifTileable;
|
143
|
+
|
144
|
+
dest.resize(srcWidth + 2, srcHeight + 2);
|
145
|
+
|
146
|
+
// The borders are made "harder" by duplicating the original bitmap's
|
147
|
+
// borders.
|
148
|
+
|
149
|
+
// Top.
|
150
|
+
if (imageFlags & ifTileableTop)
|
151
|
+
dest.insert(source, 1, 0, srcX, srcY, srcWidth, 1);
|
152
|
+
// Bottom.
|
153
|
+
if (imageFlags & ifTileableBottom)
|
154
|
+
dest.insert(source, 1, dest.height() - 1,
|
155
|
+
srcX, srcY + srcHeight - 1, srcWidth, 1);
|
156
|
+
// Left.
|
157
|
+
if (imageFlags & ifTileableLeft)
|
158
|
+
dest.insert(source, 0, 1, srcX, srcY, 1, srcHeight);
|
159
|
+
// Right.
|
160
|
+
if (imageFlags & ifTileableRight)
|
161
|
+
dest.insert(source, dest.width() - 1, 1,
|
162
|
+
srcX + srcWidth - 1, srcY, 1, srcHeight);
|
163
|
+
|
164
|
+
// Top left.
|
165
|
+
if ((imageFlags & ifTileableTop) && (imageFlags & ifTileableLeft))
|
166
|
+
dest.setPixel(0, 0,
|
167
|
+
source.getPixel(srcX, srcY));
|
168
|
+
// Top right.
|
169
|
+
if ((imageFlags & ifTileableTop) && (imageFlags & ifTileableRight))
|
170
|
+
dest.setPixel(dest.width() - 1, 0,
|
171
|
+
source.getPixel(srcX + srcWidth - 1, srcY));
|
172
|
+
// Bottom left.
|
173
|
+
if ((imageFlags & ifTileableBottom) && (imageFlags & ifTileableLeft))
|
174
|
+
dest.setPixel(0, dest.height() - 1,
|
175
|
+
source.getPixel(srcX, srcY + srcHeight - 1));
|
176
|
+
// Bottom right.
|
177
|
+
if ((imageFlags & ifTileableBottom) && (imageFlags & ifTileableRight))
|
178
|
+
dest.setPixel(dest.width() - 1, dest.height() - 1,
|
179
|
+
source.getPixel(srcX + srcWidth - 1, srcY + srcHeight - 1));
|
180
|
+
|
181
|
+
// Now put the final image into the prepared borders.
|
182
|
+
dest.insert(source, 1, 1, srcX, srcY, srcWidth, srcHeight);
|
183
|
+
}
|