gosu 0.9.2 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
+
}
|