import from git: added extra usage explanation, added -s command-line option to set multisample level, added a fallback to AV::start() to try multisample level of 1 if attempting samples>1 fails, fixed audio bug for combining multiple streams getting staticky, added documentation for joint and sound Lua member methods

git-svn-id: svn://anubis/anaglym/trunk@300 99a6e188-d820-4881-8870-2d33a10e2619
This commit is contained in:
Josh Holtrop 2010-08-06 01:56:27 +00:00
parent 82254ff82c
commit 8dbcc0b043
4 changed files with 210 additions and 9 deletions

47
AV.cc
View File

@ -17,6 +17,15 @@ using namespace std;
#define CALLBACK_SAMPLES 4096
#define CHANNELS 2
#define BYTES_PER_SAMPLE 2
#if AV_SOUND_FORMAT == AUDIO_S16SYS
# define SAMPLE_MIN SHRT_MIN
# define SAMPLE_MAX SHRT_MAX
#elif AV_SOUND_FORMAT == AUDIO_U16SYS
# define SAMPLE_MIN 0
# define SAMPLE_MAX USHRT_MAX
#else
# error Unknown AV_SOUND_FORMAT
#endif
void AV_sound_callback(void * userdata, Uint8 * stream, int len)
{
@ -56,12 +65,13 @@ AV::AV()
desired.samples = CALLBACK_SAMPLES;
desired.callback = AV_sound_callback;
desired.userdata = this;
desired.silence = 0;
if (SDL_OpenAudio(&desired, NULL) < 0)
{
cerr << "SDL_OpenAudio() error." << endl;
exit(3);
}
m_sound_buffer = new int16_t[CALLBACK_SAMPLES * CHANNELS];
m_sound_buffer = new sample_t[CALLBACK_SAMPLES * CHANNELS];
m_active_sounds_mutex = SDL_CreateMutex();
}
@ -76,7 +86,7 @@ AV::~AV()
delete[] m_sound_buffer;
}
void AV::start(int width, int height, bool fullscreen, bool grab_input,
bool AV::start(int width, int height, bool fullscreen, bool grab_input,
int samples)
{
if (m_surface == NULL)
@ -96,6 +106,31 @@ void AV::start(int width, int height, bool fullscreen, bool grab_input,
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, samples);
}
m_surface = SDL_SetVideoMode(width, height, 32, flags);
if (m_surface == NULL)
{
if (samples > 1)
{
cerr << "Error setting video mode, trying again without multisampling" << endl;
/* failed to set SDL video mode with multisampling, try without */
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLEBUFFERS, 0);
SDL_GL_SetAttribute(SDL_GL_MULTISAMPLESAMPLES, 0);
m_surface = SDL_SetVideoMode(width, height, 32, flags);
if (m_surface != NULL)
{
cerr << "Successfully set video mode without multisampling" << endl;
}
}
}
if (m_surface == NULL)
{
cerr << "Error setting SDL video mode." << endl;
cerr << "Parameters:" << endl;
cerr << " width = " << width << endl;
cerr << " height = " << height << endl;
cerr << " fullscreen = " << fullscreen << endl;
cerr << " input grab = " << grab_input << endl;
return false;
}
if (grab_input)
{
SDL_ShowCursor(SDL_DISABLE);
@ -119,6 +154,7 @@ void AV::start(int width, int height, bool fullscreen, bool grab_input,
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
return true;
}
void AV::stop()
@ -161,7 +197,7 @@ void AV::stopSound(AV::Sound * s)
void AV::playCallback(Uint8 * stream, int len)
{
uint16_t * stream16 = (uint16_t *) stream;
sample_t * stream16 = (sample_t *) stream;
memset(stream, 0, len);
SDL_mutexP(m_active_sounds_mutex);
#ifdef DEBUG
@ -188,7 +224,7 @@ void AV::playCallback(Uint8 * stream, int len)
i++)
{
int sample_val = stream16[i] + (int)(volume * m_sound_buffer[i]);
stream16[i] = min(SHRT_MAX, max(SHRT_MIN, sample_val));
stream16[i] = min(SAMPLE_MAX, max(SAMPLE_MIN, sample_val));
}
}
int sz = m_active_sounds.size();
@ -237,10 +273,9 @@ bool AV::Sound::load(FileLoader & fileLoader, const FileLoader::Path & path)
}
else
{
SDL_FreeRW(m_rwops);
m_rwops = NULL;
cerr << "Error loading sound " << path.toString() << ": "
<< Sound_GetError() << endl;
m_rwops = NULL;
}
}
return false;

13
AV.h
View File

@ -11,9 +11,18 @@
#include "FileLoader/FileLoader.h"
#include "refptr/refptr.h"
#define AV_SOUND_FORMAT AUDIO_S16SYS
class AV
{
public:
#if AV_SOUND_FORMAT == AUDIO_S16SYS
typedef int16_t sample_t;
#elif AV_SOUND_FORMAT == AUDIO_U16SYS
typedef uint16_t sample_t;
#else
# error Unknown AV_SOUND_FORMAT
#endif
class Sound
{
public:
@ -41,7 +50,7 @@ class AV
AV();
~AV();
void start(int width = 0, int height = 0,
bool start(int width = 0, int height = 0,
bool fullscreen = true, bool grab_input = true,
int samples = 4);
void stop();
@ -87,7 +96,7 @@ class AV
#endif
std::set< Sound * > m_active_sounds;
SDL_mutex * m_active_sounds_mutex;
int16_t * m_sound_buffer;
sample_t * m_sound_buffer;
};
#endif

View File

@ -13,6 +13,12 @@ static void usage();
static void usage()
{
cerr << "Usage: anaglym [options] program.lua[c]" << endl;
cerr << "Options:" << endl;
cerr << " -w<width> : set window width" << endl;
cerr << " -h<height> : set window height" << endl;
cerr << " -f : do not fullscreen" << endl;
cerr << " -g : do not grab mouse input" << endl;
cerr << " -s<samples>: set multisample level (default 4)" << endl;
exit(42);
}
@ -22,6 +28,7 @@ int main(int argc, char * argv[])
bool grab_input = true;
int width = 0;
int height = 0;
int samples = 4;
const char * program = NULL;
for (int i = 1; i < argc; i++)
{
@ -55,6 +62,10 @@ int main(int argc, char * argv[])
{
height = atoi((strlen(argv[i]) == 2) ? argv[++i] : argv[i] + 2);
}
else if (!strncmp(argv[i], "-s", 2))
{
samples = atoi((strlen(argv[i]) == 2) ? argv[++i] : argv[i] + 2);
}
else
{
cerr << "Warning: Unrecognized option '" << argv[i]+1
@ -72,7 +83,11 @@ int main(int argc, char * argv[])
srand(time(NULL));
AV av;
av.start(width, height, fullscreen, grab_input);
if (!av.start(width, height, fullscreen, grab_input, samples))
{
cerr << "anaglym: exiting." << endl;
return -1;
}
dInitODE();
g_engine = new Engine(argv[0], av);

View File

@ -34,6 +34,8 @@ The library functions are documented below.
<ul>
<li><a href="#object_creation">object creation functions</a></li>
<li><a href="#object">object member methods</a></li>
<li><a href="#joint">joint member methods</a></li>
<li><a href="#sound">sound member methods</a></li>
</ul>
</li>
<li><a href="#std"><tt>std</tt> library</a></li>
@ -58,6 +60,7 @@ The library functions are documented below.
<li><tt>-h height</tt> - specify the height in pixels of the window</li>
<li><tt>-f</tt> - do not fullscreen window</li>
<li><tt>-g</tt> - do not grab mouse input</li>
<li><tt>-s samples</tt> - set multisample level (default 4)</li>
</ul>
</p>
@ -476,6 +479,16 @@ You can instantiate a reference object into a normal object by calling
the <a href="#object_clone">clone()</a> method on the object.
</p>
<a name="ag_loadSound" />
<h3>loadSound</h3>
<p><tt>sound = ag.loadSound(sound_name)</tt></p>
<p>
This routine loads a <a href="#sound">sound</a> object from file
<tt>sound_name</tt> and returns a Lua reference to the loaded sound.
The <tt>sound_name</tt> should contain the file extension,
since multiple formats are supported (.wav, .mp3, etc...).
</p>
<a name="ag_loadTexture" />
<h3>loadTexture</h3>
<p><tt>texture = ag.loadTexture(texture_name)</tt></p>
@ -925,6 +938,135 @@ Newly created objects are visible by default.
<hr />
<a name="joint" />
<h2>Joint member methods</h2>
<a name="joint_setAMotorAxis" />
<h3>setAMotorAxis</h3>
<p><tt>joint:setAMotorAxis(anum, rel, x, y, z)</tt></p>
<p>
Set axis parameters of the AMotor joint.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<a name="joint_setNumAxes" />
<h3>setAMotorNumAxes</h3>
<p><tt>joint:setAMotorNumAxes(num)</tt></p>
<p>
Set the number of axes of the AMotor joint.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<a name="joint_setAMotorAngle" />
<h3>setAMotorAngle</h3>
<p><tt>joint:setAMotorAngle(anum, angle)</tt></p>
<p>
Set the angle of the specified of axis of the AMotor joint.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<a name="joint_setAMotorLoStop" />
<h3>setAMotorLoStop</h3>
<p><tt>joint:setAMotorLoStop(anum, lostop)</tt></p>
<p>
Set the low stop angle of the specified axis of the AMotor joint.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<a name="joint_setAMotorHiStop" />
<h3>setAMotorHiStop</h3>
<p><tt>joint:setAMotorHiStop(anum, histop)</tt></p>
<p>
Set the high stop angle of the specified axis of the AMotor joint.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<a name="joint_setAMotorVel" />
<h3>setAMotorVel</h3>
<p><tt>joint:setAMotorVel(vel)</tt></p>
<p>
Set the velocity of the AMotor joint.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<a name="joint_setAMotorFMax" />
<h3>setAMotorFMax</h3>
<p><tt>joint:setAMotorFMax(vel)</tt></p>
<p>
Set the maximum force that the AMotor joint will apply to
maintain its constraints.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<a name="joint_setAMotorBounce" />
<h3>setAMotorBounce</h3>
<p><tt>joint:setAMotorBounce(bounce)</tt></p>
<p>
Set the bounciness of the AMotor joint.
See <a href="#ag_createAMotor">ag.createAMotor()</a> for more information.
</p>
<hr />
<a name="sound" />
<h2>Sound member methods</h2>
<a name="sound_play" />
<h3>play</h3>
<p><tt>snd:play()</tt></p>
<p>
Begins playing the <tt>snd</tt> sound at the beginning.
</p>
<a name="sound_resume" />
<h3>resume</h3>
<p><tt>snd:resume()</tt></p>
<p>
Begins playing the <tt>snd</tt> sound where it stopped after calling
<a href="#sound_stop">stop()</a>.
</p>
<a name="sound_stop" />
<h3>stop</h3>
<p><tt>snd:stop()</tt></p>
<p>
Stops playing the <tt>snd</tt> sound at its current position.
</p>
<a name="sound_loop" />
<h3>loop</h3>
<p><tt>snd:loop(count)</tt></p>
<p>
Begins playing the <tt>snd</tt> sound at the beginning and sets the loop
count to <tt>count</tt>. <tt>snd:loop(1)</tt> is equivalent to
<tt>snd:play()</tt>.
</p>
<a name="sound_loopForever" />
<h3>loopForever</h3>
<p><tt>snd:loopForever()</tt></p>
<p>
Begins playing the <tt>snd</tt> sound at the beginning and sets the loop
count to infinity. This routine is good for background music.
</p>
<a name="sound_getVolume" />
<h3>getVolume</h3>
<p><tt>snd:getVolume()</tt></p>
<p>
Get the volume for the <tt>snd</tt> sound.
</p>
<a name="sound_setVolume" />
<h3>setVolume</h3>
<p><tt>snd:setVolume(vol)</tt></p>
<p>
Set the volume for the <tt>snd</tt> sound to <tt>snd</tt>.
<tt>snd</tt> should be between <tt>0.0</tt> and <tt>1.0</tt>.
</p>
<hr />
<a name="std" />
<h2><tt>std</tt> library</h2>