Audio: Clean up threading and add AudioStream fadein (RGSS3)
This commit is contained in:
		
							parent
							
								
									46497eae01
								
							
						
					
					
						commit
						51a0f3903c
					
				
					 10 changed files with 228 additions and 146 deletions
				
			
		| 
						 | 
					@ -153,6 +153,7 @@ set(MAIN_HEADERS
 | 
				
			||||||
	src/tileatlasvx.h
 | 
						src/tileatlasvx.h
 | 
				
			||||||
	src/sharedmidistate.h
 | 
						src/sharedmidistate.h
 | 
				
			||||||
	src/fluid-fun.h
 | 
						src/fluid-fun.h
 | 
				
			||||||
 | 
						src/sdl-util.h
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(MAIN_SOURCE
 | 
					set(MAIN_SOURCE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,6 @@ Missing RGSS3 functionality:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
* Text outline
 | 
					* Text outline
 | 
				
			||||||
* Movie playback
 | 
					* Movie playback
 | 
				
			||||||
* Audio fade-in
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
Some other things might be implemented, but simply not bound yet.
 | 
					Some other things might be implemented, but simply not bound yet.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										3
									
								
								mkxp.pro
									
										
									
									
									
								
							
							
						
						
									
										3
									
								
								mkxp.pro
									
										
									
									
									
								
							| 
						 | 
					@ -131,7 +131,8 @@ HEADERS += \
 | 
				
			||||||
	src/tilemapvx.h \
 | 
						src/tilemapvx.h \
 | 
				
			||||||
	src/tileatlasvx.h \
 | 
						src/tileatlasvx.h \
 | 
				
			||||||
	src/sharedmidistate.h \
 | 
						src/sharedmidistate.h \
 | 
				
			||||||
	src/fluid-fun.h
 | 
						src/fluid-fun.h \
 | 
				
			||||||
 | 
						src/sdl-util.h
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SOURCES += \
 | 
					SOURCES += \
 | 
				
			||||||
	src/main.cpp \
 | 
						src/main.cpp \
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -26,6 +26,7 @@
 | 
				
			||||||
#include "filesystem.h"
 | 
					#include "filesystem.h"
 | 
				
			||||||
#include "aldatasource.h"
 | 
					#include "aldatasource.h"
 | 
				
			||||||
#include "fluid-fun.h"
 | 
					#include "fluid-fun.h"
 | 
				
			||||||
 | 
					#include "sdl-util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <SDL_mutex.h>
 | 
					#include <SDL_mutex.h>
 | 
				
			||||||
#include <SDL_thread.h>
 | 
					#include <SDL_thread.h>
 | 
				
			||||||
| 
						 | 
					@ -38,8 +39,6 @@ ALStream::ALStream(LoopMode loopMode,
 | 
				
			||||||
	  source(0),
 | 
						  source(0),
 | 
				
			||||||
	  thread(0),
 | 
						  thread(0),
 | 
				
			||||||
	  preemptPause(false),
 | 
						  preemptPause(false),
 | 
				
			||||||
	  streamInited(false),
 | 
					 | 
				
			||||||
	  needsRewind(false),
 | 
					 | 
				
			||||||
      pitch(1.0)
 | 
					      pitch(1.0)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	alSrc = AL::Source::gen();
 | 
						alSrc = AL::Source::gen();
 | 
				
			||||||
| 
						 | 
					@ -198,7 +197,7 @@ void ALStream::openSource(const std::string &filename)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const char *ext;
 | 
						const char *ext;
 | 
				
			||||||
	shState->fileSystem().openRead(srcOps, filename.c_str(), FileSystem::Audio, false, &ext);
 | 
						shState->fileSystem().openRead(srcOps, filename.c_str(), FileSystem::Audio, false, &ext);
 | 
				
			||||||
	needsRewind = false;
 | 
						needsRewind.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Try to read ogg file signature */
 | 
						/* Try to read ogg file signature */
 | 
				
			||||||
	char sig[5] = { 0 };
 | 
						char sig[5] = { 0 };
 | 
				
			||||||
| 
						 | 
					@ -227,13 +226,13 @@ void ALStream::openSource(const std::string &filename)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ALStream::stopStream()
 | 
					void ALStream::stopStream()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	threadTermReq = true;
 | 
						threadTermReq.set();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (thread)
 | 
						if (thread)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		SDL_WaitThread(thread, 0);
 | 
							SDL_WaitThread(thread, 0);
 | 
				
			||||||
		thread = 0;
 | 
							thread = 0;
 | 
				
			||||||
		needsRewind = true;
 | 
							needsRewind.set();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Need to stop the source _after_ the thread has terminated,
 | 
						/* Need to stop the source _after_ the thread has terminated,
 | 
				
			||||||
| 
						 | 
					@ -249,14 +248,15 @@ void ALStream::startStream(float offset)
 | 
				
			||||||
	AL::Source::clearQueue(alSrc);
 | 
						AL::Source::clearQueue(alSrc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	preemptPause = false;
 | 
						preemptPause = false;
 | 
				
			||||||
	streamInited = false;
 | 
						streamInited.clear();
 | 
				
			||||||
	sourceExhausted = false;
 | 
						sourceExhausted.clear();
 | 
				
			||||||
	threadTermReq = false;
 | 
						threadTermReq.clear();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	startOffset = offset;
 | 
						startOffset = offset;
 | 
				
			||||||
	procFrames = offset * source->sampleRate();
 | 
						procFrames = offset * source->sampleRate();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	thread = SDL_CreateThread(streamDataFun, threadName.c_str(), this);
 | 
						thread = createSDLThread
 | 
				
			||||||
 | 
							<ALStream, &ALStream::streamData>(this, threadName);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ALStream::pauseStream()
 | 
					void ALStream::pauseStream()
 | 
				
			||||||
| 
						 | 
					@ -344,7 +344,7 @@ void ALStream::streamData()
 | 
				
			||||||
			resumeStream();
 | 
								resumeStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			firstBuffer = false;
 | 
								firstBuffer = false;
 | 
				
			||||||
			streamInited = true;
 | 
								streamInited.set();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (threadTermReq)
 | 
							if (threadTermReq)
 | 
				
			||||||
| 
						 | 
					@ -352,7 +352,7 @@ void ALStream::streamData()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (status == ALDataSource::EndOfStream)
 | 
							if (status == ALDataSource::EndOfStream)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			sourceExhausted = true;
 | 
								sourceExhausted.set();
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -400,7 +400,7 @@ void ALStream::streamData()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (status == ALDataSource::Error)
 | 
								if (status == ALDataSource::Error)
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				sourceExhausted = true;
 | 
									sourceExhausted.set();
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -419,7 +419,7 @@ void ALStream::streamData()
 | 
				
			||||||
				lastBuf = buf;
 | 
									lastBuf = buf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (status == ALDataSource::EndOfStream)
 | 
								if (status == ALDataSource::EndOfStream)
 | 
				
			||||||
				sourceExhausted = true;
 | 
									sourceExhausted.set();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (threadTermReq)
 | 
							if (threadTermReq)
 | 
				
			||||||
| 
						 | 
					@ -428,10 +428,3 @@ void ALStream::streamData()
 | 
				
			||||||
		SDL_Delay(AUDIO_SLEEP);
 | 
							SDL_Delay(AUDIO_SLEEP);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
int ALStream::streamDataFun(void *_self)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	ALStream &self = *static_cast<ALStream*>(_self);
 | 
					 | 
				
			||||||
	self.streamData();
 | 
					 | 
				
			||||||
	return 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,12 +23,11 @@
 | 
				
			||||||
#define ALSTREAM_H
 | 
					#define ALSTREAM_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "al-util.h"
 | 
					#include "al-util.h"
 | 
				
			||||||
 | 
					#include "sdl-util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <SDL_rwops.h>
 | 
					#include <SDL_rwops.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SDL_mutex;
 | 
					 | 
				
			||||||
struct SDL_thread;
 | 
					 | 
				
			||||||
struct ALDataSource;
 | 
					struct ALDataSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define STREAM_BUFS 3
 | 
					#define STREAM_BUFS 3
 | 
				
			||||||
| 
						 | 
					@ -59,12 +58,12 @@ struct ALStream
 | 
				
			||||||
	/* When this flag isn't set and alSrc is
 | 
						/* When this flag isn't set and alSrc is
 | 
				
			||||||
	 * in 'STOPPED' state, stream isn't over
 | 
						 * in 'STOPPED' state, stream isn't over
 | 
				
			||||||
	 * (it just hasn't started yet) */
 | 
						 * (it just hasn't started yet) */
 | 
				
			||||||
	bool streamInited;
 | 
						AtomicFlag streamInited;
 | 
				
			||||||
	bool sourceExhausted;
 | 
						AtomicFlag sourceExhausted;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool threadTermReq;
 | 
						AtomicFlag threadTermReq;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool needsRewind;
 | 
						AtomicFlag needsRewind;
 | 
				
			||||||
	float startOffset;
 | 
						float startOffset;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float pitch;
 | 
						float pitch;
 | 
				
			||||||
| 
						 | 
					@ -118,7 +117,6 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* thread func */
 | 
						/* thread func */
 | 
				
			||||||
	void streamData();
 | 
						void streamData();
 | 
				
			||||||
	static int streamDataFun(void *);
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // ALSTREAM_H
 | 
					#endif // ALSTREAM_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@
 | 
				
			||||||
#include "soundemitter.h"
 | 
					#include "soundemitter.h"
 | 
				
			||||||
#include "sharedstate.h"
 | 
					#include "sharedstate.h"
 | 
				
			||||||
#include "sharedmidistate.h"
 | 
					#include "sharedmidistate.h"
 | 
				
			||||||
 | 
					#include "sdl-util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -55,8 +56,7 @@ struct AudioPrivate
 | 
				
			||||||
	struct
 | 
						struct
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		SDL_Thread *thread;
 | 
							SDL_Thread *thread;
 | 
				
			||||||
		bool active;
 | 
							AtomicFlag termReq;
 | 
				
			||||||
		bool termReq;
 | 
					 | 
				
			||||||
		MeWatchState state;
 | 
							MeWatchState state;
 | 
				
			||||||
	} meWatch;
 | 
						} meWatch;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -66,19 +66,18 @@ struct AudioPrivate
 | 
				
			||||||
	      me(ALStream::NotLooped, "me"),
 | 
						      me(ALStream::NotLooped, "me"),
 | 
				
			||||||
	      se(conf)
 | 
						      se(conf)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		meWatch.active = false;
 | 
					 | 
				
			||||||
		meWatch.termReq = false;
 | 
					 | 
				
			||||||
		meWatch.state = MeNotPlaying;
 | 
							meWatch.state = MeNotPlaying;
 | 
				
			||||||
		meWatch.thread = SDL_CreateThread(meWatchFun, "audio_mewatch", this);
 | 
							meWatch.thread = createSDLThread
 | 
				
			||||||
 | 
								<AudioPrivate, &AudioPrivate::meWatchFun>(this, "audio_mewatch");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	~AudioPrivate()
 | 
						~AudioPrivate()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		meWatch.termReq = true;
 | 
							meWatch.termReq.set();
 | 
				
			||||||
		SDL_WaitThread(meWatch.thread, 0);
 | 
							SDL_WaitThread(meWatch.thread, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void meWatchFunInt()
 | 
						void meWatchFun()
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		const float fadeOutStep = 1.f / (200  / AUDIO_SLEEP);
 | 
							const float fadeOutStep = 1.f / (200  / AUDIO_SLEEP);
 | 
				
			||||||
		const float fadeInStep  = 1.f / (1000 / AUDIO_SLEEP);
 | 
							const float fadeInStep  = 1.f / (1000 / AUDIO_SLEEP);
 | 
				
			||||||
| 
						 | 
					@ -121,13 +120,13 @@ struct AudioPrivate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bgm.lockStream();
 | 
									bgm.lockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				float vol = bgm.extVolume;
 | 
									float vol = bgm.getVolume(AudioStream::External);
 | 
				
			||||||
				vol -= fadeOutStep;
 | 
									vol -= fadeOutStep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (vol < 0 || bgm.stream.queryState() != ALStream::Playing)
 | 
									if (vol < 0 || bgm.stream.queryState() != ALStream::Playing)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					/* Either BGM has fully faded out, or stopped midway. -> MePlaying */
 | 
										/* Either BGM has fully faded out, or stopped midway. -> MePlaying */
 | 
				
			||||||
					bgm.setExtVolume1(0);
 | 
										bgm.setVolume(AudioStream::External, 0);
 | 
				
			||||||
					bgm.stream.pause();
 | 
										bgm.stream.pause();
 | 
				
			||||||
					meWatch.state = MePlaying;
 | 
										meWatch.state = MePlaying;
 | 
				
			||||||
					bgm.unlockStream();
 | 
										bgm.unlockStream();
 | 
				
			||||||
| 
						 | 
					@ -136,7 +135,7 @@ struct AudioPrivate
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bgm.setExtVolume1(vol);
 | 
									bgm.setVolume(AudioStream::External, vol);
 | 
				
			||||||
				bgm.unlockStream();
 | 
									bgm.unlockStream();
 | 
				
			||||||
				me.unlockStream();
 | 
									me.unlockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -165,7 +164,7 @@ struct AudioPrivate
 | 
				
			||||||
					else
 | 
										else
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						/* BGM is stopped. -> MeNotPlaying */
 | 
											/* BGM is stopped. -> MeNotPlaying */
 | 
				
			||||||
						bgm.setExtVolume1(1.0);
 | 
											bgm.setVolume(AudioStream::External, 1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						if (!bgm.noResumeStop)
 | 
											if (!bgm.noResumeStop)
 | 
				
			||||||
							bgm.stream.play();
 | 
												bgm.stream.play();
 | 
				
			||||||
| 
						 | 
					@ -188,7 +187,7 @@ struct AudioPrivate
 | 
				
			||||||
				if (bgm.stream.queryState() == ALStream::Stopped)
 | 
									if (bgm.stream.queryState() == ALStream::Stopped)
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					/* BGM stopped midway fade in. -> MeNotPlaying */
 | 
										/* BGM stopped midway fade in. -> MeNotPlaying */
 | 
				
			||||||
					bgm.setExtVolume1(1.0);
 | 
										bgm.setVolume(AudioStream::External, 1.0);
 | 
				
			||||||
					meWatch.state = MeNotPlaying;
 | 
										meWatch.state = MeNotPlaying;
 | 
				
			||||||
					bgm.unlockStream();
 | 
										bgm.unlockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -208,7 +207,7 @@ struct AudioPrivate
 | 
				
			||||||
					break;
 | 
										break;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				float vol = bgm.extVolume;
 | 
									float vol = bgm.getVolume(AudioStream::External);
 | 
				
			||||||
				vol += fadeInStep;
 | 
									vol += fadeInStep;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (vol >= 1)
 | 
									if (vol >= 1)
 | 
				
			||||||
| 
						 | 
					@ -218,7 +217,7 @@ struct AudioPrivate
 | 
				
			||||||
					meWatch.state = MeNotPlaying;
 | 
										meWatch.state = MeNotPlaying;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				bgm.setExtVolume1(vol);
 | 
									bgm.setVolume(AudioStream::External, vol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				me.unlockStream();
 | 
									me.unlockStream();
 | 
				
			||||||
				bgm.unlockStream();
 | 
									bgm.unlockStream();
 | 
				
			||||||
| 
						 | 
					@ -230,13 +229,6 @@ struct AudioPrivate
 | 
				
			||||||
			SDL_Delay(AUDIO_SLEEP);
 | 
								SDL_Delay(AUDIO_SLEEP);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	static int meWatchFun(void *self)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		static_cast<AudioPrivate*>(self)->meWatchFunInt();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Audio::Audio(const Config &conf)
 | 
					Audio::Audio(const Config &conf)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -30,19 +30,21 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
AudioStream::AudioStream(ALStream::LoopMode loopMode,
 | 
					AudioStream::AudioStream(ALStream::LoopMode loopMode,
 | 
				
			||||||
                         const std::string &threadId)
 | 
					                         const std::string &threadId)
 | 
				
			||||||
	: baseVolume(1.0),
 | 
						: extPaused(false),
 | 
				
			||||||
	  fadeVolume(1.0),
 | 
					 | 
				
			||||||
	  extVolume(1.0),
 | 
					 | 
				
			||||||
	  extPaused(false),
 | 
					 | 
				
			||||||
	  noResumeStop(false),
 | 
						  noResumeStop(false),
 | 
				
			||||||
	  stream(loopMode, threadId)
 | 
						  stream(loopMode, threadId)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	current.volume = 1.0;
 | 
						current.volume = 1.0;
 | 
				
			||||||
	current.pitch = 1.0;
 | 
						current.pitch = 1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fade.active = false;
 | 
						for (size_t i = 0; i < VolumeTypeCount; ++i)
 | 
				
			||||||
 | 
							volumes[i] = 1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fade.thread = 0;
 | 
						fade.thread = 0;
 | 
				
			||||||
	fade.threadName = std::string("audio_fade (") + threadId + ")";
 | 
						fade.threadName = std::string("audio_fadeout (") + threadId + ")";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fadeIn.thread = 0;
 | 
				
			||||||
 | 
						fadeIn.threadName = std::string("audio_fadein (") + threadId + ")";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	streamMut = SDL_CreateMutex();
 | 
						streamMut = SDL_CreateMutex();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -51,10 +53,16 @@ AudioStream::~AudioStream()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (fade.thread)
 | 
						if (fade.thread)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		fade.reqTerm = true;
 | 
							fade.reqTerm.set();
 | 
				
			||||||
		SDL_WaitThread(fade.thread, 0);
 | 
							SDL_WaitThread(fade.thread, 0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fadeIn.thread)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fadeIn.rqTerm.set();
 | 
				
			||||||
 | 
							SDL_WaitThread(fadeIn.thread, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockStream();
 | 
						lockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	stream.stop();
 | 
						stream.stop();
 | 
				
			||||||
| 
						 | 
					@ -70,7 +78,7 @@ void AudioStream::play(const std::string &filename,
 | 
				
			||||||
                       int pitch,
 | 
					                       int pitch,
 | 
				
			||||||
                       float offset)
 | 
					                       float offset)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	finiFadeInt();
 | 
						finiFadeOutInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockStream();
 | 
						lockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -96,7 +104,7 @@ void AudioStream::play(const std::string &filename,
 | 
				
			||||||
	&&  _pitch   == current.pitch
 | 
						&&  _pitch   == current.pitch
 | 
				
			||||||
	&&  (sState == ALStream::Playing || sState == ALStream::Paused))
 | 
						&&  (sState == ALStream::Playing || sState == ALStream::Paused))
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		setBaseVolume(_volume);
 | 
							setVolume(Base, _volume);
 | 
				
			||||||
		current.volume = _volume;
 | 
							current.volume = _volume;
 | 
				
			||||||
		unlockStream();
 | 
							unlockStream();
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -132,9 +140,15 @@ void AudioStream::play(const std::string &filename,
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	setBaseVolume(_volume);
 | 
						setVolume(Base, _volume);
 | 
				
			||||||
	stream.setPitch(_pitch);
 | 
						stream.setPitch(_pitch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (offset > 0)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							setVolume(FadeIn, 0);
 | 
				
			||||||
 | 
							startFadeIn();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	current.filename = filename;
 | 
						current.filename = filename;
 | 
				
			||||||
	current.volume = _volume;
 | 
						current.volume = _volume;
 | 
				
			||||||
	current.pitch = _pitch;
 | 
						current.pitch = _pitch;
 | 
				
			||||||
| 
						 | 
					@ -149,7 +163,7 @@ void AudioStream::play(const std::string &filename,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioStream::stop()
 | 
					void AudioStream::stop()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	finiFadeInt();
 | 
						finiFadeOutInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	lockStream();
 | 
						lockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -190,18 +204,19 @@ void AudioStream::fadeOut(int duration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (fade.thread)
 | 
						if (fade.thread)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		fade.reqFini = true;
 | 
							fade.reqFini.set();
 | 
				
			||||||
		SDL_WaitThread(fade.thread, 0);
 | 
							SDL_WaitThread(fade.thread, 0);
 | 
				
			||||||
		fade.thread = 0;
 | 
							fade.thread = 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fade.active = true;
 | 
						fade.active.set();
 | 
				
			||||||
	fade.msStep = (1.0) / duration;
 | 
						fade.msStep = (1.0) / duration;
 | 
				
			||||||
	fade.reqFini = false;
 | 
						fade.reqFini.clear();
 | 
				
			||||||
	fade.reqTerm = false;
 | 
						fade.reqTerm.clear();
 | 
				
			||||||
	fade.startTicks = SDL_GetTicks();
 | 
						fade.startTicks = SDL_GetTicks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fade.thread = SDL_CreateThread(fadeThreadFun, fade.threadName.c_str(), this);
 | 
						fade.thread = createSDLThread
 | 
				
			||||||
 | 
							<AudioStream, &AudioStream::fadeOutThread>(this, fade.threadName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	unlockStream();
 | 
						unlockStream();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -219,16 +234,15 @@ void AudioStream::unlockStream()
 | 
				
			||||||
	SDL_UnlockMutex(streamMut);
 | 
						SDL_UnlockMutex(streamMut);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioStream::setFadeVolume(float value)
 | 
					void AudioStream::setVolume(VolumeType type, float value)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	fadeVolume = value;
 | 
						volumes[type] = value;
 | 
				
			||||||
	updateVolume();
 | 
						updateVolume();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioStream::setExtVolume1(float value)
 | 
					float AudioStream::getVolume(VolumeType type)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	extVolume = value;
 | 
						return volumes[type];
 | 
				
			||||||
	updateVolume();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float AudioStream::playingOffset()
 | 
					float AudioStream::playingOffset()
 | 
				
			||||||
| 
						 | 
					@ -236,28 +250,47 @@ float AudioStream::playingOffset()
 | 
				
			||||||
	return stream.queryOffset();
 | 
						return stream.queryOffset();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioStream::finiFadeInt()
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	if (!fade.thread)
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	fade.reqFini = true;
 | 
					 | 
				
			||||||
	SDL_WaitThread(fade.thread, 0);
 | 
					 | 
				
			||||||
	fade.thread = 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void AudioStream::updateVolume()
 | 
					void AudioStream::updateVolume()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	stream.setVolume(baseVolume * fadeVolume * extVolume);
 | 
						float vol = 1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for (size_t i = 0; i < VolumeTypeCount; ++i)
 | 
				
			||||||
 | 
							vol *= volumes[i];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						stream.setVolume(vol);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioStream::setBaseVolume(float value)
 | 
					void AudioStream::finiFadeOutInt()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	baseVolume = value;
 | 
						if (fade.thread)
 | 
				
			||||||
	updateVolume();
 | 
						{
 | 
				
			||||||
 | 
							fade.reqFini.set();
 | 
				
			||||||
 | 
							SDL_WaitThread(fade.thread, 0);
 | 
				
			||||||
 | 
							fade.thread = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (fadeIn.thread)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							fadeIn.rqFini.set();
 | 
				
			||||||
 | 
							SDL_WaitThread(fadeIn.thread, 0);
 | 
				
			||||||
 | 
							fadeIn.thread = 0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void AudioStream::fadeThread()
 | 
					void AudioStream::startFadeIn()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						/* Previous fadein should always be terminated in play() */
 | 
				
			||||||
 | 
						assert(!fadeIn.thread);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fadeIn.rqFini.clear();
 | 
				
			||||||
 | 
						fadeIn.rqTerm.clear();
 | 
				
			||||||
 | 
						fadeIn.startTicks = SDL_GetTicks();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fadeIn.thread = createSDLThread
 | 
				
			||||||
 | 
							<AudioStream, &AudioStream::fadeInThread>(this, fadeIn.threadName);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void AudioStream::fadeOutThread()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	while (true)
 | 
						while (true)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
| 
						 | 
					@ -273,31 +306,59 @@ void AudioStream::fadeThread()
 | 
				
			||||||
		ALStream::State state = stream.queryState();
 | 
							ALStream::State state = stream.queryState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (state != ALStream::Playing
 | 
							if (state != ALStream::Playing
 | 
				
			||||||
		||  resVol < 0
 | 
							|| resVol < 0
 | 
				
			||||||
		||  fade.reqFini)
 | 
							|| fade.reqFini)
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			if (state != ALStream::Paused)
 | 
								if (state != ALStream::Paused)
 | 
				
			||||||
				stream.stop();
 | 
									stream.stop();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			setFadeVolume(1.0);
 | 
								setVolume(FadeOut, 1.0);
 | 
				
			||||||
			unlockStream();
 | 
								unlockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		setFadeVolume(resVol);
 | 
							setVolume(FadeOut, resVol);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		unlockStream();
 | 
							unlockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		SDL_Delay(AUDIO_SLEEP);
 | 
							SDL_Delay(AUDIO_SLEEP);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fade.active = false;
 | 
						fade.active.clear();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int AudioStream::fadeThreadFun(void *self)
 | 
					void AudioStream::fadeInThread()
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	static_cast<AudioStream*>(self)->fadeThread();
 | 
						while (true)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if (fadeIn.rqTerm)
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return 0;
 | 
							lockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Fade in duration is always 1 second */
 | 
				
			||||||
 | 
							uint32_t cur = SDL_GetTicks() - fadeIn.startTicks;
 | 
				
			||||||
 | 
							float prog = cur / 1000.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							ALStream::State state = stream.queryState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (state != ALStream::Playing
 | 
				
			||||||
 | 
							||  prog >= 1.0
 | 
				
			||||||
 | 
							||  fadeIn.rqFini)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								setVolume(FadeIn, 1.0);
 | 
				
			||||||
 | 
								unlockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								break;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							/* Quadratic increase (not really the same as
 | 
				
			||||||
 | 
							 * in RMVXA, but close enough) */
 | 
				
			||||||
 | 
							setVolume(FadeIn, prog*prog);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unlockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SDL_Delay(AUDIO_SLEEP);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,12 +24,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "al-util.h"
 | 
					#include "al-util.h"
 | 
				
			||||||
#include "alstream.h"
 | 
					#include "alstream.h"
 | 
				
			||||||
 | 
					#include "sdl-util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct SDL_mutex;
 | 
					 | 
				
			||||||
struct SDL_Thread;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
struct AudioStream
 | 
					struct AudioStream
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct
 | 
						struct
 | 
				
			||||||
| 
						 | 
					@ -39,17 +37,21 @@ struct AudioStream
 | 
				
			||||||
		float pitch;
 | 
							float pitch;
 | 
				
			||||||
	} current;
 | 
						} current;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Volume set with 'play()' */
 | 
						/* Volumes set by external threads,
 | 
				
			||||||
	float baseVolume;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	/* Volume set by external threads,
 | 
					 | 
				
			||||||
	 * such as for fade-in/out.
 | 
						 * such as for fade-in/out.
 | 
				
			||||||
	 * Multiplied with intVolume for final
 | 
						 * Multiplied together for final
 | 
				
			||||||
	 * playback volume.
 | 
						 * playback volume. Used with setVolume().
 | 
				
			||||||
	 * fadeVolume: used by fade-out thread.
 | 
						 * Base is set by play().
 | 
				
			||||||
	 * extVolume: used by MeWatch. */
 | 
						 * External is used by MeWatch */
 | 
				
			||||||
	float fadeVolume;
 | 
						enum VolumeType
 | 
				
			||||||
	float extVolume;
 | 
						{
 | 
				
			||||||
 | 
							Base = 0,
 | 
				
			||||||
 | 
							FadeOut,
 | 
				
			||||||
 | 
							FadeIn,
 | 
				
			||||||
 | 
							External,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							VolumeTypeCount
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Note that 'extPaused' and 'noResumeStop' are
 | 
						/* Note that 'extPaused' and 'noResumeStop' are
 | 
				
			||||||
	 * effectively only used with the AudioStream
 | 
						 * effectively only used with the AudioStream
 | 
				
			||||||
| 
						 | 
					@ -76,18 +78,19 @@ struct AudioStream
 | 
				
			||||||
	ALStream stream;
 | 
						ALStream stream;
 | 
				
			||||||
	SDL_mutex *streamMut;
 | 
						SDL_mutex *streamMut;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fade out */
 | 
				
			||||||
	struct
 | 
						struct
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		/* Fade is in progress */
 | 
							/* Fade out is in progress */
 | 
				
			||||||
		bool active;
 | 
							AtomicFlag active;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Request fade thread to finish and
 | 
							/* Request fade thread to finish and
 | 
				
			||||||
		 * cleanup (like it normally would) */
 | 
							 * cleanup (like it normally would) */
 | 
				
			||||||
		bool reqFini;
 | 
							AtomicFlag reqFini;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		/* Request fade thread to terminate
 | 
							/* Request fade thread to terminate
 | 
				
			||||||
		 * immediately */
 | 
							 * immediately */
 | 
				
			||||||
		bool reqTerm;
 | 
							AtomicFlag reqTerm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		SDL_Thread *thread;
 | 
							SDL_Thread *thread;
 | 
				
			||||||
		std::string threadName;
 | 
							std::string threadName;
 | 
				
			||||||
| 
						 | 
					@ -100,6 +103,18 @@ struct AudioStream
 | 
				
			||||||
		uint32_t startTicks;
 | 
							uint32_t startTicks;
 | 
				
			||||||
	} fade;
 | 
						} fade;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						/* Fade in */
 | 
				
			||||||
 | 
						struct
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							AtomicFlag rqFini;
 | 
				
			||||||
 | 
							AtomicFlag rqTerm;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							SDL_Thread *thread;
 | 
				
			||||||
 | 
							std::string threadName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							uint32_t startTicks;
 | 
				
			||||||
 | 
						} fadeIn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	AudioStream(ALStream::LoopMode loopMode,
 | 
						AudioStream(ALStream::LoopMode loopMode,
 | 
				
			||||||
	            const std::string &threadId);
 | 
						            const std::string &threadId);
 | 
				
			||||||
	~AudioStream();
 | 
						~AudioStream();
 | 
				
			||||||
| 
						 | 
					@ -117,19 +132,20 @@ struct AudioStream
 | 
				
			||||||
	void lockStream();
 | 
						void lockStream();
 | 
				
			||||||
	void unlockStream();
 | 
						void unlockStream();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void setFadeVolume(float value);
 | 
						void setVolume(VolumeType type, float value);
 | 
				
			||||||
	void setExtVolume1(float value);
 | 
						float getVolume(VolumeType type);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float playingOffset();
 | 
						float playingOffset();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void finiFadeInt();
 | 
						float volumes[VolumeTypeCount];
 | 
				
			||||||
 | 
					 | 
				
			||||||
	void updateVolume();
 | 
						void updateVolume();
 | 
				
			||||||
	void setBaseVolume(float value);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void fadeThread();
 | 
						void finiFadeOutInt();
 | 
				
			||||||
	static int fadeThreadFun(void *);
 | 
						void startFadeIn();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void fadeOutThread();
 | 
				
			||||||
 | 
						void fadeInThread();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif // AUDIOSTREAM_H
 | 
					#endif // AUDIOSTREAM_H
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,47 +24,20 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "config.h"
 | 
					#include "config.h"
 | 
				
			||||||
#include "etc-internal.h"
 | 
					#include "etc-internal.h"
 | 
				
			||||||
 | 
					#include "sdl-util.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <SDL_scancode.h>
 | 
					#include <SDL_scancode.h>
 | 
				
			||||||
#include <SDL_joystick.h>
 | 
					#include <SDL_joystick.h>
 | 
				
			||||||
#include <SDL_mouse.h>
 | 
					#include <SDL_mouse.h>
 | 
				
			||||||
#include <SDL_mutex.h>
 | 
					#include <SDL_mutex.h>
 | 
				
			||||||
#include <SDL_atomic.h>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdint.h>
 | 
					#include <stdint.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct RGSSThreadData;
 | 
					struct RGSSThreadData;
 | 
				
			||||||
struct SDL_Thread;
 | 
					 | 
				
			||||||
struct SDL_Window;
 | 
					struct SDL_Window;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct AtomicFlag
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	AtomicFlag()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		clear();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void set()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		SDL_AtomicSet(&atom, 1);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void clear()
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		SDL_AtomicSet(&atom, 0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	operator bool() const
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		return SDL_AtomicGet(&atom);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	mutable SDL_atomic_t atom;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class EventThread
 | 
					class EventThread
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										48
									
								
								src/sdl-util.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										48
									
								
								src/sdl-util.h
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,48 @@
 | 
				
			||||||
 | 
					#ifndef SDLUTIL_H
 | 
				
			||||||
 | 
					#define SDLUTIL_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <SDL_atomic.h>
 | 
				
			||||||
 | 
					#include <SDL_thread.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct AtomicFlag
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						AtomicFlag()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							clear();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void set()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SDL_AtomicSet(&atom, 1);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void clear()
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							SDL_AtomicSet(&atom, 0);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						operator bool() const
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							return SDL_AtomicGet(&atom);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						mutable SDL_atomic_t atom;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class C, void (C::*func)()>
 | 
				
			||||||
 | 
					int __sdlThreadFun(void *obj)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						(static_cast<C*>(obj)->*func)();
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					template<class C, void (C::*func)()>
 | 
				
			||||||
 | 
					SDL_Thread *createSDLThread(C *obj, const std::string &name = std::string())
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						return SDL_CreateThread(__sdlThreadFun<C, func>, name.c_str(), obj);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif // SDLUTIL_H
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue