gosu 0.14.0 → 0.14.3.pre1

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,69 +1,69 @@
1
- #include <Gosu/Platform.hpp>
2
- #if defined(GOSU_IS_WIN)
3
-
4
- #include "WinUtility.hpp"
5
- #include <Gosu/Directories.hpp>
6
- #include <Gosu/Utility.hpp>
7
- #include <cwchar>
8
- #include <stdexcept>
1
+ #include <Gosu/Platform.hpp>
2
+ #if defined(GOSU_IS_WIN)
3
+
4
+ #include "WinUtility.hpp"
5
+ #include <Gosu/Directories.hpp>
6
+ #include <Gosu/Utility.hpp>
7
+ #include <cwchar>
8
+ #include <stdexcept>
9
9
  #include <shlobj.h>
10
- using namespace std;
11
-
12
- static string special_folder_path(int csidl)
13
- {
14
- WCHAR buf[MAX_PATH + 2];
15
- if (FAILED(SHGetFolderPathW(nullptr, csidl | CSIDL_FLAG_CREATE, nullptr, 0, buf))) {
16
- throw runtime_error("Error getting special folder path");
17
- }
18
- size_t len = wcslen(buf);
19
- if (buf[len - 1] != L'\\') {
20
- buf[len] = L'\\';
21
- buf[len + 1] = 0;
22
- }
23
- return Gosu::utf16_to_utf8(buf);
24
- }
25
-
26
- static string exe_filename()
27
- {
28
- static string result;
29
- if (result.empty()) {
30
- WCHAR buffer[MAX_PATH * 2];
31
- Gosu::winapi_check(GetModuleFileNameW(nullptr, buffer, MAX_PATH * 2),
32
- "getting the module filename");
33
- result = Gosu::utf16_to_utf8(buffer);
34
- }
35
- return result;
36
- }
37
-
38
- void Gosu::use_resource_directory()
39
- {
40
- SetCurrentDirectory(utf8_to_utf16(resource_prefix()).c_str());
41
- }
42
-
43
- string Gosu::resource_prefix()
44
- {
45
- static string result;
46
- if (result.empty()) {
47
- result = exe_filename();
48
- auto last_delim = result.find_last_of("\\/");
49
- result.resize(last_delim == string::npos ? 0 : last_delim + 1);
50
- }
51
- return result;
52
- }
53
-
54
- string Gosu::shared_resource_prefix()
55
- {
56
- return resource_prefix();
57
- }
58
-
59
- string Gosu::user_settings_prefix()
60
- {
61
- return special_folder_path(CSIDL_APPDATA);
62
- }
63
-
64
- string Gosu::user_documents_prefix()
65
- {
66
- return special_folder_path(CSIDL_PERSONAL);
67
- }
68
-
69
- #endif
10
+ using namespace std;
11
+
12
+ static string special_folder_path(int csidl)
13
+ {
14
+ WCHAR buf[MAX_PATH + 2];
15
+ if (FAILED(SHGetFolderPathW(nullptr, csidl | CSIDL_FLAG_CREATE, nullptr, 0, buf))) {
16
+ throw runtime_error("Error getting special folder path");
17
+ }
18
+ size_t len = wcslen(buf);
19
+ if (buf[len - 1] != L'\\') {
20
+ buf[len] = L'\\';
21
+ buf[len + 1] = 0;
22
+ }
23
+ return Gosu::utf16_to_utf8(buf);
24
+ }
25
+
26
+ static string exe_filename()
27
+ {
28
+ static string result;
29
+ if (result.empty()) {
30
+ WCHAR buffer[MAX_PATH * 2];
31
+ Gosu::winapi_check(GetModuleFileNameW(nullptr, buffer, MAX_PATH * 2),
32
+ "getting the module filename");
33
+ result = Gosu::utf16_to_utf8(buffer);
34
+ }
35
+ return result;
36
+ }
37
+
38
+ void Gosu::use_resource_directory()
39
+ {
40
+ SetCurrentDirectory(utf8_to_utf16(resource_prefix()).c_str());
41
+ }
42
+
43
+ string Gosu::resource_prefix()
44
+ {
45
+ static string result;
46
+ if (result.empty()) {
47
+ result = exe_filename();
48
+ auto last_delim = result.find_last_of("\\/");
49
+ result.resize(last_delim == string::npos ? 0 : last_delim + 1);
50
+ }
51
+ return result;
52
+ }
53
+
54
+ string Gosu::shared_resource_prefix()
55
+ {
56
+ return resource_prefix();
57
+ }
58
+
59
+ string Gosu::user_settings_prefix()
60
+ {
61
+ return special_folder_path(CSIDL_APPDATA);
62
+ }
63
+
64
+ string Gosu::user_documents_prefix()
65
+ {
66
+ return special_folder_path(CSIDL_PERSONAL);
67
+ }
68
+
69
+ #endif
data/src/Graphics.cpp CHANGED
@@ -265,7 +265,8 @@ void Gosu::Graphics::clip_to(double x, double y, double width, double height,
265
265
  current_queue().end_clipping();
266
266
  }
267
267
 
268
- Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()>& f)
268
+ Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()>& f,
269
+ unsigned image_flags)
269
270
  {
270
271
  ensure_current_context();
271
272
 
@@ -285,7 +286,7 @@ Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()
285
286
  #endif
286
287
 
287
288
  // This is the actual render-to-texture step.
288
- Image result = OffScreenTarget(width, height).render([&] {
289
+ Image result = OffScreenTarget(width, height, image_flags).render([&] {
289
290
  glClearColor(0, 0, 0, 0);
290
291
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
291
292
  queues.emplace_back(QM_RENDER_TO_TEXTURE);
data/src/InputUIKit.cpp CHANGED
@@ -171,7 +171,8 @@ void Gosu::Input::set_text_input(TextInput* text_input)
171
171
  if (text_input) {
172
172
  pimpl->text_input = text_input;
173
173
  [pimpl->view becomeFirstResponder];
174
- } else {
174
+ }
175
+ else {
175
176
  [pimpl->view resignFirstResponder];
176
177
  pimpl->text_input = nullptr;
177
178
  }
data/src/MarkupParser.cpp CHANGED
@@ -139,7 +139,7 @@ bool Gosu::MarkupParser::parse_escape_entity()
139
139
 
140
140
  void Gosu::MarkupParser::add_current_substring()
141
141
  {
142
- if (! substring.empty()) {
142
+ if (!substring.empty()) {
143
143
  add_composed_substring(utf8_to_composed_utc4(substring));
144
144
  substring.clear();
145
145
  }
@@ -152,7 +152,7 @@ void Gosu::MarkupParser::add_composed_substring(u32string&& substring)
152
152
  fstr.flags = flags();
153
153
  fstr.color = c.back();
154
154
 
155
- if (! substrings.empty() && substrings.back().can_be_merged_with(fstr)) {
155
+ if (!substrings.empty() && substrings.back().can_be_merged_with(fstr)) {
156
156
  substrings.back().text.append(move(fstr.text));
157
157
  }
158
158
  else {
@@ -162,7 +162,7 @@ void Gosu::MarkupParser::add_composed_substring(u32string&& substring)
162
162
 
163
163
  void Gosu::MarkupParser::flush_to_consumer()
164
164
  {
165
- if (! substrings.empty()) {
165
+ if (!substrings.empty()) {
166
166
  consumer(move(substrings));
167
167
  substrings.clear();
168
168
  }
@@ -221,7 +221,8 @@ void Gosu::MarkupParser::parse(const std::string& markup_string)
221
221
  add_current_substring();
222
222
  flush_to_consumer();
223
223
  word_state = ADDING_WHITESPACE;
224
- } else if (!whitespace_except_newline && word_state == ADDING_WHITESPACE) {
224
+ }
225
+ else if (!whitespace_except_newline && word_state == ADDING_WHITESPACE) {
225
226
  // We are in word-parsing mode, and this is was the start of a word.
226
227
  add_current_substring();
227
228
  flush_to_consumer();
@@ -28,7 +28,7 @@ using namespace std;
28
28
  GL_DEPTH_COMPONENT
29
29
  #endif
30
30
 
31
- Gosu::OffScreenTarget::OffScreenTarget(int width, int height)
31
+ Gosu::OffScreenTarget::OffScreenTarget(int width, int height, unsigned image_flags)
32
32
  {
33
33
  #ifndef GOSU_IS_IPHONE
34
34
  if (!SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) {
@@ -37,7 +37,7 @@ Gosu::OffScreenTarget::OffScreenTarget(int width, int height)
37
37
  #endif
38
38
 
39
39
  // Create a new texture that will be our rendering target.
40
- texture = make_shared<Texture>(width, height, false);
40
+ texture = make_shared<Texture>(width, height, image_flags & IF_RETRO);
41
41
  // Mark the full texture as blocked for our TexChunk.
42
42
  texture->block(0, 0, width, height);
43
43
 
@@ -16,7 +16,7 @@ namespace Gosu
16
16
  OffScreenTarget& operator=(OffScreenTarget&& other) = delete;
17
17
 
18
18
  public:
19
- OffScreenTarget(int width, int height);
19
+ OffScreenTarget(int width, int height, unsigned image_flags);
20
20
  ~OffScreenTarget();
21
21
  Gosu::Image render(const std::function<void ()>& f);
22
22
  };
data/src/Resolution.cpp CHANGED
@@ -34,7 +34,7 @@ unsigned Gosu::screen_height(Window* window)
34
34
  static NSSize max_window_size(Gosu::Window* window)
35
35
  {
36
36
  // Keep in sync with SDL_cocoawindow.m.
37
- auto style = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskMiniaturizable;
37
+ auto style = NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask;
38
38
 
39
39
  auto index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
40
40
  auto screen_frame = NSScreen.screens[index].visibleFrame;
@@ -63,7 +63,8 @@ static SIZE max_window_size(Gosu::Window* window)
63
63
  if (window == nullptr) {
64
64
  // Easy case: Return the work area of the primary monitor.
65
65
  SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
66
- } else {
66
+ }
67
+ else {
67
68
  // Return the work area of the monitor the window is on.
68
69
  SDL_SysWMinfo wm_info;
69
70
  SDL_VERSION(&wm_info.version);
data/src/RubyGosu.cxx CHANGED
@@ -2408,8 +2408,34 @@ namespace Gosu
2408
2408
  return new Gosu::Image(Gosu::Graphics::record(width, height, [] { rb_yield(Qnil); }));
2409
2409
  }
2410
2410
 
2411
- Gosu::Image* render(int width, int height) {
2412
- return new Gosu::Image(Gosu::Graphics::render(width, height, [] { rb_yield(Qnil); }));
2411
+ Gosu::Image* render(int width, int height, VALUE options = 0) {
2412
+ unsigned image_flags = 0;
2413
+
2414
+ if (options) {
2415
+ Check_Type(options, T_HASH);
2416
+
2417
+ VALUE keys = rb_funcall(options, rb_intern("keys"), 0, NULL);
2418
+ int keys_size = NUM2INT(rb_funcall(keys, rb_intern("size"), 0, NULL));
2419
+
2420
+ for (int i = 0; i < keys_size; ++i) {
2421
+ VALUE key = rb_ary_entry(keys, i);
2422
+ const char* key_string = Gosu::cstr_from_symbol(key);
2423
+
2424
+ VALUE value = rb_hash_aref(options, key);
2425
+ if (!strcmp(key_string, "retro")) {
2426
+ if (RTEST(value)) image_flags |= Gosu::IF_RETRO;
2427
+ }
2428
+ else {
2429
+ static bool issued_warning = false;
2430
+ if (!issued_warning) {
2431
+ issued_warning = true;
2432
+ rb_warn("Unknown keyword argument: :%s", key_string);
2433
+ }
2434
+ }
2435
+ }
2436
+ }
2437
+
2438
+ return new Gosu::Image(Gosu::Graphics::render(width, height, [] { rb_yield(Qnil); }, image_flags));
2413
2439
  }
2414
2440
 
2415
2441
  // This method cannot be called "transform" because then it would be an ambiguous overload of
@@ -10890,6 +10916,7 @@ SWIGINTERN VALUE
10890
10916
  _wrap_render(int argc, VALUE *argv, VALUE self) {
10891
10917
  int arg1 ;
10892
10918
  int arg2 ;
10919
+ VALUE arg3 = (VALUE) 0 ;
10893
10920
  int val1 ;
10894
10921
  int ecode1 = 0 ;
10895
10922
  int val2 ;
@@ -10897,7 +10924,7 @@ _wrap_render(int argc, VALUE *argv, VALUE self) {
10897
10924
  Gosu::Image *result = 0 ;
10898
10925
  VALUE vresult = Qnil;
10899
10926
 
10900
- if ((argc < 2) || (argc > 2)) {
10927
+ if ((argc < 2) || (argc > 3)) {
10901
10928
  rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
10902
10929
  }
10903
10930
  ecode1 = SWIG_AsVal_int(argv[0], &val1);
@@ -10910,15 +10937,18 @@ _wrap_render(int argc, VALUE *argv, VALUE self) {
10910
10937
  SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "int","Gosu::render", 2, argv[1] ));
10911
10938
  }
10912
10939
  arg2 = static_cast< int >(val2);
10940
+ if (argc > 2) {
10941
+ arg3 = argv[2];
10942
+ }
10913
10943
  {
10914
10944
  try {
10915
- result = (Gosu::Image *)Gosu::render(arg1,arg2);
10945
+ result = (Gosu::Image *)Gosu::render(arg1,arg2,arg3);
10916
10946
  }
10917
10947
  catch (const std::exception& e) {
10918
10948
  SWIG_exception(SWIG_RuntimeError, e.what());
10919
10949
  }
10920
10950
  }
10921
- vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Gosu__Image, 0 | 0 );
10951
+ vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Gosu__Image, SWIG_POINTER_OWN | 0 );
10922
10952
  return vresult;
10923
10953
  fail:
10924
10954
  return Qnil;
@@ -11671,7 +11701,7 @@ SWIGEXPORT void Init_gosu(void) {
11671
11701
  rb_define_const(mGosu, "LICENSES", SWIG_From_std_string(static_cast< std::string >(Gosu::LICENSES)));
11672
11702
  rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(0)));
11673
11703
  rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(14)));
11674
- rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(0)));
11704
+ rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(3)));
11675
11705
  rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
11676
11706
  rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
11677
11707
  rb_define_module_function(mGosu, "degrees_to_radians", VALUEFUNC(_wrap_degrees_to_radians), -1);
data/src/SndFile.hpp CHANGED
@@ -19,9 +19,8 @@ namespace Gosu
19
19
  Reader reader;
20
20
  Buffer buffer;
21
21
 
22
- // Cannot use /DELAYLOAD with libsndfile.dll because it was compiled
23
- // using arcane GNU tools of dark magic (or maybe it's the filename).
24
- #ifdef GOSU_IS_WIN
22
+ // /DELAYLOAD doesn't work with libsndfile.dll (is this still true?); manually lazy-load it.
23
+ #ifdef GOSU_IS_WIN
25
24
  static HMODULE dll()
26
25
  {
27
26
  static HMODULE dll = LoadLibrary(L"libsndfile.dll");
@@ -29,7 +28,7 @@ namespace Gosu
29
28
  return dll;
30
29
  }
31
30
 
32
- #define CREATE_STUB(NAME, RETURN, PARAMS, NAMES) \
31
+ #define CREATE_STUB(NAME, RETURN, PARAMS, NAMES) \
33
32
  static RETURN NAME PARAMS \
34
33
  { \
35
34
  typedef RETURN (__cdecl *NAME##_ptr) PARAMS; \
@@ -54,8 +53,8 @@ namespace Gosu
54
53
  CREATE_STUB(sf_strerror, const char*,
55
54
  (SNDFILE* sndfile),
56
55
  (sndfile))
57
- #undef CREATE_STUB
58
- #endif
56
+ #undef CREATE_STUB
57
+ #endif
59
58
 
60
59
  static sf_count_t get_filelen(SndFile* self)
61
60
  {
@@ -126,12 +125,12 @@ namespace Gosu
126
125
  info.format = 0;
127
126
  // TODO: Not sure if this is still necessary.
128
127
  // Can libsndfile open UTF-8 filenames on Windows?
129
- #ifdef GOSU_IS_WIN
128
+ #ifdef GOSU_IS_WIN
130
129
  load_file(buffer, filename);
131
130
  file = sf_open_virtual(io_interface(), SFM_READ, &info, this);
132
- #else
131
+ #else
133
132
  file = sf_open(filename.c_str(), SFM_READ, &info);
134
- #endif
133
+ #endif
135
134
  if (!file) {
136
135
  throw std::runtime_error(sf_strerror(nullptr));
137
136
  }
data/src/TextBuilder.cpp CHANGED
@@ -7,7 +7,7 @@ using namespace std;
7
7
 
8
8
  Gosu::WordInfo::WordInfo(const string& font_name, double font_height, vector<FormattedString> parts)
9
9
  {
10
- assert (! parts.empty());
10
+ assert (!parts.empty());
11
11
 
12
12
  auto* properties = utf8proc_get_property(parts.front().text.front());
13
13
 
@@ -21,7 +21,7 @@ Gosu::WordInfo::WordInfo(const string& font_name, double font_height, vector<For
21
21
 
22
22
  width = 0;
23
23
  for (const auto& part : parts) {
24
- assert (is_end_of_line || ! part.text.empty());
24
+ assert (is_end_of_line || !part.text.empty());
25
25
 
26
26
  width += text_width(part.text, font_name, font_height, part.flags);
27
27
  }
@@ -42,7 +42,7 @@ void Gosu::TextBuilder::flush_current_line(EndOfLineReason reason)
42
42
  if (current_line.back().is_whitespace) current_line.pop_back();
43
43
 
44
44
  // Shouldn't happen because the first word on a line should never be whitespace.
45
- assert (! current_line.empty());
45
+ assert (!current_line.empty());
46
46
 
47
47
  double words_width = 0, whitespace_width = 0;
48
48
  for (const auto& word : current_line) {
data/src/TrueTypeFont.cpp CHANGED
@@ -199,12 +199,13 @@ double Gosu::TrueTypeFont::draw_text(const u32string &text, double height,
199
199
  return pimpl->draw_text(text, true, height, bitmap, x, y, c);
200
200
  }
201
201
 
202
- bool Gosu::TrueTypeFont::verify_font_name(const unsigned char* ttf_data, const string& font_name, unsigned font_flags)
202
+ bool Gosu::TrueTypeFont::matches(const unsigned char* ttf_data,
203
+ const string& font_name, unsigned font_flags)
203
204
  {
204
- // Gosu's FontFlags enum mostly uses the same values as the STBTT_ macros.
205
+ // Gosu::FontFlags uses the same values as the STBTT_ macros, except for this one.
205
206
  int flags = (font_flags == 0 ? STBTT_MACSTYLE_NONE : font_flags);
206
207
 
207
- return stbtt_FindMatchingFont(ttf_data, font_name.c_str(), font_flags) >= 0 ||
208
+ return stbtt_FindMatchingFont(ttf_data, font_name.c_str(), flags) >= 0 ||
208
209
  stbtt_FindMatchingFont(ttf_data, font_name.c_str(), STBTT_MACSTYLE_DONTCARE) >= 0;
209
210
  }
210
211
 
@@ -248,7 +249,8 @@ Gosu::TrueTypeFont& Gosu::font_by_name(const string& font_name, unsigned font_fl
248
249
  if (font_name.find_first_of("./\\") != string::npos) {
249
250
  // A filename? Load it and add it to the stack.
250
251
  ttf_stack.push_back(ttf_data_from_file(font_name));
251
- } else if (font_name != default_font_name()) {
252
+ }
253
+ else if (font_name != default_font_name()) {
252
254
  // A font name? Add it to the stack, both with font_flags and without.
253
255
  ttf_stack.push_back(ttf_data_by_name(font_name, 0));
254
256
  ttf_stack.push_back(ttf_data_by_name(font_name, font_flags));
data/src/TrueTypeFont.hpp CHANGED
@@ -25,8 +25,8 @@ namespace Gosu
25
25
  Bitmap* bitmap, double x, double y, Color c);
26
26
 
27
27
  //! Returns true if the supplied buffer seems to be a font of the given name.
28
- static bool verify_font_name(const unsigned char* ttf_data,
29
- const std::string& font_name, unsigned font_flags);
28
+ static bool matches(const unsigned char* ttf_data,
29
+ const std::string& font_name, unsigned font_flags);
30
30
  };
31
31
 
32
32
  TrueTypeFont& font_by_name(const std::string& font_name, unsigned font_flags);
@@ -36,6 +36,19 @@ namespace Gosu
36
36
  //! In case of failure, this method must not return nullptr, but raise an exception.
37
37
  //! Note that this method does not accept any font flags, and so it will always load the first
38
38
  //! font in a TTC font collection.
39
+ //!
40
+ //! This function does not yet support Gosu::FontFlags, and consequently, custom TTF fonts do
41
+ //! not support markup or bold/italic text right now.
42
+ //!
43
+ //! Options for the future:
44
+ //! 1. Use stbtt_FindMatchingFont. This will only work for TTC font collections, and we will
45
+ //! have to patch stb_truetype to look for fonts only based on `int flags`, while ignoring
46
+ //! the name of fonts inside a bundle (who wants to deal with strings, anyway).
47
+ //! 2. Maybe Gosu should accept filename patterns like "LibreBaskerville-*.ttf" as the font
48
+ //! name and then replace the * with "Regular", "Bold", "Italic" etc.?
49
+ //! 3. As a last resort, Gosu could implement faux bold and faux italics. I think faux
50
+ //! underlines are a must anyway, since no font provides a dedicated TTF file for that.
51
+ //! These options are not mutually exclusive.
39
52
  const unsigned char* ttf_data_from_file(const std::string& filename);
40
53
 
41
54
  //! This method loads a TODO
@@ -46,22 +59,4 @@ namespace Gosu
46
59
  //! This method has a different implementation on each platform.
47
60
  //! In case of failure, this method must not return nullptr, but raise an exception.
48
61
  const unsigned char* ttf_fallback_data();
49
-
50
- // TODO still true? ↓
51
- // These functions do not yet support Gosu::FontFlags. This is fine for system fonts like Arial,
52
- // where the callers of these methods will typically load the correct file (e.g. ArialBold.ttf).
53
- // However, games which ship with their own font files (which is a good idea) can't use bold or
54
- // italic text using <b> or <i> markup because there is no way to associate one TTF file as the
55
- // "bold variant" of another.
56
- //
57
- // Options for the future:
58
- // 1. Use stbtt_FindMatchingFont. This will only work for TTC font collections, and we will
59
- // have to patch stb_truetype to look for fonts only based on `int flags`, while ignoring
60
- // the name of fonts inside a bundle (who wants to deal with strings, anyway).
61
- // 2. Maybe Gosu should accept filename patterns like "LibreBaskerville-*.ttf" as the font
62
- // name and then replace the * with "Regular", "Bold", "Italic" etc.?
63
- // 3. As a last resort, Gosu could implement faux bold and faux italics. I think faux
64
- // underlines are a must anyway, since no font provides a dedicated TTF file for that.
65
- // These options are not mutually exclusive.
66
-
67
62
  }