gosu 1.4.6 → 2.0.0.pre6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING +2 -1
- data/dependencies/SDL/include/SDL_atomic.h +2 -3
- data/dependencies/SDL/include/SDL_audio.h +7 -7
- data/dependencies/SDL/include/SDL_blendmode.h +1 -1
- data/dependencies/SDL/include/SDL_endian.h +3 -3
- data/dependencies/SDL/include/SDL_gamecontroller.h +4 -4
- data/dependencies/SDL/include/SDL_hints.h +72 -28
- data/dependencies/SDL/include/SDL_joystick.h +8 -5
- data/dependencies/SDL/include/SDL_keycode.h +1 -1
- data/dependencies/SDL/include/SDL_main.h +7 -0
- data/dependencies/SDL/include/SDL_mouse.h +6 -7
- data/dependencies/SDL/include/SDL_mutex.h +79 -5
- data/dependencies/SDL/include/SDL_opengl_glext.h +5 -1
- data/dependencies/SDL/include/SDL_power.h +7 -8
- data/dependencies/SDL/include/SDL_render.h +5 -0
- data/dependencies/SDL/include/SDL_revision.h +2 -2
- data/dependencies/SDL/include/SDL_sensor.h +1 -1
- data/dependencies/SDL/include/SDL_stdinc.h +19 -11
- data/dependencies/SDL/include/SDL_thread.h +2 -2
- data/dependencies/SDL/include/SDL_version.h +2 -2
- data/dependencies/SDL/include/SDL_video.h +30 -2
- data/dependencies/SDL/include/begin_code.h +7 -7
- data/dependencies/SDL/include/close_code.h +2 -2
- 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.h +1 -1
- data/dependencies/SDL_sound/dr_flac.h +48 -23
- data/dependencies/SDL_sound/dr_mp3.h +34 -14
- data/dependencies/SDL_sound/stb_vorbis.h +3 -2
- data/dependencies/mojoAL/mojoal.c +1 -1
- data/ext/{gosu → gosu-ffi}/extconf.rb +34 -33
- data/ext/gosu-ffi/gosu-ffi.def +464 -0
- data/ffi/Gosu.cpp +307 -0
- data/ffi/Gosu.h +84 -0
- data/ffi/Gosu_Channel.cpp +62 -0
- data/ffi/Gosu_Channel.h +17 -0
- data/ffi/Gosu_Color.cpp +132 -0
- data/ffi/Gosu_Color.h +31 -0
- data/ffi/Gosu_Constants.cpp +334 -0
- data/ffi/Gosu_FFI.h +34 -0
- data/ffi/Gosu_FFI_internal.h +161 -0
- data/ffi/Gosu_Font.cpp +92 -0
- data/ffi/Gosu_Font.h +32 -0
- data/ffi/Gosu_Image.cpp +206 -0
- data/ffi/Gosu_Image.h +60 -0
- data/ffi/Gosu_Sample.cpp +29 -0
- data/ffi/Gosu_Sample.h +14 -0
- data/ffi/Gosu_Song.cpp +69 -0
- data/ffi/Gosu_Song.h +18 -0
- data/ffi/Gosu_TextInput.cpp +94 -0
- data/ffi/Gosu_TextInput.h +25 -0
- data/ffi/Gosu_Window.cpp +314 -0
- data/ffi/Gosu_Window.h +78 -0
- data/include/Gosu/Audio.hpp +6 -11
- data/include/Gosu/Bitmap.hpp +38 -53
- data/include/Gosu/Buffer.hpp +54 -0
- data/include/Gosu/Color.hpp +27 -35
- data/include/Gosu/Directories.hpp +25 -28
- data/include/Gosu/Drawable.hpp +58 -0
- data/include/Gosu/Font.hpp +6 -5
- data/include/Gosu/Fwd.hpp +4 -6
- data/include/Gosu/Gosu.hpp +5 -5
- data/include/Gosu/Graphics.hpp +51 -61
- data/include/Gosu/GraphicsBase.hpp +1 -11
- data/include/Gosu/Image.hpp +11 -14
- data/include/Gosu/Math.hpp +50 -72
- data/include/Gosu/Transform.hpp +32 -0
- data/include/Gosu/Utility.hpp +51 -1
- data/include/Gosu/Version.hpp +3 -3
- data/include/Gosu/Window.hpp +15 -9
- data/lib/SDL2.dll +0 -0
- data/lib/gosu/channel.rb +49 -0
- data/lib/gosu/color.rb +150 -0
- data/lib/gosu/compat.rb +29 -8
- data/lib/gosu/constants.rb +386 -0
- data/lib/gosu/ffi.rb +258 -0
- data/lib/gosu/font.rb +56 -0
- data/lib/gosu/gl_tex_info.rb +33 -0
- data/lib/gosu/gosu.rb +210 -0
- data/lib/gosu/image.rb +141 -0
- data/lib/gosu/numeric.rb +17 -0
- data/lib/gosu/preview.rb +6 -6
- data/lib/gosu/sample.rb +24 -0
- data/lib/gosu/song.rb +56 -0
- data/lib/gosu/text_input.rb +69 -0
- data/lib/gosu/window.rb +228 -0
- data/lib/gosu.rb +29 -8
- data/lib64/SDL2.dll +0 -0
- data/rdoc/gosu.rb +0 -2
- data/src/Audio.cpp +12 -12
- data/src/AudioFile.hpp +5 -4
- data/src/AudioFileAudioToolbox.cpp +8 -8
- data/src/AudioFileSDLSound.cpp +7 -10
- data/src/BinPacker.cpp +187 -0
- data/src/BinPacker.hpp +55 -0
- data/src/Bitmap.cpp +166 -144
- data/src/BitmapIO.cpp +60 -86
- data/src/Buffer.cpp +159 -0
- data/src/Color.cpp +75 -80
- data/src/Directories.cpp +47 -0
- data/src/DirectoriesUIKit.cpp +50 -0
- data/src/DrawOp.hpp +9 -4
- data/src/DrawOpQueue.hpp +2 -2
- data/src/Drawable.cpp +95 -0
- data/src/EmptyDrawable.hpp +38 -0
- data/src/FPS.cpp +31 -0
- data/src/Font.cpp +104 -74
- data/src/GosuGLView.cpp +14 -6
- data/src/GosuViewController.cpp +2 -10
- data/src/Graphics.cpp +60 -126
- data/src/GraphicsImpl.hpp +17 -47
- data/src/Image.cpp +41 -35
- data/src/Input.cpp +7 -8
- data/src/Macro.cpp +6 -6
- data/src/Macro.hpp +4 -4
- data/src/MarkupParser.cpp +5 -5
- data/src/Math.cpp +35 -22
- data/src/OffScreenTarget.cpp +53 -49
- data/src/OffScreenTarget.hpp +13 -11
- data/src/OpenGLContext.cpp +117 -0
- data/src/OpenGLContext.hpp +41 -0
- data/src/RenderState.hpp +21 -19
- data/src/Resolution.cpp +23 -21
- data/src/TexChunk.cpp +35 -80
- data/src/TexChunk.hpp +44 -35
- data/src/Text.cpp +1 -1
- data/src/TextBuilder.cpp +35 -21
- data/src/TextBuilder.hpp +6 -9
- data/src/Texture.cpp +62 -80
- data/src/Texture.hpp +25 -23
- data/src/TiledDrawable.cpp +150 -0
- data/src/TiledDrawable.hpp +47 -0
- data/src/TimingApple.cpp +1 -1
- data/src/Transform.cpp +45 -50
- data/src/TransformStack.hpp +16 -16
- data/src/TrueTypeFont.cpp +59 -51
- data/src/TrueTypeFont.hpp +6 -7
- data/src/TrueTypeFontApple.cpp +28 -19
- data/src/TrueTypeFontUnix.cpp +27 -23
- data/src/TrueTypeFontWin.cpp +30 -30
- data/src/Utility.cpp +84 -21
- data/src/UtilityWin.cpp +45 -0
- data/src/Window.cpp +92 -142
- data/src/WindowUIKit.cpp +14 -14
- metadata +72 -31
- data/include/Gosu/IO.hpp +0 -254
- data/include/Gosu/ImageData.hpp +0 -53
- data/include/Gosu/Inspection.hpp +0 -7
- data/lib/gosu/patches.rb +0 -66
- data/lib/gosu/run.rb +0 -20
- data/lib/gosu/swig_patches.rb +0 -110
- data/src/BlockAllocator.cpp +0 -131
- data/src/BlockAllocator.hpp +0 -32
- data/src/DirectoriesApple.cpp +0 -69
- data/src/DirectoriesUnix.cpp +0 -46
- data/src/DirectoriesWin.cpp +0 -65
- data/src/EmptyImageData.hpp +0 -52
- data/src/FileUnix.cpp +0 -99
- data/src/FileWin.cpp +0 -88
- data/src/IO.cpp +0 -60
- data/src/Iconv.hpp +0 -51
- data/src/Inspection.cpp +0 -27
- data/src/LargeImageData.cpp +0 -215
- data/src/LargeImageData.hpp +0 -39
- data/src/Log.hpp +0 -19
- data/src/RubyGosu.cxx +0 -13100
- data/src/RubyGosu.h +0 -49
- data/src/WinUtility.cpp +0 -61
- data/src/WinUtility.hpp +0 -27
data/src/TextBuilder.hpp
CHANGED
@@ -6,6 +6,9 @@
|
|
6
6
|
|
7
7
|
namespace Gosu
|
8
8
|
{
|
9
|
+
// A single word and its formatting context. A "word" is anything that is atomic in terms of
|
10
|
+
// where Gosu can introduce line breaks. Even a single word has several "parts" because e.g. a
|
11
|
+
// single character in the middle could be bold.
|
9
12
|
struct WordInfo
|
10
13
|
{
|
11
14
|
std::vector<FormattedString> parts;
|
@@ -25,16 +28,10 @@ namespace Gosu
|
|
25
28
|
double m_line_spacing;
|
26
29
|
Alignment m_align;
|
27
30
|
|
28
|
-
enum EndOfLineReason
|
29
|
-
{
|
30
|
-
LINE_TOO_LONG,
|
31
|
-
END_OF_PARAGRAPH,
|
32
|
-
END_OF_TEXT
|
33
|
-
};
|
34
|
-
|
35
31
|
// Input.
|
36
32
|
std::vector<WordInfo> m_current_line;
|
37
33
|
int m_current_line_width = 0;
|
34
|
+
enum EndOfLineReason : int;
|
38
35
|
void flush_current_line(EndOfLineReason reason);
|
39
36
|
|
40
37
|
// Output.
|
@@ -42,13 +39,13 @@ namespace Gosu
|
|
42
39
|
int m_used_lines = 0;
|
43
40
|
int m_allocated_lines = 0;
|
44
41
|
void allocate_next_line();
|
45
|
-
void
|
42
|
+
void reallocate(int lines);
|
46
43
|
|
47
44
|
public:
|
48
45
|
TextBuilder(const std::string& font_name, int font_height, int line_spacing, int width,
|
49
46
|
Alignment align);
|
50
47
|
|
51
|
-
void feed_word(std::vector<FormattedString
|
48
|
+
void feed_word(std::vector<FormattedString> word);
|
52
49
|
|
53
50
|
Bitmap move_into_bitmap() &&;
|
54
51
|
};
|
data/src/Texture.cpp
CHANGED
@@ -1,39 +1,35 @@
|
|
1
1
|
#include "Texture.hpp"
|
2
|
-
#include "TexChunk.hpp"
|
3
|
-
#include "Log.hpp"
|
4
2
|
#include <Gosu/Bitmap.hpp>
|
5
|
-
#include <Gosu/Graphics.hpp>
|
6
3
|
#include <Gosu/Platform.hpp>
|
4
|
+
#include "OpenGLContext.hpp"
|
5
|
+
#include "TexChunk.hpp"
|
7
6
|
#include <stdexcept>
|
8
|
-
using namespace std;
|
9
7
|
|
10
|
-
|
8
|
+
Gosu::Texture::Texture(int width, int height, bool retro)
|
9
|
+
: m_bin_packer(width, height),
|
10
|
+
m_tex_name(0),
|
11
|
+
m_retro(retro)
|
11
12
|
{
|
12
|
-
|
13
|
-
|
13
|
+
if (width <= 0 || height <= 0) {
|
14
|
+
throw std::invalid_argument("Gosu::Texture must not be empty");
|
15
|
+
}
|
14
16
|
|
15
|
-
|
16
|
-
: allocator_(width, height), retro_(retro)
|
17
|
-
{
|
18
|
-
log("Allocating a new texture of size %dx%d (retro=%d)", width, height, (int) retro);
|
17
|
+
const OpenGLContext current_context;
|
19
18
|
|
20
|
-
ensure_current_context();
|
21
|
-
|
22
19
|
// Create texture name.
|
23
|
-
glGenTextures(1, &
|
24
|
-
|
20
|
+
glGenTextures(1, &m_tex_name);
|
21
|
+
// GCOV_EXCL_START: Hard to simulate out-of-texture situations.
|
22
|
+
if (m_tex_name == static_cast<GLuint>(-1)) {
|
23
|
+
throw std::runtime_error("Failed to allocate OpenGL texture");
|
24
|
+
}
|
25
|
+
// GCOV_EXCL_END
|
25
26
|
|
26
27
|
// Create empty texture.
|
27
|
-
glBindTexture(GL_TEXTURE_2D,
|
28
|
-
|
29
|
-
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, allocator_.width(), allocator_.height(), 0, GL_RGBA,
|
28
|
+
glBindTexture(GL_TEXTURE_2D, m_tex_name);
|
29
|
+
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_bin_packer.width(), m_bin_packer.height(), 0, GL_RGBA,
|
30
30
|
GL_UNSIGNED_BYTE, nullptr);
|
31
|
-
|
32
|
-
|
33
|
-
GL_UNSIGNED_BYTE, nullptr);
|
34
|
-
#endif
|
35
|
-
|
36
|
-
if (retro || undocumented_retrofication) {
|
31
|
+
|
32
|
+
if (retro) {
|
37
33
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
|
38
34
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
39
35
|
}
|
@@ -41,7 +37,7 @@ Gosu::Texture::Texture(unsigned width, unsigned height, bool retro)
|
|
41
37
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
42
38
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
43
39
|
}
|
44
|
-
|
40
|
+
|
45
41
|
#ifdef GL_CLAMP_TO_EDGE
|
46
42
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
47
43
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
@@ -53,79 +49,65 @@ Gosu::Texture::Texture(unsigned width, unsigned height, bool retro)
|
|
53
49
|
|
54
50
|
Gosu::Texture::~Texture()
|
55
51
|
{
|
56
|
-
|
57
|
-
|
58
|
-
|
52
|
+
try {
|
53
|
+
const OpenGLContext current_context;
|
54
|
+
glDeleteTextures(1, &m_tex_name);
|
55
|
+
} catch (...)
|
56
|
+
{
|
57
|
+
// Leaking is better than throwing in a destructor.
|
58
|
+
}
|
59
59
|
}
|
60
60
|
|
61
|
-
|
61
|
+
std::unique_ptr<Gosu::TexChunk> Gosu::Texture::try_alloc(const Bitmap& bitmap, int padding)
|
62
62
|
{
|
63
|
-
|
64
|
-
}
|
63
|
+
const std::shared_ptr<const Rect> rect = m_bin_packer.alloc(bitmap.width(), bitmap.height());
|
65
64
|
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
}
|
65
|
+
if (!rect) {
|
66
|
+
return nullptr;
|
67
|
+
}
|
70
68
|
|
71
|
-
|
72
|
-
{
|
73
|
-
return tex_name_;
|
74
|
-
}
|
69
|
+
insert(bitmap, rect->x, rect->y);
|
75
70
|
|
76
|
-
|
77
|
-
|
78
|
-
return
|
71
|
+
const Rect rect_without_padding { rect->x + padding, rect->y + padding,
|
72
|
+
rect->width - 2 * padding, rect->height - 2 * padding };
|
73
|
+
return std::make_unique<TexChunk>(shared_from_this(), rect_without_padding, rect);
|
79
74
|
}
|
80
75
|
|
81
|
-
|
76
|
+
void Gosu::Texture::insert(const Gosu::Bitmap& bitmap, int x, int y)
|
82
77
|
{
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
unique_ptr<TexChunk> result(new TexChunk(shared_from_this(),
|
88
|
-
block.left + padding,
|
89
|
-
block.top + padding,
|
90
|
-
block.width - 2 * padding,
|
91
|
-
block.height - 2 * padding,
|
92
|
-
padding));
|
93
|
-
|
94
|
-
ensure_current_context();
|
95
|
-
|
96
|
-
glBindTexture(GL_TEXTURE_2D, tex_name_);
|
97
|
-
glTexSubImage2D(GL_TEXTURE_2D, 0, block.left, block.top, block.width, block.height,
|
98
|
-
Color::GL_FORMAT, GL_UNSIGNED_BYTE, bmp.data());
|
99
|
-
|
100
|
-
return result;
|
101
|
-
}
|
78
|
+
if (!Rect::covering(*this).contains(Rect { x, y, bitmap.width(), bitmap.height() })) {
|
79
|
+
throw std::invalid_argument("Gosu::Texture::insert: Rect exceeds bounds");
|
80
|
+
}
|
102
81
|
|
103
|
-
|
104
|
-
|
105
|
-
|
82
|
+
const OpenGLContext current_context;
|
83
|
+
glBindTexture(GL_TEXTURE_2D, m_tex_name);
|
84
|
+
glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, bitmap.width(), bitmap.height(), GL_RGBA,
|
85
|
+
GL_UNSIGNED_BYTE, bitmap.data());
|
106
86
|
}
|
107
87
|
|
108
|
-
|
88
|
+
Gosu::Bitmap Gosu::Texture::to_bitmap(const Rect& rect) const
|
109
89
|
{
|
110
|
-
|
111
|
-
|
90
|
+
if (!Rect::covering(*this).contains(rect)) {
|
91
|
+
throw std::invalid_argument("Gosu::Texture::to_bitmap: Rect exceeds bounds");
|
92
|
+
}
|
112
93
|
|
113
|
-
Gosu::Bitmap Gosu::Texture::to_bitmap(unsigned x, unsigned y, unsigned width, unsigned height) const
|
114
|
-
{
|
115
94
|
#ifdef GOSU_IS_OPENGLES
|
116
95
|
// See here for one possible implementation: https://github.com/apitrace/apitrace/issues/70
|
117
96
|
// (Could reuse a lot of code from OffScreenTarget)
|
118
|
-
throw logic_error("Texture::to_bitmap not supported
|
97
|
+
throw std::logic_error("Gosu::Texture::to_bitmap not supported in OpenGL ES");
|
119
98
|
#else
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
99
|
+
const OpenGLContext current_context;
|
100
|
+
Bitmap bitmap(width(), height());
|
101
|
+
glBindTexture(GL_TEXTURE_2D, m_tex_name);
|
102
|
+
// This should use glGetTextureSubImage where available: https://stackoverflow.com/a/38148494
|
103
|
+
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, bitmap.data());
|
104
|
+
|
105
|
+
if (rect != Rect::covering(*this)) {
|
106
|
+
Bitmap smaller_bitmap(rect.width, rect.height);
|
107
|
+
smaller_bitmap.insert(bitmap, -rect.x, -rect.y);
|
108
|
+
bitmap = std::move(smaller_bitmap);
|
109
|
+
}
|
110
|
+
|
129
111
|
return bitmap;
|
130
112
|
#endif
|
131
113
|
}
|
data/src/Texture.hpp
CHANGED
@@ -1,29 +1,31 @@
|
|
1
1
|
#pragma once
|
2
2
|
|
3
|
-
#include "BlockAllocator.hpp"
|
4
|
-
#include "GraphicsImpl.hpp"
|
5
|
-
#include "TexChunk.hpp"
|
6
3
|
#include <Gosu/Fwd.hpp>
|
7
|
-
#include
|
4
|
+
#include "BinPacker.hpp"
|
5
|
+
#include "TexChunk.hpp"
|
6
|
+
#include <cstdint>
|
8
7
|
#include <memory>
|
9
|
-
#include <vector>
|
10
8
|
|
11
|
-
|
9
|
+
namespace Gosu
|
12
10
|
{
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
11
|
+
class Texture : public std::enable_shared_from_this<Texture>, private Noncopyable
|
12
|
+
{
|
13
|
+
BinPacker m_bin_packer;
|
14
|
+
std::uint32_t m_tex_name;
|
15
|
+
const bool m_retro;
|
16
|
+
|
17
|
+
public:
|
18
|
+
Texture(int width, int height, bool retro);
|
19
|
+
~Texture();
|
20
|
+
|
21
|
+
int width() const { return m_bin_packer.width(); }
|
22
|
+
int height() const { return m_bin_packer.height(); }
|
23
|
+
std::uint32_t tex_name() const { return m_tex_name; }
|
24
|
+
bool retro() const { return m_retro; }
|
25
|
+
|
26
|
+
[[nodiscard]] std::unique_ptr<TexChunk> try_alloc(const Bitmap& bitmap, int padding);
|
27
|
+
|
28
|
+
void insert(const Bitmap& bitmap, int x, int y);
|
29
|
+
Bitmap to_bitmap(const Rect& rect) const;
|
30
|
+
};
|
31
|
+
}
|
@@ -0,0 +1,150 @@
|
|
1
|
+
#include <Gosu/Bitmap.hpp>
|
2
|
+
#include <Gosu/Graphics.hpp>
|
3
|
+
#include <Gosu/Math.hpp>
|
4
|
+
#include "GraphicsImpl.hpp"
|
5
|
+
#include "TiledDrawable.hpp"
|
6
|
+
#include <cmath>
|
7
|
+
#include <stdexcept>
|
8
|
+
|
9
|
+
Gosu::TiledDrawable::TiledDrawable(const Bitmap& source, const Rect& source_rect, int tile_size,
|
10
|
+
unsigned image_flags)
|
11
|
+
: m_width(source_rect.width),
|
12
|
+
m_height(source_rect.height)
|
13
|
+
{
|
14
|
+
if (!Rect::covering(source).contains(source_rect) || source_rect.empty()) {
|
15
|
+
throw std::invalid_argument("Invalid TiledDrawable source_rect");
|
16
|
+
}
|
17
|
+
if (tile_size <= 0) {
|
18
|
+
throw std::invalid_argument("tile_size must be greater than 0");
|
19
|
+
}
|
20
|
+
|
21
|
+
// Manually round up during this integer division.
|
22
|
+
const int tiles_x = (source_rect.width + tile_size - 1) / tile_size;
|
23
|
+
const int tiles_y = (source_rect.height + tile_size - 1) / tile_size;
|
24
|
+
|
25
|
+
for (int ty = 0; ty < tiles_y; ++ty) {
|
26
|
+
for (int tx = 0; tx < tiles_x; ++tx) {
|
27
|
+
Rect tile_source_rect { .x = source_rect.x + tx * tile_size,
|
28
|
+
.y = source_rect.y + ty * tile_size,
|
29
|
+
.width = tile_size,
|
30
|
+
.height = tile_size };
|
31
|
+
tile_source_rect.clip_to(source_rect);
|
32
|
+
|
33
|
+
unsigned local_flags = image_flags;
|
34
|
+
|
35
|
+
// The left edge must always be tileable in all columns except for the first.
|
36
|
+
if (tx > 0) {
|
37
|
+
local_flags |= IF_TILEABLE_LEFT;
|
38
|
+
}
|
39
|
+
// The right edge must always be tileable in all columns except for the last.
|
40
|
+
if (tx < tiles_x - 1) {
|
41
|
+
local_flags |= IF_TILEABLE_RIGHT;
|
42
|
+
}
|
43
|
+
// The top edge must always be tileable in all rows except for the first.
|
44
|
+
if (ty > 0) {
|
45
|
+
local_flags |= IF_TILEABLE_TOP;
|
46
|
+
}
|
47
|
+
// The bottom edge must always be tileable in all rows except for the last.
|
48
|
+
if (ty < tiles_y - 1) {
|
49
|
+
local_flags |= IF_TILEABLE_BOTTOM;
|
50
|
+
}
|
51
|
+
|
52
|
+
m_tiles.push_back(Tile {
|
53
|
+
.x = tile_source_rect.x,
|
54
|
+
.y = tile_source_rect.y,
|
55
|
+
.data = create_drawable(source, tile_source_rect, local_flags),
|
56
|
+
});
|
57
|
+
}
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
Gosu::TiledDrawable::TiledDrawable(const TiledDrawable& parent, const Rect& rect)
|
62
|
+
: m_width(rect.width),
|
63
|
+
m_height(rect.height)
|
64
|
+
{
|
65
|
+
for (const Tile& tile : parent.m_tiles) {
|
66
|
+
// rect is the source area on the parent, tile_rect is this tile's area on the parent.
|
67
|
+
Rect tile_rect { tile.x, tile.y, tile.data->width(), tile.data->height() };
|
68
|
+
// The x/y source position on the tile...
|
69
|
+
int x = 0, y = 0;
|
70
|
+
// ...must be adjusted while clipping.
|
71
|
+
tile_rect.clip_to(rect, &x, &y);
|
72
|
+
// If there is anything left of the tile_rect after clipping, we need to create a tile too.
|
73
|
+
if (!tile_rect.empty()) {
|
74
|
+
m_tiles.push_back(Tile {
|
75
|
+
.x = tile.x - rect.x,
|
76
|
+
.y = tile.y - rect.y,
|
77
|
+
.data = tile.data->subimage(Rect { x, y, tile_rect.width, tile_rect.height }),
|
78
|
+
});
|
79
|
+
}
|
80
|
+
}
|
81
|
+
}
|
82
|
+
|
83
|
+
void Gosu::TiledDrawable::draw(double x1, double y1, Color c1, double x2, double y2, Color c2,
|
84
|
+
double x3, double y3, Color c3, double x4, double y4, Color c4,
|
85
|
+
ZPos z, BlendMode mode) const
|
86
|
+
{
|
87
|
+
normalize_coordinates(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
|
88
|
+
|
89
|
+
double f_width = m_width, f_height = m_height;
|
90
|
+
for (const Tile& tile : m_tiles) {
|
91
|
+
double rel_x_l = tile.x / f_width;
|
92
|
+
double rel_x_r = (tile.x + tile.data->width()) / f_width;
|
93
|
+
double rel_y_t = tile.y / f_height;
|
94
|
+
double rel_y_b = (tile.y + tile.data->height()) / f_height;
|
95
|
+
|
96
|
+
using std::lerp;
|
97
|
+
// NOLINTNEXTLINE(cppcoreguidelines-macro-usage)
|
98
|
+
#define LERP2D(what, x_weight, y_weight) \
|
99
|
+
lerp(lerp(what##1, what##3, y_weight), lerp(what##2, what##4, y_weight), x_weight);
|
100
|
+
|
101
|
+
double x_t_l = LERP2D(x, rel_x_l, rel_y_t);
|
102
|
+
double x_t_r = LERP2D(x, rel_x_r, rel_y_t);
|
103
|
+
double x_b_l = LERP2D(x, rel_x_l, rel_y_b);
|
104
|
+
double x_b_r = LERP2D(x, rel_x_r, rel_y_b);
|
105
|
+
|
106
|
+
double y_t_l = LERP2D(y, rel_x_l, rel_y_t);
|
107
|
+
double y_t_r = LERP2D(y, rel_x_r, rel_y_t);
|
108
|
+
double y_b_l = LERP2D(y, rel_x_l, rel_y_b);
|
109
|
+
double y_b_r = LERP2D(y, rel_x_r, rel_y_b);
|
110
|
+
|
111
|
+
Color c_t_l = LERP2D(c, rel_x_l, rel_y_t);
|
112
|
+
Color c_t_r = LERP2D(c, rel_x_r, rel_y_t);
|
113
|
+
Color c_b_l = LERP2D(c, rel_x_l, rel_y_b);
|
114
|
+
Color c_b_r = LERP2D(c, rel_x_r, rel_y_b);
|
115
|
+
|
116
|
+
tile.data->draw(x_t_l, y_t_l, c_t_l, x_t_r, y_t_r, c_t_r, //
|
117
|
+
x_b_l, y_b_l, c_b_l, x_b_r, y_b_r, c_b_r, z, mode);
|
118
|
+
}
|
119
|
+
}
|
120
|
+
|
121
|
+
std::unique_ptr<Gosu::Drawable> Gosu::TiledDrawable::subimage(const Rect& source_rect) const
|
122
|
+
{
|
123
|
+
auto tiled_drawable = std::make_unique<TiledDrawable>(*this, source_rect);
|
124
|
+
if (tiled_drawable->m_tiles.size() == 1) {
|
125
|
+
// Optimization: If the tiled subimage only contains a single tile, return that.
|
126
|
+
return std::move(tiled_drawable->m_tiles[0].data);
|
127
|
+
}
|
128
|
+
return tiled_drawable;
|
129
|
+
}
|
130
|
+
|
131
|
+
Gosu::Bitmap Gosu::TiledDrawable::to_bitmap() const
|
132
|
+
{
|
133
|
+
Bitmap bitmap(width(), height());
|
134
|
+
for (const Tile& tile : m_tiles) {
|
135
|
+
bitmap.insert(tile.data->to_bitmap(), tile.x, tile.y);
|
136
|
+
}
|
137
|
+
return bitmap;
|
138
|
+
}
|
139
|
+
|
140
|
+
void Gosu::TiledDrawable::insert(const Bitmap& bitmap, int x, int y)
|
141
|
+
{
|
142
|
+
const Rect target_rect { x, y, bitmap.width(), bitmap.height() };
|
143
|
+
for (const Tile& tile : m_tiles) {
|
144
|
+
Rect tile_rect { tile.x, tile.y, tile.data->width(), tile.data->height() };
|
145
|
+
tile_rect.clip_to(target_rect);
|
146
|
+
if (!tile_rect.empty()) {
|
147
|
+
tile.data->insert(bitmap, x - tile.x, y - tile.y);
|
148
|
+
}
|
149
|
+
}
|
150
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include <Gosu/Fwd.hpp>
|
4
|
+
#include <Gosu/Drawable.hpp>
|
5
|
+
#include <Gosu/Platform.hpp>
|
6
|
+
#include <functional>
|
7
|
+
#include <memory>
|
8
|
+
#include <vector>
|
9
|
+
|
10
|
+
namespace Gosu
|
11
|
+
{
|
12
|
+
/// When an image file is too large to be represented by a single OpenGL texture, Gosu automatically
|
13
|
+
/// splits it up into a rectangle of tiles instead of throwing an error.
|
14
|
+
class TiledDrawable : public Drawable
|
15
|
+
{
|
16
|
+
int m_width, m_height;
|
17
|
+
struct Tile
|
18
|
+
{
|
19
|
+
int x = 0, y = 0;
|
20
|
+
std::unique_ptr<Drawable> data = nullptr;
|
21
|
+
};
|
22
|
+
std::vector<Tile> m_tiles;
|
23
|
+
|
24
|
+
public:
|
25
|
+
TiledDrawable(const Bitmap& source, const Rect& source_rect, int tile_size,
|
26
|
+
unsigned image_flags);
|
27
|
+
/// This constructor is used to implement subimage().
|
28
|
+
TiledDrawable(const TiledDrawable& parent, const Rect& rect);
|
29
|
+
|
30
|
+
int width() const override { return m_width; }
|
31
|
+
int height() const override { return m_height; }
|
32
|
+
|
33
|
+
void draw(double x1, double y1, Color c1, //
|
34
|
+
double x2, double y2, Color c2, //
|
35
|
+
double x3, double y3, Color c3, //
|
36
|
+
double x4, double y4, Color c4, //
|
37
|
+
ZPos z, BlendMode mode) const override;
|
38
|
+
|
39
|
+
const GLTexInfo* gl_tex_info() const override { return nullptr; }
|
40
|
+
|
41
|
+
std::unique_ptr<Drawable> subimage(const Rect& rect) const override;
|
42
|
+
|
43
|
+
Bitmap to_bitmap() const override;
|
44
|
+
|
45
|
+
void insert(const Bitmap& bitmap, int x, int y) override;
|
46
|
+
};
|
47
|
+
}
|
data/src/TimingApple.cpp
CHANGED
data/src/Transform.cpp
CHANGED
@@ -1,73 +1,68 @@
|
|
1
|
-
// Default matrices, adapted from original Transform support
|
2
|
-
// contribution by erisdiscord. Thank you!
|
1
|
+
// Default matrices, adapted from original Transform support contribution by erisdiscord. Thank you!
|
3
2
|
|
4
|
-
#include "GraphicsImpl.hpp"
|
5
|
-
#include <Gosu/GraphicsBase.hpp>
|
6
3
|
#include <Gosu/Math.hpp>
|
4
|
+
#include <Gosu/Transform.hpp>
|
7
5
|
#include <cmath>
|
8
|
-
using namespace std;
|
9
6
|
|
10
|
-
Gosu::Transform
|
7
|
+
void Gosu::Transform::apply(double& x, double& y) const
|
11
8
|
{
|
12
|
-
double
|
13
|
-
double
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
0, 0, 0, 1
|
19
|
-
};
|
20
|
-
if (around_x != 0 || around_y != 0) {
|
21
|
-
result = concat(concat(translate(-around_x, -around_y), result),
|
22
|
-
translate(around_x, around_y));
|
9
|
+
double in[4] = { x, y, 0, 1 };
|
10
|
+
double out[4] = { 0, 0, 0, 0 };
|
11
|
+
for (int i = 0; i < 4; ++i) {
|
12
|
+
for (int j = 0; j < 4; ++j) {
|
13
|
+
out[i] += in[j] * matrix[j * 4 + i];
|
14
|
+
}
|
23
15
|
}
|
24
|
-
|
16
|
+
x = out[0] / out[3];
|
17
|
+
y = out[1] / out[3];
|
25
18
|
}
|
26
19
|
|
27
|
-
Gosu::Transform Gosu::translate(double x, double y)
|
20
|
+
Gosu::Transform Gosu::Transform::translate(double x, double y)
|
28
21
|
{
|
29
|
-
Transform
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
x, y, 0, 1
|
34
|
-
};
|
35
|
-
return result;
|
22
|
+
return Transform { 1, 0, 0, 0, //
|
23
|
+
0, 1, 0, 0, //
|
24
|
+
0, 0, 1, 0, //
|
25
|
+
x, y, 0, 1 };
|
36
26
|
}
|
37
27
|
|
38
|
-
Gosu::Transform Gosu::
|
28
|
+
Gosu::Transform Gosu::Transform::rotate(double angle)
|
39
29
|
{
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
return result;
|
30
|
+
double c = std::cos(degrees_to_radians(angle));
|
31
|
+
double s = std::sin(degrees_to_radians(angle));
|
32
|
+
return Transform { +c, +s, 0, 0, //
|
33
|
+
-s, +c, 0, 0, //
|
34
|
+
0, 0, 1, 0, //
|
35
|
+
0, 0, 0, 1 };
|
47
36
|
}
|
48
37
|
|
49
|
-
Gosu::Transform Gosu::scale(double
|
38
|
+
Gosu::Transform Gosu::Transform::scale(double factor)
|
50
39
|
{
|
51
|
-
Transform
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
40
|
+
return Transform { factor, 0, 0, 0, //
|
41
|
+
0, factor, 0, 0, //
|
42
|
+
0, 0, 1, 0, //
|
43
|
+
0, 0, 0, 1 };
|
44
|
+
}
|
45
|
+
|
46
|
+
Gosu::Transform Gosu::Transform::scale(double scale_x, double scale_y)
|
47
|
+
{
|
48
|
+
return Transform { scale_x, 0, 0, 0, //
|
49
|
+
0, scale_y, 0, 0, //
|
50
|
+
0, 0, 1, 0, //
|
51
|
+
0, 0, 0, 1 };
|
52
|
+
}
|
53
|
+
|
54
|
+
Gosu::Transform Gosu::Transform::around(double around_x, double around_y) const
|
55
|
+
{
|
56
|
+
return translate(-around_x, -around_y) * *this * translate(around_x, around_y);
|
62
57
|
}
|
63
58
|
|
64
|
-
Gosu::Transform Gosu::
|
59
|
+
Gosu::Transform Gosu::Transform::operator*(const Transform& rhs) const
|
65
60
|
{
|
66
|
-
Transform result;
|
61
|
+
Transform result { 0 };
|
67
62
|
for (int i = 0; i < 16; ++i) {
|
68
|
-
result[i] = 0;
|
63
|
+
result.matrix[i] = 0;
|
69
64
|
for (int j = 0; j < 4; ++j) {
|
70
|
-
result[i] +=
|
65
|
+
result.matrix[i] += matrix[i / 4 * 4 + j] * rhs.matrix[i % 4 + j * 4];
|
71
66
|
}
|
72
67
|
}
|
73
68
|
return result;
|