gosu 0.10.9.pre1 → 0.11.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. data/Gosu/Audio.hpp +35 -66
  3. data/Gosu/AutoLink.hpp +14 -16
  4. data/Gosu/Bitmap.hpp +50 -37
  5. data/Gosu/Buttons.hpp +246 -265
  6. data/Gosu/Color.hpp +32 -76
  7. data/Gosu/Directories.hpp +14 -17
  8. data/Gosu/Font.hpp +28 -34
  9. data/Gosu/Fwd.hpp +27 -31
  10. data/Gosu/Gosu.hpp +2 -5
  11. data/Gosu/Graphics.hpp +31 -48
  12. data/Gosu/GraphicsBase.hpp +27 -58
  13. data/Gosu/IO.hpp +44 -56
  14. data/Gosu/Image.hpp +29 -73
  15. data/Gosu/ImageData.hpp +13 -17
  16. data/Gosu/Input.hpp +42 -57
  17. data/Gosu/Inspection.hpp +2 -6
  18. data/Gosu/Math.hpp +32 -38
  19. data/Gosu/Platform.hpp +10 -29
  20. data/Gosu/Text.hpp +30 -39
  21. data/Gosu/TextInput.hpp +29 -36
  22. data/Gosu/Timing.hpp +14 -16
  23. data/Gosu/Utility.hpp +10 -15
  24. data/Gosu/Version.hpp +13 -14
  25. data/Gosu/Window.hpp +53 -68
  26. data/README.md +23 -11
  27. data/ext/gosu/extconf.rb +31 -81
  28. data/lib/gosu/patches.rb +35 -19
  29. data/lib/gosu/run.rb +13 -4
  30. data/rdoc/gosu.rb +24 -20
  31. data/src/ALChannelManagement.hpp +119 -0
  32. data/src/{Audio/Audio.cpp → Audio.cpp} +177 -211
  33. data/src/AudioFile.hpp +57 -0
  34. data/src/AudioToolboxFile.hpp +214 -0
  35. data/src/Bitmap.cpp +159 -0
  36. data/src/BitmapIO.cpp +141 -0
  37. data/src/BlockAllocator.cpp +133 -0
  38. data/src/{Graphics/BlockAllocator.hpp → BlockAllocator.hpp} +34 -35
  39. data/src/ClipRectStack.hpp +87 -0
  40. data/src/{Graphics/Color.cpp → Color.cpp} +30 -28
  41. data/src/DirectoriesApple.cpp +68 -0
  42. data/src/DirectoriesUnix.cpp +20 -18
  43. data/src/DirectoriesWin.cpp +40 -41
  44. data/src/DrawOp.hpp +168 -0
  45. data/src/DrawOpQueue.hpp +190 -0
  46. data/src/FileUnix.cpp +40 -46
  47. data/src/FileWin.cpp +42 -38
  48. data/src/Font.cpp +165 -0
  49. data/src/{Text/FormattedString.hpp → FormattedString.hpp} +114 -114
  50. data/src/GosuAppDelegate.cpp +30 -0
  51. data/src/{UIKit/GosuAppDelegate.h → GosuAppDelegate.h} +0 -0
  52. data/src/{UIKit/GosuGLView.mm → GosuGLView.cpp} +22 -17
  53. data/src/{UIKit/GosuGLView.h → GosuGLView.h} +0 -0
  54. data/src/GosuViewController.cpp +231 -0
  55. data/src/{UIKit/GosuViewController.h → GosuViewController.h} +0 -0
  56. data/src/Graphics.cpp +464 -0
  57. data/src/{Graphics/Common.hpp → GraphicsImpl.hpp} +29 -32
  58. data/src/IO.cpp +17 -16
  59. data/src/Iconv.hpp +13 -22
  60. data/src/Image.cpp +142 -0
  61. data/src/Input.cpp +459 -0
  62. data/src/InputUIKit.cpp +197 -0
  63. data/src/Inspection.cpp +4 -5
  64. data/src/LargeImageData.cpp +151 -0
  65. data/src/LargeImageData.hpp +43 -0
  66. data/src/{Graphics/Macro.cpp → Macro.cpp} +77 -78
  67. data/src/Macro.hpp +30 -0
  68. data/src/Math.cpp +17 -29
  69. data/src/{Audio/OggFile.hpp → OggFile.hpp} +19 -24
  70. data/src/RenderState.hpp +205 -0
  71. data/src/Resolution.cpp +86 -0
  72. data/src/ResolutionApple.cpp +25 -0
  73. data/{ext/gosu/gosu_wrap.cxx → src/RubyGosu.cxx} +2256 -1707
  74. data/{ext/gosu/gosu_wrap.h → src/RubyGosu.h} +9 -9
  75. data/src/{Audio/SndFile.hpp → SndFile.hpp} +54 -43
  76. data/src/TexChunk.cpp +117 -0
  77. data/src/{Graphics/TexChunk.hpp → TexChunk.hpp} +13 -18
  78. data/src/Text.cpp +371 -0
  79. data/src/TextApple.cpp +209 -0
  80. data/src/TextInput.cpp +278 -0
  81. data/src/TextTTFWin.cpp +251 -0
  82. data/src/{Text/TextUnix.cpp → TextUnix.cpp} +96 -92
  83. data/src/TextWin.cpp +194 -0
  84. data/src/{Graphics/Texture.cpp → Texture.cpp} +35 -38
  85. data/src/{Graphics/Texture.hpp → Texture.hpp} +9 -13
  86. data/src/TimingApple.cpp +11 -7
  87. data/src/TimingUnix.cpp +13 -7
  88. data/src/TimingWin.cpp +6 -1
  89. data/src/{Graphics/Transform.cpp → Transform.cpp} +17 -12
  90. data/src/{Graphics/TransformStack.hpp → TransformStack.hpp} +24 -25
  91. data/src/Utility.cpp +29 -70
  92. data/src/UtilityApple.cpp +52 -0
  93. data/src/UtilityWin.cpp +7 -4
  94. data/src/Version.cpp +22 -0
  95. data/src/WinMain.cpp +30 -33
  96. data/src/WinUtility.cpp +24 -22
  97. data/src/WinUtility.hpp +11 -20
  98. data/src/Window.cpp +142 -112
  99. data/src/WindowUIKit.cpp +155 -0
  100. data/src/stb_image.h +384 -173
  101. data/src/stb_vorbis.c +20 -18
  102. metadata +60 -62
  103. data/Gosu/TR1.hpp +0 -56
  104. data/src/AppleUtility.hpp +0 -66
  105. data/src/Audio/ALChannelManagement.hpp +0 -114
  106. data/src/Audio/Audio.mm +0 -1
  107. data/src/Audio/AudioFile.hpp +0 -53
  108. data/src/Audio/AudioToolboxFile.hpp +0 -207
  109. data/src/Bitmap/Bitmap.cpp +0 -183
  110. data/src/Bitmap/BitmapIO.cpp +0 -176
  111. data/src/DirectoriesApple.mm +0 -71
  112. data/src/Graphics/BlockAllocator.cpp +0 -142
  113. data/src/Graphics/ClipRectStack.hpp +0 -93
  114. data/src/Graphics/DrawOp.hpp +0 -175
  115. data/src/Graphics/DrawOpQueue.hpp +0 -188
  116. data/src/Graphics/Graphics.cpp +0 -478
  117. data/src/Graphics/Image.cpp +0 -193
  118. data/src/Graphics/LargeImageData.cpp +0 -133
  119. data/src/Graphics/LargeImageData.hpp +0 -46
  120. data/src/Graphics/Macro.hpp +0 -36
  121. data/src/Graphics/RenderState.hpp +0 -211
  122. data/src/Graphics/Resolution.cpp +0 -91
  123. data/src/Graphics/ResolutionApple.mm +0 -19
  124. data/src/Graphics/TexChunk.cpp +0 -112
  125. data/src/Input/Input.cpp +0 -463
  126. data/src/Input/InputUIKit.mm +0 -190
  127. data/src/Input/TextInput.cpp +0 -261
  128. data/src/Text/Font.cpp +0 -175
  129. data/src/Text/Text.cpp +0 -391
  130. data/src/Text/TextApple.mm +0 -227
  131. data/src/Text/TextTTFWin.cpp +0 -249
  132. data/src/Text/TextWin.cpp +0 -186
  133. data/src/UIKit/GosuAppDelegate.mm +0 -24
  134. data/src/UIKit/GosuViewController.mm +0 -211
  135. data/src/UtilityApple.mm +0 -63
  136. data/src/WindowUIKit.mm +0 -139
@@ -1,91 +0,0 @@
1
- #include <Gosu/Gosu.hpp>
2
-
3
- #ifdef GOSU_IS_WIN
4
- #include <windows.h>
5
-
6
- // Note: On Windows, do not use the SDL 2 code below. It reports 2560x1920 in my Windows VM, which is running at 2560x1080. (SDL 2.0.3)
7
-
8
- unsigned Gosu::screenWidth()
9
- {
10
- return GetSystemMetrics(SM_CXSCREEN);
11
- }
12
-
13
- unsigned Gosu::screenHeight()
14
- {
15
- return GetSystemMetrics(SM_CYSCREEN);
16
- }
17
-
18
- namespace
19
- {
20
- SIZE calculateAvailableSize()
21
- {
22
- RECT workArea;
23
- SystemParametersInfo(SPI_GETWORKAREA, 0, &workArea, 0);
24
-
25
- RECT windowSize = workArea;
26
- // Note: This should be kept in sync with STYLE_NORMAL in SDL_windowswindow.c.
27
- DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
28
- AdjustWindowRectEx(&windowSize, style, FALSE, 0);
29
-
30
- SIZE availableSize;
31
- availableSize.cx = 2 * (workArea.right - workArea.left) - (windowSize.right - windowSize.left);
32
- availableSize.cy = 2 * (workArea.bottom - workArea.top) - (windowSize.bottom - windowSize.top);
33
- return availableSize;
34
- }
35
-
36
- SIZE availableSize = calculateAvailableSize();
37
- }
38
-
39
- unsigned Gosu::availableWidth()
40
- {
41
- return availableSize.cx;
42
- }
43
-
44
- unsigned Gosu::availableHeight()
45
- {
46
- return availableSize.cy;
47
- }
48
- #else
49
- #include <SDL.h>
50
-
51
- namespace
52
- {
53
- SDL_DisplayMode currentDisplayMode = { 0, 0 };
54
- }
55
-
56
- unsigned Gosu::screenWidth()
57
- {
58
- // TODO - not thread-safe
59
- if (currentDisplayMode.w == 0) {
60
- SDL_Init(SDL_INIT_VIDEO);
61
- SDL_GetDisplayMode(0, 0, &currentDisplayMode);
62
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
63
- }
64
- return currentDisplayMode.w;
65
- }
66
-
67
- unsigned Gosu::screenHeight()
68
- {
69
- // TODO - not thread-safe
70
- if (currentDisplayMode.h == 0) {
71
- SDL_Init(SDL_INIT_VIDEO);
72
- SDL_GetDisplayMode(0, 0, &currentDisplayMode);
73
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
74
- }
75
- return currentDisplayMode.h;
76
- }
77
-
78
- // Pessimistic fallback implementation for availableWidth / availableHeight.
79
-
80
- #if !defined(GOSU_IS_MAC)
81
- unsigned Gosu::availableWidth()
82
- {
83
- return Gosu::screenWidth() * 0.9;
84
- }
85
-
86
- unsigned Gosu::availableHeight()
87
- {
88
- return Gosu::screenHeight() * 0.8;
89
- }
90
- #endif
91
- #endif
@@ -1,19 +0,0 @@
1
- #include <Gosu/Gosu.hpp>
2
- #import <AppKit/AppKit.h>
3
-
4
- namespace Gosu
5
- {
6
- NSUInteger styleMaskFromSDL2 = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask;
7
- NSRect availableFrame = [[[NSScreen screens] objectAtIndex:0] visibleFrame];
8
- NSRect availableContentFrame = [NSWindow contentRectForFrameRect:availableFrame styleMask:styleMaskFromSDL2];
9
- }
10
-
11
- unsigned Gosu::availableWidth()
12
- {
13
- return availableContentFrame.size.width;
14
- }
15
-
16
- unsigned Gosu::availableHeight()
17
- {
18
- return availableContentFrame.size.height;
19
- }
@@ -1,112 +0,0 @@
1
- #include "TexChunk.hpp"
2
- #include "Texture.hpp"
3
- #include "DrawOpQueue.hpp"
4
- #include <Gosu/Bitmap.hpp>
5
- #include <Gosu/Graphics.hpp>
6
-
7
- void Gosu::TexChunk::setTexInfo()
8
- {
9
- info.texName = texture->texName();
10
- float textureSize = texture->size();
11
- info.left = x / textureSize;
12
- info.top = y / textureSize;
13
- info.right = (x + w) / textureSize;
14
- info.bottom = (y + h) / textureSize;
15
- }
16
-
17
- Gosu::TexChunk::TexChunk(std::tr1::shared_ptr<Texture> texture,
18
- int x, int y, int w, int h, int padding)
19
- : texture(texture), x(x), y(y), w(w), h(h), padding(padding)
20
- {
21
- setTexInfo();
22
- }
23
-
24
- Gosu::TexChunk::TexChunk(const TexChunk& parentChunk, int x, int y, int w, int h)
25
- : texture(parentChunk.texture), x(parentChunk.x + x), y(parentChunk.y + y), w(w), h(h), padding(0)
26
- {
27
- setTexInfo();
28
- texture->block(this->x, this->y, this->w, this->h);
29
- }
30
-
31
- Gosu::TexChunk::~TexChunk()
32
- {
33
- texture->free(x - padding, y - padding, w + 2 * padding, h + 2 * padding);
34
- }
35
-
36
- void Gosu::TexChunk::draw(double x1, double y1, Color c1,
37
- double x2, double y2, Color c2,
38
- double x3, double y3, Color c3,
39
- double x4, double y4, Color c4,
40
- ZPos z, AlphaMode mode) const
41
- {
42
- DrawOp op;
43
- op.renderState.texture = texture;
44
- op.renderState.mode = mode;
45
-
46
- reorderCoordinatesIfNecessary(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
47
-
48
- op.verticesOrBlockIndex = 4;
49
- op.vertices[0] = DrawOp::Vertex(x1, y1, c1);
50
- op.vertices[1] = DrawOp::Vertex(x2, y2, c2);
51
- // TODO: Should be harmonized
52
- #ifdef GOSU_IS_OPENGLES
53
- op.vertices[2] = DrawOp::Vertex(x3, y3, c3);
54
- op.vertices[3] = DrawOp::Vertex(x4, y4, c4);
55
- #else
56
- op.vertices[3] = DrawOp::Vertex(x3, y3, c3);
57
- op.vertices[2] = DrawOp::Vertex(x4, y4, c4);
58
- #endif
59
- op.left = info.left;
60
- op.top = info.top;
61
- op.right = info.right;
62
- op.bottom = info.bottom;
63
-
64
- op.z = z;
65
- Graphics::scheduleDrawOp(op);
66
- }
67
-
68
- const Gosu::GLTexInfo* Gosu::TexChunk::glTexInfo() const
69
- {
70
- return &info;
71
- }
72
-
73
- Gosu::Bitmap Gosu::TexChunk::toBitmap() const
74
- {
75
- return texture->toBitmap(x, y, w, h);
76
- }
77
-
78
- GOSU_UNIQUE_PTR<Gosu::ImageData> Gosu::TexChunk::subimage(int x, int y, int width, int height) const
79
- {
80
- return GOSU_UNIQUE_PTR<Gosu::ImageData>(new TexChunk(*this, x, y, width, height));
81
- }
82
-
83
- void Gosu::TexChunk::insert(const Bitmap& original, int x, int y)
84
- {
85
- // TODO: Should respect borderFlags.
86
-
87
- Bitmap alternate;
88
- const Bitmap* bitmap = &original;
89
- if (x < 0 || y < 0 || x + original.width() > w || y + original.height() > h)
90
- {
91
- int offsetX = 0, offsetY = 0, trimmedWidth = original.width(), trimmedHeight = original.height();
92
- if (x < 0)
93
- offsetX = x, trimmedWidth += x, x = 0;
94
- if (y < 0)
95
- offsetY = y, trimmedHeight += y, y = 0;
96
- if (x + trimmedWidth > w)
97
- trimmedWidth -= (w - x - trimmedWidth);
98
- if (y + trimmedHeight > h)
99
- trimmedHeight -= (h - y - trimmedHeight);
100
-
101
- if (trimmedWidth <= 0 || trimmedHeight <= 0)
102
- return;
103
-
104
- alternate.resize(trimmedWidth, trimmedHeight);
105
- alternate.insert(original, offsetX, offsetY);
106
- bitmap = &alternate;
107
- }
108
-
109
- glBindTexture(GL_TEXTURE_2D, texName());
110
- glTexSubImage2D(GL_TEXTURE_2D, 0, this->x + x, this->y + y, bitmap->width(), bitmap->height(),
111
- Color::GL_FORMAT, GL_UNSIGNED_BYTE, bitmap->data());
112
- }
@@ -1,463 +0,0 @@
1
- #include <Gosu/Input.hpp>
2
- #include <Gosu/TextInput.hpp>
3
- #include <Gosu/TR1.hpp>
4
- #include <Gosu/Utility.hpp>
5
- #include <SDL.h>
6
- #include <cwctype>
7
- #include <cstdlib>
8
- #include <algorithm>
9
-
10
- namespace
11
- {
12
- void cleanup();
13
-
14
- void requireSDLVideo()
15
- {
16
- static bool initialized = false;
17
- if (!initialized)
18
- {
19
- SDL_InitSubSystem(SDL_INIT_VIDEO);
20
- initialized = true;
21
- std::atexit(cleanup);
22
- }
23
- }
24
-
25
- void cleanup()
26
- {
27
- SDL_QuitSubSystem(SDL_INIT_VIDEO);
28
- }
29
-
30
- std::tr1::array<bool, Gosu::numButtons> buttonStates = { { false } };
31
- }
32
-
33
- struct Gosu::Input::Impl
34
- {
35
- Input& input;
36
- SDL_Window* window;
37
- TextInput* textInput;
38
- double mouseX, mouseY;
39
- double mouseFactorX, mouseFactorY;
40
- double mouseOffsetX, mouseOffsetY;
41
-
42
- Impl(Input& input, SDL_Window* window)
43
- : input(input), window(window), textInput(NULL)
44
- {
45
- mouseFactorX = mouseFactorY = 1;
46
- mouseOffsetX = mouseOffsetY = 0;
47
- }
48
-
49
- void updateMousePosition()
50
- {
51
- // Do not use GetGlobalMouseState on Linux for now to prevent this bug:
52
- // https://github.com/gosu/gosu/issues/326
53
- // Once SDL 2.0.5 has been released, we can use this function as a workaround:
54
- // https://wiki.libsdl.org/SDL_GetWindowBordersSize
55
- #if SDL_VERSION_ATLEAST(2, 0, 4) && !defined(GOSU_IS_X)
56
- int x, y, windowX, windowY;
57
- SDL_GetWindowPosition(window, &windowX, &windowY);
58
- SDL_GetGlobalMouseState(&x, &y);
59
- mouseX = x - windowX, mouseY = y - windowY;
60
- #else
61
- int x, y;
62
- SDL_GetMouseState(&x, &y);
63
- mouseX = x, mouseY = y;
64
- #endif
65
- }
66
-
67
- void setMousePosition(double x, double y)
68
- {
69
- SDL_WarpMouseInWindow(window,
70
- (x - mouseOffsetX) / mouseFactorX, (y - mouseOffsetY) / mouseFactorY);
71
-
72
- #if SDL_VERSION_ATLEAST(2, 0, 4) && !defined(GOSU_IS_X)
73
- // On systems where we have a working GetGlobalMouseState, we can warp the mouse and
74
- // retrieve its position directly afterwards.
75
- updateMousePosition();
76
- #else
77
- // Otherwise, we have to assume that setting the position worked, because if we update the
78
- // mouse position now, we'll get the previous position.
79
- mouseX = x, mouseY = y;
80
- #endif
81
- }
82
-
83
- void enqueueEvent(int id, bool down)
84
- {
85
- eventQueue.push_back(down ? id : ~id);
86
- }
87
-
88
- void dispatchEnqueuedEvents()
89
- {
90
- for (unsigned i = 0; i < eventQueue.size(); ++i) {
91
- int event = eventQueue[i];
92
- bool down = (event >= 0);
93
- Button button(down ? event : ~event);
94
-
95
- buttonStates[button.id()] = down;
96
- if (down && input.onButtonDown) {
97
- input.onButtonDown(button);
98
- }
99
- else if (!down && input.onButtonUp) {
100
- input.onButtonUp(button);
101
- }
102
- }
103
- eventQueue.clear();
104
- }
105
-
106
- void initializeGamepads()
107
- {
108
- SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER);
109
-
110
- int numGamepads = std::min<int>(Gosu::numGamepads, SDL_NumJoysticks());
111
-
112
- for (int i = 0; i < numGamepads; ++i) {
113
- // Prefer the SDL_GameController API...
114
- if (SDL_IsGameController(i)) {
115
- SDL_GameController *gameController = SDL_GameControllerOpen(i);
116
- if (gameController) {
117
- gameControllers.push_back(gameController);
118
- continue;
119
- }
120
- }
121
- // ...but fall back on the good, old SDL_Joystick API :)
122
- SDL_Joystick *joystick = SDL_JoystickOpen(i);
123
- if (joystick) {
124
- joysticks.push_back(joystick);
125
- }
126
- }
127
- }
128
-
129
- void releaseGamepads()
130
- {
131
- std::for_each(joysticks.begin(), joysticks.end(), &SDL_JoystickClose);
132
- joysticks.clear();
133
- std::for_each(gameControllers.begin(), gameControllers.end(), &SDL_GameControllerClose);
134
- gameControllers.clear();
135
-
136
- SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
137
- }
138
-
139
- typedef std::tr1::array<bool, gpNumPerGamepad> GamepadBuffer;
140
-
141
- void pollGamepads()
142
- {
143
- // This gamepad is an OR-ed version of all the other gamepads. If button
144
- // 3 is pressed on any attached gamepad, down(gpButton3) will return
145
- // true. This is handy for singleplayer games.
146
- GamepadBuffer anyGamepad = { false };
147
-
148
- std::size_t availableGamepads = gameControllers.size() + joysticks.size();
149
-
150
- for (int i = 0; i < availableGamepads; ++i) {
151
- GamepadBuffer currentGamepad = { false };
152
-
153
- // Poll data from SDL, using either of two API interfaces.
154
- if (i < gameControllers.size()) {
155
- SDL_GameController *gameController = gameControllers[i];
156
- pollGameController(gameController, currentGamepad);
157
- }
158
- else {
159
- SDL_Joystick *joystick = joysticks[i - gameControllers.size()];
160
- pollJoystick(joystick, currentGamepad);
161
- }
162
-
163
- // Now at the same time, enqueue all events for this particular
164
- // gamepad, and OR the keyboard state into anyGamepad.
165
- int offset = gpRangeBegin + gpNumPerGamepad * (i + 1);
166
- for (int j = 0; j < currentGamepad.size(); ++j) {
167
- anyGamepad[j] = anyGamepad[j] || currentGamepad[j];
168
-
169
- if (currentGamepad[j] && !buttonStates[j + offset]) {
170
- buttonStates[j + offset] = true;
171
- enqueueEvent(j + offset, true);
172
- }
173
- else if (!currentGamepad[j] && buttonStates[j + offset]) {
174
- buttonStates[j + offset] = false;
175
- enqueueEvent(j + offset, false);
176
- }
177
- }
178
- }
179
-
180
- // And lastly, enqueue events for the virtual "any" gamepad.
181
- for (int j = 0; j < anyGamepad.size(); ++j) {
182
- if (anyGamepad[j] && !buttonStates[j + gpRangeBegin]) {
183
- buttonStates[j + gpRangeBegin] = true;
184
- enqueueEvent(j + gpRangeBegin, true);
185
- }
186
- else if (!anyGamepad[j] && buttonStates[j + gpRangeBegin]) {
187
- buttonStates[j + gpRangeBegin] = false;
188
- enqueueEvent(j + gpRangeBegin, false);
189
- }
190
- }
191
- }
192
-
193
- private:
194
- // For button down event: Button name value (>= 0)
195
- // For button up event: ~Button name value (< 0)
196
- std::vector<int> eventQueue;
197
-
198
- std::vector<SDL_Joystick*> joysticks;
199
- std::vector<SDL_GameController*> gameControllers;
200
-
201
- // SDL returns axis values in the range -2^15 through 2^15-1, so we consider
202
- // -2^14 through 2^14 the dead zone.
203
-
204
- enum { DEAD_ZONE = (1 << 14) };
205
-
206
- void pollGameController(SDL_GameController *gameController, GamepadBuffer& gamepad)
207
- {
208
- gamepad[gpLeft - gpRangeBegin] =
209
- SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_LEFT) ||
210
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX) < -DEAD_ZONE ||
211
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTX) < -DEAD_ZONE;
212
-
213
- gamepad[gpRight - gpRangeBegin] =
214
- SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_RIGHT) ||
215
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTX) > +DEAD_ZONE ||
216
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTX) > +DEAD_ZONE;
217
-
218
- gamepad[gpUp - gpRangeBegin] =
219
- SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_UP) ||
220
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY) < -DEAD_ZONE ||
221
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTY) < -DEAD_ZONE;
222
-
223
- gamepad[gpDown - gpRangeBegin] =
224
- SDL_GameControllerGetButton(gameController, SDL_CONTROLLER_BUTTON_DPAD_DOWN) ||
225
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_LEFTY) > +DEAD_ZONE ||
226
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_RIGHTY) > +DEAD_ZONE;
227
-
228
- int button = 0;
229
- for (button; button < SDL_CONTROLLER_BUTTON_DPAD_UP; ++button) {
230
- gamepad[gpButton0 + button - gpRangeBegin] =
231
- SDL_GameControllerGetButton(gameController, (SDL_GameControllerButton)button);
232
- }
233
- gamepad[gpButton0 + button++ - gpRangeBegin] =
234
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERLEFT) > +DEAD_ZONE;
235
- gamepad[gpButton0 + button++ - gpRangeBegin] =
236
- SDL_GameControllerGetAxis(gameController, SDL_CONTROLLER_AXIS_TRIGGERRIGHT) > +DEAD_ZONE;
237
- }
238
-
239
- void pollJoystick(SDL_Joystick *joystick, GamepadBuffer& gamepad)
240
- {
241
- int axes = SDL_JoystickNumAxes(joystick),
242
- hats = SDL_JoystickNumHats(joystick),
243
- buttons = std::min<int>(gpNumPerGamepad - 4, SDL_JoystickNumButtons(joystick));
244
-
245
- for (int axis = 0; axis < axes; ++axis) {
246
- Sint16 value = SDL_JoystickGetAxis(joystick, axis);
247
-
248
- if (value < -DEAD_ZONE) {
249
- if (axis % 2 == 0)
250
- gamepad[gpLeft - gpRangeBegin] = true;
251
- else
252
- gamepad[gpUp - gpRangeBegin] = true;
253
- }
254
- else if (value > +DEAD_ZONE) {
255
- if (axis % 2 == 0)
256
- gamepad[gpRight - gpRangeBegin] = true;
257
- else
258
- gamepad[gpDown - gpRangeBegin] = true;
259
- }
260
- }
261
-
262
- for (int hat = 0; hat < hats; ++hat) {
263
- Uint8 value = SDL_JoystickGetHat(joystick, hat);
264
-
265
- if (value & SDL_HAT_LEFT)
266
- gamepad[gpLeft - gpRangeBegin] = true;
267
- if (value & SDL_HAT_RIGHT)
268
- gamepad[gpRight - gpRangeBegin] = true;
269
- if (value & SDL_HAT_UP)
270
- gamepad[gpUp - gpRangeBegin] = true;
271
- if (value & SDL_HAT_DOWN)
272
- gamepad[gpDown - gpRangeBegin] = true;
273
- }
274
-
275
- for (int button = 0; button < buttons; ++button) {
276
- if (SDL_JoystickGetButton(joystick, button)) {
277
- gamepad[gpButton0 + button - gpRangeBegin] = true;
278
- }
279
- }
280
- }
281
- };
282
-
283
- Gosu::Input::Input(void* window)
284
- : pimpl(new Impl(*this, (SDL_Window*)window))
285
- {
286
- requireSDLVideo();
287
-
288
- pimpl->initializeGamepads();
289
- }
290
-
291
- Gosu::Input::~Input()
292
- {
293
- pimpl->releaseGamepads();
294
- }
295
-
296
- bool Gosu::Input::feedSDLEvent(void* event)
297
- {
298
- const SDL_Event* e = static_cast<SDL_Event*>(event);
299
-
300
- if (pimpl->textInput && pimpl->textInput->feedSDLEvent(event)) {
301
- return true;
302
- }
303
-
304
- switch (e->type) {
305
- case SDL_KEYDOWN:
306
- case SDL_KEYUP: {
307
- if (e->key.repeat == 0 && e->key.keysym.scancode <= kbRangeEnd) {
308
- pimpl->enqueueEvent(e->key.keysym.scancode, e->type == SDL_KEYDOWN);
309
- return true;
310
- }
311
- break;
312
- }
313
- case SDL_MOUSEBUTTONDOWN:
314
- case SDL_MOUSEBUTTONUP: {
315
- if (e->button.button >= 1 && e->button.button <= 3) {
316
- pimpl->enqueueEvent(msLeft + e->button.button - 1, e->type == SDL_MOUSEBUTTONDOWN);
317
- return true;
318
- }
319
- break;
320
- }
321
- case SDL_MOUSEWHEEL: {
322
- if (e->wheel.y > 0) {
323
- pimpl->enqueueEvent(msWheelUp, true);
324
- pimpl->enqueueEvent(msWheelUp, false);
325
- return true;
326
- }
327
- else if (e->wheel.y < 0) {
328
- pimpl->enqueueEvent(msWheelDown, true);
329
- pimpl->enqueueEvent(msWheelDown, false);
330
- return true;
331
- }
332
- break;
333
- }
334
- }
335
- return false;
336
- }
337
-
338
- wchar_t Gosu::Input::idToChar(Button btn)
339
- {
340
- requireSDLVideo();
341
-
342
- if (btn.id() > kbRangeEnd)
343
- return 0;
344
-
345
- // SDL_GetKeyName would return "Space" for this value.
346
- if (btn.id() == kbSpace)
347
- return L' ';
348
-
349
- SDL_Keycode keycode = SDL_GetKeyFromScancode(static_cast<SDL_Scancode>(btn.id()));
350
- if (keycode == SDLK_UNKNOWN)
351
- return 0;
352
-
353
- const char* name = SDL_GetKeyName(keycode);
354
- if (name == NULL)
355
- return 0;
356
-
357
- std::wstring wname = utf8ToWstring(name);
358
- if (wname.length() != 1)
359
- return 0;
360
-
361
- // Convert to lower case to be consistent with previous versions of Gosu.
362
- // Also, German umlauts are already reported in lower-case by the SDL, so
363
- // this makes everything a little more consistent.
364
- //
365
- // This should handle Turkish i/I just fine because it uses the current
366
- // locale, but if we ever receive bug reports from Turkish users, they are
367
- // likely caused by a combination of this line and an invalid locale :)
368
- return std::towlower(wname[0]);
369
- }
370
-
371
- Gosu::Button Gosu::Input::charToId(wchar_t ch)
372
- {
373
- requireSDLVideo();
374
-
375
- std::wstring string(1, ch);
376
- SDL_Keycode keycode = SDL_GetKeyFromName(wstringToUTF8(string).c_str());
377
-
378
- if (keycode == SDLK_UNKNOWN) {
379
- return noButton;
380
- }
381
- else {
382
- return Button(SDL_GetScancodeFromKey(keycode));
383
- }
384
- }
385
-
386
- bool Gosu::Input::down(Gosu::Button btn)
387
- {
388
- if (btn == noButton || btn.id() >= numButtons)
389
- return false;
390
-
391
- return buttonStates[btn.id()];
392
- }
393
-
394
- double Gosu::Input::mouseX() const
395
- {
396
- return pimpl->mouseX * pimpl->mouseFactorX + pimpl->mouseOffsetX;
397
- }
398
-
399
- double Gosu::Input::mouseY() const
400
- {
401
- return pimpl->mouseY * pimpl->mouseFactorY + pimpl->mouseOffsetY;
402
- }
403
-
404
- void Gosu::Input::setMousePosition(double x, double y)
405
- {
406
- pimpl->setMousePosition(x, y);
407
- }
408
-
409
- void Gosu::Input::setMouseFactors(double factorX, double factorY,
410
- double blackBarWidth, double blackBarHeight)
411
- {
412
- pimpl->mouseFactorX = factorX;
413
- pimpl->mouseFactorY = factorY;
414
- pimpl->mouseOffsetX = -blackBarWidth;
415
- pimpl->mouseOffsetY = -blackBarHeight;
416
- }
417
-
418
- const Gosu::Touches& Gosu::Input::currentTouches() const
419
- {
420
- // Note: We can actually use the SDL's touch API to implement this, even on OS X! Neat.
421
-
422
- static Gosu::Touches none;
423
- return none;
424
- }
425
-
426
- double Gosu::Input::accelerometerX() const
427
- {
428
- return 0.0;
429
- }
430
-
431
- double Gosu::Input::accelerometerY() const
432
- {
433
- return 0.0;
434
- }
435
-
436
- double Gosu::Input::accelerometerZ() const
437
- {
438
- return 0.0;
439
- }
440
-
441
- void Gosu::Input::update()
442
- {
443
- pimpl->updateMousePosition();
444
- pimpl->dispatchEnqueuedEvents();
445
- pimpl->pollGamepads();
446
- }
447
-
448
- Gosu::TextInput* Gosu::Input::textInput() const
449
- {
450
- return pimpl->textInput;
451
- }
452
-
453
- void Gosu::Input::setTextInput(TextInput* textInput)
454
- {
455
- if (pimpl->textInput && textInput == NULL) {
456
- SDL_StopTextInput();
457
- }
458
- else if (pimpl->textInput == NULL && textInput) {
459
- SDL_StartTextInput();
460
- }
461
-
462
- pimpl->textInput = textInput;
463
- }