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.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/Gosu/Audio.hpp +35 -66
  3. data/Gosu/AutoLink.hpp +14 -16
  4. data/Gosu/Bitmap.hpp +50 -37
  5. data/Gosu/Buttons.hpp +246 -265
  6. data/Gosu/Color.hpp +32 -76
  7. data/Gosu/Directories.hpp +14 -17
  8. data/Gosu/Font.hpp +28 -34
  9. data/Gosu/Fwd.hpp +27 -31
  10. data/Gosu/Gosu.hpp +2 -5
  11. data/Gosu/Graphics.hpp +31 -48
  12. data/Gosu/GraphicsBase.hpp +27 -58
  13. data/Gosu/IO.hpp +44 -56
  14. data/Gosu/Image.hpp +29 -73
  15. data/Gosu/ImageData.hpp +13 -17
  16. data/Gosu/Input.hpp +42 -57
  17. data/Gosu/Inspection.hpp +2 -6
  18. data/Gosu/Math.hpp +32 -38
  19. data/Gosu/Platform.hpp +10 -29
  20. data/Gosu/Text.hpp +30 -39
  21. data/Gosu/TextInput.hpp +29 -36
  22. data/Gosu/Timing.hpp +14 -16
  23. data/Gosu/Utility.hpp +10 -15
  24. data/Gosu/Version.hpp +13 -14
  25. data/Gosu/Window.hpp +53 -68
  26. data/README.md +23 -11
  27. data/ext/gosu/extconf.rb +31 -81
  28. data/lib/gosu/patches.rb +35 -19
  29. data/lib/gosu/run.rb +13 -4
  30. data/rdoc/gosu.rb +24 -20
  31. data/src/ALChannelManagement.hpp +119 -0
  32. data/src/{Audio/Audio.cpp → Audio.cpp} +177 -211
  33. data/src/AudioFile.hpp +57 -0
  34. data/src/AudioToolboxFile.hpp +214 -0
  35. data/src/Bitmap.cpp +159 -0
  36. data/src/BitmapIO.cpp +141 -0
  37. data/src/BlockAllocator.cpp +133 -0
  38. data/src/{Graphics/BlockAllocator.hpp → BlockAllocator.hpp} +34 -35
  39. data/src/ClipRectStack.hpp +87 -0
  40. data/src/{Graphics/Color.cpp → Color.cpp} +30 -28
  41. data/src/DirectoriesApple.cpp +68 -0
  42. data/src/DirectoriesUnix.cpp +20 -18
  43. data/src/DirectoriesWin.cpp +40 -41
  44. data/src/DrawOp.hpp +168 -0
  45. data/src/DrawOpQueue.hpp +190 -0
  46. data/src/FileUnix.cpp +40 -46
  47. data/src/FileWin.cpp +42 -38
  48. data/src/Font.cpp +165 -0
  49. data/src/{Text/FormattedString.hpp → FormattedString.hpp} +114 -114
  50. data/src/GosuAppDelegate.cpp +30 -0
  51. data/src/{UIKit/GosuAppDelegate.h → GosuAppDelegate.h} +0 -0
  52. data/src/{UIKit/GosuGLView.mm → GosuGLView.cpp} +22 -17
  53. data/src/{UIKit/GosuGLView.h → GosuGLView.h} +0 -0
  54. data/src/GosuViewController.cpp +231 -0
  55. data/src/{UIKit/GosuViewController.h → GosuViewController.h} +0 -0
  56. data/src/Graphics.cpp +464 -0
  57. data/src/{Graphics/Common.hpp → GraphicsImpl.hpp} +29 -32
  58. data/src/IO.cpp +17 -16
  59. data/src/Iconv.hpp +13 -22
  60. data/src/Image.cpp +142 -0
  61. data/src/Input.cpp +459 -0
  62. data/src/InputUIKit.cpp +197 -0
  63. data/src/Inspection.cpp +4 -5
  64. data/src/LargeImageData.cpp +151 -0
  65. data/src/LargeImageData.hpp +43 -0
  66. data/src/{Graphics/Macro.cpp → Macro.cpp} +77 -78
  67. data/src/Macro.hpp +30 -0
  68. data/src/Math.cpp +17 -29
  69. data/src/{Audio/OggFile.hpp → OggFile.hpp} +19 -24
  70. data/src/RenderState.hpp +205 -0
  71. data/src/Resolution.cpp +86 -0
  72. data/src/ResolutionApple.cpp +25 -0
  73. data/{ext/gosu/gosu_wrap.cxx → src/RubyGosu.cxx} +2256 -1707
  74. data/{ext/gosu/gosu_wrap.h → src/RubyGosu.h} +9 -9
  75. data/src/{Audio/SndFile.hpp → SndFile.hpp} +54 -43
  76. data/src/TexChunk.cpp +117 -0
  77. data/src/{Graphics/TexChunk.hpp → TexChunk.hpp} +13 -18
  78. data/src/Text.cpp +371 -0
  79. data/src/TextApple.cpp +209 -0
  80. data/src/TextInput.cpp +278 -0
  81. data/src/TextTTFWin.cpp +251 -0
  82. data/src/{Text/TextUnix.cpp → TextUnix.cpp} +96 -92
  83. data/src/TextWin.cpp +194 -0
  84. data/src/{Graphics/Texture.cpp → Texture.cpp} +35 -38
  85. data/src/{Graphics/Texture.hpp → Texture.hpp} +9 -13
  86. data/src/TimingApple.cpp +11 -7
  87. data/src/TimingUnix.cpp +13 -7
  88. data/src/TimingWin.cpp +6 -1
  89. data/src/{Graphics/Transform.cpp → Transform.cpp} +17 -12
  90. data/src/{Graphics/TransformStack.hpp → TransformStack.hpp} +24 -25
  91. data/src/Utility.cpp +29 -70
  92. data/src/UtilityApple.cpp +52 -0
  93. data/src/UtilityWin.cpp +7 -4
  94. data/src/Version.cpp +22 -0
  95. data/src/WinMain.cpp +30 -33
  96. data/src/WinUtility.cpp +24 -22
  97. data/src/WinUtility.hpp +11 -20
  98. data/src/Window.cpp +142 -112
  99. data/src/WindowUIKit.cpp +155 -0
  100. data/src/stb_image.h +384 -173
  101. data/src/stb_vorbis.c +20 -18
  102. metadata +60 -62
  103. data/Gosu/TR1.hpp +0 -56
  104. data/src/AppleUtility.hpp +0 -66
  105. data/src/Audio/ALChannelManagement.hpp +0 -114
  106. data/src/Audio/Audio.mm +0 -1
  107. data/src/Audio/AudioFile.hpp +0 -53
  108. data/src/Audio/AudioToolboxFile.hpp +0 -207
  109. data/src/Bitmap/Bitmap.cpp +0 -183
  110. data/src/Bitmap/BitmapIO.cpp +0 -176
  111. data/src/DirectoriesApple.mm +0 -71
  112. data/src/Graphics/BlockAllocator.cpp +0 -142
  113. data/src/Graphics/ClipRectStack.hpp +0 -93
  114. data/src/Graphics/DrawOp.hpp +0 -175
  115. data/src/Graphics/DrawOpQueue.hpp +0 -188
  116. data/src/Graphics/Graphics.cpp +0 -478
  117. data/src/Graphics/Image.cpp +0 -193
  118. data/src/Graphics/LargeImageData.cpp +0 -133
  119. data/src/Graphics/LargeImageData.hpp +0 -46
  120. data/src/Graphics/Macro.hpp +0 -36
  121. data/src/Graphics/RenderState.hpp +0 -211
  122. data/src/Graphics/Resolution.cpp +0 -91
  123. data/src/Graphics/ResolutionApple.mm +0 -19
  124. data/src/Graphics/TexChunk.cpp +0 -112
  125. data/src/Input/Input.cpp +0 -463
  126. data/src/Input/InputUIKit.mm +0 -190
  127. data/src/Input/TextInput.cpp +0 -261
  128. data/src/Text/Font.cpp +0 -175
  129. data/src/Text/Text.cpp +0 -391
  130. data/src/Text/TextApple.mm +0 -227
  131. data/src/Text/TextTTFWin.cpp +0 -249
  132. data/src/Text/TextWin.cpp +0 -186
  133. data/src/UIKit/GosuAppDelegate.mm +0 -24
  134. data/src/UIKit/GosuViewController.mm +0 -211
  135. data/src/UtilityApple.mm +0 -63
  136. data/src/WindowUIKit.mm +0 -139
@@ -1 +0,0 @@
1
- #include "Audio.cpp"
@@ -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
@@ -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
- }
@@ -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
- }