gosu 0.15.2 → 1.1.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/dependencies/SDL/include/SDL.h +138 -0
- data/dependencies/SDL/include/SDL_assert.h +293 -0
- data/dependencies/SDL/include/SDL_atomic.h +295 -0
- data/dependencies/SDL/include/SDL_audio.h +859 -0
- data/dependencies/SDL/include/SDL_bits.h +121 -0
- data/dependencies/SDL/include/SDL_blendmode.h +123 -0
- data/dependencies/SDL/include/SDL_clipboard.h +71 -0
- data/dependencies/SDL/include/SDL_config.h +55 -0
- data/dependencies/SDL/include/SDL_config_android.h +182 -0
- data/dependencies/SDL/include/SDL_config_iphoneos.h +207 -0
- data/dependencies/SDL/include/SDL_config_macosx.h +266 -0
- data/dependencies/SDL/include/SDL_config_minimal.h +85 -0
- data/dependencies/SDL/include/SDL_config_os2.h +188 -0
- data/dependencies/SDL/include/SDL_config_pandora.h +135 -0
- data/dependencies/SDL/include/SDL_config_psp.h +165 -0
- data/dependencies/SDL/include/SDL_config_windows.h +288 -0
- data/dependencies/SDL/include/SDL_config_winrt.h +243 -0
- data/dependencies/SDL/include/SDL_config_wiz.h +149 -0
- data/dependencies/SDL/include/SDL_copying.h +20 -0
- data/dependencies/SDL/include/SDL_cpuinfo.h +299 -0
- data/dependencies/SDL/include/SDL_egl.h +1676 -0
- data/dependencies/SDL/include/SDL_endian.h +263 -0
- data/dependencies/SDL/include/SDL_error.h +112 -0
- data/dependencies/SDL/include/SDL_events.h +827 -0
- data/dependencies/SDL/include/SDL_filesystem.h +136 -0
- data/dependencies/SDL/include/SDL_gamecontroller.h +541 -0
- data/dependencies/SDL/include/SDL_gesture.h +87 -0
- data/dependencies/SDL/include/SDL_haptic.h +1247 -0
- data/dependencies/SDL/include/SDL_hints.h +1578 -0
- data/dependencies/SDL/include/SDL_joystick.h +499 -0
- data/dependencies/SDL/include/SDL_keyboard.h +217 -0
- data/dependencies/SDL/include/SDL_keycode.h +351 -0
- data/dependencies/SDL/include/SDL_loadso.h +81 -0
- data/dependencies/SDL/include/SDL_locale.h +101 -0
- data/dependencies/SDL/include/SDL_log.h +211 -0
- data/dependencies/SDL/include/SDL_main.h +180 -0
- data/dependencies/SDL/include/SDL_messagebox.h +146 -0
- data/dependencies/SDL/include/SDL_metal.h +117 -0
- data/dependencies/SDL/include/SDL_misc.h +75 -0
- data/dependencies/SDL/include/SDL_mouse.h +302 -0
- data/dependencies/SDL/include/SDL_mutex.h +251 -0
- data/dependencies/SDL/include/SDL_name.h +33 -0
- data/dependencies/SDL/include/SDL_opengl.h +2183 -0
- data/dependencies/SDL/include/SDL_opengl_glext.h +11180 -0
- data/dependencies/SDL/include/SDL_opengles.h +39 -0
- data/dependencies/SDL/include/SDL_opengles2.h +52 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2.h +621 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2ext.h +2050 -0
- data/dependencies/SDL/include/SDL_opengles2_gl2platform.h +30 -0
- data/dependencies/SDL/include/SDL_opengles2_khrplatform.h +282 -0
- data/dependencies/SDL/include/SDL_pixels.h +479 -0
- data/dependencies/SDL/include/SDL_platform.h +198 -0
- data/dependencies/SDL/include/SDL_power.h +75 -0
- data/dependencies/SDL/include/SDL_quit.h +58 -0
- data/dependencies/SDL/include/SDL_rect.h +174 -0
- data/dependencies/SDL/include/SDL_render.h +1158 -0
- data/dependencies/SDL/include/SDL_revision.h +2 -0
- data/dependencies/SDL/include/SDL_rwops.h +283 -0
- data/dependencies/SDL/include/SDL_scancode.h +413 -0
- data/dependencies/SDL/include/SDL_sensor.h +267 -0
- data/dependencies/SDL/include/SDL_shape.h +144 -0
- data/dependencies/SDL/include/SDL_stdinc.h +647 -0
- data/dependencies/SDL/include/SDL_surface.h +563 -0
- data/dependencies/SDL/include/SDL_system.h +325 -0
- data/dependencies/SDL/include/SDL_syswm.h +354 -0
- data/dependencies/SDL/include/SDL_test.h +69 -0
- data/dependencies/SDL/include/SDL_test_assert.h +105 -0
- data/dependencies/SDL/include/SDL_test_common.h +218 -0
- data/dependencies/SDL/include/SDL_test_compare.h +69 -0
- data/dependencies/SDL/include/SDL_test_crc32.h +124 -0
- data/dependencies/SDL/include/SDL_test_font.h +81 -0
- data/dependencies/SDL/include/SDL_test_fuzzer.h +384 -0
- data/dependencies/SDL/include/SDL_test_harness.h +134 -0
- data/dependencies/SDL/include/SDL_test_images.h +78 -0
- data/dependencies/SDL/include/SDL_test_log.h +67 -0
- data/dependencies/SDL/include/SDL_test_md5.h +129 -0
- data/dependencies/SDL/include/SDL_test_memory.h +63 -0
- data/dependencies/SDL/include/SDL_test_random.h +115 -0
- data/dependencies/SDL/include/SDL_thread.h +366 -0
- data/dependencies/SDL/include/SDL_timer.h +115 -0
- data/dependencies/SDL/include/SDL_touch.h +102 -0
- data/dependencies/SDL/include/SDL_types.h +29 -0
- data/dependencies/SDL/include/SDL_version.h +162 -0
- data/dependencies/SDL/include/SDL_video.h +1282 -0
- data/dependencies/SDL/include/SDL_vulkan.h +276 -0
- data/dependencies/SDL/include/begin_code.h +166 -0
- data/dependencies/SDL/include/close_code.h +40 -0
- data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
- data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
- data/dependencies/SDL_sound/SDL_sound.c +795 -0
- data/dependencies/SDL_sound/SDL_sound.h +725 -0
- data/dependencies/SDL_sound/SDL_sound_aiff.c +537 -0
- data/dependencies/SDL_sound/SDL_sound_au.c +352 -0
- data/dependencies/SDL_sound/SDL_sound_coreaudio.c +747 -0
- data/dependencies/SDL_sound/SDL_sound_flac.c +182 -0
- data/dependencies/SDL_sound/SDL_sound_internal.h +304 -0
- data/dependencies/SDL_sound/SDL_sound_modplug.c +228 -0
- data/dependencies/SDL_sound/SDL_sound_mp3.c +184 -0
- data/dependencies/SDL_sound/SDL_sound_raw.c +164 -0
- data/dependencies/SDL_sound/SDL_sound_shn.c +1309 -0
- data/dependencies/SDL_sound/SDL_sound_voc.c +550 -0
- data/dependencies/SDL_sound/SDL_sound_vorbis.c +223 -0
- data/dependencies/SDL_sound/SDL_sound_wav.c +783 -0
- data/dependencies/SDL_sound/dr_flac.h +5906 -0
- data/dependencies/SDL_sound/dr_mp3.h +2832 -0
- data/dependencies/SDL_sound/libmodplug/fastmix.c +1748 -0
- data/dependencies/SDL_sound/libmodplug/libmodplug.h +1001 -0
- data/dependencies/SDL_sound/libmodplug/load_669.c +188 -0
- data/dependencies/SDL_sound/libmodplug/load_abc.c +4725 -0
- data/dependencies/SDL_sound/libmodplug/load_amf.c +403 -0
- data/dependencies/SDL_sound/libmodplug/load_ams.c +587 -0
- data/dependencies/SDL_sound/libmodplug/load_dbm.c +357 -0
- data/dependencies/SDL_sound/libmodplug/load_dmf.c +531 -0
- data/dependencies/SDL_sound/libmodplug/load_dsm.c +232 -0
- data/dependencies/SDL_sound/libmodplug/load_far.c +253 -0
- data/dependencies/SDL_sound/libmodplug/load_it.c +796 -0
- data/dependencies/SDL_sound/libmodplug/load_mdl.c +488 -0
- data/dependencies/SDL_sound/libmodplug/load_med.c +757 -0
- data/dependencies/SDL_sound/libmodplug/load_mid.c +1405 -0
- data/dependencies/SDL_sound/libmodplug/load_mod.c +269 -0
- data/dependencies/SDL_sound/libmodplug/load_mt2.c +546 -0
- data/dependencies/SDL_sound/libmodplug/load_mtm.c +142 -0
- data/dependencies/SDL_sound/libmodplug/load_okt.c +192 -0
- data/dependencies/SDL_sound/libmodplug/load_pat.c +1143 -0
- data/dependencies/SDL_sound/libmodplug/load_pat.h +25 -0
- data/dependencies/SDL_sound/libmodplug/load_psm.c +350 -0
- data/dependencies/SDL_sound/libmodplug/load_ptm.c +204 -0
- data/dependencies/SDL_sound/libmodplug/load_s3m.c +325 -0
- data/dependencies/SDL_sound/libmodplug/load_stm.c +180 -0
- data/dependencies/SDL_sound/libmodplug/load_ult.c +206 -0
- data/dependencies/SDL_sound/libmodplug/load_umx.c +51 -0
- data/dependencies/SDL_sound/libmodplug/load_xm.c +554 -0
- data/dependencies/SDL_sound/libmodplug/mmcmp.c +382 -0
- data/dependencies/SDL_sound/libmodplug/modplug.c +170 -0
- data/dependencies/SDL_sound/libmodplug/modplug.h +90 -0
- data/dependencies/SDL_sound/libmodplug/snd_dsp.c +301 -0
- data/dependencies/SDL_sound/libmodplug/snd_flt.c +63 -0
- data/dependencies/SDL_sound/libmodplug/snd_fx.c +2350 -0
- data/dependencies/SDL_sound/libmodplug/sndfile.c +1169 -0
- data/dependencies/SDL_sound/libmodplug/sndmix.c +1034 -0
- data/dependencies/SDL_sound/libmodplug/tables.h +371 -0
- data/{src/stb_vorbis.c → dependencies/SDL_sound/stb_vorbis.h} +143 -78
- data/dependencies/al_soft/AL/al.h +655 -0
- data/dependencies/al_soft/AL/alc.h +270 -0
- data/dependencies/al_soft/AL/alext.h +585 -0
- data/dependencies/al_soft/AL/efx-creative.h +3 -0
- data/dependencies/al_soft/AL/efx-presets.h +402 -0
- data/dependencies/al_soft/AL/efx.h +762 -0
- data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
- data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
- data/{src → dependencies/stb}/stb_image.h +330 -127
- data/{src → dependencies/stb}/stb_image_write.h +156 -85
- data/{src → dependencies/stb}/stb_truetype.h +192 -69
- data/{src → dependencies/utf8proc}/utf8proc.c +0 -0
- data/{src → dependencies/utf8proc}/utf8proc.h +0 -0
- data/{src → dependencies/utf8proc}/utf8proc_data.h +0 -0
- data/ext/gosu/extconf.rb +53 -39
- data/{Gosu → include/Gosu}/Audio.hpp +6 -8
- data/include/Gosu/Bitmap.hpp +100 -0
- data/{Gosu → include/Gosu}/Buttons.hpp +104 -44
- data/{Gosu → include/Gosu}/Color.hpp +0 -0
- data/{Gosu → include/Gosu}/Directories.hpp +0 -0
- data/{Gosu → include/Gosu}/Font.hpp +1 -1
- data/{Gosu → include/Gosu}/Fwd.hpp +0 -5
- data/{Gosu → include/Gosu}/Gosu.hpp +0 -0
- data/{Gosu → include/Gosu}/Graphics.hpp +0 -0
- data/{Gosu → include/Gosu}/GraphicsBase.hpp +0 -0
- data/{Gosu → include/Gosu}/IO.hpp +0 -0
- data/{Gosu → include/Gosu}/Image.hpp +7 -6
- data/{Gosu → include/Gosu}/ImageData.hpp +0 -0
- data/{Gosu → include/Gosu}/Input.hpp +39 -51
- data/{Gosu → include/Gosu}/Inspection.hpp +0 -0
- data/{Gosu → include/Gosu}/Math.hpp +0 -0
- data/{Gosu → include/Gosu}/Platform.hpp +0 -0
- data/{Gosu → include/Gosu}/Text.hpp +0 -0
- data/{Gosu → include/Gosu}/TextInput.hpp +0 -0
- data/{Gosu → include/Gosu}/Timing.hpp +0 -0
- data/{Gosu → include/Gosu}/Utility.hpp +15 -4
- data/{Gosu → include/Gosu}/Version.hpp +3 -3
- data/{Gosu → include/Gosu}/Window.hpp +46 -34
- data/lib/OpenAL32.dll +0 -0
- data/lib/SDL2.dll +0 -0
- data/lib/gosu.rb +0 -3
- data/lib/gosu/patches.rb +0 -23
- data/lib/gosu/preview.rb +1 -3
- data/lib/gosu/swig_patches.rb +14 -12
- data/lib64/OpenAL32.dll +0 -0
- data/lib64/SDL2.dll +0 -0
- data/rdoc/gosu.rb +112 -23
- data/src/Audio.cpp +50 -224
- data/src/AudioFile.hpp +20 -37
- data/src/AudioFileAudioToolbox.cpp +237 -0
- data/src/AudioFileSDLSound.cpp +147 -0
- data/src/AudioImpl.cpp +3 -12
- data/src/AudioImpl.hpp +3 -1
- data/src/Bitmap.cpp +85 -83
- data/src/BitmapIO.cpp +52 -58
- data/src/Font.cpp +3 -1
- data/src/Graphics.cpp +7 -4
- data/src/Image.cpp +13 -16
- data/src/Input.cpp +412 -164
- data/src/LargeImageData.cpp +1 -1
- data/src/MarkupParser.cpp +2 -1
- data/src/Resolution.cpp +8 -8
- data/src/RubyGosu.cxx +1017 -196
- data/src/RubyGosu.h +4 -2
- data/src/TexChunk.cpp +1 -1
- data/src/TextBuilder.cpp +3 -1
- data/src/Texture.cpp +1 -1
- data/src/TrueTypeFont.cpp +1 -1
- data/src/TrueTypeFontWin.cpp +3 -3
- data/src/Utility.cpp +11 -7
- data/src/Window.cpp +90 -62
- data/src/WindowUIKit.cpp +21 -9
- metadata +194 -65
- data/Gosu/AutoLink.hpp +0 -14
- data/Gosu/Bitmap.hpp +0 -113
- data/Gosu/Channel.h +0 -25
- data/Gosu/Color.h +0 -38
- data/Gosu/Font.h +0 -36
- data/Gosu/Gosu.h +0 -79
- data/Gosu/Image.h +0 -54
- data/Gosu/Sample.h +0 -19
- data/Gosu/Song.h +0 -24
- data/Gosu/TextInput.h +0 -30
- data/Gosu/Window.h +0 -61
- data/lib/gosu/zen.rb +0 -89
- data/src/AudioToolboxFile.hpp +0 -210
- data/src/ChannelWrapper.cpp +0 -50
- data/src/ColorWrapper.cpp +0 -126
- data/src/Constants.cpp +0 -287
- data/src/FontWrapper.cpp +0 -74
- data/src/GosuWrapper.cpp +0 -232
- data/src/ImageWrapper.cpp +0 -168
- data/src/MPEGFile.hpp +0 -90
- data/src/OggFile.hpp +0 -92
- data/src/SampleWrapper.cpp +0 -30
- data/src/SndFile.hpp +0 -174
- data/src/SongWrapper.cpp +0 -52
- data/src/TextInputWrapper.cpp +0 -101
- data/src/WinMain.cpp +0 -64
- data/src/WindowWrapper.cpp +0 -289
data/src/AudioImpl.cpp
CHANGED
@@ -23,6 +23,9 @@ void Gosu::al_initialize()
|
|
23
23
|
_context = alcCreateContext(_device, nullptr);
|
24
24
|
alcMakeContextCurrent(_context);
|
25
25
|
alGenSources(CHANNELS, _sources);
|
26
|
+
|
27
|
+
// Don't worry about ever closing the OpenAL device; it's hard to know when to clean up within
|
28
|
+
// the scope of a Ruby C extension. Let the operating system clean up after us.
|
26
29
|
}
|
27
30
|
|
28
31
|
bool Gosu::al_initialized()
|
@@ -30,18 +33,6 @@ bool Gosu::al_initialized()
|
|
30
33
|
return _device != nullptr;
|
31
34
|
}
|
32
35
|
|
33
|
-
void Gosu::al_shutdown()
|
34
|
-
{
|
35
|
-
if (_device == nullptr) return;
|
36
|
-
|
37
|
-
alDeleteSources(CHANNELS, _sources);
|
38
|
-
alcMakeContextCurrent(nullptr);
|
39
|
-
alcDestroyContext(_context);
|
40
|
-
_context = nullptr;
|
41
|
-
alcCloseDevice(_device);
|
42
|
-
_device = nullptr;
|
43
|
-
}
|
44
|
-
|
45
36
|
ALCdevice* Gosu::al_device()
|
46
37
|
{
|
47
38
|
al_initialize();
|
data/src/AudioImpl.hpp
CHANGED
@@ -3,6 +3,9 @@
|
|
3
3
|
#include <Gosu/Audio.hpp>
|
4
4
|
#include <Gosu/Platform.hpp>
|
5
5
|
#ifdef GOSU_IS_MAC
|
6
|
+
// Ignore OpenAL deprecation warnings. If macOS stops shipping OpenAL, it's more likely that we bundle our own version
|
7
|
+
// of it than that we switch to another audio API.
|
8
|
+
#define OPENAL_DEPRECATED
|
6
9
|
#include <OpenAL/al.h>
|
7
10
|
#include <OpenAL/alc.h>
|
8
11
|
#else
|
@@ -14,7 +17,6 @@ namespace Gosu
|
|
14
17
|
{
|
15
18
|
void al_initialize();
|
16
19
|
bool al_initialized();
|
17
|
-
void al_shutdown();
|
18
20
|
|
19
21
|
// Will initialize OpenAL if necessary.
|
20
22
|
ALCdevice* al_device();
|
data/src/Bitmap.cpp
CHANGED
@@ -1,57 +1,66 @@
|
|
1
1
|
#include <Gosu/Bitmap.hpp>
|
2
|
-
#include <
|
3
|
-
#include <
|
4
|
-
#include <
|
5
|
-
|
2
|
+
#include <Gosu/GraphicsBase.hpp>
|
3
|
+
#include <stdexcept> // for std::invalid_argument
|
4
|
+
#include <utility> // for std::swap
|
5
|
+
|
6
|
+
Gosu::Bitmap::Bitmap(int width, int height, Gosu::Color c)
|
7
|
+
{
|
8
|
+
resize(width, height, c);
|
9
|
+
}
|
6
10
|
|
7
11
|
void Gosu::Bitmap::swap(Bitmap& other)
|
8
12
|
{
|
9
|
-
std::swap(
|
10
|
-
std::swap(
|
11
|
-
std::swap(
|
13
|
+
std::swap(m_pixels, other.m_pixels);
|
14
|
+
std::swap(m_width, other.m_width);
|
15
|
+
std::swap(m_height, other.m_height);
|
12
16
|
}
|
13
17
|
|
14
|
-
void Gosu::Bitmap::resize(
|
18
|
+
void Gosu::Bitmap::resize(int width, int height, Color c)
|
15
19
|
{
|
16
|
-
if (width
|
20
|
+
if (width < 0 || height < 0) throw std::invalid_argument{"negative bitmap size"};
|
17
21
|
|
18
|
-
|
19
|
-
|
22
|
+
if (width == m_width && height == m_height) return;
|
23
|
+
|
24
|
+
Bitmap temp;
|
25
|
+
temp.m_width = width;
|
26
|
+
temp.m_height = height;
|
27
|
+
temp.m_pixels.resize(width * height, c);
|
28
|
+
temp.insert(0, 0, *this);
|
20
29
|
swap(temp);
|
21
30
|
}
|
22
31
|
|
23
|
-
void Gosu::Bitmap::blend_pixel(
|
32
|
+
void Gosu::Bitmap::blend_pixel(int x, int y, Color c)
|
24
33
|
{
|
25
34
|
if (c.alpha() == 0) return;
|
26
|
-
|
35
|
+
|
27
36
|
Color out = get_pixel(x, y);
|
28
37
|
if (out.alpha() == 0) {
|
29
38
|
set_pixel(x, y, c);
|
30
39
|
return;
|
31
40
|
}
|
32
|
-
|
41
|
+
|
33
42
|
int inv_alpha = out.alpha() * (255 - c.alpha()) / 255;
|
34
|
-
|
43
|
+
|
35
44
|
out.set_alpha(c.alpha() + inv_alpha);
|
36
45
|
out.set_red ((c.red() * c.alpha() + out.red() * inv_alpha) / out.alpha());
|
37
46
|
out.set_green((c.green() * c.alpha() + out.green() * inv_alpha) / out.alpha());
|
38
47
|
out.set_blue ((c.blue() * c.alpha() + out.blue() * inv_alpha) / out.alpha());
|
39
|
-
|
48
|
+
|
40
49
|
set_pixel(x, y, out);
|
41
50
|
}
|
42
51
|
|
43
|
-
void Gosu::Bitmap::insert(
|
52
|
+
void Gosu::Bitmap::insert(int x, int y, const Bitmap& source)
|
44
53
|
{
|
45
|
-
insert(
|
54
|
+
insert(x, y, source, 0, 0, source.width(), source.height());
|
46
55
|
}
|
47
56
|
|
48
|
-
void Gosu::Bitmap::insert(
|
49
|
-
|
57
|
+
void Gosu::Bitmap::insert(int x, int y, const Bitmap& source,
|
58
|
+
int src_x, int src_y, int src_width, int src_height)
|
50
59
|
{
|
51
60
|
// TODO: This should use memcpy if possible (x == 0 && src_width == this->width())
|
52
61
|
|
53
62
|
if (x < 0) {
|
54
|
-
|
63
|
+
int clip_left = -x;
|
55
64
|
|
56
65
|
if (clip_left >= src_width) return;
|
57
66
|
|
@@ -61,7 +70,7 @@ void Gosu::Bitmap::insert(const Bitmap& source, int x, int y, unsigned src_x, un
|
|
61
70
|
}
|
62
71
|
|
63
72
|
if (y < 0) {
|
64
|
-
|
73
|
+
int clip_top = -y;
|
65
74
|
|
66
75
|
if (clip_top >= src_height) return;
|
67
76
|
|
@@ -70,20 +79,20 @@ void Gosu::Bitmap::insert(const Bitmap& source, int x, int y, unsigned src_x, un
|
|
70
79
|
y = 0;
|
71
80
|
}
|
72
81
|
|
73
|
-
if (x + src_width >
|
74
|
-
if (
|
82
|
+
if (x + src_width > m_width) {
|
83
|
+
if (x >= m_width) return;
|
75
84
|
|
76
|
-
src_width =
|
85
|
+
src_width = m_width - x;
|
77
86
|
}
|
78
87
|
|
79
|
-
if (y + src_height >
|
80
|
-
if (
|
88
|
+
if (y + src_height > m_height) {
|
89
|
+
if (y >= m_height) return;
|
81
90
|
|
82
|
-
src_height =
|
91
|
+
src_height = m_height - y;
|
83
92
|
}
|
84
93
|
|
85
|
-
for (
|
86
|
-
for (
|
94
|
+
for (int rel_y = 0; rel_y < src_height; ++rel_y) {
|
95
|
+
for (int rel_x = 0; rel_x < src_width; ++rel_x) {
|
87
96
|
set_pixel(x + rel_x, y + rel_y, source.get_pixel(src_x + rel_x, src_y + rel_y));
|
88
97
|
}
|
89
98
|
}
|
@@ -91,85 +100,76 @@ void Gosu::Bitmap::insert(const Bitmap& source, int x, int y, unsigned src_x, un
|
|
91
100
|
|
92
101
|
void Gosu::apply_color_key(Bitmap& bitmap, Color key)
|
93
102
|
{
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
for (unsigned y = 0; y < bitmap.height(); ++y) {
|
98
|
-
for (unsigned x = 0; x < bitmap.width(); ++x) {
|
103
|
+
for (int y = 0; y < bitmap.height(); ++y) {
|
104
|
+
for (int x = 0; x < bitmap.width(); ++x) {
|
99
105
|
if (bitmap.get_pixel(x, y) == key) {
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
// Calculate the average R/G/B of adjacent, non-transparent pixels.
|
107
|
+
unsigned neighbors = 0, red = 0, green = 0, blue = 0;
|
108
|
+
auto visit = [&](Color c) {
|
109
|
+
if (c != key) {
|
110
|
+
neighbors += 1;
|
111
|
+
red += c.red();
|
112
|
+
green += c.green();
|
113
|
+
blue += c.blue();
|
114
|
+
}
|
115
|
+
};
|
116
|
+
|
117
|
+
if (x > 0) visit(bitmap.get_pixel(x - 1, y));
|
118
|
+
if (x < bitmap.width() - 1) visit(bitmap.get_pixel(x + 1, y));
|
119
|
+
if (y > 0) visit(bitmap.get_pixel(x, y - 1));
|
120
|
+
if (y < bitmap.height() - 1) visit(bitmap.get_pixel(x, y + 1));
|
121
|
+
|
122
|
+
Color replacement = Color::NONE;
|
123
|
+
if (neighbors > 0) {
|
124
|
+
replacement.set_red(red / neighbors);
|
125
|
+
replacement.set_green(green / neighbors);
|
126
|
+
replacement.set_blue(blue / neighbors);
|
109
127
|
}
|
110
|
-
|
111
|
-
surrounding_colors.push_back(bitmap.get_pixel(x, y + 1));
|
112
|
-
}
|
113
|
-
|
114
|
-
if (surrounding_colors.empty()) {
|
115
|
-
bitmap.set_pixel(x, y, Color::NONE);
|
116
|
-
continue;
|
117
|
-
}
|
118
|
-
|
119
|
-
unsigned red = 0, green = 0, blue = 0;
|
120
|
-
for (auto& color : surrounding_colors) {
|
121
|
-
red += color.red();
|
122
|
-
green += color.green();
|
123
|
-
blue += color.blue();
|
124
|
-
}
|
125
|
-
bitmap.set_pixel(x, y, Color(0,
|
126
|
-
red / surrounding_colors.size(),
|
127
|
-
green / surrounding_colors.size(),
|
128
|
-
blue / surrounding_colors.size()));
|
128
|
+
bitmap.set_pixel(x, y, replacement);
|
129
129
|
}
|
130
130
|
}
|
131
131
|
}
|
132
132
|
}
|
133
133
|
|
134
|
-
|
134
|
+
Gosu::Bitmap Gosu::apply_border_flags(unsigned image_flags, const Bitmap& source,
|
135
|
+
int src_x, int src_y, int src_width, int src_height)
|
135
136
|
{
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
}
|
145
|
-
}
|
137
|
+
// By default, we add one pixel of transparent data around the whole image to so that during
|
138
|
+
// interpolation, the image just fades out, instead of bleeding into adjacent image data on
|
139
|
+
// whatever shared texture atlas it ends up on.
|
140
|
+
// However, if a border is marked as "tileable", we instead repeat the outermost pixels, which
|
141
|
+
// leads to a nice sharp/hard border with no interpolation at all.
|
142
|
+
|
143
|
+
// TODO: Instead of using Color::NONE (transparent black) for non-tileable image, still repeat
|
144
|
+
// the border pixel colors, but turn them fully transparent.
|
146
145
|
|
147
|
-
void Gosu::apply_border_flags(Bitmap& dest, const Bitmap& source, unsigned src_x, unsigned src_y,
|
148
|
-
unsigned src_width, unsigned src_height, unsigned image_flags)
|
149
|
-
{
|
150
146
|
// Backward compatibility: This used to be 'bool tileable'.
|
151
147
|
if (image_flags == 1) image_flags = IF_TILEABLE;
|
152
148
|
|
153
|
-
dest
|
149
|
+
Gosu::Bitmap dest{src_width + 2, src_height + 2};
|
154
150
|
|
155
151
|
// The borders are made "harder" by duplicating the original bitmap's
|
156
152
|
// borders.
|
157
153
|
|
158
154
|
// Top.
|
159
155
|
if (image_flags & IF_TILEABLE_TOP) {
|
160
|
-
dest.insert(
|
156
|
+
dest.insert(1, 0,
|
157
|
+
source, src_x, src_y, src_width, 1);
|
161
158
|
}
|
162
159
|
// Bottom.
|
163
160
|
if (image_flags & IF_TILEABLE_BOTTOM) {
|
164
|
-
dest.insert(
|
161
|
+
dest.insert(1, dest.height() - 1,
|
162
|
+
source, src_x, src_y + src_height - 1, src_width, 1);
|
165
163
|
}
|
166
164
|
// Left.
|
167
165
|
if (image_flags & IF_TILEABLE_LEFT) {
|
168
|
-
dest.insert(
|
166
|
+
dest.insert(0, 1,
|
167
|
+
source, src_x, src_y, 1, src_height);
|
169
168
|
}
|
170
169
|
// Right.
|
171
170
|
if (image_flags & IF_TILEABLE_RIGHT) {
|
172
|
-
dest.insert(
|
171
|
+
dest.insert(dest.width() - 1, 1,
|
172
|
+
source, src_x + src_width - 1, src_y, 1, src_height);
|
173
173
|
}
|
174
174
|
|
175
175
|
// Top left.
|
@@ -194,5 +194,7 @@ void Gosu::apply_border_flags(Bitmap& dest, const Bitmap& source, unsigned src_x
|
|
194
194
|
}
|
195
195
|
|
196
196
|
// Now put the final image into the prepared borders.
|
197
|
-
dest.insert(
|
197
|
+
dest.insert(1, 1,
|
198
|
+
source, src_x, src_y, src_width, src_height);
|
199
|
+
return dest;
|
198
200
|
}
|
data/src/BitmapIO.cpp
CHANGED
@@ -1,9 +1,7 @@
|
|
1
1
|
#include <Gosu/Bitmap.hpp>
|
2
|
-
#include <Gosu/IO.hpp>
|
3
|
-
#include <Gosu/Platform.hpp>
|
4
2
|
#include <Gosu/Utility.hpp>
|
5
|
-
#include <cstring>
|
6
|
-
#include <stdexcept>
|
3
|
+
#include <cstring> // for std::memcpy, std::size_t
|
4
|
+
#include <stdexcept> // for std::runtime_error
|
7
5
|
|
8
6
|
#define STB_IMAGE_IMPLEMENTATION
|
9
7
|
#define STBI_NO_STDIO
|
@@ -15,79 +13,73 @@
|
|
15
13
|
#pragma GCC diagnostic ignored "-Wcomma"
|
16
14
|
#endif
|
17
15
|
|
18
|
-
#include
|
16
|
+
#include <stb_image.h>
|
19
17
|
|
20
18
|
#ifdef __GNUC__
|
21
19
|
#pragma GCC diagnostic pop
|
22
20
|
#endif
|
23
21
|
|
24
|
-
|
25
|
-
|
26
|
-
namespace
|
22
|
+
static int read_callback(void* user, char* data, int size)
|
27
23
|
{
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
return static_cast<int>(actual_size);
|
35
|
-
}
|
24
|
+
Gosu::Reader* reader = static_cast<Gosu::Reader*>(user);
|
25
|
+
std::size_t remaining = reader->resource().size() - reader->position();
|
26
|
+
std::size_t adjusted_size = (size < remaining ? size : remaining);
|
27
|
+
reader->read(data, adjusted_size);
|
28
|
+
return static_cast<int>(adjusted_size);
|
29
|
+
}
|
36
30
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
31
|
+
static void skip_callback(void* user, int n)
|
32
|
+
{
|
33
|
+
Gosu::Reader* reader = static_cast<Gosu::Reader*>(user);
|
34
|
+
reader->set_position(reader->position() + n);
|
35
|
+
}
|
42
36
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
37
|
+
static int eof_callback(void* user)
|
38
|
+
{
|
39
|
+
Gosu::Reader* reader = static_cast<Gosu::Reader*>(user);
|
40
|
+
return reader->position() == reader->resource().size();
|
41
|
+
}
|
48
42
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
}
|
43
|
+
static bool is_bmp(Gosu::Reader reader)
|
44
|
+
{
|
45
|
+
std::size_t remaining = reader.resource().size() - reader.position();
|
46
|
+
if (remaining < 2) return false;
|
47
|
+
char magic_bytes[2];
|
48
|
+
reader.read(&magic_bytes, sizeof magic_bytes);
|
49
|
+
return magic_bytes[0] == 'B' && magic_bytes[1] == 'M';
|
57
50
|
}
|
58
51
|
|
59
|
-
|
52
|
+
Gosu::Bitmap Gosu::load_image_file(const std::string& filename)
|
60
53
|
{
|
61
54
|
Buffer buffer;
|
62
55
|
load_file(buffer, filename);
|
63
|
-
load_image_file(
|
56
|
+
return load_image_file(buffer.front_reader());
|
64
57
|
}
|
65
58
|
|
66
|
-
|
59
|
+
Gosu::Bitmap Gosu::load_image_file(Reader input)
|
67
60
|
{
|
68
61
|
bool needs_color_key = is_bmp(input);
|
69
|
-
|
70
|
-
stbi_io_callbacks callbacks;
|
62
|
+
|
63
|
+
stbi_io_callbacks callbacks{};
|
71
64
|
callbacks.read = read_callback;
|
72
65
|
callbacks.skip = skip_callback;
|
73
66
|
callbacks.eof = eof_callback;
|
74
|
-
int x, y, n;
|
75
|
-
stbi_uc* bytes = stbi_load_from_callbacks(&callbacks, &input, &x, &y, &n, STBI_rgb_alpha);
|
67
|
+
int x = 0, y = 0, n = 0;
|
76
68
|
|
69
|
+
stbi_uc* bytes = stbi_load_from_callbacks(&callbacks, &input, &x, &y, &n, STBI_rgb_alpha);
|
77
70
|
if (bytes == nullptr) {
|
78
|
-
|
79
|
-
// mutex.
|
80
|
-
throw runtime_error("Cannot load image: " + string(stbi_failure_reason()));
|
71
|
+
throw std::runtime_error{"Cannot load image: " + std::string(stbi_failure_reason())};
|
81
72
|
}
|
82
73
|
|
83
|
-
bitmap
|
84
|
-
memcpy(bitmap.data(), bytes, x * y * sizeof(Gosu::Color));
|
74
|
+
Gosu::Bitmap bitmap{x, y};
|
75
|
+
std::memcpy(bitmap.data(), bytes, x * y * sizeof(Gosu::Color));
|
85
76
|
|
86
77
|
stbi_image_free(bytes);
|
87
|
-
|
78
|
+
|
88
79
|
if (needs_color_key) {
|
89
80
|
apply_color_key(bitmap, Gosu::Color::FUCHSIA);
|
90
81
|
}
|
82
|
+
return bitmap;
|
91
83
|
}
|
92
84
|
|
93
85
|
// Disable comma warnings in stb headers.
|
@@ -97,16 +89,16 @@ void Gosu::load_image_file(Gosu::Bitmap& bitmap, Reader input)
|
|
97
89
|
#endif
|
98
90
|
|
99
91
|
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
100
|
-
#include
|
92
|
+
#include <stb_image_write.h>
|
101
93
|
|
102
94
|
#ifdef __GNUC__
|
103
95
|
#pragma GCC diagnostic pop
|
104
96
|
#endif
|
105
97
|
|
106
|
-
void Gosu::save_image_file(const Gosu::Bitmap& bitmap, const string& filename)
|
98
|
+
void Gosu::save_image_file(const Gosu::Bitmap& bitmap, const std::string& filename)
|
107
99
|
{
|
108
100
|
int ok;
|
109
|
-
|
101
|
+
|
110
102
|
if (has_extension(filename, "bmp")) {
|
111
103
|
ok = stbi_write_bmp(filename.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data());
|
112
104
|
}
|
@@ -116,20 +108,22 @@ void Gosu::save_image_file(const Gosu::Bitmap& bitmap, const string& filename)
|
|
116
108
|
else {
|
117
109
|
ok = stbi_write_png(filename.c_str(), bitmap.width(), bitmap.height(), 4, bitmap.data(), 0);
|
118
110
|
}
|
119
|
-
|
120
|
-
if (ok == 0)
|
111
|
+
|
112
|
+
if (ok == 0) {
|
113
|
+
throw std::runtime_error("Could not save image data to file: " + filename);
|
114
|
+
}
|
121
115
|
}
|
122
116
|
|
123
117
|
static void stbi_write_to_writer(void* context, void* data, int size)
|
124
118
|
{
|
125
|
-
|
119
|
+
static_cast<Gosu::Writer*>(context)->write(data, size);
|
126
120
|
}
|
127
121
|
|
128
122
|
void Gosu::save_image_file(const Gosu::Bitmap& bitmap, Gosu::Writer writer,
|
129
|
-
const
|
123
|
+
const std::string_view& format_hint)
|
130
124
|
{
|
131
125
|
int ok;
|
132
|
-
|
126
|
+
|
133
127
|
if (has_extension(format_hint, "bmp")) {
|
134
128
|
ok = stbi_write_bmp_to_func(stbi_write_to_writer, &writer, bitmap.width(), bitmap.height(),
|
135
129
|
4, bitmap.data());
|
@@ -143,9 +137,9 @@ void Gosu::save_image_file(const Gosu::Bitmap& bitmap, Gosu::Writer writer,
|
|
143
137
|
ok = stbi_write_png_to_func(stbi_write_to_writer, &writer, bitmap.width(), bitmap.height(),
|
144
138
|
4, bitmap.data(), 0);
|
145
139
|
}
|
146
|
-
|
140
|
+
|
147
141
|
if (ok == 0) {
|
148
|
-
throw runtime_error("Could not save image data to memory (format hint = '" +
|
149
|
-
|
142
|
+
throw std::runtime_error("Could not save image data to memory (format hint = '" +
|
143
|
+
std::string{format_hint} + "'");
|
150
144
|
}
|
151
145
|
}
|