gosu 0.10.9.pre1 → 0.11.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 +35 -66
- data/Gosu/AutoLink.hpp +14 -16
- data/Gosu/Bitmap.hpp +50 -37
- data/Gosu/Buttons.hpp +246 -265
- data/Gosu/Color.hpp +32 -76
- data/Gosu/Directories.hpp +14 -17
- data/Gosu/Font.hpp +28 -34
- data/Gosu/Fwd.hpp +27 -31
- data/Gosu/Gosu.hpp +2 -5
- data/Gosu/Graphics.hpp +31 -48
- data/Gosu/GraphicsBase.hpp +27 -58
- data/Gosu/IO.hpp +44 -56
- data/Gosu/Image.hpp +29 -73
- data/Gosu/ImageData.hpp +13 -17
- data/Gosu/Input.hpp +42 -57
- data/Gosu/Inspection.hpp +2 -6
- data/Gosu/Math.hpp +32 -38
- data/Gosu/Platform.hpp +10 -29
- data/Gosu/Text.hpp +30 -39
- data/Gosu/TextInput.hpp +29 -36
- data/Gosu/Timing.hpp +14 -16
- data/Gosu/Utility.hpp +10 -15
- data/Gosu/Version.hpp +13 -14
- data/Gosu/Window.hpp +53 -68
- data/README.md +23 -11
- data/ext/gosu/extconf.rb +31 -81
- data/lib/gosu/patches.rb +35 -19
- data/lib/gosu/run.rb +13 -4
- data/rdoc/gosu.rb +24 -20
- data/src/ALChannelManagement.hpp +119 -0
- data/src/{Audio/Audio.cpp → Audio.cpp} +177 -211
- data/src/AudioFile.hpp +57 -0
- data/src/AudioToolboxFile.hpp +214 -0
- data/src/Bitmap.cpp +159 -0
- data/src/BitmapIO.cpp +141 -0
- data/src/BlockAllocator.cpp +133 -0
- data/src/{Graphics/BlockAllocator.hpp → BlockAllocator.hpp} +34 -35
- data/src/ClipRectStack.hpp +87 -0
- data/src/{Graphics/Color.cpp → Color.cpp} +30 -28
- data/src/DirectoriesApple.cpp +68 -0
- data/src/DirectoriesUnix.cpp +20 -18
- data/src/DirectoriesWin.cpp +40 -41
- data/src/DrawOp.hpp +168 -0
- data/src/DrawOpQueue.hpp +190 -0
- data/src/FileUnix.cpp +40 -46
- data/src/FileWin.cpp +42 -38
- data/src/Font.cpp +165 -0
- data/src/{Text/FormattedString.hpp → FormattedString.hpp} +114 -114
- data/src/GosuAppDelegate.cpp +30 -0
- data/src/{UIKit/GosuAppDelegate.h → GosuAppDelegate.h} +0 -0
- data/src/{UIKit/GosuGLView.mm → GosuGLView.cpp} +22 -17
- data/src/{UIKit/GosuGLView.h → GosuGLView.h} +0 -0
- data/src/GosuViewController.cpp +231 -0
- data/src/{UIKit/GosuViewController.h → GosuViewController.h} +0 -0
- data/src/Graphics.cpp +464 -0
- data/src/{Graphics/Common.hpp → GraphicsImpl.hpp} +29 -32
- data/src/IO.cpp +17 -16
- data/src/Iconv.hpp +13 -22
- data/src/Image.cpp +142 -0
- data/src/Input.cpp +459 -0
- data/src/InputUIKit.cpp +197 -0
- data/src/Inspection.cpp +4 -5
- data/src/LargeImageData.cpp +151 -0
- data/src/LargeImageData.hpp +43 -0
- data/src/{Graphics/Macro.cpp → Macro.cpp} +77 -78
- data/src/Macro.hpp +30 -0
- data/src/Math.cpp +17 -29
- data/src/{Audio/OggFile.hpp → OggFile.hpp} +19 -24
- data/src/RenderState.hpp +205 -0
- data/src/Resolution.cpp +86 -0
- data/src/ResolutionApple.cpp +25 -0
- data/{ext/gosu/gosu_wrap.cxx → src/RubyGosu.cxx} +2256 -1707
- data/{ext/gosu/gosu_wrap.h → src/RubyGosu.h} +9 -9
- data/src/{Audio/SndFile.hpp → SndFile.hpp} +54 -43
- data/src/TexChunk.cpp +117 -0
- data/src/{Graphics/TexChunk.hpp → TexChunk.hpp} +13 -18
- data/src/Text.cpp +371 -0
- data/src/TextApple.cpp +209 -0
- data/src/TextInput.cpp +278 -0
- data/src/TextTTFWin.cpp +251 -0
- data/src/{Text/TextUnix.cpp → TextUnix.cpp} +96 -92
- data/src/TextWin.cpp +194 -0
- data/src/{Graphics/Texture.cpp → Texture.cpp} +35 -38
- data/src/{Graphics/Texture.hpp → Texture.hpp} +9 -13
- data/src/TimingApple.cpp +11 -7
- data/src/TimingUnix.cpp +13 -7
- data/src/TimingWin.cpp +6 -1
- data/src/{Graphics/Transform.cpp → Transform.cpp} +17 -12
- data/src/{Graphics/TransformStack.hpp → TransformStack.hpp} +24 -25
- data/src/Utility.cpp +29 -70
- data/src/UtilityApple.cpp +52 -0
- data/src/UtilityWin.cpp +7 -4
- data/src/Version.cpp +22 -0
- data/src/WinMain.cpp +30 -33
- data/src/WinUtility.cpp +24 -22
- data/src/WinUtility.hpp +11 -20
- data/src/Window.cpp +142 -112
- data/src/WindowUIKit.cpp +155 -0
- data/src/stb_image.h +384 -173
- data/src/stb_vorbis.c +20 -18
- metadata +60 -62
- data/Gosu/TR1.hpp +0 -56
- data/src/AppleUtility.hpp +0 -66
- data/src/Audio/ALChannelManagement.hpp +0 -114
- data/src/Audio/Audio.mm +0 -1
- data/src/Audio/AudioFile.hpp +0 -53
- data/src/Audio/AudioToolboxFile.hpp +0 -207
- data/src/Bitmap/Bitmap.cpp +0 -183
- data/src/Bitmap/BitmapIO.cpp +0 -176
- data/src/DirectoriesApple.mm +0 -71
- data/src/Graphics/BlockAllocator.cpp +0 -142
- data/src/Graphics/ClipRectStack.hpp +0 -93
- data/src/Graphics/DrawOp.hpp +0 -175
- data/src/Graphics/DrawOpQueue.hpp +0 -188
- data/src/Graphics/Graphics.cpp +0 -478
- data/src/Graphics/Image.cpp +0 -193
- data/src/Graphics/LargeImageData.cpp +0 -133
- data/src/Graphics/LargeImageData.hpp +0 -46
- data/src/Graphics/Macro.hpp +0 -36
- data/src/Graphics/RenderState.hpp +0 -211
- data/src/Graphics/Resolution.cpp +0 -91
- data/src/Graphics/ResolutionApple.mm +0 -19
- data/src/Graphics/TexChunk.cpp +0 -112
- data/src/Input/Input.cpp +0 -463
- data/src/Input/InputUIKit.mm +0 -190
- data/src/Input/TextInput.cpp +0 -261
- data/src/Text/Font.cpp +0 -175
- data/src/Text/Text.cpp +0 -391
- data/src/Text/TextApple.mm +0 -227
- data/src/Text/TextTTFWin.cpp +0 -249
- data/src/Text/TextWin.cpp +0 -186
- data/src/UIKit/GosuAppDelegate.mm +0 -24
- data/src/UIKit/GosuViewController.mm +0 -211
- data/src/UtilityApple.mm +0 -63
- data/src/WindowUIKit.mm +0 -139
data/src/Audio/Audio.mm
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
#include "Audio.cpp"
|
data/src/Audio/AudioFile.hpp
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
#ifndef GOSU_SRC_AUDIO_AUDIOFILE_HPP
|
2
|
-
#define GOSU_SRC_AUDIO_AUDIOFILE_HPP
|
3
|
-
|
4
|
-
#include <vector>
|
5
|
-
#include <Gosu/Platform.hpp>
|
6
|
-
#ifdef GOSU_IS_MAC
|
7
|
-
#include <OpenAL/al.h>
|
8
|
-
#else
|
9
|
-
#include <AL/al.h>
|
10
|
-
#endif
|
11
|
-
|
12
|
-
namespace Gosu
|
13
|
-
{
|
14
|
-
class AudioFile
|
15
|
-
{
|
16
|
-
AudioFile(const AudioFile&);
|
17
|
-
AudioFile& operator=(const AudioFile&);
|
18
|
-
|
19
|
-
std::vector<char> decodedData_;
|
20
|
-
|
21
|
-
public:
|
22
|
-
AudioFile() {}
|
23
|
-
virtual ~AudioFile() {}
|
24
|
-
virtual ALenum format() const = 0;
|
25
|
-
virtual ALuint sampleRate() const = 0;
|
26
|
-
virtual std::size_t readData(void* dest, std::size_t length) = 0;
|
27
|
-
virtual void rewind() = 0;
|
28
|
-
|
29
|
-
const std::vector<char>& decodedData()
|
30
|
-
{
|
31
|
-
static const unsigned INCREMENT = 512*1024;
|
32
|
-
|
33
|
-
if (!decodedData_.empty())
|
34
|
-
return decodedData_;
|
35
|
-
|
36
|
-
for (;;)
|
37
|
-
{
|
38
|
-
decodedData_.resize(decodedData_.size() + INCREMENT);
|
39
|
-
int readBytes = readData(&decodedData_[decodedData_.size() - INCREMENT],
|
40
|
-
INCREMENT);
|
41
|
-
if (readBytes < INCREMENT)
|
42
|
-
{
|
43
|
-
decodedData_.resize(decodedData_.size() - INCREMENT + readBytes);
|
44
|
-
break;
|
45
|
-
}
|
46
|
-
}
|
47
|
-
|
48
|
-
return decodedData_;
|
49
|
-
}
|
50
|
-
};
|
51
|
-
}
|
52
|
-
|
53
|
-
#endif
|
@@ -1,207 +0,0 @@
|
|
1
|
-
#ifndef GOSU_SRC_AUDIO_AUDIOFILE_MAC_HPP
|
2
|
-
#define GOSU_SRC_AUDIO_AUDIOFILE_MAC_HPP
|
3
|
-
|
4
|
-
#include "AudioFile.hpp"
|
5
|
-
#include <AudioToolbox/AudioToolbox.h>
|
6
|
-
#include <AudioToolbox/AudioConverter.h>
|
7
|
-
#include <AudioToolbox/ExtendedAudioFile.h>
|
8
|
-
#include <OpenAL/al.h>
|
9
|
-
#include <Gosu/IO.hpp>
|
10
|
-
#include <Gosu/Utility.hpp>
|
11
|
-
#include <Gosu/Platform.hpp>
|
12
|
-
#include "../AppleUtility.hpp"
|
13
|
-
#include <algorithm>
|
14
|
-
#include <vector>
|
15
|
-
#include <arpa/inet.h>
|
16
|
-
#import <Foundation/Foundation.h>
|
17
|
-
|
18
|
-
namespace Gosu
|
19
|
-
{
|
20
|
-
class AudioToolboxFile : public AudioFile
|
21
|
-
{
|
22
|
-
Gosu::Buffer buffer_;
|
23
|
-
AudioFileID fileID_;
|
24
|
-
ExtAudioFileRef file_;
|
25
|
-
SInt64 position_;
|
26
|
-
SInt64 seekOffset_;
|
27
|
-
|
28
|
-
ALenum format_;
|
29
|
-
ALuint sampleRate_;
|
30
|
-
UInt32 bytesPerFrame_;
|
31
|
-
bool bigEndian_;
|
32
|
-
|
33
|
-
static OSStatus AudioFile_ReadProc(void* inClientData, SInt64 inPosition,
|
34
|
-
UInt32 requestCount, void* buffer, UInt32* actualCount)
|
35
|
-
{
|
36
|
-
const Resource& res = *static_cast<Resource*>(inClientData);
|
37
|
-
*actualCount = std::min<UInt32>(requestCount, res.size() - inPosition);
|
38
|
-
res.read(inPosition, *actualCount, buffer);
|
39
|
-
return noErr;
|
40
|
-
}
|
41
|
-
|
42
|
-
static SInt64 AudioFile_GetSizeProc(void* inClientData)
|
43
|
-
{
|
44
|
-
const Resource& res = *static_cast<Resource*>(inClientData);
|
45
|
-
return res.size();
|
46
|
-
}
|
47
|
-
|
48
|
-
void initSeekOffset()
|
49
|
-
{
|
50
|
-
AudioConverterRef acRef;
|
51
|
-
UInt32 acrSize = sizeof acRef;
|
52
|
-
CHECK_OS(ExtAudioFileGetProperty(file_, kExtAudioFileProperty_AudioConverter,
|
53
|
-
&acrSize, &acRef));
|
54
|
-
|
55
|
-
AudioConverterPrimeInfo primeInfo;
|
56
|
-
UInt32 piSize = sizeof primeInfo;
|
57
|
-
OSStatus result = AudioConverterGetProperty(acRef, kAudioConverterPrimeInfo,
|
58
|
-
&piSize, &primeInfo);
|
59
|
-
if (result != kAudioConverterErr_PropertyNotSupported)
|
60
|
-
{
|
61
|
-
CHECK_OS(result);
|
62
|
-
seekOffset_ = primeInfo.leadingFrames;
|
63
|
-
}
|
64
|
-
}
|
65
|
-
|
66
|
-
void initClientFormatBasedOn(const AudioStreamBasicDescription& base)
|
67
|
-
{
|
68
|
-
AudioStreamBasicDescription clientData = { 0 };
|
69
|
-
sampleRate_ = clientData.mSampleRate = 22050;
|
70
|
-
clientData.mFormatID = kAudioFormatLinearPCM;
|
71
|
-
clientData.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked;
|
72
|
-
clientData.mBitsPerChannel = 16;
|
73
|
-
clientData.mChannelsPerFrame = base.mChannelsPerFrame;
|
74
|
-
clientData.mFramesPerPacket = 1;
|
75
|
-
clientData.mBytesPerPacket =
|
76
|
-
clientData.mBytesPerFrame =
|
77
|
-
clientData.mChannelsPerFrame * clientData.mBitsPerChannel / 8;
|
78
|
-
CHECK_OS(ExtAudioFileSetProperty(file_,
|
79
|
-
kExtAudioFileProperty_ClientDataFormat,
|
80
|
-
sizeof clientData, &clientData));
|
81
|
-
|
82
|
-
initSeekOffset();
|
83
|
-
|
84
|
-
format_ = clientData.mChannelsPerFrame == 1 ? AL_FORMAT_MONO16 : AL_FORMAT_STEREO16;
|
85
|
-
}
|
86
|
-
|
87
|
-
void init()
|
88
|
-
{
|
89
|
-
// Streaming starts at beginning
|
90
|
-
position_ = 0;
|
91
|
-
|
92
|
-
// Unless overridden later, assume that the index into seek() is 0-based
|
93
|
-
seekOffset_ = 0;
|
94
|
-
|
95
|
-
AudioStreamBasicDescription desc;
|
96
|
-
UInt32 sizeOfProperty = sizeof desc;
|
97
|
-
CHECK_OS(ExtAudioFileGetProperty(file_, kExtAudioFileProperty_FileDataFormat,
|
98
|
-
&sizeOfProperty, &desc));
|
99
|
-
|
100
|
-
// Sample rate for OpenAL
|
101
|
-
sampleRate_ = desc.mSampleRate;
|
102
|
-
|
103
|
-
// Sanity checks
|
104
|
-
if (desc.mFormatFlags & kAudioFormatFlagIsNonInterleaved)
|
105
|
-
throw std::runtime_error("Non-interleaved formats are unsupported");
|
106
|
-
|
107
|
-
// Easy formats
|
108
|
-
format_ = 0;
|
109
|
-
if (desc.mChannelsPerFrame == 1)
|
110
|
-
{
|
111
|
-
/*if (desc.mBitsPerChannel == 8)
|
112
|
-
format_ = AL_FORMAT_MONO8;
|
113
|
-
else*/ if (desc.mBitsPerChannel == 16)
|
114
|
-
format_ = AL_FORMAT_MONO16;
|
115
|
-
}
|
116
|
-
else if (desc.mChannelsPerFrame == 2)
|
117
|
-
{
|
118
|
-
/*if (desc.mBitsPerChannel == 8)
|
119
|
-
format_ = AL_FORMAT_STEREO8;
|
120
|
-
else */if (desc.mBitsPerChannel == 16)
|
121
|
-
format_ = AL_FORMAT_STEREO16;
|
122
|
-
}
|
123
|
-
|
124
|
-
if (format_ == 0 ||
|
125
|
-
// If format not native for OpenAL, set client data format
|
126
|
-
// to enable conversion
|
127
|
-
desc.mFormatFlags & kAudioFormatFlagIsBigEndian ||
|
128
|
-
desc.mFormatFlags & kAudioFormatFlagIsFloat ||
|
129
|
-
!(desc.mFormatFlags & kAudioFormatFlagIsSignedInteger)) {
|
130
|
-
initClientFormatBasedOn(desc);
|
131
|
-
}
|
132
|
-
else {
|
133
|
-
// Just set the old format as the client format so
|
134
|
-
// ExtAudioFileSeek will work for us.
|
135
|
-
CHECK_OS(ExtAudioFileSetProperty(file_,
|
136
|
-
kExtAudioFileProperty_ClientDataFormat,
|
137
|
-
sizeof desc, &desc));
|
138
|
-
}
|
139
|
-
}
|
140
|
-
|
141
|
-
public:
|
142
|
-
AudioToolboxFile(const std::wstring& filename)
|
143
|
-
{
|
144
|
-
NSString *utf8Filename = [NSString stringWithUTF8String:wstringToUTF8(filename).c_str()];
|
145
|
-
NSURL *URL = [NSURL fileURLWithPath:utf8Filename];
|
146
|
-
CHECK_OS(ExtAudioFileOpenURL((__bridge CFURLRef)URL, &file_));
|
147
|
-
|
148
|
-
fileID_ = 0;
|
149
|
-
|
150
|
-
init();
|
151
|
-
}
|
152
|
-
|
153
|
-
AudioToolboxFile(Gosu::Reader reader)
|
154
|
-
{
|
155
|
-
buffer_.resize(reader.resource().size() - reader.position());
|
156
|
-
reader.read(buffer_.data(), buffer_.size());
|
157
|
-
|
158
|
-
// TODO: This fails on iOS with MP3 files.
|
159
|
-
// TODO: ^ Is the comment above still true on non-ancient iOS versions?
|
160
|
-
|
161
|
-
void* clientData = &buffer_;
|
162
|
-
CHECK_OS(AudioFileOpenWithCallbacks(clientData, AudioFile_ReadProc, 0,
|
163
|
-
AudioFile_GetSizeProc, 0, 0, &fileID_));
|
164
|
-
CHECK_OS(ExtAudioFileWrapAudioFileID(fileID_, false, &file_));
|
165
|
-
|
166
|
-
init();
|
167
|
-
}
|
168
|
-
|
169
|
-
~AudioToolboxFile()
|
170
|
-
{
|
171
|
-
ExtAudioFileDispose(file_);
|
172
|
-
|
173
|
-
if (fileID_) {
|
174
|
-
AudioFileClose(fileID_);
|
175
|
-
}
|
176
|
-
}
|
177
|
-
|
178
|
-
ALenum format() const
|
179
|
-
{
|
180
|
-
return format_;
|
181
|
-
}
|
182
|
-
|
183
|
-
ALuint sampleRate() const
|
184
|
-
{
|
185
|
-
return sampleRate_;
|
186
|
-
}
|
187
|
-
|
188
|
-
void rewind()
|
189
|
-
{
|
190
|
-
CHECK_OS(ExtAudioFileSeek(file_, 0 + seekOffset_));
|
191
|
-
}
|
192
|
-
|
193
|
-
std::size_t readData(void* dest, size_t length)
|
194
|
-
{
|
195
|
-
AudioBufferList abl;
|
196
|
-
abl.mNumberBuffers = 1;
|
197
|
-
abl.mBuffers[0].mNumberChannels = 1;
|
198
|
-
abl.mBuffers[0].mDataByteSize = length;
|
199
|
-
abl.mBuffers[0].mData = dest;
|
200
|
-
UInt32 numFrames = 0xffffffff; // give us as many frames as possible given our buffer
|
201
|
-
CHECK_OS(ExtAudioFileRead(file_, &numFrames, &abl));
|
202
|
-
return abl.mBuffers[0].mDataByteSize;
|
203
|
-
}
|
204
|
-
};
|
205
|
-
}
|
206
|
-
|
207
|
-
#endif
|
data/src/Bitmap/Bitmap.cpp
DELETED
@@ -1,183 +0,0 @@
|
|
1
|
-
#include <Gosu/Bitmap.hpp>
|
2
|
-
#include <cassert>
|
3
|
-
#include <algorithm>
|
4
|
-
#include <vector>
|
5
|
-
|
6
|
-
void Gosu::Bitmap::swap(Bitmap& other)
|
7
|
-
{
|
8
|
-
std::swap(pixels, other.pixels);
|
9
|
-
std::swap(w, other.w);
|
10
|
-
std::swap(h, other.h);
|
11
|
-
}
|
12
|
-
|
13
|
-
void Gosu::Bitmap::resize(unsigned width, unsigned height, Color c)
|
14
|
-
{
|
15
|
-
if (width == w && height == h)
|
16
|
-
return;
|
17
|
-
|
18
|
-
Bitmap temp(width, height, c);
|
19
|
-
temp.insert(*this, 0, 0);
|
20
|
-
swap(temp);
|
21
|
-
}
|
22
|
-
|
23
|
-
void Gosu::Bitmap::fill(Color c)
|
24
|
-
{
|
25
|
-
std::fill(pixels.begin(), pixels.end(), c);
|
26
|
-
}
|
27
|
-
|
28
|
-
void Gosu::Bitmap::replace(Color what, Color with)
|
29
|
-
{
|
30
|
-
std::replace(pixels.begin(), pixels.end(), what, with);
|
31
|
-
}
|
32
|
-
|
33
|
-
void Gosu::Bitmap::insert(const Bitmap& source, int x, int y)
|
34
|
-
{
|
35
|
-
insert(source, x, y, 0, 0, source.width(), source.height());
|
36
|
-
}
|
37
|
-
|
38
|
-
void Gosu::Bitmap::insert(const Bitmap& source, int x, int y, unsigned srcX,
|
39
|
-
unsigned srcY, unsigned srcWidth, unsigned srcHeight)
|
40
|
-
{
|
41
|
-
// TODO: This should use memcpy if possible (x == 0 && srcWidth == this->width())
|
42
|
-
|
43
|
-
if (x < 0)
|
44
|
-
{
|
45
|
-
unsigned clipLeft = -x;
|
46
|
-
|
47
|
-
if (clipLeft >= srcWidth)
|
48
|
-
return;
|
49
|
-
|
50
|
-
srcX += clipLeft;
|
51
|
-
srcWidth -= clipLeft;
|
52
|
-
x = 0;
|
53
|
-
}
|
54
|
-
|
55
|
-
if (y < 0)
|
56
|
-
{
|
57
|
-
unsigned clipTop = -y;
|
58
|
-
|
59
|
-
if (clipTop >= srcHeight)
|
60
|
-
return;
|
61
|
-
|
62
|
-
srcY += clipTop;
|
63
|
-
srcHeight -= clipTop;
|
64
|
-
y = 0;
|
65
|
-
}
|
66
|
-
|
67
|
-
if (x + srcWidth > w)
|
68
|
-
{
|
69
|
-
if (static_cast<unsigned>(x) >= w)
|
70
|
-
return;
|
71
|
-
|
72
|
-
srcWidth = w - x;
|
73
|
-
}
|
74
|
-
|
75
|
-
if (y + srcHeight > h)
|
76
|
-
{
|
77
|
-
if (static_cast<unsigned>(y) >= h)
|
78
|
-
return;
|
79
|
-
|
80
|
-
srcHeight = h - y;
|
81
|
-
}
|
82
|
-
|
83
|
-
for (unsigned relY = 0; relY < srcHeight; ++relY)
|
84
|
-
for (unsigned relX = 0; relX < srcWidth; ++relX)
|
85
|
-
setPixel(x + relX, y + relY,
|
86
|
-
source.getPixel(srcX + relX, srcY + relY));
|
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
|
-
}
|
data/src/Bitmap/BitmapIO.cpp
DELETED
@@ -1,176 +0,0 @@
|
|
1
|
-
#include <Gosu/Bitmap.hpp>
|
2
|
-
#include <Gosu/Platform.hpp>
|
3
|
-
#include <Gosu/IO.hpp>
|
4
|
-
#include <Gosu/Utility.hpp>
|
5
|
-
|
6
|
-
#include <cstring>
|
7
|
-
#include <stdexcept>
|
8
|
-
|
9
|
-
#define STB_IMAGE_IMPLEMENTATION
|
10
|
-
#define STBI_NO_STDIO
|
11
|
-
#define STBI_NO_LINEAR
|
12
|
-
|
13
|
-
// Work around this bug:
|
14
|
-
// https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899
|
15
|
-
#ifdef GOSU_IS_X
|
16
|
-
#define STBI_NO_SIMD
|
17
|
-
#endif
|
18
|
-
|
19
|
-
#include "../stb_image.h"
|
20
|
-
|
21
|
-
namespace
|
22
|
-
{
|
23
|
-
int readCallback(void* user, char* data, int size)
|
24
|
-
{
|
25
|
-
Gosu::Reader* reader = static_cast<Gosu::Reader*>(user);
|
26
|
-
std::size_t remaining = reader->resource().size() - reader->position();
|
27
|
-
std::size_t actualSize = (size < remaining ? size : remaining);
|
28
|
-
reader->read(data, actualSize);
|
29
|
-
return actualSize;
|
30
|
-
}
|
31
|
-
|
32
|
-
void skipCallback(void* user, int n)
|
33
|
-
{
|
34
|
-
Gosu::Reader* reader = static_cast<Gosu::Reader*>(user);
|
35
|
-
reader->setPosition(reader->position() + n);
|
36
|
-
}
|
37
|
-
|
38
|
-
int eofCallback(void* user)
|
39
|
-
{
|
40
|
-
Gosu::Reader* reader = static_cast<Gosu::Reader*>(user);
|
41
|
-
return reader->position() == reader->resource().size();
|
42
|
-
}
|
43
|
-
|
44
|
-
bool isBMP(Gosu::Reader reader)
|
45
|
-
{
|
46
|
-
std::size_t remaining = reader.resource().size() - reader.position();
|
47
|
-
if (remaining < 2)
|
48
|
-
return false;
|
49
|
-
char magicBytes[2];
|
50
|
-
reader.read(magicBytes, sizeof magicBytes);
|
51
|
-
reader.seek(sizeof magicBytes);
|
52
|
-
return magicBytes[0] == 'B' && magicBytes[1] == 'M';
|
53
|
-
}
|
54
|
-
}
|
55
|
-
|
56
|
-
void Gosu::loadImageFile(Gosu::Bitmap& bitmap, const std::wstring& filename)
|
57
|
-
{
|
58
|
-
Buffer buffer;
|
59
|
-
loadFile(buffer, filename);
|
60
|
-
loadImageFile(bitmap, buffer.frontReader());
|
61
|
-
}
|
62
|
-
|
63
|
-
void Gosu::loadImageFile(Gosu::Bitmap& bitmap, Reader input)
|
64
|
-
{
|
65
|
-
bool needsColorKey = isBMP(input);
|
66
|
-
|
67
|
-
stbi_io_callbacks callbacks;
|
68
|
-
callbacks.read = readCallback;
|
69
|
-
callbacks.skip = skipCallback;
|
70
|
-
callbacks.eof = eofCallback;
|
71
|
-
int x, y, n;
|
72
|
-
stbi_uc* bytes = stbi_load_from_callbacks(&callbacks, &input, &x, &y, &n, STBI_rgb_alpha);
|
73
|
-
|
74
|
-
if (bytes == 0) {
|
75
|
-
// TODO - stbi_failure_reason is not thread safe. Everything here should be wrapped in a mutex.
|
76
|
-
throw std::runtime_error("Cannot load image: " + std::string(stbi_failure_reason()));
|
77
|
-
}
|
78
|
-
|
79
|
-
bitmap.resize(x, y);
|
80
|
-
std::memcpy(bitmap.data(), bytes, x * y * sizeof(Gosu::Color));
|
81
|
-
|
82
|
-
stbi_image_free(bytes);
|
83
|
-
|
84
|
-
if (needsColorKey)
|
85
|
-
applyColorKey(bitmap, Gosu::Color::FUCHSIA);
|
86
|
-
}
|
87
|
-
|
88
|
-
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
89
|
-
#include "../stb_image_write.h"
|
90
|
-
|
91
|
-
// TODO: Move into proper internal header
|
92
|
-
namespace Gosu { bool isExtension(const wchar_t* str, const wchar_t* ext); }
|
93
|
-
|
94
|
-
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, const std::wstring& filename)
|
95
|
-
{
|
96
|
-
int ok;
|
97
|
-
std::string utf8 = Gosu::wstringToUTF8(filename);
|
98
|
-
|
99
|
-
if (isExtension(filename.c_str(), L"bmp"))
|
100
|
-
{
|
101
|
-
ok = stbi_write_bmp(utf8.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data());
|
102
|
-
}
|
103
|
-
else if (isExtension(filename.c_str(), L"tga"))
|
104
|
-
{
|
105
|
-
ok = stbi_write_tga(utf8.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data());
|
106
|
-
}
|
107
|
-
else
|
108
|
-
{
|
109
|
-
ok = stbi_write_png(utf8.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data(), 0);
|
110
|
-
}
|
111
|
-
|
112
|
-
if (ok == 0)
|
113
|
-
throw std::runtime_error("Could not save image data to file: " + utf8);
|
114
|
-
}
|
115
|
-
|
116
|
-
namespace
|
117
|
-
{
|
118
|
-
void stbiWriteToWriter(void *context, void *data, int size)
|
119
|
-
{
|
120
|
-
Gosu::Writer *writer = reinterpret_cast<Gosu::Writer*>(context);
|
121
|
-
writer->write(data, size);
|
122
|
-
}
|
123
|
-
}
|
124
|
-
|
125
|
-
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, Gosu::Writer writer,
|
126
|
-
const std::wstring& formatHint)
|
127
|
-
{
|
128
|
-
int ok;
|
129
|
-
|
130
|
-
if (isExtension(formatHint.c_str(), L"bmp"))
|
131
|
-
{
|
132
|
-
ok = stbi_write_bmp_to_func(stbiWriteToWriter, &writer,
|
133
|
-
bitmap.width(), bitmap.height(), 4, bitmap.data());
|
134
|
-
}
|
135
|
-
else if (isExtension(formatHint.c_str(), L"tga"))
|
136
|
-
{
|
137
|
-
stbi_write_tga_with_rle = 0;
|
138
|
-
ok = stbi_write_tga_to_func(stbiWriteToWriter, &writer,
|
139
|
-
bitmap.width(), bitmap.height(), 4, bitmap.data());
|
140
|
-
}
|
141
|
-
else
|
142
|
-
{
|
143
|
-
ok = stbi_write_png_to_func(stbiWriteToWriter, &writer,
|
144
|
-
bitmap.width(), bitmap.height(), 4, bitmap.data(), 0);
|
145
|
-
}
|
146
|
-
|
147
|
-
if (ok == 0)
|
148
|
-
throw std::runtime_error("Could not save image data to memory (format hint = '" +
|
149
|
-
Gosu::wstringToUTF8(formatHint) + "'");
|
150
|
-
}
|
151
|
-
|
152
|
-
// Deprecated methods.
|
153
|
-
|
154
|
-
Gosu::Reader Gosu::loadFromPNG(Bitmap& bitmap, Reader reader)
|
155
|
-
{
|
156
|
-
loadImageFile(bitmap, reader);
|
157
|
-
reader.setPosition(reader.resource().size());
|
158
|
-
return reader;
|
159
|
-
}
|
160
|
-
|
161
|
-
Gosu::Reader Gosu::loadFromBMP(Bitmap& bitmap, Reader reader)
|
162
|
-
{
|
163
|
-
return loadFromPNG(bitmap, reader);
|
164
|
-
}
|
165
|
-
|
166
|
-
Gosu::Writer Gosu::saveToPNG(const Bitmap& bitmap, Writer writer)
|
167
|
-
{
|
168
|
-
saveImageFile(bitmap, writer, L".png");
|
169
|
-
return writer.resource().backWriter();
|
170
|
-
}
|
171
|
-
|
172
|
-
Gosu::Writer Gosu::saveToBMP(const Bitmap& bitmap, Writer writer)
|
173
|
-
{
|
174
|
-
saveImageFile(bitmap, writer, L".bmp");
|
175
|
-
return writer.resource().backWriter();
|
176
|
-
}
|