gosu 0.7.33 → 0.7.35
Sign up to get free protection for your applications and to get access to all the features.
- 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)
|