diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5366a572..a2aabeb6 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -118,7 +118,7 @@ if( OZ_GL_ES )
# On embedded platform GLES is part of system libraries and is guaranteed to exist in toolchain or
# platform directory, no need to explicitly check existence or to detect library names.
if( NOT PLATFORM_EMBEDDED )
- pkg_check_modules( GLES2 REQUIRED gles2 )
+ pkg_check_modules( GLES2 REQUIRED glesv2 )
endif()
else()
find_package( OpenGL REQUIRED )
@@ -169,7 +169,7 @@ if( ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang )
# Use libc++ instead of libstdc++.
# set( flags "${flags} -stdlib=libc++" )
# AddressSanitizer memory checker
- # set( flags "${flags} -faddress-sanitizer" )
+ # set( flags "${flags} -fsanitize=address" )
elseif( ${CMAKE_CXX_COMPILER_VERSION} VERSION_LESS 4.5 )
set( flags "-pipe -std=gnu++0x" )
elseif( ANDROID )
diff --git a/ChangeLog.md b/ChangeLog.md
index 053a1501..05f4762f 100644
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -2,9 +2,10 @@
- ozCore
* null replaced by nullptr keyword
+ * global abs(), min(), max(), clamp() and hash() functions, overloaded where necessary
* container improvements
+ improved iterators: much less code duplication, no more key() and value() members
- + STL-like begin() and end() members for containers
+ + STL-like begin() and end() members on containers
+ new Set template class: Map with arbitrary elements instead of key-value pairs
+ HashIndex and HashString merged into new HashMap template class with an arbitrary key type
+ new HashSet template class: hashtable of key-only elements instead of key-value pairs
diff --git a/doc/PREBERI.html b/doc/PREBERI.html
index e0f1e528..a5b6b86b 100644
--- a/doc/PREBERI.html
+++ b/doc/PREBERI.html
@@ -361,7 +361,7 @@
-v |
- Zgovornejši dnevnik.
+ Izpisuj podrobna dnevniška sporočila na terminal.
|
@@ -386,8 +386,8 @@
-L <jezik> |
- Nastavi jezik »<jezik>. Mora sovpadati s podimenikom imenika »lingua/« v podatkovnih
- arhivih.
+ Nastavi jezik »<jezik>. Mora sovpadati s imenom podimenika v imeniku »lingua/« v
+ podatkovnih arhivih.
|
diff --git a/doc/README.html b/doc/README.html
index c91b9231..b54da563 100644
--- a/doc/README.html
+++ b/doc/README.html
@@ -361,13 +361,13 @@
-v |
- More verbose log output.
+ Print verbose log messages to terminal.
|
-l |
- Skip main menu and load the last autosaved state.
+ Skip main menu and load the last autosaved game.
|
@@ -386,7 +386,8 @@
-L <lang> |
- Use language <lang>. Should match a subdirectory of 'lingua/' directory in game data.
+ Use language <lang>. Should match a subdirectory name in 'lingua/' directory inside game
+ data archives.
|
diff --git a/etc/PKGBUILD b/etc/PKGBUILD
index a3d71aa1..eae8816d 100644
--- a/etc/PKGBUILD
+++ b/etc/PKGBUILD
@@ -17,9 +17,10 @@ build()
cd "${srcdir}/${pkgbase}-${pkgver}/build"
cmake \
- -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr \
- -D CMAKE_CXX_FLAGS="$CXXFLAGS -msse3 -mfpmath=sse" \
+ -D CMAKE_BUILD_TYPE=Release \
+ -D CMAKE_CXX_FLAGS="${CXXFLAGS/-O2} -msse3 -mfpmath=sse" \
+ -D CMAKE_CXX_FLAGS_RELEASE="-Ofast -flto" \
-D OZ_LUAJIT=1 \
-D OZ_NONFREE=1 \
..
diff --git a/etc/openzone.spec b/etc/openzone.spec
index 0f05ce52..c2e8b8f1 100644
--- a/etc/openzone.spec
+++ b/etc/openzone.spec
@@ -69,10 +69,10 @@ Game data for OpenZone. Includes tutorial, test world and cviček mission.
cd build
cmake \
- -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_INSTALL_PREFIX=/usr \
- -D CMAKE_C_FLAGS="-msse3 -mfpmath=sse" \
+ -D CMAKE_BUILD_TYPE=Release \
-D CMAKE_CXX_FLAGS="-msse3 -mfpmath=sse" \
+ -D CMAKE_CXX_FLAGS_RELEASE="-Ofast -flto" \
..
make %{?_smp_mflags}
diff --git a/nacl-test.sh b/nacl-test.sh
index 727fe83d..25d8902d 100755
--- a/nacl-test.sh
+++ b/nacl-test.sh
@@ -20,7 +20,7 @@ for i in share/openzone/*.{7z,zip} share/openzone/packages.ozManifest \
build/NaCl-*/src/tools/openzone.*.nexe etc/nacl/openzone.nmf \
etc/nacl/openzone.??.html doc
do
- [[ -e $i ]] && ln -sf $i build/NaCl-test
+ [[ -e $i ]] && ln -sf ../../$i build/NaCl-test
done
# Strip binaries if "strip" parameter given.
diff --git a/src/client/Audio.cc b/src/client/Audio.cc
index 20ad0cee..6330ff26 100644
--- a/src/client/Audio.cc
+++ b/src/client/Audio.cc
@@ -41,11 +41,6 @@ void Audio::playSound( int sound, float volume, const Object* parent ) const
{
hard_assert( uint( sound ) < uint( liber.sounds.length() ) );
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( sound );
- static_cast( volume );
- static_cast( parent );
-#else
const Dynamic* dynParent = static_cast( parent );
uint srcId = context.addSource( sound );
@@ -80,18 +75,12 @@ void Audio::playSound( int sound, float volume, const Object* parent ) const
alSourcePlay( srcId );
OZ_AL_CHECK_ERROR();
-#endif
}
void Audio::playContSound( int sound, float volume, const Object* parent ) const
{
hard_assert( uint( sound ) < uint( liber.sounds.length() ) );
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( sound );
- static_cast( volume );
- static_cast( parent );
-#else
int key = obj->index * ObjectClass::MAX_SOUNDS + sound;
Context::ContSource* contSource = context.contSources.find( key );
@@ -128,16 +117,10 @@ void Audio::playContSound( int sound, float volume, const Object* parent ) const
}
OZ_AL_CHECK_ERROR();
-#endif
}
bool Audio::playSpeak( const char* text, float volume, const Object* parent ) const
{
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( text );
- static_cast( volume );
- static_cast( parent );
-#else
const Dynamic* dynParent = static_cast( parent );
if( context.speakSource.owner < 0 ) {
@@ -169,7 +152,6 @@ bool Audio::playSpeak( const char* text, float volume, const Object* parent ) co
}
OZ_AL_CHECK_ERROR();
-#endif
return true;
}
@@ -179,11 +161,6 @@ void Audio::playEngineSound( int sound, float volume, float pitch ) const
hard_assert( uint( sound ) < uint( liber.sounds.length() ) );
hard_assert( obj->flags & Object::VEHICLE_BIT );
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( sound );
- static_cast( volume );
- static_cast( pitch );
-#else
const Vehicle* veh = static_cast( obj );
if( !camera.isExternal && veh->pilot >= 0 && veh->pilot == camera.bot ) {
@@ -224,13 +201,11 @@ void Audio::playEngineSound( int sound, float volume, float pitch ) const
}
OZ_AL_CHECK_ERROR();
-#endif
}
Audio::Audio( const Object* obj_ ) :
obj( obj_ ), clazz( obj_->clazz ), flags( 0 )
{
-#ifndef OZ_ADDRESS_SANITIZER
const int* sounds = clazz->audioSounds;
Log::verboseMode = true;
@@ -244,12 +219,10 @@ Audio::Audio( const Object* obj_ ) :
Log::verboseMode = false;
OZ_AL_CHECK_ERROR();
-#endif
}
Audio::~Audio()
{
-#ifndef OZ_ADDRESS_SANITIZER
const int* sounds = clazz->audioSounds;
Log::verboseMode = true;
@@ -263,7 +236,6 @@ Audio::~Audio()
Log::verboseMode = false;
OZ_AL_CHECK_ERROR();
-#endif
}
}
diff --git a/src/client/BSPAudio.cc b/src/client/BSPAudio.cc
index aafd0c88..b376a7ab 100644
--- a/src/client/BSPAudio.cc
+++ b/src/client/BSPAudio.cc
@@ -36,10 +36,6 @@ void BSPAudio::playDemolish( const Struct* str, int sound ) const
{
hard_assert( uint( sound ) < uint( liber.sounds.length() ) );
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( str );
- static_cast( sound );
-#else
uint srcId = context.addSource( sound );
if( srcId == Context::INVALID_SOURCE ) {
return;
@@ -53,17 +49,12 @@ void BSPAudio::playDemolish( const Struct* str, int sound ) const
alSourcePlay( srcId );
OZ_AL_CHECK_ERROR();
-#endif
}
void BSPAudio::playSound( const Entity* entity, int sound ) const
{
hard_assert( uint( sound ) < uint( liber.sounds.length() ) );
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( entity );
- static_cast( sound );
-#else
const Struct* str = entity->str;
Point p = str->toAbsoluteCS( entity->clazz->p() + entity->offset );
Vec3 velocity = str->toAbsoluteCS( entity->velocity );
@@ -82,17 +73,12 @@ void BSPAudio::playSound( const Entity* entity, int sound ) const
alSourcePlay( srcId );
OZ_AL_CHECK_ERROR();
-#endif
}
void BSPAudio::playContSound( const Entity* entity, int sound ) const
{
hard_assert( uint( sound ) < uint( liber.sounds.length() ) );
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( entity );
- static_cast( sound );
-#else
const Struct* str = entity->str;
int key = str->index * Struct::MAX_ENTITIES +
int( entity - str->entities.begin() );
@@ -122,26 +108,21 @@ void BSPAudio::playContSound( const Entity* entity, int sound ) const
}
OZ_AL_CHECK_ERROR();
-#endif
}
BSPAudio::BSPAudio( const matrix::BSP* bsp_ ) :
bsp( bsp_ )
{
-#ifndef OZ_ADDRESS_SANITIZER
foreach( i, bsp->sounds.citer() ) {
context.requestSound( *i );
}
-#endif
}
BSPAudio::~BSPAudio()
{
-#ifndef OZ_ADDRESS_SANITIZER
foreach( i, bsp->sounds.citer() ) {
context.releaseSound( *i );
}
-#endif
}
void BSPAudio::play( const Struct* str ) const
diff --git a/src/client/BasicAudio.cc b/src/client/BasicAudio.cc
index 46ca19eb..eba47cd2 100644
--- a/src/client/BasicAudio.cc
+++ b/src/client/BasicAudio.cc
@@ -46,7 +46,7 @@ Audio* BasicAudio::create( const Object* obj )
void BasicAudio::play( const Audio* parent )
{
- const int ( & sounds )[ObjectClass::MAX_SOUNDS] = obj->clazz->audioSounds;
+ const auto& sounds = obj->clazz->audioSounds;
for( int i = 0; i < ObjectClass::MAX_SOUNDS; ++i ) {
recent[i] = max( recent[i] - 1, 0 );
diff --git a/src/client/BotAudio.cc b/src/client/BotAudio.cc
index e8068aed..c97dd424 100644
--- a/src/client/BotAudio.cc
+++ b/src/client/BotAudio.cc
@@ -112,7 +112,7 @@ void BotAudio::play( const Audio* parent )
prevStep = 0;
}
-// if( bot->clazz->name.equals( "bauul" ) ) {
+ if( bot->clazz->name.equals( "bauul" ) ) {
// playSpeak( "Gil-galad was an Elven-king.\n"
// "Of him the harpers sadly sing:\n"
// "the last whose realm was fair and free\n"
@@ -128,8 +128,8 @@ void BotAudio::play( const Audio* parent )
// "for into darkness fell his star\n"
// "in Mordor where the shadows are.\n",
// 1.0f, bot );
-// playSpeak( "Booa-ha-ha-ha-ha!", 1.0f, bot );
-// }
+ playSpeak( "Joj prejoj, kako sem žejen!", 1.0f, bot );
+ }
}
}
diff --git a/src/client/BuildInfo.cc.in b/src/client/BuildInfo.cc.in
index a1f5596b..53fdbabf 100644
--- a/src/client/BuildInfo.cc.in
+++ b/src/client/BuildInfo.cc.in
@@ -24,7 +24,7 @@ namespace oz
{
#ifdef OZ_MSVC
-static const String COMPILER_STRING = "MSVC " + String::str( "%g", float( OZ_MSVC ) / 100.0f );
+static const String COMPILER_STRING = String::str( "MSVC %g", float( OZ_MSVC ) / 100.0f );
#endif
const char* const BuildInfo::TIME = __DATE__ " " __TIME__;
@@ -34,6 +34,8 @@ const char* const BuildInfo::TARGET_ARCH = "@CMAKE_SYSTEM_NAME@-@CMAKE_SYSTEM_
const char* const BuildInfo::BUILD_TYPE = "@CMAKE_BUILD_TYPE@";
#if defined( OZ_MSVC )
const char* const BuildInfo::COMPILER = COMPILER_STRING;
+#elif defined( OZ_OPEN64 )
+const char* const BuildInfo::COMPILER = "Open64 " __OPEN64__;
#elif defined( OZ_CLANG )
const char* const BuildInfo::COMPILER = "LLVM/Clang " __clang_version__;
#else
diff --git a/src/client/CinematicProxy.cc b/src/client/CinematicProxy.cc
index 017c4e82..085aca8a 100644
--- a/src/client/CinematicProxy.cc
+++ b/src/client/CinematicProxy.cc
@@ -233,7 +233,7 @@ void CinematicProxy::update()
sound.stopMusic();
}
else if( step.track != -1 ) {
- sound.playMusic( step.track, false );
+ sound.playMusic( step.track );
}
if( !step.title.isEmpty() ) {
diff --git a/src/client/Client.cc b/src/client/Client.cc
index 99c64863..91048280 100644
--- a/src/client/Client.cc
+++ b/src/client/Client.cc
@@ -41,11 +41,10 @@
#include
#include
-#include
-
#include
#include
#include
+#include
#if defined( __native_client__ )
# include
@@ -62,22 +61,22 @@ namespace client
void Client::printUsage( const char* invocationName )
{
+
Log::printRaw(
"Usage:\n"
" %s [-v] [-l | -i ] [-t ] [-L ] [-p ]\n"
"\n"
- " -v More verbose log output.\n"
- " -l Skip main menu and load the last autosaved state.\n"
+ " -v Print verbose log messages to terminal.\n"
+ " -l Skip main menu and load the last autosaved game.\n"
" -i Skip main menu and start mission .\n"
" -t Exit after seconds (can be a floating-point number) and\n"
" use 42 as the random seed. Useful for benchmarking.\n"
- " -L Use language . Should match a subdirectory of 'lingua/'\n"
- " directory in game data.\n"
+ " -L Use language . Should match a subdirectory name in\n"
+ " 'lingua/' directory inside game data archives.\n"
" -p Sets data directory to '/share/openzone'.\n"
" Defaults to '%s'.\n"
"\n",
- invocationName,
- OZ_INSTALL_PREFIX );
+ invocationName, OZ_INSTALL_PREFIX );
}
int Client::init( int argc, char** argv )
diff --git a/src/client/Client.hh b/src/client/Client.hh
index 0e1b879c..8293bfb8 100644
--- a/src/client/Client.hh
+++ b/src/client/Client.hh
@@ -38,21 +38,21 @@ class Client
{
private:
- static const int INIT_PHYSFS = 0x00000001;
- static const int INIT_SDL = 0x00000002;
- static const int INIT_SDL_TTF = 0x00000004;
- static const int INIT_CONFIG = 0x00000010;
- static const int INIT_WINDOW = 0x00000020;
- static const int INIT_INPUT = 0x00000040;
- static const int INIT_NETWORK = 0x00000080;
- static const int INIT_LINGUA = 0x00000100;
- static const int INIT_LIBRARY = 0x00000200;
- static const int INIT_CONTEXT = 0x00001000;
- static const int INIT_RENDER = 0x00002000;
- static const int INIT_AUDIO = 0x00004000;
- static const int INIT_STAGE_INIT = 0x00010000;
- static const int INIT_STAGE_LOAD = 0x00020000;
- static const int INIT_MAIN_LOOP = 0x00040000;
+ static const int INIT_PHYSFS = 0x0001;
+ static const int INIT_SDL = 0x0002;
+ static const int INIT_SDL_TTF = 0x0004;
+ static const int INIT_CONFIG = 0x0008;
+ static const int INIT_WINDOW = 0x0010;
+ static const int INIT_INPUT = 0x0020;
+ static const int INIT_NETWORK = 0x0040;
+ static const int INIT_LINGUA = 0x0080;
+ static const int INIT_LIBRARY = 0x0100;
+ static const int INIT_CONTEXT = 0x0200;
+ static const int INIT_RENDER = 0x0400;
+ static const int INIT_AUDIO = 0x0800;
+ static const int INIT_STAGE_INIT = 0x1000;
+ static const int INIT_STAGE_LOAD = 0x2000;
+ static const int INIT_MAIN_LOOP = 0x4000;
Stage* stage;
int initFlags;
diff --git a/src/client/Context.cc b/src/client/Context.cc
index dcaaeccf..6744a247 100644
--- a/src/client/Context.cc
+++ b/src/client/Context.cc
@@ -271,6 +271,8 @@ Context::Context() :
uint Context::readTextureLayer( InputStream* istream )
{
+ OZ_GL_CHECK_ERROR();
+
uint texId;
glGenTextures( 1, &texId );
glBindTexture( GL_TEXTURE_2D, texId );
@@ -306,7 +308,9 @@ uint Context::readTextureLayer( InputStream* istream )
}
}
- OZ_GL_CHECK_ERROR();
+ if( glGetError() != GL_NO_ERROR ) {
+ OZ_ERROR( "Texture loading error; maybe missing S3 texture compression support?" );
+ }
return texId;
}
@@ -636,13 +640,11 @@ void Context::updateLoad()
void Context::load()
{
speakSource.owner = -1;
-#ifndef OZ_ADDRESS_SANITIZER
alGenBuffers( 2, speakSource.bufferIds );
alGenSources( 1, &speakSource.id );
if( alGetError() != AL_NO_ERROR ) {
OZ_ERROR( "Failed to create speak source" );
}
-#endif
maxImagines = 0;
maxAudios = 0;
@@ -691,7 +693,6 @@ void Context::unload()
Log::unindent();
Log::println( "}" );
-#ifndef OZ_ADDRESS_SANITIZER
// Speak source must be destroyed before anything else using OpenAL since it calls OpenAL
// functions from its own thread.
if( speakSource.thread.isValid() ) {
@@ -701,7 +702,6 @@ void Context::unload()
alDeleteSources( 1, &speakSource.id );
alDeleteBuffers( 2, speakSource.bufferIds );
-#endif
imagines.free();
imagines.deallocate();
diff --git a/src/client/NaCl.cc b/src/client/NaCl.cc
index 1a5d1e96..2bcc1655 100644
--- a/src/client/NaCl.cc
+++ b/src/client/NaCl.cc
@@ -30,16 +30,14 @@
#include
#include
#include
-#include
namespace oz
{
namespace client
{
-static SpinLock messageLock;
-static List messageQueue;
-static pp::Graphics3D context;
+static SpinLock messageLock;
+static List messageQueue;
Semaphore NaCl::mainCallSemaphore;
diff --git a/src/client/OpenAL.cc b/src/client/OpenAL.cc
index 63a0e9f1..a7112c89 100644
--- a/src/client/OpenAL.cc
+++ b/src/client/OpenAL.cc
@@ -33,11 +33,6 @@ namespace client
void alCheckError( const char* function, const char* file, int line )
{
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( function );
- static_cast( file );
- static_cast( line );
-#else
const char* message;
ALenum result = alGetError();
@@ -72,7 +67,6 @@ void alCheckError( const char* function, const char* file, int line )
}
System::error( function, file, line, 1, "AL error '%s'", message );
-#endif
}
#endif
diff --git a/src/client/Sound.cc b/src/client/Sound.cc
index 30b7a9bf..79092188 100644
--- a/src/client/Sound.cc
+++ b/src/client/Sound.cc
@@ -25,7 +25,6 @@
#include
#include
-
#include
#include
@@ -441,12 +440,13 @@ void Sound::musicRun()
musicMainSemaphore.post();
musicAuxSemaphore.wait();
- if( currentTrack != streamedTrack ) {
+ if( selectedTrack != -1 ) {
if( streamedTrack >= 0 ) {
musicClear();
}
- streamedTrack = currentTrack;
+ streamedTrack = selectedTrack == -2 ? -1 : selectedTrack;
+ selectedTrack = -1;
if( streamedTrack >= 0 ) {
musicOpen( liber.musicTracks[streamedTrack].path );
@@ -491,10 +491,7 @@ void Sound::updateMusic()
return;
}
- if( selectedTrack != -1 && selectedTrack != currentTrack ) {
- currentTrack = selectedTrack == -2 ? -1 : selectedTrack;
- selectedTrack = -1;
-
+ if( selectedTrack != -1 ) {
musicBuffersQueued = 0;
alSourceStop( musicSource );
@@ -509,14 +506,9 @@ void Sound::updateMusic()
musicAuxSemaphore.post();
}
- else if( currentTrack < 0 ) {
+ else if( streamedTrack < 0 ) {
musicMainSemaphore.post();
}
- else if( streamedBytes == 0 ) {
- currentTrack = -1;
-
- musicAuxSemaphore.post();
- }
else {
bool hasLoaded = false;
@@ -524,14 +516,24 @@ void Sound::updateMusic()
alGetSourcei( musicSource, AL_BUFFERS_PROCESSED, &nProcessed );
if( nProcessed != 0 ) {
- hasLoaded = true;
+ if( streamedBytes == 0 ) {
+ --musicBuffersQueued;
- uint buffer;
- alSourceUnqueueBuffers( musicSource, 1, &buffer );
- alBufferData( buffer, musicFormat, musicBuffer, streamedBytes, musicRate );
- alSourceQueueBuffers( musicSource, 1, &buffer );
+ if( musicBuffersQueued == 0 ) {
+ streamedTrack = -1;
+ }
+ }
+ else {
+ hasLoaded = true;
+
+ uint buffer;
+ alSourceUnqueueBuffers( musicSource, 1, &buffer );
+ alBufferData( buffer, musicFormat, musicBuffer, streamedBytes, musicRate );
+ alSourceQueueBuffers( musicSource, 1, &buffer );
+ }
}
- else if( musicBuffersQueued != 2 ) {
+ // If beginning a track.
+ else if( musicBuffersQueued != 2 && streamedBytes != 0 ) {
hasLoaded = true;
int i = musicBuffersQueued;
@@ -542,11 +544,13 @@ void Sound::updateMusic()
alSourcePlay( musicSource );
}
- ALint value;
- alGetSourcei( musicSource, AL_SOURCE_STATE, &value );
+ if( musicBuffersQueued != 0 ) {
+ ALint value;
+ alGetSourcei( musicSource, AL_SOURCE_STATE, &value );
- if( value == AL_STOPPED ) {
- alSourcePlay( musicSource );
+ if( value == AL_STOPPED ) {
+ alSourcePlay( musicSource );
+ }
}
if( hasLoaded ) {
@@ -565,7 +569,6 @@ void Sound::soundRun()
soundAuxSemaphore.wait();
while( isSoundAlive ) {
-#ifndef OZ_ADDRESS_SANITIZER
float orientation[] = {
camera.at.x, camera.at.y, camera.at.z,
camera.up.x, camera.up.y, camera.up.z
@@ -577,7 +580,6 @@ void Sound::soundRun()
alListenerfv( AL_ORIENTATION, orientation );
alListenerfv( AL_POSITION, camera.p );
alListenerfv( AL_VELOCITY, camera.velocity );
-#endif
if( playedStructs.length() < orbis.structs.length() ) {
playedStructs.deallocate();
@@ -593,9 +595,7 @@ void Sound::soundRun()
}
}
-#ifndef OZ_ADDRESS_SANITIZER
updateMusic();
-#endif
soundMainSemaphore.post();
soundAuxSemaphore.wait();
@@ -605,38 +605,29 @@ void Sound::soundRun()
void Sound::setVolume( float volume_ )
{
volume = volume_;
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( volume_ );
-#else
alListenerf( AL_GAIN, volume_ );
-#endif
}
void Sound::setMusicVolume( float volume ) const
{
-#ifdef OZ_ADDRESS_SANITIZER
- static_cast( volume );
-#else
alSourcef( musicSource, AL_GAIN, 0.5f * volume );
-#endif
}
bool Sound::isMusicPlaying() const
{
- return currentTrack >= 0 || selectedTrack >= 0;
+ return streamedTrack >= 0;
}
int Sound::getCurrentTrack() const
{
- return currentTrack;
+ return streamedTrack;
}
-void Sound::playMusic( int track, bool advanceTrack_ )
+void Sound::playMusic( int track )
{
hard_assert( track >= 0 );
selectedTrack = track;
- advanceTrack = advanceTrack_;
}
void Sound::stopMusic()
@@ -646,18 +637,12 @@ void Sound::stopMusic()
void Sound::resume() const
{
-#ifndef OZ_ADDRESS_SANITIZER
alcProcessContext( soundContext );
- alListenerf( AL_GAIN, volume );
-#endif
}
void Sound::suspend() const
{
-#ifndef OZ_ADDRESS_SANITIZER
- alListenerf( AL_GAIN, 0.0f );
alcSuspendContext( soundContext );
-#endif
}
void Sound::play()
@@ -681,10 +666,6 @@ void Sound::init()
Log::println( "Initialising Sound {" );
Log::indent();
-#ifdef OZ_ADDRESS_SANITIZER
- config["sound.device"];
-#else
-
#ifdef __native_client__
alSetPpapiInfo( System::instance->pp_instance(), System::module->get_browser_interface() );
#endif
@@ -801,20 +782,15 @@ void Sound::init()
Log::println( "}" );
Log::verboseMode = false;
-#endif // !OZ_ADDRESS_SANITIZER
-
selectedTrack = -1;
- currentTrack = -1;
streamedTrack = -1;
-#ifndef OZ_ADDRESS_SANITIZER
alGenBuffers( 2, musicBufferIds );
alGenSources( 1, &musicSource );
musicBuffersQueued = 0;
alSourcei( musicSource, AL_SOURCE_RELATIVE, AL_TRUE );
-#endif
setVolume( config.include( "sound.volume", 1.0f ).asFloat() );
setMusicVolume( 0.5f );
@@ -858,7 +834,6 @@ void Sound::destroy()
}
selectedTrack = -1;
- currentTrack = -1;
streamedTrack = -1;
isSoundAlive = false;
@@ -877,7 +852,6 @@ void Sound::destroy()
playedStructs.deallocate();
if( soundContext != nullptr ) {
-#ifndef OZ_ADDRESS_SANITIZER
alSourceStop( musicSource );
alDeleteSources( 1, &musicSource );
alDeleteBuffers( 2, musicBufferIds );
@@ -889,7 +863,6 @@ void Sound::destroy()
alcCloseDevice( soundDevice );
soundDevice = nullptr;
-#endif
}
#ifndef __native_client__
diff --git a/src/client/Sound.hh b/src/client/Sound.hh
index bf9b158f..87519f6e 100644
--- a/src/client/Sound.hh
+++ b/src/client/Sound.hh
@@ -97,11 +97,6 @@ class Sound
// Music track id to switch to, -1 to do nothing, -2 stop playing.
int selectedTrack;
- // Automatically advance to the next track when one finishes.
- bool advanceTrack;
- // Music track id, -1 for not playing.
- volatile int currentTrack;
-
int streamedTrack;
volatile int streamedBytes;
@@ -138,7 +133,7 @@ class Sound
bool isMusicPlaying() const;
int getCurrentTrack() const;
- void playMusic( int track, bool advanceTrack );
+ void playMusic( int track );
void stopMusic();
void resume() const;
diff --git a/src/client/VehicleAudio.cc b/src/client/VehicleAudio.cc
index c14f282e..9eef9b7f 100644
--- a/src/client/VehicleAudio.cc
+++ b/src/client/VehicleAudio.cc
@@ -47,6 +47,10 @@ void VehicleAudio::play( const Audio* parent )
const VehicleClass* clazz = static_cast( this->clazz );
const auto& sounds = obj->clazz->audioSounds;
+ for( int i = 0; i < ObjectClass::MAX_SOUNDS; ++i ) {
+ recent[i] = max( recent[i] - 1, 0 );
+ }
+
// engine sound
if( ( vehicle->pilot >= 0 ) && sounds[Vehicle::EVENT_ENGINE] >= 0 ) {
float pitch = clazz->enginePitchBias +
diff --git a/src/client/Window.cc b/src/client/Window.cc
index 2aa1a97d..28fe9e74 100644
--- a/src/client/Window.cc
+++ b/src/client/Window.cc
@@ -87,9 +87,11 @@ void Window::warpMouse()
NaCl::moveZ = 0;
NaCl::moveW = 0;
#elif SDL_MAJOR_VERSION < 2
- SDL_WarpMouse( ushort( width / 2 ), ushort( height / 2 ) );
- SDL_PumpEvents();
- SDL_GetRelativeMouseState( nullptr, nullptr );
+ if( !isFull ) {
+ SDL_WarpMouse( ushort( width / 2 ), ushort( height / 2 ) );
+ SDL_PumpEvents();
+ SDL_GetRelativeMouseState( nullptr, nullptr );
+ }
#else
SDL_WarpMouseInWindow( descriptor, width / 2, height / 2 );
#endif
diff --git a/src/client/eSpeak.cc b/src/client/eSpeak.cc
index c7e2c4cf..de20b294 100644
--- a/src/client/eSpeak.cc
+++ b/src/client/eSpeak.cc
@@ -29,12 +29,12 @@ namespace oz
namespace client
{
-decltype( ::espeak_Initialize )* espeak_Initialize = nullptr;
-decltype( ::espeak_Terminate )* espeak_Terminate = nullptr;
-decltype( ::espeak_SetParameter )* espeak_SetParameter = nullptr;
-decltype( ::espeak_SetVoiceByName )* espeak_SetVoiceByName = nullptr;
-decltype( ::espeak_SetSynthCallback )* espeak_SetSynthCallback = nullptr;
-decltype( ::espeak_Synth )* espeak_Synth = nullptr;
+OZ_DL_DEFINE( espeak_Initialize );
+OZ_DL_DEFINE( espeak_Terminate );
+OZ_DL_DEFINE( espeak_SetParameter );
+OZ_DL_DEFINE( espeak_SetVoiceByName );
+OZ_DL_DEFINE( espeak_SetSynthCallback );
+OZ_DL_DEFINE( espeak_Synth );
}
}
diff --git a/src/client/eSpeak.hh b/src/client/eSpeak.hh
index 5ca498df..384f70d1 100644
--- a/src/client/eSpeak.hh
+++ b/src/client/eSpeak.hh
@@ -32,12 +32,12 @@ namespace oz
namespace client
{
-extern decltype( ::espeak_Initialize )* espeak_Initialize;
-extern decltype( ::espeak_Terminate )* espeak_Terminate;
-extern decltype( ::espeak_SetParameter )* espeak_SetParameter;
-extern decltype( ::espeak_SetVoiceByName )* espeak_SetVoiceByName;
-extern decltype( ::espeak_SetSynthCallback )* espeak_SetSynthCallback;
-extern decltype( ::espeak_Synth )* espeak_Synth;
+extern OZ_DL_DECLARE( espeak_Initialize );
+extern OZ_DL_DECLARE( espeak_Terminate );
+extern OZ_DL_DECLARE( espeak_SetParameter );
+extern OZ_DL_DECLARE( espeak_SetVoiceByName );
+extern OZ_DL_DECLARE( espeak_SetSynthCallback );
+extern OZ_DL_DECLARE( espeak_Synth );
}
}
diff --git a/src/client/ui/Area.cc b/src/client/ui/Area.cc
index f886a6f9..02d0e59e 100644
--- a/src/client/ui/Area.cc
+++ b/src/client/ui/Area.cc
@@ -179,6 +179,16 @@ void Area::enable( bool doEnable )
onVisibilityChange( doShow );
}
+Pair Area::align( int localX, int localY, int width, int height ) const
+{
+ return {
+ localX == CENTRE ? this->x + ( this->width - width ) / 2 :
+ localX < 0 ? this->x + this->width - width + localX : this->x + localX,
+ localY == CENTRE ? this->y + ( this->height - height ) / 2 :
+ localY < 0 ? this->y + this->height - height + localY : this->y + localY
+ };
+}
+
void Area::add( Area* area, int localX, int localY )
{
area->width = clamp( area->width, 1, width );
diff --git a/src/client/ui/Area.hh b/src/client/ui/Area.hh
index 79a6e598..6ae0fbf1 100644
--- a/src/client/ui/Area.hh
+++ b/src/client/ui/Area.hh
@@ -107,6 +107,11 @@ class Area
void show( bool doShow );
void enable( bool doEnable );
+ /**
+ * Calculate global (x, y) for given relative rectangle coordinates/dimension.
+ */
+ Pair align( int localX, int localY, int width, int height ) const;
+
void add( Area* area, int localX, int localY );
void remove( Area* area );
void raise();
diff --git a/src/client/ui/HudArea.cc b/src/client/ui/HudArea.cc
index 1ac6fda7..45736139 100644
--- a/src/client/ui/HudArea.cc
+++ b/src/client/ui/HudArea.cc
@@ -25,14 +25,11 @@
#include
#include
-
#include
#include
#include
#include
-#include
-
namespace oz
{
namespace client
@@ -43,6 +40,25 @@ namespace ui
const float HudArea::VEHICLE_DIM = VEHICLE_SIZE / 2.0f;
const float HudArea::CROSS_FADE_COEFF = 8.0f;
+void HudArea::drawBar( const Style::Bar* barStyle, float ratio ) const
+{
+ int x = barStyle->x == CENTRE ? ( width - barStyle->w ) / 2 :
+ barStyle->x < 0 ? width - barStyle->w + barStyle->x : barStyle->x;
+ int y = barStyle->y == CENTRE ? ( width - barStyle->h ) / 2 :
+ barStyle->y < 0 ? height - barStyle->h + barStyle->y : barStyle->y;
+
+ int width = int( float( barStyle->w - 2 ) * ratio + 0.5f );
+
+ shape.colour( style.colours.barBorder );
+ shape.rect( x, y, barStyle->w, barStyle->h );
+
+ shape.colour( Math::mix( barStyle->minColour, barStyle->maxColour, ratio ) );
+ shape.fill( x + 1, y + 1, width, barStyle->h - 2 );
+
+ shape.colour( style.colours.barBackground );
+ shape.fill( x + 1 + width, y + 1, barStyle->w - 2 - width, barStyle->h - 2 );
+}
+
void HudArea::drawBotCrosshair()
{
const Bot* me = camera.botObj;
@@ -199,36 +215,23 @@ void HudArea::drawBotStatus()
const Bot* bot = camera.botObj;
const BotClass* botClazz = static_cast( camera.botObj->clazz );
- float life = 2.0f * bot->life / botClazz->life - 1.0f;
- float stamina = bot->stamina / botClazz->stamina;
- int lifeWidth = max( int( life * float( style.layout.botHealth.w - 2 ) ), 0 );
- int staminaWidth = max( int( stamina * float( style.layout.botStamina.w - 2 ) ), 0 );
+ float stamina = max( bot->stamina / botClazz->stamina, 0.0f );
+ float life = max( 2.0f * bot->life / botClazz->life - 1.0f, 0.0f );
- shape.colour( 1.0f - life, life, 0.0f, 0.5f );
- shape.fill( style.layout.botHealth.x + 1, style.layout.botHealth.y + 1,
- lifeWidth, style.layout.botHealth.h - 2 );
- shape.colour( 0.7f - 0.7f * stamina, 0.3f, 0.5f + 0.5f * stamina, 0.5f );
- shape.fill( style.layout.botStamina.x + 1, style.layout.botStamina.y + 1,
- staminaWidth, style.layout.botStamina.h - 2 );
-
- shape.colour( 0.0f, 0.0f, 0.0f, 0.1f );
- shape.fill( style.layout.botHealth.x + 1 + lifeWidth, style.layout.botHealth.y + 1,
- style.layout.botHealth.w - 2 - lifeWidth, style.layout.botHealth.h - 2 );
- shape.fill( style.layout.botHealth.x + 1 + staminaWidth, style.layout.botHealth.x + 1,
- style.layout.botHealth.w - 2 - staminaWidth, style.layout.botHealth.h - 2 );
-
- shape.colour( style.colours.barBorder );
- shape.rect( style.layout.botHealth.x, style.layout.botHealth.y,
- style.layout.botHealth.w, style.layout.botHealth.h );
- shape.rect( style.layout.botStamina.x, style.layout.botStamina.y,
- style.layout.botStamina.w, style.layout.botStamina.h );
+ drawBar( &style.botHealth, life );
+ drawBar( &style.botStamina, stamina );
if( bot->weapon >= 0 && orbis.objects[bot->weapon] != nullptr ) {
const Weapon* weaponObj = static_cast( orbis.objects[bot->weapon] );
+ Pair pos = align( style.botWeapon.x, style.botWeapon.y,
+ style.botWeapon.w, style.botWeapon.h );
+
shape.colour( style.colours.frame );
- shape.fill( style.layout.botWeapon.x, style.layout.botWeapon.y,
- style.layout.botWeapon.w, style.layout.botWeapon.h );
+ shape.fill( pos.x, pos.y, style.botWeapon.w, style.botWeapon.h );
+
+ weaponName.set( pos.x + 4, pos.y + 2 );
+ weaponRounds.set( pos.x + style.botWeapon.w - 4, pos.y + 2 );
if( lastWeaponId != bot->weapon ) {
lastWeaponId = bot->weapon;
@@ -280,61 +283,47 @@ void HudArea::drawVehicleStatus()
shape.bind();
shader.program( shader.plain );
- float life = vehicle->life / vehClazz->life;
- int lifeWidth = max( int( life * 198.0f ), 0 );
- float fuel = vehicle->fuel / vehClazz->fuel;
- int fuelWidth = int( fuel * 198.0f );
+ float fuel = max( vehicle->fuel / vehClazz->fuel, 0.0f );
+ float hull = max( vehicle->life / vehClazz->life, 0.0f );
- shape.colour( 1.0f - life, life, 0.0f, 0.5f );
- shape.fill( width - 207, 31, lifeWidth, 12 );
- shape.colour( 0.7f - 0.7f * fuel, 0.3f, 0.5f + 0.5f * fuel, 0.5f );
- shape.fill( width - 207, 9, fuelWidth, 12 );
+ drawBar( &style.vehicleFuel, fuel );
+ drawBar( &style.vehicleHull, hull );
- shape.colour( 0.0f, 0.0f, 0.0f, 0.1f );
- shape.fill( width - 207 + lifeWidth, 31, 198 - lifeWidth, 12 );
- shape.fill( width - 207 + fuelWidth, 9, 198 - fuelWidth, 12 );
-
- shape.colour( style.colours.barBorder );
- shape.rect( style.layout.vehicleFuel.x, style.layout.vehicleFuel.y,
- style.layout.vehicleFuel.w, style.layout.vehicleFuel.h );
- shape.rect( style.layout.vehicleFuel.x, style.layout.vehicleFuel.y,
- style.layout.vehicleFuel.w, style.layout.vehicleFuel.h );
-
- if( lastVehicleId != bot->parent ) {
- lastVehicleId = bot->parent;
+ for( int i = 0; i < vehClazz->nWeapons; ++i ) {
+ int labelIndex = vehClazz->nWeapons - i - 1;
+ Label& nameLabel = vehicleWeaponNames[labelIndex];
+ Label& roundsLabel = vehicleWeaponRounds[labelIndex];
+ const Style::Area& areaStyle = style.vehicleWeapon[labelIndex];
- for( int i = 0; i < vehClazz->nWeapons; ++i ) {
- int labelIndex = vehClazz->nWeapons - i - 1;
+ Pair pos = align( areaStyle.x, areaStyle.y, areaStyle.w, areaStyle.h );
- vehicleWeaponNames[labelIndex].set( "%s", vehClazz->weaponTitles[i].cstr() );
- }
- }
-
- for( int i = 0; i < vehClazz->nWeapons; ++i ) {
if( i == vehicle->weapon ) {
- int step = style.fonts[Font::LARGE].height + 8;
-
shape.colour( style.colours.frame );
- shape.fill( width - 208, 52 + ( vehClazz->nWeapons - 1 - i ) * step,
- 200, style.fonts[Font::LARGE].height + 8 );
+ shape.fill( pos.x, pos.y, areaStyle.w, areaStyle.h );
}
- int labelIndex = vehClazz->nWeapons - i - 1;
+ nameLabel.set( pos.x + 2, pos.y + 2 );
+ roundsLabel.set( pos.x + areaStyle.w - 4, pos.y + 2 );
+ if( lastVehicleId != bot->parent ) {
+ nameLabel.set( "%s", vehClazz->weaponTitles[i].cstr() );
+ }
if( lastVehicleWeaponRounds[labelIndex] != vehicle->nRounds[i] ) {
lastVehicleWeaponRounds[labelIndex] = vehicle->nRounds[i];
if( vehicle->nRounds[i] < 0 ) {
- vehicleWeaponRounds[labelIndex].set( "∞" );
+ roundsLabel.set( "∞" );
}
else {
- vehicleWeaponRounds[labelIndex].set( "%d", vehicle->nRounds[i] );
+ roundsLabel.set( "%d", vehicle->nRounds[i] );
}
}
- vehicleWeaponNames[labelIndex].draw( this, false );
- vehicleWeaponRounds[labelIndex].draw( this, true );
+ nameLabel.draw( this, false );
+ roundsLabel.draw( this, true );
}
+
+ lastVehicleId = bot->parent;
}
void HudArea::onReposition()
@@ -408,8 +397,8 @@ void HudArea::onDraw()
HudArea::HudArea() :
Area( camera.width, camera.height ),
- weaponName( 16, 54, ALIGN_LEFT, Font::LARGE, " " ),
- weaponRounds( 200, 54, ALIGN_RIGHT, Font::LARGE, "∞" ),
+ weaponName( 0, 0, ALIGN_LEFT, Font::LARGE, " " ),
+ weaponRounds( 0, 0, ALIGN_RIGHT, Font::LARGE, "0" ),
lastObjectId( -1 ),
lastEntityId( -1 ),
lastWeaponId( -1 ),
@@ -418,12 +407,11 @@ HudArea::HudArea() :
{
flags = UPDATE_BIT | IGNORE_BIT | PINNED_BIT;
- int step = style.fonts[Font::LARGE].height + 8;
for( int i = 0; i < Vehicle::MAX_WEAPONS; ++i ) {
lastVehicleWeaponRounds[i] = -1;
- vehicleWeaponNames[i].set( -200, 54 + i * step, ALIGN_LEFT, Font::LARGE, " " );
- vehicleWeaponRounds[i].set( -16, 54 + i * step, ALIGN_RIGHT, Font::LARGE, "∞" );
+ vehicleWeaponNames[i].set( 0, 0, ALIGN_LEFT, Font::LARGE, " " );
+ vehicleWeaponRounds[i].set( 0, 0, ALIGN_RIGHT, Font::LARGE, "0" );
}
Log::verboseMode = true;
diff --git a/src/client/ui/HudArea.hh b/src/client/ui/HudArea.hh
index df11c30b..ea8d86ce 100644
--- a/src/client/ui/HudArea.hh
+++ b/src/client/ui/HudArea.hh
@@ -24,9 +24,9 @@
#pragma once
#include
-
#include
#include
+#include
namespace oz
{
@@ -85,6 +85,7 @@ class HudArea : public Area
int bottomIconX;
int bottomIconY;
+ void drawBar( const Style::Bar* barStype, float ratio ) const;
void drawBotCrosshair();
void drawBotStatus();
void drawVehicleStatus();
diff --git a/src/client/ui/MusicPlayer.cc b/src/client/ui/MusicPlayer.cc
index 46433810..f7ccb984 100644
--- a/src/client/ui/MusicPlayer.cc
+++ b/src/client/ui/MusicPlayer.cc
@@ -43,7 +43,7 @@ void MusicPlayer::prevTrack( Button* sender )
if( nTracks != 0 ) {
musicPlayer->currentTrack = ( musicPlayer->currentTrack + nTracks - 1 ) % nTracks;
- sound.playMusic( musicPlayer->currentTrack, true );
+ sound.playMusic( musicPlayer->currentTrack );
musicPlayer->title.set( "%s", liber.musicTracks[musicPlayer->currentTrack].name.cstr() );
musicPlayer->trackLabel.set( "%d", musicPlayer->currentTrack + 1 );
@@ -59,7 +59,7 @@ void MusicPlayer::nextTrack( Button* sender )
if( nTracks != 0 ) {
musicPlayer->currentTrack = ( musicPlayer->currentTrack + 1 ) % nTracks;
- sound.playMusic( musicPlayer->currentTrack, true );
+ sound.playMusic( musicPlayer->currentTrack );
musicPlayer->title.set( "%s", liber.musicTracks[musicPlayer->currentTrack].name.cstr() );
musicPlayer->trackLabel.set( "%d", musicPlayer->currentTrack + 1 );
@@ -73,7 +73,7 @@ void MusicPlayer::playTrack( Button* sender )
int nTracks = liber.musicTracks.length();
if( nTracks != 0 ) {
- sound.playMusic( musicPlayer->currentTrack, true );
+ sound.playMusic( musicPlayer->currentTrack );
musicPlayer->title.set( "%s", liber.musicTracks[musicPlayer->currentTrack].name.cstr() );
musicPlayer->trackLabel.set( "%d", musicPlayer->currentTrack + 1 );
@@ -135,24 +135,18 @@ void MusicPlayer::onUpdate()
int soundTrack = sound.getCurrentTrack();
if( isPlaying && soundTrack != currentTrack ) {
if( soundTrack == -1 ) {
- // Go to next track.
+ // Go to the next track.
int nTracks = liber.musicTracks.length();
if( nTracks > 0 ) {
currentTrack = ( currentTrack + 1 ) % nTracks;
- sound.stopMusic();
- sound.playMusic( currentTrack, true );
+ sound.playMusic( currentTrack );
title.set( "%s", liber.musicTracks[currentTrack].name.cstr() );
trackLabel.set( "%d", currentTrack + 1 );
}
}
- else {
- // Probably a cinematic sequence scheduled a new track.
- isPlaying = false;
- title.set( " " );
- }
}
}
diff --git a/src/client/ui/QuestFrame.cc b/src/client/ui/QuestFrame.cc
index 94e181bf..410ce42a 100644
--- a/src/client/ui/QuestFrame.cc
+++ b/src/client/ui/QuestFrame.cc
@@ -133,8 +133,8 @@ void QuestFrame::onDraw()
QuestFrame::QuestFrame() :
Frame( 500, 2, OZ_GETTEXT( "No quest" ) ),
- description( 6, 4, 488, 10, Font::SANS, Area::ALIGN_NONE ),
- contentHeight( 8 + 10 * style.fonts[Font::SANS].height ),
+ description( 6, 4, 488, 16, Font::SANS, Area::ALIGN_NONE ),
+ contentHeight( 8 + 16 * style.fonts[Font::SANS].height ),
isOpened( false ), lastQuest( -1 ), lastState( Quest::NONE )
{
flags |= UPDATE_BIT;
diff --git a/src/client/ui/Style.cc b/src/client/ui/Style.cc
index ea7566c4..5182a892 100644
--- a/src/client/ui/Style.cc
+++ b/src/client/ui/Style.cc
@@ -27,13 +27,24 @@
#define OZ_READ_COLOUR( var, r, g, b, a ) \
colours.var = coloursConfig[#var].get( Vec4( r, g, b, a ) )
-#define OZ_READ_BAR( var, x_, y_, w_, h_ ) \
+#define OZ_READ_AREA( area, x_, y_, w_, h_ ) \
( \
- layout.var.x = x_, \
- layout.var.y = y_, \
- layout.var.w = w_, \
- layout.var.h = h_, \
- layoutConfig[#var].get( &layout.var.x, 4 ) \
+ area.x = x_, \
+ area.y = y_, \
+ area.w = w_, \
+ area.h = h_, \
+ config[#area].get( &area.x, 4 ) \
+ )
+
+#define OZ_READ_BAR( bar, x_, y_, w_, h_, minColour_, maxColour_ ) \
+ ( \
+ bar.x = x_, \
+ bar.y = y_, \
+ bar.w = w_, \
+ bar.h = h_, \
+ bar.minColour = minColour_, \
+ bar.maxColour = maxColour_, \
+ config[#bar].get( &bar.x, 16 ) \
)
namespace oz
@@ -94,24 +105,37 @@ void Style::init()
OZ_READ_COLOUR( background, 0.05f, 0.05f, 0.05f, 1.00f );
OZ_READ_COLOUR( barBorder, 1.00f, 1.00f, 1.00f, 0.50f );
+ OZ_READ_COLOUR( barBackground, 0.00f, 0.00f, 0.00f, 0.10f );
OZ_READ_COLOUR( galileoNormal, 1.00f, 1.00f, 1.00f, 0.60f );
OZ_READ_COLOUR( galileoMaximised, 1.00f, 1.00f, 1.00f, 0.80f );
OZ_READ_COLOUR( menuStrip, 0.00f, 0.00f, 0.00f, 1.00f );
- const JSON& layoutConfig = config["layout"];
+ int weaponBarHeight = fonts[Font::LARGE].height + 8;
+
+ OZ_READ_BAR( botStamina, 8, 8, 200, 14,
+ Vec4( 0.70f, 0.30f, 0.40f, 0.50f ),
+ Vec4( 0.00f, 0.30f, 1.00f, 0.50f ) );
+
+ OZ_READ_BAR( botHealth, 8, 30, 200, 14,
+ Vec4( 1.00f, 0.00f, 0.00f, 0.50f ),
+ Vec4( 0.00f, 1.00f, 0.00f, 0.50f ) );
+
+ OZ_READ_AREA( botWeapon, 8, 52, 200, weaponBarHeight );
+
+ OZ_READ_BAR( vehicleFuel, -8, 8, 200, 14,
+ Vec4( 0.70f, 0.30f, 0.40f, 0.50f ),
+ Vec4( 0.00f, 0.30f, 1.00f, 0.50f ) );
- OZ_READ_BAR( botStamina, 8, 8, 200, 14 );
- OZ_READ_BAR( botHealth, 8, 30, 200, 14 );
- OZ_READ_BAR( botWeapon, 8, 52, 200, fonts[Font::LARGE].height + 8 );
+ OZ_READ_BAR( vehicleHull, -8, 30, 200, 14,
+ Vec4( 1.00f, 0.00f, 0.00f, 0.50f ),
+ Vec4( 0.00f, 1.00f, 0.00f, 0.50f ) );
- OZ_READ_BAR( vehicleFuel, -8, 8, 200, 14 );
- OZ_READ_BAR( vehicleHull, -8, 30, 200, 14 );
- OZ_READ_BAR( vehicleWeapon[0], -8, 52, 200, fonts[Font::LARGE].height + 8 );
- OZ_READ_BAR( vehicleWeapon[1], -8, 52, 200, fonts[Font::LARGE].height + 8 );
- OZ_READ_BAR( vehicleWeapon[2], -8, 52, 200, fonts[Font::LARGE].height + 8 );
- OZ_READ_BAR( vehicleWeapon[3], -8, 52, 200, fonts[Font::LARGE].height + 8 );
+ OZ_READ_AREA( vehicleWeapon[0], -8, 52 + 0 * ( weaponBarHeight + 2 ), 200, weaponBarHeight );
+ OZ_READ_AREA( vehicleWeapon[1], -8, 52 + 1 * ( weaponBarHeight + 2 ), 200, weaponBarHeight );
+ OZ_READ_AREA( vehicleWeapon[2], -8, 52 + 2 * ( weaponBarHeight + 2 ), 200, weaponBarHeight );
+ OZ_READ_AREA( vehicleWeapon[3], -8, 52 + 3 * ( weaponBarHeight + 2 ), 200, weaponBarHeight );
config.clear( true );
diff --git a/src/client/ui/Style.hh b/src/client/ui/Style.hh
index d7605528..d64f2673 100644
--- a/src/client/ui/Style.hh
+++ b/src/client/ui/Style.hh
@@ -52,14 +52,7 @@ class Style
Vec4 background;
Vec4 barBorder;
- Vec4 healthMin;
- Vec4 healthMax;
- Vec4 staminaMin;
- Vec4 staminaMax;
- Vec4 hullMin;
- Vec4 hullMax;
- Vec4 fuelMin;
- Vec4 fuelMax;
+ Vec4 barBackground;
Vec4 galileoNormal;
Vec4 galileoMaximised;
@@ -67,7 +60,7 @@ class Style
Vec4 menuStrip;
};
- struct Bar
+ struct Area
{
int x;
int y;
@@ -75,22 +68,24 @@ class Style
int h;
};
- struct Layout
+ struct Bar : Area
{
- int iconSize;
-
- Bar botHealth;
- Bar botStamina;
- Bar botWeapon;
-
- Bar vehicleHull;
- Bar vehicleFuel;
- Bar vehicleWeapon[4];
+ Vec4 minColour;
+ Vec4 maxColour;
};
+ public:
+
Font fonts[Font::MAX];
Colours colours;
- Layout layout;
+ int iconSize;
+
+ Bar botHealth;
+ Bar botStamina;
+ Bar botWeapon;
+ Bar vehicleHull;
+ Bar vehicleFuel;
+ Bar vehicleWeapon[4];
public:
diff --git a/src/matrix/common.hh b/src/matrix/common.hh
index f14888eb..3eeff238 100644
--- a/src/matrix/common.hh
+++ b/src/matrix/common.hh
@@ -29,6 +29,9 @@
namespace oz
{
+/**
+ * Matrix layer.
+ */
namespace matrix
{
diff --git a/src/ozCore/Alloc.cc b/src/ozCore/Alloc.cc
index 2a55a3d4..55506bf1 100644
--- a/src/ozCore/Alloc.cc
+++ b/src/ozCore/Alloc.cc
@@ -32,6 +32,13 @@
#include
#include
+#ifdef __has_feature
+# if __has_feature( address_sanitizer )
+// AddressSanitizer already overrides new/delete, implementations in this file must be disabled.
+# define OZ_ADDRESS_SANITIZER
+# endif
+#endif
+
namespace oz
{
diff --git a/src/ozCore/Alloc.hh b/src/ozCore/Alloc.hh
index cdfa1e43..55169647 100644
--- a/src/ozCore/Alloc.hh
+++ b/src/ozCore/Alloc.hh
@@ -23,7 +23,7 @@
/**
* @file ozCore/Alloc.hh
*
- * Alloc class and `new`/`delete` operator overloads.
+ * Alloc class and `new`/`delete` operator overrides.
*
* Apart form Alloc class, enhanced `new`/`delete` operators are defined in this module, overriding
* ones provided by standard C++ library, including `std::nothrow` versions. Those operators count
@@ -38,7 +38,7 @@
* @li If compiled with `OZ_SIMD_MATH` allocated chunks are aligned to size of 4 floats.
*
* @note
- * Enabling AddressSanitizer during compilation of liboz disables `new`/`delete` overloads.
+ * Enabling AddressSanitizer during compilation of liboz custom `new`/`delete` implementations.
*/
#pragma once
@@ -49,7 +49,7 @@ namespace oz
{
/**
- * Auxiliary class for overloaded `new`/`delete` operators.
+ * Auxiliary class for custom `new`/`delete` operators.
*
* @sa ozCore/Alloc.hh
*/
@@ -64,7 +64,7 @@ class Alloc
static const size_t ALIGNMENT = sizeof( void* );
#endif
- /// True iff `new` and `delete` operator overloads are enabled (AddressSanitizer disables them).
+ /// True iff `new` and `delete` operators are overridden (AddressSanitizer disables them).
static const bool OVERLOADS_NEW_AND_DELETE;
static int count; ///< Current number of allocated memory chunks.
diff --git a/src/ozCore/System.cc b/src/ozCore/System.cc
index c1ccf248..683fe5c8 100644
--- a/src/ozCore/System.cc
+++ b/src/ozCore/System.cc
@@ -53,6 +53,7 @@
# define _exit( code ) _Exit( code )
# define isatty( fd ) _isatty( fd )
#else
+# include
# include
# include
# include
@@ -256,19 +257,16 @@ static void stopBellCallback( void* info_, int )
info->audio->StopPlayback();
info->audio->~Audio();
free( info->audio );
+ free( info );
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
}
-static void bellPlayCallback( void* buffer, uint size, void* info_ )
+static void bellPlayCallback( void* buffer, uint, void* info_ )
{
- static_cast( size );
-
SampleInfo* info = static_cast( info_ );
short* samples = static_cast( buffer );
- hard_assert( size / uint( sizeof( short[2] ) ) >= uint( info->nFrameSamples ) );
-
if( info->offset >= info->end ) {
System::core->CallOnMainThread( 0, pp::CompletionCallback( stopBellCallback, info ) );
}
@@ -278,9 +276,12 @@ static void bellPlayCallback( void* buffer, uint size, void* info_ )
info->offset += info->nFrameSamples;
}
-static void bellInitCallback( void* info_, int )
+static void bellInitCallback( void*, int )
{
- SampleInfo* info = static_cast( info_ );
+ SampleInfo* info = static_cast( malloc( sizeof( SampleInfo ) ) );
+ if( info == nullptr ) {
+ return;
+ }
PP_AudioSampleRate rate = pp::AudioConfig::RecommendSampleRate( System::instance );
uint nFrameSamples = pp::AudioConfig::RecommendSampleFrameCount( System::instance, rate, 4096 );
@@ -295,26 +296,24 @@ static void bellInitCallback( void* info_, int )
void* audioPtr = malloc( sizeof( pp::Audio ) );
if( audioPtr == nullptr ) {
- OZ_ERROR( "pp::Audio object allocation failed" );
+ free( info );
+ return;
}
info->audio = new( audioPtr ) pp::Audio( System::instance, config, bellPlayCallback, info );
if( info->audio->StartPlayback() == PP_FALSE ) {
info->audio->~Audio();
free( info->audio );
+ free( info );
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
+ return;
}
}
static void* bellMain( void* )
{
- SampleInfo info;
- System::core->CallOnMainThread( 0, pp::CompletionCallback( bellInitCallback, &info ) );
-
- while( isBellPlaying ) {
- nanosleep( &TIMESPEC_10MS, nullptr );
- }
+ System::core->CallOnMainThread( 0, pp::CompletionCallback( bellInitCallback, nullptr ) );
return nullptr;
}
@@ -357,7 +356,7 @@ static DWORD WINAPI bellMain( void* )
PlaySound( reinterpret_cast( wave ), nullptr, SND_MEMORY | SND_SYNC );
free( wave );
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
return 0;
}
@@ -367,8 +366,8 @@ static void* bellMain( void* )
{
const pa_sample_spec PA_SAMPLE_SPEC = { PA_SAMPLE_S16NE, BELL_PREFERRED_RATE, 2 };
- pa_simple* pa = pa_simple_new( nullptr, "oz", PA_STREAM_PLAYBACK, nullptr, "bell",
- &PA_SAMPLE_SPEC, nullptr, nullptr, nullptr );
+ pa_simple* pa = pa_simple_new( nullptr, program_invocation_short_name, PA_STREAM_PLAYBACK,
+ nullptr, "bell", &PA_SAMPLE_SPEC, nullptr, nullptr, nullptr );
if( pa != nullptr ) {
int nSamples = int( BELL_TIME * float( BELL_PREFERRED_RATE ) );
size_t size = size_t( nSamples * 2 ) * sizeof( short );
@@ -381,7 +380,7 @@ static void* bellMain( void* )
pa_simple_drain( pa, nullptr );
pa_simple_free( pa );
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
return nullptr;
}
@@ -389,7 +388,7 @@ static void* bellMain( void* )
snd_pcm_t* alsa;
if( snd_pcm_open( &alsa, "default", SND_PCM_STREAM_PLAYBACK, 0 ) != 0 ) {
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
return nullptr;
}
@@ -409,7 +408,7 @@ static void* bellMain( void* )
{
snd_pcm_close( alsa );
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
return nullptr;
}
@@ -431,7 +430,7 @@ static void* bellMain( void* )
( fd = open( "/dev/dsp0", O_WRONLY, 0 ) ) < 0 &&
( fd = open( "/dev/dsp1", O_WRONLY, 0 ) ) < 0 )
{
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
return nullptr;
}
@@ -449,7 +448,7 @@ static void* bellMain( void* )
{
close( fd );
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
return nullptr;
}
@@ -465,7 +464,7 @@ static void* bellMain( void* )
#endif
- isBellPlaying = false;
+ __sync_lock_release( &isBellPlaying );
return nullptr;
}
@@ -564,8 +563,6 @@ void System::bell()
#endif
if( !__sync_lock_test_and_set( &isBellPlaying, true ) ) {
- __sync_synchronize();
-
#ifdef _WIN32
HANDLE bellThread = CreateThread( nullptr, 0, bellMain, nullptr, 0, nullptr );
diff --git a/src/ozCore/config.hh.in b/src/ozCore/config.hh.in
index a1591b76..d03358fd 100644
--- a/src/ozCore/config.hh.in
+++ b/src/ozCore/config.hh.in
@@ -78,16 +78,9 @@ namespace std { typedef __PTRDIFF_TYPE__ nullptr_t; }
# define __extern_always_inline extern __always_inline __attribute__(( __gnu_inline__ ))
#endif
-// Check for AddressSanitizer (currently only supported by LLVM/Clang 3.1+).
-#ifdef __has_feature
-# if __has_feature( address_sanitizer )
-# define OZ_ADDRESS_SANITIZER
-# endif
-#endif
-
#ifdef _WIN32
-// At least Visual Studio 2005 run-time libraries required.
-# define __MSVCRT_VERSION__ 0x0800
+// At least Visual Studio 2008 run-time libraries required.
+# define __MSVCRT_VERSION__ 0x0900
// At least Windows XP/2003 required.
# define WINVER 0x0501
// At least Internet Explorer 6.0 libraries required.
diff --git a/src/ozDynamics/physics/Physics.cc b/src/ozDynamics/physics/Physics.cc
index fb3b2b5a..3f25707c 100644
--- a/src/ozDynamics/physics/Physics.cc
+++ b/src/ozDynamics/physics/Physics.cc
@@ -96,7 +96,7 @@ void Physics::update( float time )
if( collider->overlaps( body0, body1, &result ) ) {
Point p = Math::mix( body0->pos, body1->pos, 0.5f );
- Log() << result.depth << ", " << result.axis << "\n";
+// Log() << result.depth << ", " << result.axis << "\n";
dContact contact;
contact.surface.mode = dContactBounce;
diff --git a/src/tests/test.cc b/src/tests/test.cc
index bb0a7ce1..a2df179c 100644
--- a/src/tests/test.cc
+++ b/src/tests/test.cc
@@ -109,15 +109,8 @@ class Foo
};
-template
-static Foo foo( T&&... args )
-{
- return Foo( static_cast( args )... );
-}
-
int main()
{
System::init();
- System::bell();
return 0;
}