gosu 0.7.33 → 0.7.35
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.
- data/Gosu/Async.hpp +10 -8
- data/Gosu/Audio.hpp +6 -4
- data/Gosu/AutoLink.hpp +0 -0
- data/Gosu/Bitmap.hpp +4 -5
- data/Gosu/ButtonsX.hpp +1 -1
- data/Gosu/Color.hpp +8 -8
- data/Gosu/Font.hpp +2 -2
- data/Gosu/Graphics.hpp +4 -6
- data/Gosu/IO.hpp +11 -4
- data/Gosu/Image.hpp +9 -7
- data/Gosu/ImageData.hpp +10 -4
- data/Gosu/Input.hpp +4 -5
- data/Gosu/Sockets.hpp +10 -12
- data/Gosu/TR1.hpp +44 -0
- data/Gosu/TextInput.hpp +2 -2
- data/Gosu/Version.hpp +2 -2
- data/Gosu/WinUtility.hpp +5 -6
- data/Gosu/Window.hpp +5 -6
- data/GosuImpl/Async.cpp +4 -3
- data/GosuImpl/Audio/ALChannelManagement.hpp +23 -11
- data/GosuImpl/Audio/AudioFile.hpp +11 -3
- data/GosuImpl/Audio/AudioOpenAL.cpp +613 -0
- data/GosuImpl/Audio/AudioOpenAL.mm +1 -605
- data/GosuImpl/Audio/AudioSDL.cpp +12 -14
- data/GosuImpl/Audio/AudioToolboxFile.hpp +0 -1
- data/GosuImpl/Audio/OggFile.hpp +2 -0
- data/GosuImpl/Audio/SndFile.hpp +158 -0
- data/GosuImpl/DirectoriesWin.cpp +18 -18
- data/GosuImpl/Graphics/BitmapApple.mm +17 -19
- data/GosuImpl/Graphics/BitmapBMP.cpp +7 -2
- data/GosuImpl/Graphics/BitmapFreeImage.cpp +11 -12
- data/GosuImpl/Graphics/BitmapGDIplus.cpp +35 -31
- data/GosuImpl/Graphics/BitmapUtils.cpp +1 -1
- data/GosuImpl/Graphics/BlockAllocator.cpp +7 -8
- data/GosuImpl/Graphics/BlockAllocator.hpp +3 -4
- data/GosuImpl/Graphics/Common.hpp +3 -2
- data/GosuImpl/Graphics/DrawOp.hpp +2 -3
- data/GosuImpl/Graphics/DrawOpQueue.hpp +28 -20
- data/GosuImpl/Graphics/Font.cpp +13 -13
- data/GosuImpl/Graphics/FormattedString.hpp +93 -86
- data/GosuImpl/Graphics/Graphics.cpp +16 -14
- data/GosuImpl/Graphics/Image.cpp +7 -3
- data/GosuImpl/Graphics/LargeImageData.hpp +4 -5
- data/GosuImpl/Graphics/Macro.hpp +11 -11
- data/GosuImpl/Graphics/RenderState.hpp +5 -4
- data/GosuImpl/Graphics/TexChunk.cpp +3 -3
- data/GosuImpl/Graphics/TexChunk.hpp +4 -4
- data/GosuImpl/Graphics/Text.cpp +29 -30
- data/GosuImpl/Graphics/TextMac.cpp +9 -7
- data/GosuImpl/Graphics/TextTTFWin.cpp +3 -1
- data/GosuImpl/Graphics/TextTouch.mm +0 -1
- data/GosuImpl/Graphics/TextUnix.cpp +12 -4
- data/GosuImpl/Graphics/TextWin.cpp +4 -2
- data/GosuImpl/Graphics/Texture.cpp +7 -6
- data/GosuImpl/Graphics/Texture.hpp +3 -4
- data/GosuImpl/InputMac.mm +12 -15
- data/GosuImpl/InputTouch.mm +3 -3
- data/GosuImpl/InputWin.cpp +149 -159
- data/GosuImpl/InputX.cpp +0 -0
- data/GosuImpl/MacUtility.hpp +9 -4
- data/GosuImpl/RubyGosu.swg +38 -43
- data/GosuImpl/RubyGosu_wrap.cxx +89 -96
- data/GosuImpl/Sockets/CommSocket.cpp +5 -5
- data/GosuImpl/Sockets/Sockets.hpp +4 -4
- data/GosuImpl/TimingApple.cpp +2 -3
- data/GosuImpl/Utility.cpp +18 -0
- data/GosuImpl/WinMain.cpp +0 -1
- data/GosuImpl/WinUtility.cpp +2 -2
- data/GosuImpl/WindowMac.mm +20 -17
- data/GosuImpl/WindowTouch.mm +8 -7
- data/GosuImpl/WindowWin.cpp +12 -7
- data/GosuImpl/WindowX.cpp +67 -18
- data/lib/gosu.rb +14 -12
- data/linux/extconf.rb +11 -6
- metadata +8 -7
- data/GosuImpl/Audio/AudioAudiere.cpp +0 -448
- data/GosuImpl/RubyGosu_DllMain.cxx +0 -31
data/GosuImpl/Audio/AudioSDL.cpp
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
#include <Gosu/Math.hpp>
|
3
3
|
#include <Gosu/IO.hpp>
|
4
4
|
#include <Gosu/Utility.hpp>
|
5
|
-
#include <boost/algorithm/string.hpp>
|
6
5
|
#include <cassert>
|
7
6
|
#include <cstdlib>
|
8
7
|
#include <algorithm>
|
@@ -95,9 +94,10 @@ void Gosu::SampleInstance::changeSpeed(double speed)
|
|
95
94
|
* with SDL_mixer. */
|
96
95
|
}
|
97
96
|
|
98
|
-
struct Gosu::Sample::SampleData
|
97
|
+
struct Gosu::Sample::SampleData
|
99
98
|
{
|
100
99
|
Mix_Chunk* rep;
|
100
|
+
std::vector<Uint8> buffer;
|
101
101
|
|
102
102
|
SampleData(): rep(0) {}
|
103
103
|
~SampleData() {
|
@@ -121,18 +121,17 @@ Gosu::Sample::Sample(const std::wstring& filename)
|
|
121
121
|
}
|
122
122
|
|
123
123
|
Gosu::Sample::Sample(Reader reader)
|
124
|
+
: data(new SampleData)
|
124
125
|
{
|
125
126
|
requireSDLMixer();
|
126
127
|
|
127
128
|
if (noSound)
|
128
129
|
return;
|
129
130
|
|
130
|
-
|
131
|
-
|
132
|
-
reader.read(buffer, bufsize);
|
131
|
+
data->buffer.resize(reader.resource().size() - reader.position());
|
132
|
+
reader.read(&data->buffer[0], data->buffer.size());
|
133
133
|
|
134
|
-
data.
|
135
|
-
data->rep = Mix_LoadWAV_RW(SDL_RWFromMem(buffer, bufsize), 1);
|
134
|
+
data->rep = Mix_LoadWAV_RW(SDL_RWFromMem(&data->buffer[0], data->buffer.size()), 1);
|
136
135
|
if (data->rep == NULL)
|
137
136
|
throwLastSDLError();
|
138
137
|
}
|
@@ -177,10 +176,10 @@ Gosu::SampleInstance Gosu::Sample::playPan(double pan, double volume,
|
|
177
176
|
}
|
178
177
|
|
179
178
|
// No class hierarchy here; SDL_mixer abstracts this away for us.
|
180
|
-
class Gosu::Song::BaseData
|
179
|
+
class Gosu::Song::BaseData {
|
181
180
|
public:
|
182
181
|
Mix_Music* music;
|
183
|
-
//std::vector<Uint8> buffer; - used by constructor that has been commented out
|
182
|
+
// std::vector<Uint8> buffer; - used by constructor that has been commented out
|
184
183
|
double volume;
|
185
184
|
|
186
185
|
BaseData() : music(0), volume(1.0) {}
|
@@ -218,9 +217,8 @@ Gosu::Song::Song(Reader reader)
|
|
218
217
|
#if 0
|
219
218
|
// This is traditionally broken in SDL_mixer. File bugs :)
|
220
219
|
|
221
|
-
|
222
|
-
data->buffer.
|
223
|
-
reader.read(data->buffer.data(), bufsize);
|
220
|
+
data->buffer.resize(reader.resource().size() - reader.position());
|
221
|
+
reader.read(data->buffer.data(), data->buffer.size());
|
224
222
|
data->music = Mix_LoadMUS_RW(SDL_RWFromMem(data->buffer.data(), bufsize));
|
225
223
|
if (data->music == NULL)
|
226
224
|
throwLastSDLError();
|
@@ -308,10 +306,10 @@ Gosu::Sample::Sample(Audio& audio, Reader reader)
|
|
308
306
|
|
309
307
|
Gosu::Song::Song(Audio& audio, const std::wstring& filename)
|
310
308
|
{
|
311
|
-
Song(filename).data
|
309
|
+
data = Song(filename).data;
|
312
310
|
}
|
313
311
|
|
314
312
|
Gosu::Song::Song(Audio& audio, Type type, Reader reader)
|
315
313
|
{
|
316
|
-
Song(reader).data
|
314
|
+
data = Song(reader).data;
|
317
315
|
}
|
data/GosuImpl/Audio/OggFile.hpp
CHANGED
@@ -0,0 +1,158 @@
|
|
1
|
+
#ifndef GOSUIMPL_AUDIO_SNDFILE_HPP
|
2
|
+
#define GOSUIMPL_AUDIO_SNDFILE_HPP
|
3
|
+
|
4
|
+
#include <Gosu/Audio.hpp>
|
5
|
+
#include <Gosu/Platform.hpp>
|
6
|
+
#include <Gosu/Utility.hpp>
|
7
|
+
#include <sndfile.h>
|
8
|
+
|
9
|
+
namespace Gosu
|
10
|
+
{
|
11
|
+
class SndFile : public AudioFile
|
12
|
+
{
|
13
|
+
SNDFILE* file;
|
14
|
+
SF_INFO info;
|
15
|
+
Reader reader;
|
16
|
+
Buffer buffer;
|
17
|
+
|
18
|
+
// Cannot use /DELAYLOAD with libsndfile-1.dll because it was compiled
|
19
|
+
// using arcane GNU tools of dark magic (or maybe it's the filename).
|
20
|
+
#ifdef GOSU_IS_WIN
|
21
|
+
static HMODULE dll()
|
22
|
+
{
|
23
|
+
static HMODULE dll = LoadLibrary(L"libsndfile.dll");
|
24
|
+
if (!dll)
|
25
|
+
throw std::runtime_error("Cannot find libsndfile.dll");
|
26
|
+
return dll;
|
27
|
+
}
|
28
|
+
|
29
|
+
#define CREATE_STUB(NAME, RETURN, PARAMS, NAMES) \
|
30
|
+
static RETURN NAME PARAMS \
|
31
|
+
{ \
|
32
|
+
typedef RETURN (__cdecl *NAME##_ptr) PARAMS; \
|
33
|
+
static NAME##_ptr f = (NAME##_ptr)GetProcAddress(dll(), #NAME); \
|
34
|
+
if (!f) \
|
35
|
+
throw std::runtime_error("Cannot find " ## #NAME); \
|
36
|
+
return f NAMES; \
|
37
|
+
}
|
38
|
+
CREATE_STUB(sf_open_virtual, SNDFILE*,
|
39
|
+
(SF_VIRTUAL_IO* sfvirtual, int mode, SF_INFO* sfinfo, void* user_data),
|
40
|
+
(sfvirtual, mode, sfinfo, user_data))
|
41
|
+
CREATE_STUB(sf_close, int,
|
42
|
+
(SNDFILE *sndfile),
|
43
|
+
(sndfile))
|
44
|
+
CREATE_STUB(sf_read_short, sf_count_t,
|
45
|
+
(SNDFILE *sndfile, short *ptr, sf_count_t items),
|
46
|
+
(sndfile, ptr, items))
|
47
|
+
CREATE_STUB(sf_seek, sf_count_t,
|
48
|
+
(SNDFILE *sndfile, sf_count_t frames, int whence),
|
49
|
+
(sndfile, frames, whence))
|
50
|
+
CREATE_STUB(sf_strerror, const char*,
|
51
|
+
(SNDFILE* sndfile),
|
52
|
+
(sndfile))
|
53
|
+
#endif
|
54
|
+
|
55
|
+
static sf_count_t get_filelen(SndFile *self)
|
56
|
+
{
|
57
|
+
return self->buffer.size();
|
58
|
+
}
|
59
|
+
|
60
|
+
static sf_count_t seek(sf_count_t offset, int whence, SndFile *self)
|
61
|
+
{
|
62
|
+
switch (whence)
|
63
|
+
{
|
64
|
+
case SEEK_SET: self->reader.setPosition(offset); break;
|
65
|
+
case SEEK_CUR: self->reader.seek(offset); break;
|
66
|
+
case SEEK_END: self->reader.setPosition(self->buffer.size() - offset); break;
|
67
|
+
};
|
68
|
+
return 0;
|
69
|
+
}
|
70
|
+
|
71
|
+
static sf_count_t read(void *ptr, sf_count_t count, SndFile *self)
|
72
|
+
{
|
73
|
+
sf_count_t avail = self->buffer.size() - self->reader.position();
|
74
|
+
count = std::min(avail, count);
|
75
|
+
self->reader.read(ptr, count);
|
76
|
+
return count;
|
77
|
+
}
|
78
|
+
|
79
|
+
static sf_count_t tell(SndFile *self)
|
80
|
+
{
|
81
|
+
return self->reader.position();
|
82
|
+
}
|
83
|
+
|
84
|
+
static SF_VIRTUAL_IO* ioInterface()
|
85
|
+
{
|
86
|
+
static SF_VIRTUAL_IO io;
|
87
|
+
io.get_filelen = (sf_vio_get_filelen)&get_filelen;
|
88
|
+
io.seek = (sf_vio_seek)&seek;
|
89
|
+
io.read = (sf_vio_read)&read;
|
90
|
+
io.tell = (sf_vio_tell)&tell;
|
91
|
+
io.write = NULL;
|
92
|
+
return &io;
|
93
|
+
}
|
94
|
+
|
95
|
+
public:
|
96
|
+
SndFile(Reader reader)
|
97
|
+
: file(NULL), reader(buffer.frontReader())
|
98
|
+
{
|
99
|
+
info.format = 0;
|
100
|
+
buffer.resize(reader.resource().size() - reader.position());
|
101
|
+
reader.read(buffer.data(), buffer.size());
|
102
|
+
file = sf_open_virtual(ioInterface(), SFM_READ, &info, this);
|
103
|
+
if (!file)
|
104
|
+
throw std::runtime_error(std::string(sf_strerror(NULL)));
|
105
|
+
}
|
106
|
+
|
107
|
+
SndFile(const std::wstring& filename)
|
108
|
+
: file(NULL), reader(buffer.frontReader())
|
109
|
+
{
|
110
|
+
info.format = 0;
|
111
|
+
#ifdef GOSU_IS_WIN
|
112
|
+
loadFile(buffer, filename);
|
113
|
+
file = sf_open_virtual(ioInterface(), SFM_READ, &info, this);
|
114
|
+
#else
|
115
|
+
file = sf_open(wstringToUTF8(filename).c_str(), SFM_READ, &info);
|
116
|
+
#endif
|
117
|
+
if (!file)
|
118
|
+
throw std::runtime_error(std::string(sf_strerror(NULL)));
|
119
|
+
}
|
120
|
+
|
121
|
+
~SndFile()
|
122
|
+
{
|
123
|
+
if (file)
|
124
|
+
sf_close(file);
|
125
|
+
}
|
126
|
+
|
127
|
+
ALenum format() const
|
128
|
+
{
|
129
|
+
switch (info.channels)
|
130
|
+
{
|
131
|
+
case 1:
|
132
|
+
return AL_FORMAT_MONO16;
|
133
|
+
case 2:
|
134
|
+
return AL_FORMAT_STEREO16;
|
135
|
+
default:
|
136
|
+
throw std::runtime_error("Too many channels in audio file");
|
137
|
+
};
|
138
|
+
}
|
139
|
+
|
140
|
+
ALuint sampleRate() const
|
141
|
+
{
|
142
|
+
return info.samplerate;
|
143
|
+
}
|
144
|
+
|
145
|
+
std::size_t readData(void* dest, std::size_t length)
|
146
|
+
{
|
147
|
+
int itemSize = 2 * info.channels;
|
148
|
+
return sf_read_short(file, (short*)dest, length / itemSize) * itemSize;
|
149
|
+
}
|
150
|
+
|
151
|
+
void rewind()
|
152
|
+
{
|
153
|
+
sf_seek(file, 0, SEEK_SET);
|
154
|
+
}
|
155
|
+
};
|
156
|
+
}
|
157
|
+
|
158
|
+
#endif
|
data/GosuImpl/DirectoriesWin.cpp
CHANGED
@@ -6,37 +6,37 @@
|
|
6
6
|
|
7
7
|
namespace
|
8
8
|
{
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
std::wstring specialFolderPath(int csidl)
|
10
|
+
{
|
11
|
+
WCHAR buf[MAX_PATH + 2];
|
12
|
+
if (FAILED(SHGetFolderPath(NULL, csidl | CSIDL_FLAG_CREATE, NULL, 0, buf)))
|
13
|
+
throw std::runtime_error("Error getting special folder path");
|
14
|
+
std::size_t len = std::wcslen(buf);
|
15
|
+
if (buf[len - 1] != L'\\')
|
16
|
+
{
|
17
|
+
buf[len] = L'\\';
|
18
|
+
buf[len + 1] = 0;
|
19
|
+
}
|
20
|
+
return buf;
|
21
|
+
}
|
22
22
|
}
|
23
23
|
|
24
24
|
std::wstring Gosu::resourcePrefix()
|
25
25
|
{
|
26
|
-
|
26
|
+
return Win::appDirectory();
|
27
27
|
}
|
28
28
|
|
29
29
|
std::wstring Gosu::sharedResourcePrefix()
|
30
30
|
{
|
31
|
-
|
31
|
+
return Win::appDirectory();
|
32
32
|
}
|
33
33
|
|
34
34
|
std::wstring Gosu::userSettingsPrefix()
|
35
35
|
{
|
36
|
-
|
36
|
+
return specialFolderPath(CSIDL_APPDATA);
|
37
37
|
}
|
38
38
|
|
39
39
|
std::wstring Gosu::userDocsPrefix()
|
40
40
|
{
|
41
|
-
|
42
|
-
}
|
41
|
+
return specialFolderPath(CSIDL_PERSONAL);
|
42
|
+
}
|
@@ -5,8 +5,6 @@
|
|
5
5
|
#include <Gosu/Utility.hpp>
|
6
6
|
|
7
7
|
#include <GosuImpl/MacUtility.hpp>
|
8
|
-
#include <boost/algorithm/string.hpp>
|
9
|
-
#include <boost/lexical_cast.hpp>
|
10
8
|
#include <stdexcept>
|
11
9
|
|
12
10
|
#ifdef GOSU_IS_IPHONE
|
@@ -56,9 +54,10 @@ namespace
|
|
56
54
|
|
57
55
|
bitmap.resize([rep pixelsWide], [rep pixelsHigh]);
|
58
56
|
|
59
|
-
// Use a temporary context to draw the NSImage to the buffer.
|
57
|
+
// Use a temporary context to draw the NSImage to the buffer. For that, construct a color
|
58
|
+
// space that does not alter the colors while drawing from the NSImage to the CGBitmapContext.
|
60
59
|
|
61
|
-
static Gosu::CFRef<CGColorSpaceRef> colorSpace(
|
60
|
+
static Gosu::CFRef<CGColorSpaceRef> colorSpace(CGColorSpaceCreateDeviceRGB());
|
62
61
|
Gosu::CFRef<CGContextRef> context(CGBitmapContextCreate(bitmap.data(), bitmap.width(), bitmap.height(),
|
63
62
|
8, bitmap.width() * 4,
|
64
63
|
colorSpace.obj(), kCGImageAlphaPremultipliedLast)); // kCGBitmapByteOrder32Host?
|
@@ -71,21 +70,22 @@ namespace
|
|
71
70
|
#endif
|
72
71
|
}
|
73
72
|
|
74
|
-
|
73
|
+
// TODO: Move into proper internal header
|
74
|
+
namespace Gosu { bool isExtension(const wchar_t* str, const wchar_t* ext); }
|
75
|
+
|
76
|
+
void Gosu::loadImageFile(Bitmap& bitmap, const std::wstring& filename)
|
75
77
|
{
|
76
78
|
ObjRef<NSString> filenameRef([[NSString alloc] initWithUTF8String: wstringToUTF8(filename).c_str()]);
|
77
79
|
ObjRef<APPLE_IMAGE> image([[APPLE_IMAGE alloc] initWithContentsOfFile: filenameRef.obj()]);
|
78
80
|
if (!image.get())
|
79
81
|
throw std::runtime_error("Cannot load image file " + wstringToUTF8(filename));
|
80
82
|
|
81
|
-
Bitmap bitmap;
|
82
83
|
appleImageToBitmap(image.obj(), bitmap);
|
83
|
-
if (
|
84
|
+
if (isExtension(filename.c_str(), L".bmp"))
|
84
85
|
applyColorKey(bitmap, Color::FUCHSIA);
|
85
|
-
return bitmap;
|
86
86
|
}
|
87
87
|
|
88
|
-
|
88
|
+
void Gosu::loadImageFile(Bitmap& bitmap, Reader reader)
|
89
89
|
{
|
90
90
|
char signature[2];
|
91
91
|
reader.read(signature, 2);
|
@@ -101,11 +101,9 @@ Gosu::Bitmap Gosu::loadImageFile(Reader reader)
|
|
101
101
|
if (!image.get())
|
102
102
|
throw std::runtime_error("Cannot load image file from stream");
|
103
103
|
|
104
|
-
Bitmap bitmap;
|
105
104
|
appleImageToBitmap(image.obj(), bitmap);
|
106
105
|
if (signature[0] == 'B' && signature[1] == 'M')
|
107
106
|
applyColorKey(bitmap, Color::FUCHSIA);
|
108
|
-
return bitmap;
|
109
107
|
}
|
110
108
|
|
111
109
|
#ifndef GOSU_IS_IPHONE
|
@@ -118,15 +116,15 @@ void Gosu::saveImageFile(const Bitmap& bitmap, const std::wstring& filename)
|
|
118
116
|
void Gosu::saveImageFile(const Bitmap& originalBitmap, Writer writer, const std::wstring& formatHint)
|
119
117
|
{
|
120
118
|
NSBitmapImageFileType fileType;
|
121
|
-
if (
|
119
|
+
if (isExtension(formatHint.c_str(), L"png"))
|
122
120
|
fileType = NSPNGFileType;
|
123
|
-
else if (
|
121
|
+
else if (isExtension(formatHint.c_str(), L"bmp"))
|
124
122
|
fileType = NSBMPFileType;
|
125
|
-
else if (
|
123
|
+
else if (isExtension(formatHint.c_str(), L"gif"))
|
126
124
|
fileType = NSGIFFileType;
|
127
|
-
else if (
|
125
|
+
else if (isExtension(formatHint.c_str(), L"jpg") || isExtension(formatHint.c_str(), L"jpeg"))
|
128
126
|
fileType = NSJPEGFileType;
|
129
|
-
else if (
|
127
|
+
else if (isExtension(formatHint.c_str(), L"tif") || isExtension(formatHint.c_str(), L"tiff"))
|
130
128
|
fileType = NSTIFFFileType;
|
131
129
|
else
|
132
130
|
throw std::runtime_error("Unsupported image format for writing: " + wstringToUTF8(formatHint));
|
@@ -160,7 +158,7 @@ void Gosu::saveImageFile(const Bitmap& bmp, const std::wstring& filename)
|
|
160
158
|
|
161
159
|
void Gosu::saveImageFile(const Bitmap& bmp, Writer writer, const std::wstring& formatHint)
|
162
160
|
{
|
163
|
-
if (
|
161
|
+
if (isExtension(formatHint.c_str(), L"bmp"))
|
164
162
|
{
|
165
163
|
Bitmap bitmap = bmp;
|
166
164
|
unapplyColorKey(bitmap, Color::FUCHSIA);
|
@@ -182,9 +180,9 @@ void Gosu::saveImageFile(const Bitmap& bmp, Writer writer, const std::wstring& f
|
|
182
180
|
ObjRef<UIImage> image([[UIImage alloc] initWithCGImage: imageRef]);
|
183
181
|
|
184
182
|
NSData* data;
|
185
|
-
if (
|
183
|
+
if (isExtension(formatHint.c_str(), L"jpeg") || isExtension(formatHint.c_str(), L"jpg"))
|
186
184
|
data = UIImageJPEGRepresentation(image.get(), 0.0);
|
187
|
-
else if (
|
185
|
+
else if (isExtension(formatHint.c_str(), L"png"))
|
188
186
|
data = UIImagePNGRepresentation(image.get());
|
189
187
|
else
|
190
188
|
throw std::runtime_error("Unsupported image format for writing: " + wstringToUTF8(formatHint));
|
@@ -4,14 +4,19 @@
|
|
4
4
|
#ifdef GOSU_IS_IPHONE
|
5
5
|
#include <Gosu/Bitmap.hpp>
|
6
6
|
#include <Gosu/IO.hpp>
|
7
|
-
#include <
|
7
|
+
#include <Gosu/TR1.hpp>
|
8
8
|
|
9
9
|
namespace
|
10
10
|
{
|
11
|
+
template<unsigned bits> struct UintSelector;
|
12
|
+
template<> struct UintSelector<8> { typedef std::tr1::uint8_t Type; };
|
13
|
+
template<> struct UintSelector<16> { typedef std::tr1::uint16_t Type; };
|
14
|
+
template<> struct UintSelector<32> { typedef std::tr1::uint32_t Type; };
|
15
|
+
|
11
16
|
template<unsigned bits, typename T>
|
12
17
|
void writeVal(Gosu::Writer& writer, T value)
|
13
18
|
{
|
14
|
-
typename
|
19
|
+
typename UintSelector<bits>::Type val = value;
|
15
20
|
writer.writePod(val, Gosu::boLittle);
|
16
21
|
}
|
17
22
|
}
|
@@ -1,18 +1,19 @@
|
|
1
1
|
#include <Gosu/Bitmap.hpp>
|
2
2
|
#include <Gosu/IO.hpp>
|
3
3
|
#include <Gosu/Platform.hpp>
|
4
|
+
#include <Gosu/TR1.hpp>
|
4
5
|
#include <Gosu/Utility.hpp>
|
5
6
|
#include <vector>
|
6
|
-
#include <boost/cstdint.hpp>
|
7
7
|
#include <FreeImage.h>
|
8
8
|
|
9
|
-
// Compatibility with FreeImage <
|
9
|
+
// Compatibility with FreeImage <3.1.3. Subtly changes Gosu's behavior though.
|
10
10
|
#ifndef JPEG_EXIFROTATE
|
11
11
|
#define JPEG_EXIFROTATE 0
|
12
12
|
#endif
|
13
13
|
|
14
|
-
//
|
15
|
-
|
14
|
+
// With MSVC, add a suffix so FreeImage can be linked as a fallback for GDI+.
|
15
|
+
// With MinGW, Gosu uses FreeImage all the time, so no suffix is needed.
|
16
|
+
#ifdef _MSC_VER
|
16
17
|
#define FI(x) x##_FreeImage
|
17
18
|
#else
|
18
19
|
#define FI(x) x
|
@@ -26,14 +27,13 @@ namespace
|
|
26
27
|
{
|
27
28
|
// Since FreeImage gracefully ignores the MASK parameters above, we
|
28
29
|
// manually exchange the R and B channels.
|
29
|
-
|
30
|
+
std::tr1::uint32_t* p = reinterpret_cast<std::tr1::uint32_t*>(bitmap.data());
|
30
31
|
for (int i = bitmap.width() * bitmap.height(); i > 0; --i, ++p)
|
31
32
|
*p = (*p & 0xff00ff00) | ((*p << 16) & 0x00ff0000) | ((*p >> 16) & 0x000000ff);
|
32
33
|
}
|
33
34
|
|
34
|
-
Gosu::Bitmap
|
35
|
+
void fibToBitmap(Gosu::Bitmap& bitmap, FIBITMAP* fib, FREE_IMAGE_FORMAT fif)
|
35
36
|
{
|
36
|
-
Gosu::Bitmap bitmap;
|
37
37
|
bitmap.resize(FreeImage_GetWidth(fib), FreeImage_GetHeight(fib));
|
38
38
|
FreeImage_ConvertToRawBits(reinterpret_cast<BYTE*>(bitmap.data()),
|
39
39
|
fib, bitmap.width() * 4, 32,
|
@@ -42,7 +42,6 @@ namespace
|
|
42
42
|
reshuffleBitmap(bitmap);
|
43
43
|
if (fif == FIF_BMP)
|
44
44
|
Gosu::applyColorKey(bitmap, Gosu::Color::FUCHSIA);
|
45
|
-
return bitmap;
|
46
45
|
}
|
47
46
|
|
48
47
|
FIBITMAP* bitmapToFIB(Gosu::Bitmap bitmap, FREE_IMAGE_FORMAT fif)
|
@@ -82,7 +81,7 @@ namespace
|
|
82
81
|
|
83
82
|
namespace Gosu
|
84
83
|
{
|
85
|
-
|
84
|
+
void FI(loadImageFile)(Bitmap& bitmap, const std::wstring& filename)
|
86
85
|
{
|
87
86
|
#ifdef GOSU_IS_WIN
|
88
87
|
FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeU(filename.c_str());
|
@@ -93,10 +92,10 @@ namespace Gosu
|
|
93
92
|
FIBITMAP* fib = FreeImage_Load(fif, utf8Filename.c_str(), GOSU_FIFLAGS);
|
94
93
|
#endif
|
95
94
|
|
96
|
-
|
95
|
+
fibToBitmap(bitmap, fib, fif);
|
97
96
|
}
|
98
97
|
|
99
|
-
|
98
|
+
void FI(loadImageFile)(Bitmap& bitmap, Gosu::Reader input)
|
100
99
|
{
|
101
100
|
// Read all available input
|
102
101
|
std::vector<BYTE> data(input.resource().size() - input.position());
|
@@ -105,7 +104,7 @@ namespace Gosu
|
|
105
104
|
FREE_IMAGE_FORMAT fif = FreeImage_GetFileTypeFromMemory(fim);
|
106
105
|
FIBITMAP* fib = FreeImage_LoadFromMemory(fif, fim, GOSU_FIFLAGS);
|
107
106
|
|
108
|
-
|
107
|
+
fibToBitmap(bitmap, fib, fif);
|
109
108
|
}
|
110
109
|
|
111
110
|
void FI(saveImageFile)(const Bitmap& bitmap, const std::wstring& filename)
|