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 @@

Ukazna vrstica

-v - Zgovornejši dnevnik. + Izpisuj podrobna dnevniška sporočila na terminal. @@ -386,8 +386,8 @@

Ukazna vrstica

-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 @@

Command Line

-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 @@

Command Line

-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; }