gosu 0.7.10.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING.txt +29 -0
- data/Gosu/Async.hpp +48 -0
- data/Gosu/Audio.hpp +145 -0
- data/Gosu/AutoLink.hpp +16 -0
- data/Gosu/Bitmap.hpp +85 -0
- data/Gosu/ButtonsMac.hpp +114 -0
- data/Gosu/ButtonsWin.hpp +111 -0
- data/Gosu/ButtonsX.hpp +115 -0
- data/Gosu/Color.hpp +172 -0
- data/Gosu/Directories.hpp +36 -0
- data/Gosu/Font.hpp +59 -0
- data/Gosu/Fwd.hpp +31 -0
- data/Gosu/Gosu.hpp +26 -0
- data/Gosu/Graphics.hpp +86 -0
- data/Gosu/GraphicsBase.hpp +45 -0
- data/Gosu/IO.hpp +255 -0
- data/Gosu/Image.hpp +148 -0
- data/Gosu/ImageData.hpp +45 -0
- data/Gosu/Input.hpp +116 -0
- data/Gosu/Math.hpp +95 -0
- data/Gosu/Platform.hpp +61 -0
- data/Gosu/RotFlip.hpp +116 -0
- data/Gosu/Sockets.hpp +129 -0
- data/Gosu/Text.hpp +47 -0
- data/Gosu/TextInput.hpp +57 -0
- data/Gosu/Timing.hpp +16 -0
- data/Gosu/Utility.hpp +24 -0
- data/Gosu/WinUtility.hpp +76 -0
- data/Gosu/Window.hpp +84 -0
- data/GosuImpl/Async.cpp +37 -0
- data/GosuImpl/AudioFmod.cpp +417 -0
- data/GosuImpl/AudioSDL.cpp +255 -0
- data/GosuImpl/DirectoriesMac.mm +38 -0
- data/GosuImpl/DirectoriesUnix.cpp +48 -0
- data/GosuImpl/DirectoriesWin.cpp +42 -0
- data/GosuImpl/FileUnix.cpp +100 -0
- data/GosuImpl/FileWin.cpp +83 -0
- data/GosuImpl/Graphics/Bitmap.cpp +116 -0
- data/GosuImpl/Graphics/BitmapBMP.cpp +232 -0
- data/GosuImpl/Graphics/BitmapColorKey.cpp +39 -0
- data/GosuImpl/Graphics/BitmapPNG.cpp +276 -0
- data/GosuImpl/Graphics/BitmapUtils.cpp +67 -0
- data/GosuImpl/Graphics/BlockAllocator.cpp +127 -0
- data/GosuImpl/Graphics/BlockAllocator.hpp +34 -0
- data/GosuImpl/Graphics/Color.cpp +126 -0
- data/GosuImpl/Graphics/Common.hpp +21 -0
- data/GosuImpl/Graphics/DrawOp.hpp +154 -0
- data/GosuImpl/Graphics/Font.cpp +110 -0
- data/GosuImpl/Graphics/Graphics.cpp +295 -0
- data/GosuImpl/Graphics/Image.cpp +159 -0
- data/GosuImpl/Graphics/LargeImageData.cpp +115 -0
- data/GosuImpl/Graphics/LargeImageData.hpp +37 -0
- data/GosuImpl/Graphics/RotFlip.cpp +184 -0
- data/GosuImpl/Graphics/TexChunk.cpp +77 -0
- data/GosuImpl/Graphics/TexChunk.hpp +40 -0
- data/GosuImpl/Graphics/Text.cpp +223 -0
- data/GosuImpl/Graphics/TextMac.cpp +242 -0
- data/GosuImpl/Graphics/TextPangoFT.cpp +186 -0
- data/GosuImpl/Graphics/TextWin.cpp +172 -0
- data/GosuImpl/Graphics/Texture.cpp +104 -0
- data/GosuImpl/Graphics/Texture.hpp +34 -0
- data/GosuImpl/IO.cpp +48 -0
- data/GosuImpl/InputMac.mm +677 -0
- data/GosuImpl/InputWin.cpp +444 -0
- data/GosuImpl/InputX.cpp +158 -0
- data/GosuImpl/MacUtility.hpp +48 -0
- data/GosuImpl/Math.cpp +49 -0
- data/GosuImpl/RubyGosu.swg +474 -0
- data/GosuImpl/RubyGosuStub.mm +17 -0
- data/GosuImpl/RubyGosu_DllMain.cxx +30 -0
- data/GosuImpl/RubyGosu_wrap.cxx +8521 -0
- data/GosuImpl/RubyGosu_wrap.h +31 -0
- data/GosuImpl/Sockets/CommSocket.cpp +304 -0
- data/GosuImpl/Sockets/ListenerSocket.cpp +60 -0
- data/GosuImpl/Sockets/MessageSocket.cpp +136 -0
- data/GosuImpl/Sockets/Socket.cpp +145 -0
- data/GosuImpl/Sockets/Sockets.hpp +66 -0
- data/GosuImpl/TextInputMac.mm +207 -0
- data/GosuImpl/TextInputWin.cpp +197 -0
- data/GosuImpl/TextInputX.cpp +201 -0
- data/GosuImpl/TextTTFWin.cpp +247 -0
- data/GosuImpl/TimingUnix.cpp +17 -0
- data/GosuImpl/TimingWin.cpp +28 -0
- data/GosuImpl/Utility.cpp +140 -0
- data/GosuImpl/WinMain.cpp +69 -0
- data/GosuImpl/WinUtility.cpp +137 -0
- data/GosuImpl/WindowMac.mm +466 -0
- data/GosuImpl/WindowWin.cpp +447 -0
- data/GosuImpl/WindowX.cpp +392 -0
- data/GosuImpl/X11vroot.h +118 -0
- data/README.txt +13 -0
- data/Rakefile +178 -0
- data/examples/ChipmunkIntegration.rb +275 -0
- data/examples/CptnRuby.rb +231 -0
- data/examples/MoreChipmunkAndRMagick.rb +155 -0
- data/examples/OpenGLIntegration.rb +232 -0
- data/examples/RMagickIntegration.rb +449 -0
- data/examples/TextInput.cpp +170 -0
- data/examples/TextInput.rb +139 -0
- data/examples/Tutorial.cpp +215 -0
- data/examples/Tutorial.rb +137 -0
- data/examples/media/Beep.wav +0 -0
- data/examples/media/CptnRuby Gem.png +0 -0
- data/examples/media/CptnRuby Map.txt +25 -0
- data/examples/media/CptnRuby Tileset.png +0 -0
- data/examples/media/CptnRuby.png +0 -0
- data/examples/media/Cursor.png +0 -0
- data/examples/media/Earth.png +0 -0
- data/examples/media/Explosion.wav +0 -0
- data/examples/media/LargeStar.png +0 -0
- data/examples/media/Sky.jpg +0 -0
- data/examples/media/Smoke.png +0 -0
- data/examples/media/Soldier.png +0 -0
- data/examples/media/Space.png +0 -0
- data/examples/media/Star.png +0 -0
- data/examples/media/Starfighter.bmp +0 -0
- data/linux/Makefile.in +98 -0
- data/linux/configure +5658 -0
- data/linux/configure.ac +126 -0
- data/linux/extconf.rb +11 -0
- data/mac/English.lproj/InfoPlist.strings +0 -0
- data/mac/Gosu-Info.plist +26 -0
- data/mac/Gosu.xcodeproj/project.pbxproj +1194 -0
- data/mac/RubyGosu Template-Info.plist +26 -0
- data/mac/libboost_thread_1_34_1_universal.a +0 -0
- data/mac/libboost_thread_d_1_34_1_universal.a +0 -0
- data/mac/libfmod_universal.a +0 -0
- data/mac/libpng_universal.a +0 -0
- data/mac/libz_universal.a +0 -0
- data/reference/Async_8hpp-source.html +70 -0
- data/reference/Audio_8hpp-source.html +114 -0
- data/reference/Audio_8hpp.html +50 -0
- data/reference/AutoLink_8hpp-source.html +38 -0
- data/reference/AutoLink_8hpp.html +34 -0
- data/reference/Bitmap_8hpp-source.html +85 -0
- data/reference/Bitmap_8hpp.html +58 -0
- data/reference/ButtonsMac_8hpp-source.html +133 -0
- data/reference/ButtonsWin_8hpp-source.html +133 -0
- data/reference/ButtonsX_8hpp-source.html +134 -0
- data/reference/Color_8hpp-source.html +169 -0
- data/reference/Color_8hpp.html +85 -0
- data/reference/Directories_8hpp-source.html +42 -0
- data/reference/Directories_8hpp.html +46 -0
- data/reference/Font_8hpp-source.html +65 -0
- data/reference/Font_8hpp.html +41 -0
- data/reference/Fwd_8hpp-source.html +52 -0
- data/reference/Fwd_8hpp.html +37 -0
- data/reference/Gosu_8hpp-source.html +48 -0
- data/reference/Gosu_8hpp.html +34 -0
- data/reference/GraphicsBase_8hpp-source.html +57 -0
- data/reference/GraphicsBase_8hpp.html +56 -0
- data/reference/Graphics_8hpp-source.html +96 -0
- data/reference/Graphics_8hpp.html +53 -0
- data/reference/IO_8hpp-source.html +255 -0
- data/reference/IO_8hpp.html +74 -0
- data/reference/ImageData_8hpp-source.html +62 -0
- data/reference/ImageData_8hpp.html +43 -0
- data/reference/Image_8hpp-source.html +126 -0
- data/reference/Image_8hpp.html +48 -0
- data/reference/Input_8hpp-source.html +118 -0
- data/reference/Input_8hpp.html +50 -0
- data/reference/Math_8hpp-source.html +92 -0
- data/reference/Math_8hpp.html +74 -0
- data/reference/Platform_8hpp-source.html +83 -0
- data/reference/Platform_8hpp.html +73 -0
- data/reference/RotFlip_8hpp-source.html +138 -0
- data/reference/RotFlip_8hpp.html +77 -0
- data/reference/Sockets_8hpp-source.html +130 -0
- data/reference/Sockets_8hpp.html +66 -0
- data/reference/TextInput_8hpp-source.html +64 -0
- data/reference/TextInput_8hpp.html +41 -0
- data/reference/Text_8hpp-source.html +51 -0
- data/reference/Text_8hpp.html +46 -0
- data/reference/Timing_8hpp-source.html +36 -0
- data/reference/Timing_8hpp.html +42 -0
- data/reference/Utility_8hpp-source.html +44 -0
- data/reference/Utility_8hpp.html +48 -0
- data/reference/WinUtility_8hpp-source.html +79 -0
- data/reference/WinUtility_8hpp.html +64 -0
- data/reference/Window_8hpp-source.html +91 -0
- data/reference/Window_8hpp.html +41 -0
- data/reference/annotated.html +51 -0
- data/reference/classGosu_1_1Audio-members.html +34 -0
- data/reference/classGosu_1_1Audio.html +46 -0
- data/reference/classGosu_1_1Bitmap-members.html +44 -0
- data/reference/classGosu_1_1Bitmap.html +263 -0
- data/reference/classGosu_1_1Buffer-members.html +44 -0
- data/reference/classGosu_1_1Buffer.html +78 -0
- data/reference/classGosu_1_1Buffer.png +0 -0
- data/reference/classGosu_1_1Button-members.html +36 -0
- data/reference/classGosu_1_1Button.html +143 -0
- data/reference/classGosu_1_1Color-members.html +56 -0
- data/reference/classGosu_1_1Color.html +387 -0
- data/reference/classGosu_1_1File-members.html +41 -0
- data/reference/classGosu_1_1File.html +69 -0
- data/reference/classGosu_1_1File.png +0 -0
- data/reference/classGosu_1_1Font-members.html +39 -0
- data/reference/classGosu_1_1Font.html +309 -0
- data/reference/classGosu_1_1Graphics-members.html +50 -0
- data/reference/classGosu_1_1Graphics.html +234 -0
- data/reference/classGosu_1_1Image-members.html +45 -0
- data/reference/classGosu_1_1Image.html +518 -0
- data/reference/classGosu_1_1ImageData-members.html +37 -0
- data/reference/classGosu_1_1ImageData.html +60 -0
- data/reference/classGosu_1_1Input-members.html +44 -0
- data/reference/classGosu_1_1Input.html +223 -0
- data/reference/classGosu_1_1MessageSocket-members.html +40 -0
- data/reference/classGosu_1_1MessageSocket.html +233 -0
- data/reference/classGosu_1_1Resource-members.html +39 -0
- data/reference/classGosu_1_1Resource.html +116 -0
- data/reference/classGosu_1_1Resource.png +0 -0
- data/reference/classGosu_1_1Sample-members.html +37 -0
- data/reference/classGosu_1_1Sample.html +200 -0
- data/reference/classGosu_1_1SampleInstance-members.html +38 -0
- data/reference/classGosu_1_1SampleInstance.html +169 -0
- data/reference/classGosu_1_1Song-members.html +43 -0
- data/reference/classGosu_1_1Song.html +260 -0
- data/reference/classGosu_1_1TextInput-members.html +38 -0
- data/reference/classGosu_1_1TextInput.html +121 -0
- data/reference/classGosu_1_1Window-members.html +50 -0
- data/reference/classGosu_1_1Window.html +271 -0
- data/reference/doxyfile +233 -0
- data/reference/doxygen.css +433 -0
- data/reference/doxygen.png +0 -0
- data/reference/files.html +54 -0
- data/reference/functions.html +236 -0
- data/reference/functions_enum.html +45 -0
- data/reference/functions_func.html +227 -0
- data/reference/functions_vars.html +47 -0
- data/reference/hierarchy.html +53 -0
- data/reference/index.html +26 -0
- data/reference/namespaceGosu.html +2890 -0
- data/reference/namespaceGosu_1_1Colors.html +70 -0
- data/reference/namespaceGosu_1_1Win.html +275 -0
- data/reference/namespacemembers.html +216 -0
- data/reference/namespacemembers_enum.html +52 -0
- data/reference/namespacemembers_eval.html +54 -0
- data/reference/namespacemembers_func.html +185 -0
- data/reference/namespacemembers_type.html +46 -0
- data/reference/namespacemembers_vars.html +46 -0
- data/reference/namespaces.html +35 -0
- data/reference/tab_b.gif +0 -0
- data/reference/tab_l.gif +0 -0
- data/reference/tab_r.gif +0 -0
- data/reference/tabs.css +102 -0
- data/windows/Gosu.sln +29 -0
- data/windows/Gosu.vcproj +553 -0
- data/windows/RubyGosu.vcproj +138 -0
- metadata +305 -0
@@ -0,0 +1,255 @@
|
|
1
|
+
#include <Gosu/Audio.hpp>
|
2
|
+
#include <Gosu/Math.hpp>
|
3
|
+
#include <Gosu/IO.hpp>
|
4
|
+
#include <Gosu/Utility.hpp>
|
5
|
+
#include <boost/algorithm/string.hpp>
|
6
|
+
#include <cassert>
|
7
|
+
#include <cstdlib>
|
8
|
+
#include <algorithm>
|
9
|
+
#include <map>
|
10
|
+
#include <stdexcept>
|
11
|
+
#include <vector>
|
12
|
+
|
13
|
+
#include <SDL.h>
|
14
|
+
#include <SDL_mixer.h>
|
15
|
+
|
16
|
+
namespace Gosu {
|
17
|
+
namespace {
|
18
|
+
GOSU_NORETURN void throwLastSDLError() {
|
19
|
+
throw std::runtime_error(Mix_GetError());
|
20
|
+
}
|
21
|
+
|
22
|
+
bool mixerInitialized = false;
|
23
|
+
bool noSound = false;
|
24
|
+
Song* curSong = NULL;
|
25
|
+
}
|
26
|
+
|
27
|
+
std::map<int, int> channelRegistry;
|
28
|
+
}
|
29
|
+
|
30
|
+
#ifdef GOSU_IS_WIN
|
31
|
+
Gosu::Audio::Audio(HWND window) {
|
32
|
+
// Nothing to do; SDL_mixer does not require the window handle.
|
33
|
+
#else
|
34
|
+
Gosu::Audio::Audio() {
|
35
|
+
#endif
|
36
|
+
if (mixerInitialized)
|
37
|
+
throw std::logic_error("Multiple Gosu::Audio instances not supported.");
|
38
|
+
|
39
|
+
if (SDL_Init(SDL_INIT_AUDIO) || Mix_OpenAudio(44100, MIX_DEFAULT_FORMAT, 2, 4096) < 0)
|
40
|
+
noSound = true;
|
41
|
+
|
42
|
+
mixerInitialized = true;
|
43
|
+
}
|
44
|
+
|
45
|
+
Gosu::Audio::~Audio() {
|
46
|
+
assert(mixerInitialized);
|
47
|
+
|
48
|
+
if (!noSound)
|
49
|
+
Mix_CloseAudio();
|
50
|
+
mixerInitialized = false;
|
51
|
+
}
|
52
|
+
|
53
|
+
Gosu::SampleInstance::SampleInstance(int handle, int extra)
|
54
|
+
: handle(handle), extra(extra)
|
55
|
+
{
|
56
|
+
}
|
57
|
+
|
58
|
+
bool Gosu::SampleInstance::playing() const
|
59
|
+
{
|
60
|
+
return !noSound && channelRegistry[handle] == extra &&
|
61
|
+
Mix_Playing(handle) == 1;
|
62
|
+
}
|
63
|
+
|
64
|
+
void Gosu::SampleInstance::stop()
|
65
|
+
{
|
66
|
+
if (playing())
|
67
|
+
Mix_HaltChannel(handle);
|
68
|
+
}
|
69
|
+
|
70
|
+
void Gosu::SampleInstance::changeVolume(double volume)
|
71
|
+
{
|
72
|
+
if (playing())
|
73
|
+
Mix_Volume(handle, clamp<int>(volume * 255, 0, 255));
|
74
|
+
}
|
75
|
+
|
76
|
+
void Gosu::SampleInstance::changePan(double pan)
|
77
|
+
{
|
78
|
+
int rightPan = clamp<int>(pan * 127, 0, 127);
|
79
|
+
if (playing())
|
80
|
+
Mix_SetPanning(handle, 254 - rightPan, rightPan);
|
81
|
+
}
|
82
|
+
|
83
|
+
void Gosu::SampleInstance::changeSpeed(double speed)
|
84
|
+
{
|
85
|
+
/* We ignore the speed for now as this seems to be non-trivial
|
86
|
+
* with SDL_mixer. */
|
87
|
+
}
|
88
|
+
|
89
|
+
struct Gosu::Sample::SampleData : boost::noncopyable
|
90
|
+
{
|
91
|
+
Mix_Chunk* rep;
|
92
|
+
|
93
|
+
SampleData(): rep(0) {}
|
94
|
+
~SampleData() {
|
95
|
+
if (rep != 0) Mix_FreeChunk(rep);
|
96
|
+
}
|
97
|
+
};
|
98
|
+
|
99
|
+
Gosu::Sample::Sample(Audio& audio, const std::wstring& filename)
|
100
|
+
{
|
101
|
+
if (noSound)
|
102
|
+
return;
|
103
|
+
|
104
|
+
Buffer buf;
|
105
|
+
loadFile(buf, filename);
|
106
|
+
|
107
|
+
// Forward.
|
108
|
+
Sample(audio, buf.frontReader()).data.swap(data);
|
109
|
+
}
|
110
|
+
|
111
|
+
Gosu::Sample::Sample(Audio& audio, Reader reader) {
|
112
|
+
if (noSound)
|
113
|
+
return;
|
114
|
+
|
115
|
+
std::size_t bufsize = reader.resource().size() - reader.position();
|
116
|
+
Uint8* buffer = new Uint8[bufsize];
|
117
|
+
reader.read(buffer, bufsize);
|
118
|
+
|
119
|
+
data.reset(new SampleData);
|
120
|
+
data->rep = Mix_LoadWAV_RW(SDL_RWFromMem(buffer, bufsize), 1);
|
121
|
+
if (data->rep == NULL)
|
122
|
+
throwLastSDLError();
|
123
|
+
}
|
124
|
+
|
125
|
+
Gosu::Sample::~Sample() {
|
126
|
+
}
|
127
|
+
|
128
|
+
Gosu::SampleInstance Gosu::Sample::play(double volume, double speed) const {
|
129
|
+
int channel;
|
130
|
+
|
131
|
+
if (noSound || (channel = Mix_PlayChannel(-1, data->rep, 0)) == -1)
|
132
|
+
return SampleInstance(-1, -1);
|
133
|
+
|
134
|
+
int extra = ++channelRegistry[channel];
|
135
|
+
SampleInstance result(channel, extra);
|
136
|
+
|
137
|
+
if (volume != 1)
|
138
|
+
result.changeVolume(volume);
|
139
|
+
|
140
|
+
return result;
|
141
|
+
|
142
|
+
/* We ignore the speed for now as this seems to be non-trivial
|
143
|
+
* with SDL_mixer. */
|
144
|
+
}
|
145
|
+
|
146
|
+
Gosu::SampleInstance Gosu::Sample::playPan(double pan, double volume,
|
147
|
+
double speed) const {
|
148
|
+
int channel;
|
149
|
+
|
150
|
+
if (noSound || (channel = Mix_PlayChannel(-1, data->rep, 0)) == -1)
|
151
|
+
return SampleInstance(-1, -1);
|
152
|
+
|
153
|
+
int extra = ++channelRegistry[channel];
|
154
|
+
SampleInstance result(channel, extra);
|
155
|
+
|
156
|
+
result.changePan(pan);
|
157
|
+
|
158
|
+
if (volume != 1)
|
159
|
+
result.changeVolume(volume);
|
160
|
+
|
161
|
+
return result;
|
162
|
+
|
163
|
+
/* Speed ignored for now, as above. */
|
164
|
+
}
|
165
|
+
|
166
|
+
// No class hierarchy here; SDL_mixer abstracts this away for us.
|
167
|
+
class Gosu::Song::BaseData : boost::noncopyable {
|
168
|
+
public:
|
169
|
+
Mix_Music* music;
|
170
|
+
//std::vector<Uint8> buffer; - used by constructor that has been commented out
|
171
|
+
double volume;
|
172
|
+
|
173
|
+
BaseData() : music(0), volume(1.0) {}
|
174
|
+
~BaseData() {
|
175
|
+
if (music) Mix_FreeMusic(music);
|
176
|
+
}
|
177
|
+
|
178
|
+
static void endSongCallback() {
|
179
|
+
curSong = 0;
|
180
|
+
}
|
181
|
+
};
|
182
|
+
|
183
|
+
Gosu::Song::Song(Audio& audio, const std::wstring& filename)
|
184
|
+
: data(new BaseData)
|
185
|
+
{
|
186
|
+
if (noSound)
|
187
|
+
return;
|
188
|
+
|
189
|
+
data->music = Mix_LoadMUS(Gosu::narrow(filename).c_str());
|
190
|
+
if (data->music == NULL)
|
191
|
+
throwLastSDLError();
|
192
|
+
|
193
|
+
Mix_HookMusicFinished(BaseData::endSongCallback);
|
194
|
+
}
|
195
|
+
|
196
|
+
Gosu::Song::Song(Audio &audio, Type type, Reader reader)
|
197
|
+
: data(new BaseData)
|
198
|
+
{
|
199
|
+
#if 0
|
200
|
+
// Why oh why is LoadMUS_RW traditionally broken.
|
201
|
+
std::size_t bufsize = reader.resource().size() - reader.position();
|
202
|
+
data->buffer.resize(bufsize);
|
203
|
+
reader.read(data->buffer.data(), bufsize);
|
204
|
+
data->music = Mix_LoadMUS_RW(SDL_RWFromMem(data->buffer.data(), bufsize));
|
205
|
+
if (data->music == NULL)
|
206
|
+
throwLastSDLError();
|
207
|
+
|
208
|
+
Mix_HookMusicFinished(BaseData::endSongCallback);
|
209
|
+
#else
|
210
|
+
throw std::runtime_error("Loading files from memory not possible with libSDL_mixer");
|
211
|
+
#endif
|
212
|
+
}
|
213
|
+
|
214
|
+
Gosu::Song::~Song() {
|
215
|
+
stop();
|
216
|
+
}
|
217
|
+
|
218
|
+
void Gosu::Song::play() {
|
219
|
+
if (noSound)
|
220
|
+
return;
|
221
|
+
|
222
|
+
if (curSong)
|
223
|
+
curSong->stop();
|
224
|
+
|
225
|
+
assert(curSong == 0);
|
226
|
+
|
227
|
+
if (Mix_PlayMusic(data->music, 0) < 0)
|
228
|
+
throwLastSDLError();
|
229
|
+
curSong = this;
|
230
|
+
changeVolume(data->volume);
|
231
|
+
}
|
232
|
+
|
233
|
+
void Gosu::Song::stop() {
|
234
|
+
if (playing()) {
|
235
|
+
Mix_HaltMusic();
|
236
|
+
curSong = 0;
|
237
|
+
}
|
238
|
+
}
|
239
|
+
|
240
|
+
bool Gosu::Song::playing() const {
|
241
|
+
return curSong == this;
|
242
|
+
}
|
243
|
+
|
244
|
+
double Gosu::Song::volume() const {
|
245
|
+
return data->volume;
|
246
|
+
}
|
247
|
+
|
248
|
+
void Gosu::Song::changeVolume(double volume) {
|
249
|
+
data->volume = clamp(volume, 0.0, 1.0);
|
250
|
+
|
251
|
+
if (playing())
|
252
|
+
Mix_VolumeMusic(trunc(data->volume * MIX_MAX_VOLUME));
|
253
|
+
}
|
254
|
+
|
255
|
+
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#import <Gosu/Directories.hpp>
|
2
|
+
#import <GosuImpl/MacUtility.hpp>
|
3
|
+
#import <Gosu/Utility.hpp>
|
4
|
+
#import <Foundation/NSAutoreleasePool.h>
|
5
|
+
#import <Foundation/NSBundle.h>
|
6
|
+
#import <Foundation/NSString.h>
|
7
|
+
#import <Foundation/NSPathUtilities.h>
|
8
|
+
|
9
|
+
std::wstring Gosu::resourcePrefix()
|
10
|
+
{
|
11
|
+
static std::wstring result;
|
12
|
+
if (result.empty())
|
13
|
+
{
|
14
|
+
ObjRef<NSAutoreleasePool> pool([[NSAutoreleasePool alloc] init]);
|
15
|
+
NSBundle* bundle = [NSBundle mainBundle];
|
16
|
+
if (bundle == nil)
|
17
|
+
return L"";
|
18
|
+
NSString* str = [bundle resourcePath];
|
19
|
+
result = Gosu::widen([str fileSystemRepresentation]) + L"/";
|
20
|
+
}
|
21
|
+
return result;
|
22
|
+
}
|
23
|
+
|
24
|
+
std::wstring Gosu::sharedResourcePrefix()
|
25
|
+
{
|
26
|
+
static std::wstring result;
|
27
|
+
if (result.empty())
|
28
|
+
{
|
29
|
+
ObjRef<NSAutoreleasePool> pool([[NSAutoreleasePool alloc] init]);
|
30
|
+
NSBundle* bundle = [NSBundle mainBundle];
|
31
|
+
if (bundle == nil)
|
32
|
+
return L"";
|
33
|
+
NSString* str = [bundle bundlePath];
|
34
|
+
str = [str stringByDeletingLastPathComponent];
|
35
|
+
result = Gosu::widen([str fileSystemRepresentation]) + L"/";
|
36
|
+
}
|
37
|
+
return result;
|
38
|
+
}
|
@@ -0,0 +1,48 @@
|
|
1
|
+
#include <Gosu/Directories.hpp>
|
2
|
+
#include <Gosu/Platform.hpp>
|
3
|
+
#include <Gosu/Utility.hpp>
|
4
|
+
#include <cassert>
|
5
|
+
#include <vector>
|
6
|
+
#include <sys/types.h>
|
7
|
+
#include <unistd.h>
|
8
|
+
#include <pwd.h>
|
9
|
+
|
10
|
+
namespace
|
11
|
+
{
|
12
|
+
std::wstring homeDir()
|
13
|
+
{
|
14
|
+
passwd* pwd = getpwuid(geteuid());
|
15
|
+
assert(pwd);
|
16
|
+
return Gosu::widen(pwd->pw_dir);
|
17
|
+
}
|
18
|
+
}
|
19
|
+
|
20
|
+
#ifndef GOSU_IS_MAC
|
21
|
+
std::wstring Gosu::resourcePrefix()
|
22
|
+
{
|
23
|
+
return std::wstring();
|
24
|
+
}
|
25
|
+
|
26
|
+
std::wstring Gosu::sharedResourcePrefix()
|
27
|
+
{
|
28
|
+
return std::wstring();
|
29
|
+
}
|
30
|
+
#endif
|
31
|
+
|
32
|
+
std::wstring Gosu::userSettingsPrefix()
|
33
|
+
{
|
34
|
+
#ifdef GOSU_IS_MAC
|
35
|
+
return homeDir() + L"/Library/Preferences/";
|
36
|
+
#else
|
37
|
+
return homeDir() + L"/.";
|
38
|
+
#endif
|
39
|
+
}
|
40
|
+
|
41
|
+
std::wstring Gosu::userDocsPrefix()
|
42
|
+
{
|
43
|
+
#ifdef GOSU_IS_MAC
|
44
|
+
return homeDir() + L"/Documents/";
|
45
|
+
#else
|
46
|
+
return homeDir() + L"/";
|
47
|
+
#endif
|
48
|
+
}
|
@@ -0,0 +1,42 @@
|
|
1
|
+
#include <Gosu/Directories.hpp>
|
2
|
+
#include <Gosu/WinUtility.hpp>
|
3
|
+
#include <cwchar>
|
4
|
+
#include <stdexcept>
|
5
|
+
#include <shlobj.h>
|
6
|
+
|
7
|
+
namespace
|
8
|
+
{
|
9
|
+
std::wstring specialFolderPath(int csidl)
|
10
|
+
{
|
11
|
+
WCHAR buf[MAX_PATH + 2];
|
12
|
+
if (!SHGetSpecialFolderPath(0, buf, csidl, TRUE))
|
13
|
+
throw std::runtime_error("Error getting special folder path");
|
14
|
+
std::size_t len = std::wcslen(buf);
|
15
|
+
if (buf[len - 1] != '\\')
|
16
|
+
{
|
17
|
+
buf[len] = L'\\';
|
18
|
+
buf[len + 1] = L'\0';
|
19
|
+
}
|
20
|
+
return buf;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
std::wstring Gosu::resourcePrefix()
|
25
|
+
{
|
26
|
+
return Win::appDirectory();
|
27
|
+
}
|
28
|
+
|
29
|
+
std::wstring Gosu::sharedResourcePrefix()
|
30
|
+
{
|
31
|
+
return Win::appDirectory();
|
32
|
+
}
|
33
|
+
|
34
|
+
std::wstring Gosu::userSettingsPrefix()
|
35
|
+
{
|
36
|
+
return specialFolderPath(CSIDL_APPDATA);
|
37
|
+
}
|
38
|
+
|
39
|
+
std::wstring Gosu::userDocsPrefix()
|
40
|
+
{
|
41
|
+
return specialFolderPath(CSIDL_PERSONAL);
|
42
|
+
}
|
@@ -0,0 +1,100 @@
|
|
1
|
+
#include <Gosu/IO.hpp>
|
2
|
+
#include <Gosu/Utility.hpp>
|
3
|
+
#include <stdexcept>
|
4
|
+
#include <cstring>
|
5
|
+
#include <fcntl.h>
|
6
|
+
#include <unistd.h>
|
7
|
+
#include <sys/types.h>
|
8
|
+
#include <sys/mman.h>
|
9
|
+
|
10
|
+
#ifdef HAVE_SYS_STAT_H
|
11
|
+
#include <sys/stat.h>
|
12
|
+
#endif
|
13
|
+
|
14
|
+
namespace
|
15
|
+
{
|
16
|
+
// According to my man page, Unix folks just don't trust the 0, it's got to be a crippled -1.
|
17
|
+
void* const noMapping = reinterpret_cast<void*>(-1);
|
18
|
+
}
|
19
|
+
|
20
|
+
struct Gosu::File::Impl
|
21
|
+
{
|
22
|
+
int fd;
|
23
|
+
void* mapping;
|
24
|
+
|
25
|
+
Impl() : fd(-1), mapping(noMapping) {}
|
26
|
+
~Impl()
|
27
|
+
{
|
28
|
+
if (fd > 0)
|
29
|
+
close(fd);
|
30
|
+
}
|
31
|
+
};
|
32
|
+
|
33
|
+
Gosu::File::File(const std::wstring& filename, FileMode mode)
|
34
|
+
: pimpl(new Impl)
|
35
|
+
{
|
36
|
+
int flags;
|
37
|
+
|
38
|
+
switch (mode)
|
39
|
+
{
|
40
|
+
case fmRead:
|
41
|
+
flags = O_RDONLY;
|
42
|
+
break;
|
43
|
+
case fmReplace:
|
44
|
+
flags = O_RDWR | O_TRUNC | O_CREAT;
|
45
|
+
break;
|
46
|
+
case fmAlter:
|
47
|
+
flags = O_RDWR | O_CREAT;
|
48
|
+
break;
|
49
|
+
}
|
50
|
+
|
51
|
+
// TODO: Locking flags?
|
52
|
+
|
53
|
+
pimpl->fd = open(narrow(filename).c_str(), flags,
|
54
|
+
S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
|
55
|
+
if (pimpl->fd < 0)
|
56
|
+
throw std::runtime_error("Cannot open file " + narrow(filename));
|
57
|
+
|
58
|
+
if (mode == fmRead && size() > 0)
|
59
|
+
pimpl->mapping = mmap(0, size(), PROT_READ, 0, pimpl->fd, 0);
|
60
|
+
}
|
61
|
+
|
62
|
+
Gosu::File::~File()
|
63
|
+
{
|
64
|
+
if (pimpl->mapping != noMapping)
|
65
|
+
munmap(pimpl->mapping, size());
|
66
|
+
}
|
67
|
+
|
68
|
+
std::size_t Gosu::File::size() const
|
69
|
+
{
|
70
|
+
// IMPR: Error checking?
|
71
|
+
return lseek(pimpl->fd, 0, SEEK_END);
|
72
|
+
}
|
73
|
+
|
74
|
+
void Gosu::File::resize(std::size_t newSize)
|
75
|
+
{
|
76
|
+
ftruncate(pimpl->fd, newSize);
|
77
|
+
}
|
78
|
+
|
79
|
+
void Gosu::File::read(std::size_t offset, std::size_t length,
|
80
|
+
void* destBuffer) const
|
81
|
+
{
|
82
|
+
// TODO: err checking
|
83
|
+
if (pimpl->mapping != noMapping)
|
84
|
+
{
|
85
|
+
std::memcpy(destBuffer, static_cast<const char*>(pimpl->mapping) + offset, length);
|
86
|
+
return;
|
87
|
+
}
|
88
|
+
|
89
|
+
// IMPR: Error checking?
|
90
|
+
lseek(pimpl->fd, offset, SEEK_SET);
|
91
|
+
::read(pimpl->fd, destBuffer, length);
|
92
|
+
}
|
93
|
+
|
94
|
+
void Gosu::File::write(std::size_t offset, std::size_t length,
|
95
|
+
const void* sourceBuffer)
|
96
|
+
{
|
97
|
+
// IMPR: Error checking?
|
98
|
+
lseek(pimpl->fd, offset, SEEK_SET);
|
99
|
+
::write(pimpl->fd, sourceBuffer, length);
|
100
|
+
}
|