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)
         |