gosu 1.3.0 → 1.4.0
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 +108 -14
- data/dependencies/SDL/include/SDL_assert.h +81 -50
- data/dependencies/SDL/include/SDL_atomic.h +135 -35
- data/dependencies/SDL/include/SDL_audio.h +960 -355
- data/dependencies/SDL/include/SDL_bits.h +11 -6
- data/dependencies/SDL/include/SDL_blendmode.h +91 -14
- data/dependencies/SDL/include/SDL_clipboard.h +30 -7
- data/dependencies/SDL/include/SDL_config.h +277 -27
- data/dependencies/SDL/include/SDL_config_android.h +13 -38
- data/dependencies/SDL/include/SDL_config_iphoneos.h +21 -62
- data/dependencies/SDL/include/SDL_config_macosx.h +23 -92
- data/dependencies/SDL/include/SDL_config_minimal.h +1 -4
- data/dependencies/SDL/include/SDL_config_pandora.h +15 -22
- data/dependencies/SDL/include/SDL_config_psp.h +16 -37
- data/dependencies/SDL/include/SDL_config_windows.h +28 -91
- data/dependencies/SDL/include/SDL_config_winrt.h +33 -61
- data/dependencies/SDL/include/SDL_config_wiz.h +28 -56
- data/dependencies/SDL/include/SDL_copying.h +1 -1
- data/dependencies/SDL/include/SDL_cpuinfo.h +331 -71
- data/dependencies/SDL/include/SDL_egl.h +906 -280
- data/dependencies/SDL/include/SDL_endian.h +101 -47
- data/dependencies/SDL/include/SDL_error.h +70 -19
- data/dependencies/SDL/include/SDL_events.h +387 -79
- data/dependencies/SDL/include/SDL_filesystem.h +73 -64
- data/dependencies/SDL/include/SDL_gamecontroller.h +585 -125
- data/dependencies/SDL/include/SDL_gesture.h +36 -6
- data/dependencies/SDL/include/SDL_haptic.h +304 -210
- data/dependencies/SDL/include/SDL_hidapi.h +451 -0
- data/dependencies/SDL/include/SDL_hints.h +1286 -897
- data/dependencies/SDL/include/SDL_joystick.h +577 -130
- data/dependencies/SDL/include/SDL_keyboard.h +162 -63
- data/dependencies/SDL/include/SDL_keycode.h +7 -5
- data/dependencies/SDL/include/SDL_loadso.h +42 -8
- data/dependencies/SDL/include/SDL_locale.h +34 -32
- data/dependencies/SDL/include/SDL_log.h +212 -19
- data/dependencies/SDL/include/SDL_main.h +72 -17
- data/dependencies/SDL/include/SDL_messagebox.h +70 -23
- data/dependencies/SDL/include/SDL_metal.h +27 -32
- data/dependencies/SDL/include/SDL_misc.h +19 -15
- data/dependencies/SDL/include/SDL_mouse.h +262 -110
- data/dependencies/SDL/include/SDL_mutex.h +286 -66
- data/dependencies/SDL/include/SDL_name.h +1 -1
- data/dependencies/SDL/include/SDL_opengl.h +1 -1
- data/dependencies/SDL/include/SDL_opengles.h +1 -1
- data/dependencies/SDL/include/SDL_opengles2.h +2 -2
- data/dependencies/SDL/include/SDL_pixels.h +199 -34
- data/dependencies/SDL/include/SDL_platform.h +39 -2
- data/dependencies/SDL/include/SDL_power.h +23 -10
- data/dependencies/SDL/include/SDL_quit.h +1 -1
- data/dependencies/SDL/include/SDL_rect.h +78 -28
- data/dependencies/SDL/include/SDL_render.h +1204 -472
- data/dependencies/SDL/include/SDL_revision.h +2 -2
- data/dependencies/SDL/include/SDL_rwops.h +605 -33
- data/dependencies/SDL/include/SDL_scancode.h +1 -1
- data/dependencies/SDL/include/SDL_sensor.h +76 -42
- data/dependencies/SDL/include/SDL_shape.h +38 -27
- data/dependencies/SDL/include/SDL_stdinc.h +96 -24
- data/dependencies/SDL/include/SDL_surface.h +571 -139
- data/dependencies/SDL/include/SDL_system.h +339 -101
- data/dependencies/SDL/include/SDL_syswm.h +50 -20
- data/dependencies/SDL/include/SDL_test.h +1 -1
- data/dependencies/SDL/include/SDL_test_assert.h +2 -2
- data/dependencies/SDL/include/SDL_test_common.h +23 -6
- data/dependencies/SDL/include/SDL_test_compare.h +1 -1
- data/dependencies/SDL/include/SDL_test_crc32.h +1 -1
- data/dependencies/SDL/include/SDL_test_font.h +3 -3
- data/dependencies/SDL/include/SDL_test_fuzzer.h +28 -26
- data/dependencies/SDL/include/SDL_test_harness.h +6 -6
- data/dependencies/SDL/include/SDL_test_images.h +1 -1
- data/dependencies/SDL/include/SDL_test_log.h +1 -1
- data/dependencies/SDL/include/SDL_test_md5.h +1 -1
- data/dependencies/SDL/include/SDL_test_memory.h +1 -1
- data/dependencies/SDL/include/SDL_test_random.h +2 -2
- data/dependencies/SDL/include/SDL_thread.h +226 -128
- data/dependencies/SDL/include/SDL_timer.h +129 -22
- data/dependencies/SDL/include/SDL_touch.h +48 -8
- data/dependencies/SDL/include/SDL_types.h +1 -1
- data/dependencies/SDL/include/SDL_version.h +72 -46
- data/dependencies/SDL/include/SDL_video.h +1266 -460
- data/dependencies/SDL/include/SDL_vulkan.h +100 -161
- data/dependencies/SDL/include/begin_code.h +22 -1
- data/dependencies/SDL/include/close_code.h +1 -1
- 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 +83 -7
- data/dependencies/SDL_sound/SDL_sound.h +4 -4
- data/dependencies/SDL_sound/SDL_sound_aiff.c +9 -12
- data/dependencies/SDL_sound/SDL_sound_au.c +7 -7
- data/dependencies/SDL_sound/SDL_sound_coreaudio.c +3 -3
- data/dependencies/SDL_sound/SDL_sound_flac.c +1 -1
- data/dependencies/SDL_sound/SDL_sound_internal.h +17 -10
- data/dependencies/SDL_sound/SDL_sound_modplug.c +25 -27
- data/dependencies/SDL_sound/SDL_sound_mp3.c +5 -17
- data/dependencies/SDL_sound/SDL_sound_raw.c +11 -11
- data/dependencies/SDL_sound/SDL_sound_shn.c +8 -7
- data/dependencies/SDL_sound/SDL_sound_voc.c +6 -4
- data/dependencies/SDL_sound/SDL_sound_vorbis.c +6 -11
- data/dependencies/SDL_sound/SDL_sound_wav.c +35 -29
- data/dependencies/SDL_sound/dr_flac.h +618 -220
- data/dependencies/SDL_sound/dr_mp3.h +263 -94
- data/dependencies/SDL_sound/libmodplug/fastmix.c +58 -64
- data/dependencies/SDL_sound/libmodplug/libmodplug.h +25 -103
- data/dependencies/SDL_sound/libmodplug/load_669.c +14 -17
- data/dependencies/SDL_sound/libmodplug/load_amf.c +11 -7
- data/dependencies/SDL_sound/libmodplug/load_ams.c +65 -22
- data/dependencies/SDL_sound/libmodplug/load_dbm.c +8 -4
- data/dependencies/SDL_sound/libmodplug/load_dmf.c +55 -25
- data/dependencies/SDL_sound/libmodplug/load_far.c +9 -13
- data/dependencies/SDL_sound/libmodplug/load_gdm.c +448 -0
- data/dependencies/SDL_sound/libmodplug/load_it.c +45 -49
- data/dependencies/SDL_sound/libmodplug/load_mdl.c +80 -53
- data/dependencies/SDL_sound/libmodplug/load_med.c +20 -12
- data/dependencies/SDL_sound/libmodplug/load_mod.c +40 -15
- data/dependencies/SDL_sound/libmodplug/load_mt2.c +29 -17
- data/dependencies/SDL_sound/libmodplug/load_okt.c +12 -8
- data/dependencies/SDL_sound/libmodplug/load_psm.c +101 -78
- data/dependencies/SDL_sound/libmodplug/load_ptm.c +18 -17
- data/dependencies/SDL_sound/libmodplug/load_s3m.c +9 -7
- data/dependencies/SDL_sound/libmodplug/load_stm.c +3 -2
- data/dependencies/SDL_sound/libmodplug/load_ult.c +2 -2
- data/dependencies/SDL_sound/libmodplug/load_umx.c +315 -35
- data/dependencies/SDL_sound/libmodplug/load_xm.c +25 -21
- data/dependencies/SDL_sound/libmodplug/mmcmp.c +295 -149
- data/dependencies/SDL_sound/libmodplug/modplug.c +7 -123
- data/dependencies/SDL_sound/libmodplug/modplug.h +32 -29
- data/dependencies/SDL_sound/libmodplug/snd_dsp.c +0 -1
- data/dependencies/SDL_sound/libmodplug/snd_flt.c +2 -2
- data/dependencies/SDL_sound/libmodplug/snd_fx.c +24 -18
- data/dependencies/SDL_sound/libmodplug/sndfile.c +55 -156
- data/dependencies/SDL_sound/libmodplug/sndmix.c +7 -12
- data/dependencies/SDL_sound/libmodplug/tables.h +10 -15
- data/dependencies/SDL_sound/stb_vorbis.h +508 -325
- data/dependencies/{al_soft → mojoAL}/AL/al.h +38 -30
- data/dependencies/{al_soft → mojoAL}/AL/alc.h +27 -56
- data/dependencies/mojoAL/mojoal.c +4594 -0
- data/ext/gosu/extconf.rb +29 -30
- data/include/Gosu/Audio.hpp +70 -85
- data/include/Gosu/Color.hpp +19 -11
- data/include/Gosu/Font.hpp +40 -44
- data/include/Gosu/Graphics.hpp +58 -71
- data/include/Gosu/GraphicsBase.hpp +26 -33
- data/include/Gosu/Image.hpp +56 -62
- data/include/Gosu/ImageData.hpp +23 -27
- data/include/Gosu/Inspection.hpp +1 -4
- data/include/Gosu/TextInput.hpp +34 -40
- data/include/Gosu/Version.hpp +1 -1
- data/include/Gosu/Window.hpp +71 -70
- data/lib/SDL2.dll +0 -0
- data/lib/gosu/compat.rb +24 -37
- data/lib/gosu.rb +2 -2
- data/lib64/SDL2.dll +0 -0
- data/src/Audio.cpp +86 -86
- data/src/AudioFile.hpp +6 -6
- data/src/AudioFileAudioToolbox.cpp +1 -1
- data/src/AudioFileSDLSound.cpp +1 -1
- data/src/AudioImpl.hpp +5 -5
- data/src/BitmapIO.cpp +0 -20
- data/src/BlockAllocator.cpp +2 -1
- data/src/Channel.cpp +22 -20
- data/src/Color.cpp +12 -9
- data/src/EmptyImageData.hpp +15 -17
- data/src/FileUnix.cpp +1 -1
- data/src/FileWin.cpp +1 -1
- data/src/Font.cpp +48 -53
- data/src/Graphics.cpp +135 -143
- data/src/Image.cpp +41 -42
- data/src/Input.cpp +1 -1
- data/src/InputUIKit.cpp +1 -1
- data/src/LargeImageData.cpp +108 -101
- data/src/LargeImageData.hpp +17 -15
- data/src/Log.hpp +6 -6
- data/src/Macro.cpp +35 -37
- data/src/Macro.hpp +11 -11
- data/src/Math.cpp +8 -1
- data/src/Resolution.cpp +12 -7
- data/src/RubyGosu.cxx +5 -5
- data/src/TexChunk.cpp +50 -41
- data/src/TexChunk.hpp +22 -22
- data/src/Text.cpp +37 -37
- data/src/TextBuilder.cpp +60 -57
- data/src/TextBuilder.hpp +20 -20
- data/src/TextInput.cpp +127 -135
- data/src/TrueTypeFont.cpp +107 -107
- data/src/TrueTypeFont.hpp +39 -38
- data/src/TrueTypeFontApple.cpp +19 -22
- data/src/TrueTypeFontUnix.cpp +21 -26
- data/src/TrueTypeFontWin.cpp +30 -30
- data/src/Window.cpp +95 -86
- data/src/WindowUIKit.cpp +46 -49
- metadata +7 -17
- data/dependencies/SDL/include/SDL_config_os2.h +0 -188
- data/dependencies/SDL_sound/libmodplug/load_abc.c +0 -4725
- data/dependencies/SDL_sound/libmodplug/load_mid.c +0 -1405
- data/dependencies/SDL_sound/libmodplug/load_pat.c +0 -1143
- data/dependencies/SDL_sound/libmodplug/load_pat.h +0 -25
- data/dependencies/al_soft/AL/alext.h +0 -585
- data/dependencies/al_soft/AL/efx-creative.h +0 -3
- data/dependencies/al_soft/AL/efx-presets.h +0 -402
- data/dependencies/al_soft/AL/efx.h +0 -762
- data/dependencies/al_soft/x64/libOpenAL32.dll.a +0 -0
- data/dependencies/al_soft/x86/libOpenAL32.dll.a +0 -0
- data/lib/OpenAL32.dll +0 -0
- data/lib64/OpenAL32.dll +0 -0
data/src/TrueTypeFontUnix.cpp
CHANGED
@@ -1,22 +1,18 @@
|
|
1
1
|
#include <Gosu/Platform.hpp>
|
2
2
|
#if defined(GOSU_IS_X)
|
3
3
|
|
4
|
-
#include "TrueTypeFont.hpp"
|
5
|
-
#include "Log.hpp"
|
6
|
-
|
7
4
|
#include <Gosu/IO.hpp>
|
8
5
|
#include <Gosu/Text.hpp>
|
9
6
|
#include <Gosu/Utility.hpp>
|
10
|
-
|
7
|
+
#include "Log.hpp"
|
8
|
+
#include "TrueTypeFont.hpp"
|
11
9
|
#include <fontconfig/fontconfig.h>
|
12
|
-
|
13
10
|
#include <map>
|
14
|
-
using namespace std;
|
15
11
|
|
16
|
-
const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned font_flags)
|
12
|
+
const unsigned char* Gosu::ttf_data_by_name(const std::string& font_name, unsigned font_flags)
|
17
13
|
{
|
18
14
|
// TODO: Make this cache thread-safe.
|
19
|
-
static map<pair<string, unsigned>, const unsigned char*> ttf_file_cache;
|
15
|
+
static std::map<std::pair<std::string, unsigned>, const unsigned char*> ttf_file_cache;
|
20
16
|
|
21
17
|
auto& ttf_ptr = ttf_file_cache[make_pair(font_name, font_flags)];
|
22
18
|
if (ttf_ptr) return ttf_ptr;
|
@@ -26,27 +22,27 @@ const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned fo
|
|
26
22
|
static FcConfig* config = FcInitLoadConfigAndFonts();
|
27
23
|
if (config) {
|
28
24
|
FcPattern* pattern;
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
25
|
+
// Our search pattern does not include weight or slant so that we can compromise on these.
|
26
|
+
pattern = FcPatternBuild(nullptr, FC_FAMILY, FcTypeString,
|
27
|
+
font_name.empty() ? "sans-serif" : font_name.c_str(), FC_OUTLINE,
|
28
|
+
FcTypeBool, FcTrue, // exclude bitmap fonts
|
29
|
+
nullptr);
|
34
30
|
|
35
31
|
FcObjectSet* props = FcObjectSetBuild(FC_FILE, FC_WEIGHT, FC_SLANT, nullptr);
|
36
32
|
|
37
33
|
if (FcFontSet* fonts = FcFontList(config, pattern, props)) {
|
38
34
|
log("Looking for the best candidate among %d matching fonts", (int) fonts->nfont);
|
39
|
-
|
35
|
+
|
40
36
|
// Among all matching fonts, find the variant that is the best fit for our font_flags.
|
41
|
-
string best_filename;
|
37
|
+
std::string best_filename;
|
42
38
|
int best_diff;
|
43
|
-
|
39
|
+
|
44
40
|
for (int i = 0; i < fonts->nfont; ++i) {
|
45
41
|
int weight, slant;
|
46
|
-
|
42
|
+
|
47
43
|
FcPatternGetInteger(fonts->fonts[i], FC_WEIGHT, 0, &weight);
|
48
44
|
FcPatternGetInteger(fonts->fonts[i], FC_SLANT, 0, &slant);
|
49
|
-
|
45
|
+
|
50
46
|
// Difference between found font weight/slant and desired weight/slant.
|
51
47
|
// Lower is better, so find the font with the lowest diff.
|
52
48
|
int diff = 0;
|
@@ -62,14 +58,14 @@ const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned fo
|
|
62
58
|
else {
|
63
59
|
diff += abs(slant - FC_SLANT_ROMAN);
|
64
60
|
}
|
65
|
-
|
61
|
+
|
66
62
|
// Penalize OTF fonts since we are not really good at handling these.
|
67
|
-
FcChar8
|
63
|
+
FcChar8* file;
|
68
64
|
FcPatternGetString(fonts->fonts[i], FC_FILE, 0, &file);
|
69
65
|
if (has_extension(reinterpret_cast<char*>(file), ".otf")) {
|
70
66
|
diff += 10000;
|
71
67
|
}
|
72
|
-
|
68
|
+
|
73
69
|
if (best_filename.empty() || diff < best_diff) {
|
74
70
|
best_filename = reinterpret_cast<char*>(file);
|
75
71
|
best_diff = diff;
|
@@ -79,10 +75,10 @@ const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned fo
|
|
79
75
|
log("Loading best candidate '%s'", best_filename.c_str());
|
80
76
|
ttf_ptr = ttf_data_from_file(best_filename.c_str());
|
81
77
|
}
|
82
|
-
|
78
|
+
|
83
79
|
FcFontSetDestroy(fonts);
|
84
80
|
}
|
85
|
-
|
81
|
+
|
86
82
|
FcObjectSetDestroy(props);
|
87
83
|
FcPatternDestroy(pattern);
|
88
84
|
}
|
@@ -126,7 +122,7 @@ const unsigned char* Gosu::ttf_fallback_data()
|
|
126
122
|
// Unifont has pretty good Unicode coverage, but looks extremely ugly.
|
127
123
|
static const unsigned char* unifont = ttf_data_by_name("Unifont", 0);
|
128
124
|
if (unifont) return unifont;
|
129
|
-
|
125
|
+
|
130
126
|
// If none of the fonts above work, try to use the default sans-serif font.
|
131
127
|
static const unsigned char* default_font = ttf_data_of_default_sans_serif_font();
|
132
128
|
if (default_font) return default_font;
|
@@ -135,7 +131,7 @@ const unsigned char* Gosu::ttf_fallback_data()
|
|
135
131
|
return ttf_data_from_file("/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf");
|
136
132
|
}
|
137
133
|
|
138
|
-
string Gosu::default_font_name()
|
134
|
+
std::string Gosu::default_font_name()
|
139
135
|
{
|
140
136
|
// Liberation Sans was designed to have the same metrics as Arial, which is the default
|
141
137
|
// font on macOS and Windows.
|
@@ -143,4 +139,3 @@ string Gosu::default_font_name()
|
|
143
139
|
}
|
144
140
|
|
145
141
|
#endif
|
146
|
-
|
data/src/TrueTypeFontWin.cpp
CHANGED
@@ -1,54 +1,54 @@
|
|
1
1
|
#include <Gosu/Platform.hpp>
|
2
2
|
#if defined(GOSU_IS_WIN)
|
3
3
|
|
4
|
-
#include "TrueTypeFont.hpp"
|
5
4
|
#include "Log.hpp"
|
5
|
+
#include "TrueTypeFont.hpp"
|
6
6
|
|
7
7
|
#define _WIN32_WINNT 0x0500
|
8
|
-
#include <windows.h>
|
9
|
-
|
10
|
-
#include "WinUtility.hpp"
|
11
|
-
|
12
8
|
#include <Gosu/IO.hpp>
|
13
9
|
#include <Gosu/Text.hpp>
|
14
10
|
#include <Gosu/Utility.hpp>
|
15
|
-
|
11
|
+
#include "WinUtility.hpp"
|
16
12
|
#include <cstdlib>
|
17
13
|
#include <cwchar>
|
18
14
|
#include <map>
|
19
15
|
#include <memory>
|
20
|
-
|
16
|
+
#include <windows.h>
|
21
17
|
|
22
|
-
const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned font_flags)
|
18
|
+
const unsigned char* Gosu::ttf_data_by_name(const std::string& font_name, unsigned font_flags)
|
23
19
|
{
|
24
20
|
// TODO: Make this cache thread-safe.
|
25
|
-
static map<pair<string, unsigned>, shared_ptr<Buffer>> ttf_file_cache;
|
26
|
-
|
21
|
+
static std::map<std::pair<std::string, unsigned>, std::shared_ptr<Buffer>> ttf_file_cache;
|
22
|
+
|
27
23
|
auto& buffer_ptr = ttf_file_cache[make_pair(font_name, font_flags)];
|
28
24
|
if (buffer_ptr) return static_cast<const unsigned char*>(buffer_ptr->data());
|
29
25
|
|
30
26
|
log("Trying to find a font named '%s', flags=%x", font_name.c_str(), font_flags);
|
31
27
|
|
32
|
-
LOGFONT logfont = {
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
28
|
+
LOGFONT logfont = {0,
|
29
|
+
0,
|
30
|
+
0,
|
31
|
+
0,
|
32
|
+
(font_flags & Gosu::FF_BOLD) ? FW_BOLD : FW_NORMAL,
|
33
|
+
static_cast<BYTE>((font_flags & Gosu::FF_ITALIC) ? TRUE : FALSE),
|
34
|
+
static_cast<BYTE>((font_flags & Gosu::FF_UNDERLINE) ? TRUE : FALSE),
|
35
|
+
0 /* no strikethrough */,
|
36
|
+
ANSI_CHARSET,
|
37
|
+
OUT_OUTLINE_PRECIS,
|
38
|
+
CLIP_DEFAULT_PRECIS,
|
39
|
+
ANTIALIASED_QUALITY,
|
40
|
+
DEFAULT_PITCH};
|
41
|
+
|
42
|
+
std::wstring wfont_name = utf8_to_utf16(font_name);
|
43
|
+
std::wcsncpy(logfont.lfFaceName, wfont_name.c_str(), LF_FACESIZE);
|
44
44
|
logfont.lfFaceName[LF_FACESIZE - 1] = 0;
|
45
|
-
|
45
|
+
|
46
46
|
if (HFONT font = CreateFontIndirect(&logfont)) {
|
47
47
|
if (HDC hdc = GetDC(0)) {
|
48
48
|
HFONT last_font = (HFONT) SelectObject(hdc, (HGDIOBJ) font);
|
49
49
|
auto ttf_buffer_size = GetFontData(hdc, 0, 0, nullptr, 0);
|
50
50
|
if (ttf_buffer_size != GDI_ERROR) {
|
51
|
-
auto buffer = make_shared<Gosu::Buffer>();
|
51
|
+
auto buffer = std::make_shared<Gosu::Buffer>();
|
52
52
|
buffer->resize(ttf_buffer_size);
|
53
53
|
if (GetFontData(hdc, 0, 0, buffer->data(), buffer->size()) != GDI_ERROR) {
|
54
54
|
auto data = static_cast<const unsigned char*>(buffer->data());
|
@@ -75,18 +75,18 @@ const unsigned char* Gosu::ttf_fallback_data()
|
|
75
75
|
// Prefer Arial Unicode MS as a fallback because it covers a lot of Unicode.
|
76
76
|
static const unsigned char* arial_unicode = ttf_data_by_name("Arial Unicode MS", 0);
|
77
77
|
if (arial_unicode) return arial_unicode;
|
78
|
-
|
78
|
+
|
79
79
|
// Otherwise, just try to find *any* font.
|
80
80
|
static const unsigned char* any_font = ttf_data_by_name("", 0);
|
81
81
|
if (any_font) return any_font;
|
82
|
-
|
83
|
-
static const char* windir = getenv("WINDIR");
|
84
|
-
if (windir) return ttf_data_from_file(string(windir) + "/Fonts/arial.ttf");
|
85
|
-
|
82
|
+
|
83
|
+
static const char* windir = std::getenv("WINDIR");
|
84
|
+
if (windir) return ttf_data_from_file(std::string(windir) + "/Fonts/arial.ttf");
|
85
|
+
|
86
86
|
return ttf_data_from_file("C:/Windows/Fonts/arial.ttf");
|
87
87
|
}
|
88
88
|
|
89
|
-
string Gosu::default_font_name()
|
89
|
+
std::string Gosu::default_font_name()
|
90
90
|
{
|
91
91
|
return "Arial";
|
92
92
|
}
|
data/src/Window.cpp
CHANGED
@@ -2,16 +2,15 @@
|
|
2
2
|
#if !defined(GOSU_IS_IPHONE)
|
3
3
|
|
4
4
|
#if defined(GOSU_IS_WIN)
|
5
|
+
#define NOMINMAX
|
5
6
|
#include <windows.h>
|
6
7
|
#endif
|
7
8
|
|
8
9
|
#include <Gosu/Gosu.hpp>
|
9
10
|
#include "GraphicsImpl.hpp"
|
10
11
|
#include <SDL.h>
|
11
|
-
#include <cstdlib>
|
12
12
|
#include <algorithm>
|
13
13
|
#include <stdexcept>
|
14
|
-
using namespace std;
|
15
14
|
|
16
15
|
namespace Gosu
|
17
16
|
{
|
@@ -20,14 +19,15 @@ namespace Gosu
|
|
20
19
|
void register_frame();
|
21
20
|
}
|
22
21
|
|
23
|
-
static void throw_sdl_error(const string& operation)
|
22
|
+
[[noreturn]] static void throw_sdl_error(const std::string& operation)
|
24
23
|
{
|
25
24
|
const char* error = SDL_GetError();
|
26
|
-
throw runtime_error
|
25
|
+
throw std::runtime_error{operation + ": " + (error ? error : "(unknown error)")};
|
27
26
|
}
|
28
27
|
|
29
28
|
SDL_Window* shared_window()
|
30
29
|
{
|
30
|
+
// NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables)
|
31
31
|
static SDL_Window* window = nullptr;
|
32
32
|
if (window == nullptr) {
|
33
33
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
@@ -36,8 +36,8 @@ namespace Gosu
|
|
36
36
|
|
37
37
|
Uint32 flags = SDL_WINDOW_OPENGL | SDL_WINDOW_HIDDEN | SDL_WINDOW_ALLOW_HIGHDPI;
|
38
38
|
|
39
|
-
window =
|
40
|
-
|
39
|
+
window = SDL_CreateWindow("", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 64, 64,
|
40
|
+
flags);
|
41
41
|
if (window == nullptr) {
|
42
42
|
throw_sdl_error("Could not create window");
|
43
43
|
}
|
@@ -50,10 +50,10 @@ namespace Gosu
|
|
50
50
|
{
|
51
51
|
static SDL_GLContext context = nullptr;
|
52
52
|
if (context == nullptr) {
|
53
|
-
|
53
|
+
#ifdef GOSU_IS_OPENGLES
|
54
54
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
|
55
55
|
SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
|
56
|
-
|
56
|
+
#endif
|
57
57
|
|
58
58
|
context = SDL_GL_CreateContext(shared_window());
|
59
59
|
|
@@ -64,36 +64,41 @@ namespace Gosu
|
|
64
64
|
return context;
|
65
65
|
}
|
66
66
|
|
67
|
-
void ensure_current_context()
|
67
|
+
void ensure_current_context() //
|
68
68
|
{
|
69
69
|
SDL_GL_MakeCurrent(shared_window(), shared_gl_context());
|
70
70
|
}
|
71
71
|
}
|
72
72
|
|
73
|
-
struct Gosu::Window::Impl
|
73
|
+
struct Gosu::Window::Impl : Gosu::Noncopyable
|
74
74
|
{
|
75
|
-
bool fullscreen;
|
76
|
-
double update_interval;
|
77
|
-
bool resizable;
|
75
|
+
bool fullscreen = false;
|
76
|
+
double update_interval = 0;
|
77
|
+
bool resizable = false;
|
78
78
|
bool resizing = false;
|
79
79
|
|
80
80
|
// A single `bool open` is not good enough to support the tick() method: When close() is called
|
81
81
|
// from outside the window's call graph, the next call to tick() must return false (transition
|
82
|
-
// from CLOSING to CLOSED), but the call after that must
|
83
|
-
//
|
84
|
-
enum
|
82
|
+
// from CLOSING to CLOSED), but the call after that must show the window again (transition from
|
83
|
+
// CLOSED to OPEN).
|
84
|
+
enum
|
85
|
+
{
|
86
|
+
CLOSED,
|
87
|
+
OPEN,
|
88
|
+
CLOSING
|
89
|
+
} state = CLOSED;
|
85
90
|
|
86
|
-
unique_ptr<Graphics> graphics;
|
87
|
-
unique_ptr<Input> input;
|
91
|
+
std::unique_ptr<Graphics> graphics;
|
92
|
+
std::unique_ptr<Input> input;
|
88
93
|
};
|
89
94
|
|
90
95
|
Gosu::Window::Window(int width, int height, unsigned window_flags, double update_interval)
|
91
|
-
:
|
96
|
+
: m_impl(new Impl)
|
92
97
|
{
|
93
98
|
set_borderless(window_flags & WF_BORDERLESS);
|
94
99
|
set_resizable(window_flags & WF_RESIZABLE);
|
95
100
|
|
96
|
-
// Even in fullscreen mode, temporarily show the window in windowed mode to
|
101
|
+
// Even in fullscreen mode, temporarily show the window in windowed mode to center it.
|
97
102
|
// This ensures that the window will be centered correctly when exiting fullscreen mode.
|
98
103
|
// Fixes https://github.com/gosu/gosu/issues/369
|
99
104
|
// (This will implicitly create graphics() and input(), and make the OpenGL context current.)
|
@@ -105,11 +110,11 @@ Gosu::Window::Window(int width, int height, unsigned window_flags, double update
|
|
105
110
|
|
106
111
|
SDL_GL_SetSwapInterval(1);
|
107
112
|
|
108
|
-
|
113
|
+
m_impl->update_interval = update_interval;
|
109
114
|
|
110
115
|
input().on_button_down = [this](Button button) { button_down(button); };
|
111
|
-
input().on_button_up
|
112
|
-
input().on_gamepad_connected
|
116
|
+
input().on_button_up = [this](Button button) { button_up(button); };
|
117
|
+
input().on_gamepad_connected = [this](int index) { gamepad_connected(index); };
|
113
118
|
input().on_gamepad_disconnected = [this](int index) { gamepad_disconnected(index); };
|
114
119
|
}
|
115
120
|
|
@@ -130,12 +135,12 @@ int Gosu::Window::height() const
|
|
130
135
|
|
131
136
|
bool Gosu::Window::fullscreen() const
|
132
137
|
{
|
133
|
-
return
|
138
|
+
return m_impl->fullscreen;
|
134
139
|
}
|
135
140
|
|
136
141
|
void Gosu::Window::resize(int width, int height, bool fullscreen)
|
137
142
|
{
|
138
|
-
|
143
|
+
m_impl->fullscreen = fullscreen;
|
139
144
|
|
140
145
|
int actual_width = width;
|
141
146
|
int actual_height = height;
|
@@ -144,19 +149,19 @@ void Gosu::Window::resize(int width, int height, bool fullscreen)
|
|
144
149
|
double black_bar_height = 0;
|
145
150
|
|
146
151
|
if (fullscreen) {
|
147
|
-
actual_width
|
152
|
+
actual_width = Gosu::screen_width(this);
|
148
153
|
actual_height = Gosu::screen_height(this);
|
149
154
|
|
150
155
|
if (resizable()) {
|
151
156
|
// Resizable fullscreen windows stubbornly follow the desktop resolution.
|
152
|
-
width
|
157
|
+
width = actual_width;
|
153
158
|
height = actual_height;
|
154
159
|
}
|
155
160
|
else {
|
156
161
|
// Scale the window to fill the desktop resolution.
|
157
162
|
double scale_x = 1.0 * actual_width / width;
|
158
163
|
double scale_y = 1.0 * actual_height / height;
|
159
|
-
scale_factor = min(scale_x, scale_y);
|
164
|
+
scale_factor = std::min(scale_x, scale_y);
|
160
165
|
// Add black bars to preserve the aspect ratio, if necessary.
|
161
166
|
if (scale_x < scale_y) {
|
162
167
|
black_bar_height = (actual_height / scale_x - height) / 2;
|
@@ -167,24 +172,24 @@ void Gosu::Window::resize(int width, int height, bool fullscreen)
|
|
167
172
|
}
|
168
173
|
}
|
169
174
|
else {
|
170
|
-
int max_width
|
175
|
+
int max_width = Gosu::available_width(this);
|
171
176
|
int max_height = Gosu::available_height(this);
|
172
177
|
|
173
178
|
if (resizable()) {
|
174
179
|
// If the window is resizable, limit its size, without preserving the aspect ratio.
|
175
|
-
width
|
176
|
-
height = actual_height = min(height, max_height);
|
180
|
+
width = actual_width = std::min(width, max_width);
|
181
|
+
height = actual_height = std::min(height, max_height);
|
177
182
|
}
|
178
183
|
else if (width > max_width || height > max_height) {
|
179
184
|
// If the window cannot fit on the screen, shrink its contents.
|
180
|
-
scale_factor = min(1.0 * max_width / width, 1.0 * max_height / height);
|
181
|
-
actual_width
|
182
|
-
actual_height = height * scale_factor;
|
185
|
+
scale_factor = std::min(1.0 * max_width / width, 1.0 * max_height / height);
|
186
|
+
actual_width = static_cast<int>(width * scale_factor);
|
187
|
+
actual_height = static_cast<int>(height * scale_factor);
|
183
188
|
}
|
184
189
|
}
|
185
190
|
|
186
191
|
SDL_SetWindowFullscreen(shared_window(), fullscreen ? SDL_WINDOW_FULLSCREEN_DESKTOP : 0);
|
187
|
-
if (!
|
192
|
+
if (!m_impl->resizing) {
|
188
193
|
SDL_SetWindowSize(shared_window(), actual_width, actual_height);
|
189
194
|
}
|
190
195
|
|
@@ -192,37 +197,39 @@ void Gosu::Window::resize(int width, int height, bool fullscreen)
|
|
192
197
|
|
193
198
|
ensure_current_context();
|
194
199
|
|
195
|
-
if (!
|
196
|
-
|
200
|
+
if (!m_impl->graphics) {
|
201
|
+
m_impl->graphics.reset(new Graphics(actual_width, actual_height));
|
197
202
|
}
|
198
203
|
else {
|
199
|
-
|
204
|
+
m_impl->graphics->set_physical_resolution(actual_width, actual_height);
|
200
205
|
}
|
201
|
-
|
206
|
+
m_impl->graphics->set_resolution(width, height, black_bar_width, black_bar_height);
|
202
207
|
|
203
|
-
if (!
|
204
|
-
|
208
|
+
if (!m_impl->input) {
|
209
|
+
m_impl->input.reset(new Input(shared_window()));
|
205
210
|
}
|
206
|
-
|
207
|
-
|
211
|
+
m_impl->input->set_mouse_factors(1 / scale_factor, 1 / scale_factor, black_bar_width,
|
212
|
+
black_bar_height);
|
208
213
|
}
|
209
214
|
|
210
215
|
bool Gosu::Window::resizable() const
|
211
216
|
{
|
212
|
-
return
|
217
|
+
return m_impl->resizable;
|
213
218
|
}
|
214
219
|
|
215
220
|
void Gosu::Window::set_resizable(bool resizable)
|
216
221
|
{
|
217
|
-
|
222
|
+
m_impl->resizable = resizable;
|
218
223
|
SDL_SetWindowResizable(shared_window(), resizable ? SDL_TRUE : SDL_FALSE);
|
219
224
|
}
|
220
225
|
|
226
|
+
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
|
221
227
|
bool Gosu::Window::borderless() const
|
222
228
|
{
|
223
229
|
return SDL_GetWindowFlags(shared_window()) & SDL_WINDOW_BORDERLESS;
|
224
230
|
}
|
225
231
|
|
232
|
+
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
|
226
233
|
void Gosu::Window::set_borderless(bool borderless)
|
227
234
|
{
|
228
235
|
SDL_SetWindowBordered(shared_window(), borderless ? SDL_FALSE : SDL_TRUE);
|
@@ -230,21 +237,23 @@ void Gosu::Window::set_borderless(bool borderless)
|
|
230
237
|
|
231
238
|
double Gosu::Window::update_interval() const
|
232
239
|
{
|
233
|
-
return
|
240
|
+
return m_impl->update_interval;
|
234
241
|
}
|
235
242
|
|
236
243
|
void Gosu::Window::set_update_interval(double update_interval)
|
237
244
|
{
|
238
|
-
|
245
|
+
m_impl->update_interval = update_interval;
|
239
246
|
}
|
240
247
|
|
241
|
-
|
248
|
+
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
|
249
|
+
std::string Gosu::Window::caption() const
|
242
250
|
{
|
243
251
|
const char* title = SDL_GetWindowTitle(shared_window());
|
244
252
|
return title ? title : "";
|
245
253
|
}
|
246
254
|
|
247
|
-
|
255
|
+
// NOLINTNEXTLINE(readability-convert-member-functions-to-static)
|
256
|
+
void Gosu::Window::set_caption(const std::string& caption)
|
248
257
|
{
|
249
258
|
SDL_SetWindowTitle(shared_window(), caption.c_str());
|
250
259
|
}
|
@@ -264,16 +273,17 @@ void Gosu::Window::show()
|
|
264
273
|
while (tick()) {
|
265
274
|
// Sleep to keep this loop from eating 100% CPU.
|
266
275
|
unsigned long tick_time = milliseconds() - time_before_tick;
|
267
|
-
|
268
|
-
|
276
|
+
double sleep_time = tick_time - update_interval();
|
277
|
+
if (sleep_time >= 1) {
|
278
|
+
sleep(static_cast<unsigned long>(sleep_time));
|
269
279
|
}
|
270
280
|
|
271
281
|
time_before_tick = milliseconds();
|
272
282
|
}
|
273
283
|
} catch (...) {
|
274
|
-
|
284
|
+
#ifdef GOSU_IS_WIN
|
275
285
|
if (previous_affinity) SetThreadAffinityMask(GetCurrentThread(), previous_affinity);
|
276
|
-
|
286
|
+
#endif
|
277
287
|
throw;
|
278
288
|
}
|
279
289
|
|
@@ -281,19 +291,19 @@ void Gosu::Window::show()
|
|
281
291
|
if (previous_affinity) SetThreadAffinityMask(GetCurrentThread(), previous_affinity);
|
282
292
|
#endif
|
283
293
|
|
284
|
-
|
294
|
+
m_impl->state = Impl::CLOSED;
|
285
295
|
}
|
286
296
|
|
287
297
|
bool Gosu::Window::tick()
|
288
298
|
{
|
289
|
-
if (
|
290
|
-
|
299
|
+
if (m_impl->state == Impl::CLOSING) {
|
300
|
+
m_impl->state = Impl::CLOSED;
|
291
301
|
return false;
|
292
302
|
}
|
293
303
|
|
294
|
-
if (
|
304
|
+
if (m_impl->state == Impl::CLOSED) {
|
295
305
|
SDL_ShowWindow(shared_window());
|
296
|
-
|
306
|
+
m_impl->state = Impl::OPEN;
|
297
307
|
|
298
308
|
// SDL_GL_GetDrawableSize returns different values before and after showing the window.
|
299
309
|
// -> When first showing the window, update the physical size of Graphics (=glViewport).
|
@@ -305,15 +315,15 @@ bool Gosu::Window::tick()
|
|
305
315
|
|
306
316
|
SDL_Event e;
|
307
317
|
while (SDL_PollEvent(&e)) {
|
308
|
-
|
309
318
|
switch (e.type) {
|
310
319
|
case SDL_WINDOWEVENT: {
|
311
320
|
switch (e.window.event) {
|
312
321
|
case SDL_WINDOWEVENT_SIZE_CHANGED: {
|
313
|
-
if (
|
314
|
-
|
322
|
+
if (m_impl->resizable &&
|
323
|
+
(width() != e.window.data1 || height() != e.window.data2)) {
|
324
|
+
m_impl->resizing = true;
|
315
325
|
resize(e.window.data1, e.window.data2, fullscreen());
|
316
|
-
|
326
|
+
m_impl->resizing = false;
|
317
327
|
}
|
318
328
|
break;
|
319
329
|
}
|
@@ -336,10 +346,9 @@ bool Gosu::Window::tick()
|
|
336
346
|
break;
|
337
347
|
}
|
338
348
|
case SDL_DROPFILE: {
|
339
|
-
char
|
340
|
-
if (
|
341
|
-
drop(
|
342
|
-
SDL_free(dropped_filedir);
|
349
|
+
std::shared_ptr<char> dropped_file{e.drop.file, SDL_free};
|
350
|
+
if (dropped_file == nullptr) break;
|
351
|
+
drop(dropped_file.get());
|
343
352
|
break;
|
344
353
|
}
|
345
354
|
default: {
|
@@ -367,16 +376,16 @@ bool Gosu::Window::tick()
|
|
367
376
|
SDL_GL_SwapWindow(shared_window());
|
368
377
|
}
|
369
378
|
|
370
|
-
if (
|
371
|
-
|
379
|
+
if (m_impl->state == Impl::CLOSING) {
|
380
|
+
m_impl->state = Impl::CLOSED;
|
372
381
|
}
|
373
382
|
|
374
|
-
return
|
383
|
+
return m_impl->state == Impl::OPEN;
|
375
384
|
}
|
376
385
|
|
377
386
|
void Gosu::Window::close()
|
378
387
|
{
|
379
|
-
|
388
|
+
m_impl->state = Impl::CLOSING;
|
380
389
|
SDL_HideWindow(shared_window());
|
381
390
|
}
|
382
391
|
|
@@ -389,23 +398,23 @@ void Gosu::Window::button_down(Button button)
|
|
389
398
|
#ifdef GOSU_IS_MAC
|
390
399
|
// cmd+F and cmd+ctrl+F are both common shortcuts for toggling fullscreen mode on macOS.
|
391
400
|
toggle_fullscreen = button == KB_F &&
|
392
|
-
|
393
|
-
|
394
|
-
|
401
|
+
(Input::down(KB_LEFT_META) || Input::down(KB_RIGHT_META)) &&
|
402
|
+
!Input::down(KB_LEFT_SHIFT) && !Input::down(KB_RIGHT_SHIFT) &&
|
403
|
+
!Input::down(KB_LEFT_ALT) && !Input::down(KB_RIGHT_ALT);
|
395
404
|
#else
|
396
405
|
// Alt+Enter and Alt+Return toggle fullscreen mode on all other platforms.
|
397
406
|
toggle_fullscreen = (button == KB_RETURN || button == KB_ENTER) &&
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
407
|
+
(Input::down(KB_LEFT_ALT) || Input::down(KB_RIGHT_ALT)) &&
|
408
|
+
!Input::down(KB_LEFT_CONTROL) && !Input::down(KB_RIGHT_CONTROL) &&
|
409
|
+
!Input::down(KB_LEFT_META) && !Input::down(KB_RIGHT_META) &&
|
410
|
+
!Input::down(KB_LEFT_SHIFT) && !Input::down(KB_RIGHT_SHIFT);
|
402
411
|
#endif
|
403
412
|
// F11 is supported as a shortcut for fullscreen mode on all platforms.
|
404
|
-
if (!toggle_fullscreen && button == KB_F11 &&
|
405
|
-
!Input::down(
|
406
|
-
!Input::down(
|
407
|
-
!Input::down(
|
408
|
-
!Input::down(
|
413
|
+
if (!toggle_fullscreen && button == KB_F11 && !Input::down(KB_LEFT_ALT) &&
|
414
|
+
!Input::down(KB_RIGHT_ALT) && !Input::down(KB_LEFT_CONTROL) &&
|
415
|
+
!Input::down(KB_RIGHT_CONTROL) && !Input::down(KB_LEFT_META) &&
|
416
|
+
!Input::down(KB_RIGHT_META) && !Input::down(KB_LEFT_SHIFT) &&
|
417
|
+
!Input::down(KB_RIGHT_SHIFT)) {
|
409
418
|
toggle_fullscreen = true;
|
410
419
|
}
|
411
420
|
|
@@ -416,22 +425,22 @@ void Gosu::Window::button_down(Button button)
|
|
416
425
|
|
417
426
|
const Gosu::Graphics& Gosu::Window::graphics() const
|
418
427
|
{
|
419
|
-
return *
|
428
|
+
return *m_impl->graphics;
|
420
429
|
}
|
421
430
|
|
422
431
|
Gosu::Graphics& Gosu::Window::graphics()
|
423
432
|
{
|
424
|
-
return *
|
433
|
+
return *m_impl->graphics;
|
425
434
|
}
|
426
435
|
|
427
436
|
const Gosu::Input& Gosu::Window::input() const
|
428
437
|
{
|
429
|
-
return *
|
438
|
+
return *m_impl->input;
|
430
439
|
}
|
431
440
|
|
432
441
|
Gosu::Input& Gosu::Window::input()
|
433
442
|
{
|
434
|
-
return *
|
443
|
+
return *m_impl->input;
|
435
444
|
}
|
436
445
|
|
437
446
|
#endif
|