Merge pull request #66 from OoliteProject/zipped-oxp-support

Zipped oxp support / OpenAL
This commit is contained in:
cim 2013-11-17 03:13:51 -08:00
commit 60ef4c54ad
63 changed files with 6351 additions and 201 deletions

View File

@ -85,3 +85,28 @@ parts subject to the following license:
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The MiniZip code used is subject to the following license
License
----------------------------------------------------------
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
----------------------------------------------------------

View File

@ -57,6 +57,7 @@ libpng: Glenn Randers-Pehrson, Andreas Dilger, Guy Eric Schalnat
SDL - Simple DirectMedia Layer: Sam Lantinga and contributors.
SpiderMonkey: Brendan Eich et al, Mozilla Foundation.
LibOgg/LibVorbis: Xiph.Org Foundation.
MiniZip: Gilles Vollant, Mathias Svensson and others
Mac OS X-specific libraries:

View File

@ -2,8 +2,8 @@ include $(GNUSTEP_MAKEFILES)/common.make
include config.make
vpath %.m src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug
vpath %.h src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug
vpath %.c src/SDL:src/Core:src/BSDCompat:src/Core/Debug
vpath %.h src/SDL:src/Core:src/Core/Entities:src/Core/Materials:src/Core/Scripting:src/Core/OXPVerifier:src/Core/Debug:src/Core/MiniZip
vpath %.c src/SDL:src/Core:src/BSDCompat:src/Core/Debug:src/Core/MiniZip
GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_USER_ROOT)
ifeq ($(GNUSTEP_HOST_OS),mingw32)
GNUSTEP_OBJ_DIR_NAME := $(GNUSTEP_OBJ_DIR_NAME).win
@ -23,8 +23,8 @@ ifeq ($(GNUSTEP_HOST_OS),mingw32)
else
JS_IMPORT_LIBRARY = js32ECMAv5
endif
ADDITIONAL_INCLUDE_DIRS = -I$(WIN_DEPS_DIR)/include -I$(JS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables
ADDITIONAL_OBJC_LIBS = -lglu32 -lopengl32 -lpng14.dll -lmingw32 -lSDLmain -lSDL -lSDL_mixer -lgnustep-base -l$(JS_IMPORT_LIBRARY) -lwinmm -mwindows
ADDITIONAL_INCLUDE_DIRS = -I$(WIN_DEPS_DIR)/include -I$(JS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip
ADDITIONAL_OBJC_LIBS = -lglu32 -lopengl32 -lopenal32.dll -lpng14.dll -lmingw32 -lSDLmain -lSDL -lvorbisfile -lvorbis -lz -lgnustep-base -l$(JS_IMPORT_LIBRARY) -lwinmm -mwindows
ADDITIONAL_CFLAGS = -DWIN32 -DNEED_STRLCPY `sdl-config --cflags` -mtune=generic
# note the vpath stuff above isn't working for me, so adding src/SDL and src/Core explicitly
ADDITIONAL_OBJCFLAGS = -DLOADSAVEGUI -DWIN32 -DXP_WIN -Wno-import -std=gnu99 `sdl-config --cflags` -mtune=generic
@ -49,8 +49,8 @@ else
LIBJS_LIB_DIR = $(LIBJS_ROOT)/dist/lib
LIBJS = js_static
ADDITIONAL_INCLUDE_DIRS = -I$(LIBJS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables
ADDITIONAL_OBJC_LIBS = -lGLU -lGL -lX11 -lSDL -lSDL_mixer -lgnustep-base -l$(LIBJS) `nspr-config --libs` -lstdc++
ADDITIONAL_INCLUDE_DIRS = -I$(LIBJS_INC_DIR) -Isrc/SDL -Isrc/Core -Isrc/BSDCompat -Isrc/Core/Scripting -Isrc/Core/Materials -Isrc/Core/Entities -Isrc/Core/OXPVerifier -Isrc/Core/Debug -Isrc/Core/Tables -Isrc/Core/MiniZip
ADDITIONAL_OBJC_LIBS = -lGLU -lGL -lX11 -lSDL -lSDL_mixer -lgnustep-base -l$(LIBJS) `nspr-config --libs` -lstdc++ -lopenal
ADDITIONAL_CFLAGS = -Wall -DLINUX -DNEED_STRLCPY `sdl-config --cflags` `nspr-config --cflags`
ADDITIONAL_OBJCFLAGS = -Wall -std=c99 -DLOADSAVEGUI -DLINUX -DXP_UNIX -Wno-import `sdl-config --cflags` `nspr-config --cflags`
oolite_LIB_DIRS += -L$(LIBJS_LIB_DIR) -L/usr/X11R6/lib/
@ -147,7 +147,9 @@ oolite_C_FILES = \
legacy_random.c \
strlcpy.c \
OOTCPStreamDecoder.c \
OOPlanetData.c
OOPlanetData.c \
ioapi.c \
unzip.c
OOLITE_DEBUG_FILES = \
@ -320,16 +322,30 @@ OOLITE_SCRIPTING_FILES = \
OOJSFrameCallbacks.m \
OOJSFont.m
#OOLITE_SOUND_FILES = \
# OOBasicSoundReferencePoint.m \
#
# OOSDLConcreteSound.m \
# OOSDLSound.m \
# OOSDLSoundChannel.m \
# OOSDLSoundMixer.m \
# OOSoundSource.m \
# OOSoundSourcePool.m \
# SDLMusic.m
OOLITE_SOUND_FILES = \
OOBasicSoundReferencePoint.m \
OOMusicController.m \
OOSDLConcreteSound.m \
OOSDLSound.m \
OOSDLSoundChannel.m \
OOSDLSoundMixer.m \
OOSoundSource.m \
OOOpenALController.m \
OOMusicController.m \
OOSoundSource.m \
OOSoundSourcePool.m \
SDLMusic.m
OOALMusic.m \
OOALSound.m \
OOALSoundChannel.m \
OOALSoundMixer.m \
OOALSoundDecoder.m \
OOALBufferedSound.m \
OOALStreamedSound.m
OOLITE_UI_FILES = \
GuiDisplayGen.m \
@ -338,6 +354,7 @@ OOLITE_UI_FILES = \
OO_UTILITY_FILES = \
Comparison.m \
NSDataOOExtensions.m \
NSDictionaryOOExtensions.m \
NSFileManagerOOExtensions.m \
NSMutableDictionaryOOExtensions.m \

View File

@ -21,11 +21,14 @@ endif
SRC_BIN = $(OBJC_PROGRAM_NAME)$(OS_EXT)
DEST_BIN = $(OBJC_PROGRAM_NAME)$(EXT)$(OS_EXT)
MKMANIFEST=tools/mkmanifest.sh
PROGDIR=$(OBJC_PROGRAM_NAME).app
after-all::
$(MKDIRS) $(PROGDIR)
$(MKDIRS) $(PROGDIR)/Resources
$(MKMANIFEST) > $(PROGDIR)/Resources/manifest.plist
$(CP) $(CP_FLAGS) Resources/README.TXT $(PROGDIR)/Resources
$(CP) $(CP_FLAGS) Resources/InfoPlist.strings $(PROGDIR)/Resources
$(CP) $(CP_FLAGS) Resources/AIs $(PROGDIR)/Resources

View File

@ -52,7 +52,6 @@
1A047B7F0DCB3D7500EE1CD0 /* OOProbabilitySet.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A047B7D0DCB3D7500EE1CD0 /* OOProbabilitySet.m */; };
1A062C8911B28D8A00727C1D /* NSObjectOOExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A062C8711B28D8A00727C1D /* NSObjectOOExtensions.h */; };
1A062C8A11B28D8A00727C1D /* NSObjectOOExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A062C8811B28D8A00727C1D /* NSObjectOOExtensions.m */; };
1A06F2861196E5B100AFA5B4 /* OOCASoundDebugMonitor.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A06F2851196E5B100AFA5B4 /* OOCASoundDebugMonitor.h */; };
1A0729D90EF56D1200B0F925 /* OOConvertSystemDescriptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A0729D70EF56D1200B0F925 /* OOConvertSystemDescriptions.h */; };
1A0729DA0EF56D1200B0F925 /* OOConvertSystemDescriptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A0729D80EF56D1200B0F925 /* OOConvertSystemDescriptions.m */; };
1A0729FE0EF5796500B0F925 /* OldSchoolPropertyListWriting.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A0729FC0EF5796500B0F925 /* OldSchoolPropertyListWriting.h */; };
@ -230,6 +229,12 @@
1A54AB530E3E17A1001EB817 /* OOJSPlayerShip.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A54AB510E3E17A0001EB817 /* OOJSPlayerShip.h */; };
1A54AB540E3E17A1001EB817 /* OOJSPlayerShip.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A54AB520E3E17A0001EB817 /* OOJSPlayerShip.m */; };
1A5AA3230C0098AF0029C78A /* OOOpenGL.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A5AA3220C0098AF0029C78A /* OOOpenGL.m */; };
1A5D58871825241800C779AE /* ioapi.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D58821825241800C779AE /* ioapi.c */; };
1A5D58881825241800C779AE /* ioapi.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5D58831825241800C779AE /* ioapi.h */; };
1A5D588A1825241800C779AE /* unzip.c in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D58851825241800C779AE /* unzip.c */; };
1A5D588B1825241800C779AE /* unzip.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5D58861825241800C779AE /* unzip.h */; };
1A5D5893182525DE00C779AE /* NSDataOOExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5D5891182525DE00C779AE /* NSDataOOExtensions.h */; };
1A5D5894182525DE00C779AE /* NSDataOOExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A5D5892182525DE00C779AE /* NSDataOOExtensions.m */; };
1A5DB1EA0BBD8F0000D57389 /* OOConstToString.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5DB1E80BBD8F0000D57389 /* OOConstToString.h */; };
1A5DB1EB0BBD8F0000D57389 /* OOConstToString.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A5DB1E90BBD8F0000D57389 /* OOConstToString.m */; };
1A5DBAA60BC000DC00D57389 /* OOJavaScriptEngine.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A5DBA9A0BC000DC00D57389 /* OOJavaScriptEngine.h */; };
@ -313,8 +318,6 @@
1A817DA1106D3FF000AA2F97 /* OOPlasmaBurstEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A817D9F106D3FF000AA2F97 /* OOPlasmaBurstEntity.m */; };
1A817DC3106D443B00AA2F97 /* OOFlashEffectEntity.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A817DC1106D443B00AA2F97 /* OOFlashEffectEntity.h */; };
1A817DC4106D443B00AA2F97 /* OOFlashEffectEntity.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A817DC2106D443B00AA2F97 /* OOFlashEffectEntity.m */; };
1A81F7090A7BAC4D006580AD /* OOCAMusic.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A81F7070A7BAC4D006580AD /* OOCAMusic.m */; };
1A81F70A0A7BAC4D006580AD /* OOCAMusic.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A81F7080A7BAC4D006580AD /* OOCAMusic.h */; };
1A87063E1172029F003FDD2A /* OODebugFlags.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A87063D1172029F003FDD2A /* OODebugFlags.h */; };
1A8A37560B960337007D20B8 /* NSMutableDictionaryOOExtensions.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A8A37540B960337007D20B8 /* NSMutableDictionaryOOExtensions.m */; };
1A8A37570B960337007D20B8 /* NSMutableDictionaryOOExtensions.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A8A37550B960337007D20B8 /* NSMutableDictionaryOOExtensions.h */; };
@ -355,6 +358,24 @@
1A9FCF2315DAC8E100E965D5 /* OOMacSnowLeopardFullScreenController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9FCF2115DAC8E100E965D5 /* OOMacSnowLeopardFullScreenController.h */; };
1A9FCF2415DAC8E100E965D5 /* OOMacSnowLeopardFullScreenController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9FCF2215DAC8E100E965D5 /* OOMacSnowLeopardFullScreenController.m */; };
1A9FCF2615DAC9BC00E965D5 /* GameController+FullScreen.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9FCF2515DAC9BC00E965D5 /* GameController+FullScreen.m */; };
1AA085FE182578AF007CCAEB /* OOALBufferedSound.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA085EE182578AF007CCAEB /* OOALBufferedSound.h */; };
1AA085FF182578AF007CCAEB /* OOALBufferedSound.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA085EF182578AF007CCAEB /* OOALBufferedSound.m */; };
1AA08602182578AF007CCAEB /* OOALMusic.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA085F2182578AF007CCAEB /* OOALMusic.h */; };
1AA08603182578AF007CCAEB /* OOALMusic.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA085F3182578AF007CCAEB /* OOALMusic.m */; };
1AA08604182578AF007CCAEB /* OOALSound.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA085F4182578AF007CCAEB /* OOALSound.h */; };
1AA08605182578AF007CCAEB /* OOALSound.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA085F5182578AF007CCAEB /* OOALSound.m */; };
1AA08606182578AF007CCAEB /* OOALSoundChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA085F6182578AF007CCAEB /* OOALSoundChannel.h */; };
1AA08607182578AF007CCAEB /* OOALSoundChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA085F7182578AF007CCAEB /* OOALSoundChannel.m */; };
1AA08608182578AF007CCAEB /* OOALSoundDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA085F8182578AF007CCAEB /* OOALSoundDecoder.h */; };
1AA08609182578AF007CCAEB /* OOALSoundDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA085F9182578AF007CCAEB /* OOALSoundDecoder.m */; settings = {COMPILER_FLAGS = "-Wno-unused-variable"; }; };
1AA0860A182578AF007CCAEB /* OOALSoundMixer.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA085FA182578AF007CCAEB /* OOALSoundMixer.h */; };
1AA0860B182578AF007CCAEB /* OOALSoundMixer.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA085FB182578AF007CCAEB /* OOALSoundMixer.m */; };
1AA0860C182578AF007CCAEB /* OOALStreamedSound.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA085FC182578AF007CCAEB /* OOALStreamedSound.h */; };
1AA0860D182578AF007CCAEB /* OOALStreamedSound.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA085FD182578AF007CCAEB /* OOALStreamedSound.m */; };
1AA08611182578B8007CCAEB /* OOOpenAL.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA0860E182578B8007CCAEB /* OOOpenAL.h */; };
1AA08612182578B8007CCAEB /* OOOpenALController.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA0860F182578B8007CCAEB /* OOOpenALController.h */; };
1AA08613182578B8007CCAEB /* OOOpenALController.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA08610182578B8007CCAEB /* OOOpenALController.m */; };
1AA0861618257A11007CCAEB /* OpenAL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1AA0861518257A11007CCAEB /* OpenAL.framework */; };
1AA59C6C1780396C007C7373 /* OOJSWormhole.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA59C6A1780396C007C7373 /* OOJSWormhole.h */; };
1AA59C6D1780396C007C7373 /* OOJSWormhole.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AA59C6B1780396C007C7373 /* OOJSWormhole.m */; };
1AA7FCAB10C2B9BA0058FBED /* OOPlanetDrawable.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AA7FCA910C2B9BA0058FBED /* OOPlanetDrawable.h */; };
@ -470,25 +491,6 @@
2512834609BA281500F43D55 /* CollisionRegion.h in Headers */ = {isa = PBXBuildFile; fileRef = 2512834409BA281500F43D55 /* CollisionRegion.h */; };
2512834709BA281500F43D55 /* CollisionRegion.m in Sources */ = {isa = PBXBuildFile; fileRef = 2512834509BA281500F43D55 /* CollisionRegion.m */; settings = {COMPILER_FLAGS = $OO_MATHS_OPTS; }; };
25160E2F0995362F0037C2E1 /* OOCocoa.h in Headers */ = {isa = PBXBuildFile; fileRef = 25160E2E0995362F0037C2E1 /* OOCocoa.h */; };
251610DD099544090037C2E1 /* OOCABufferedSound.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610CA099544090037C2E1 /* OOCABufferedSound.h */; };
251610DE099544090037C2E1 /* OOCASoundMixer.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610CB099544090037C2E1 /* OOCASoundMixer.h */; };
251610E0099544090037C2E1 /* OOCASoundChannel.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610CD099544090037C2E1 /* OOCASoundChannel.h */; };
251610E2099544090037C2E1 /* OOCASoundReferencePoint.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610CF099544090037C2E1 /* OOCASoundReferencePoint.m */; };
251610E3099544090037C2E1 /* OOCASound.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610D0099544090037C2E1 /* OOCASound.h */; };
251610E4099544090037C2E1 /* OOCASoundMixer.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610D1099544090037C2E1 /* OOCASoundMixer.m */; };
251610E5099544090037C2E1 /* OOCABufferedSound.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610D2099544090037C2E1 /* OOCABufferedSound.m */; };
251610E6099544090037C2E1 /* OOCAStreamingSound.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610D3099544090037C2E1 /* OOCAStreamingSound.m */; };
251610E7099544090037C2E1 /* OOCASoundDecoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610D4099544090037C2E1 /* OOCASoundDecoder.h */; };
251610E8099544090037C2E1 /* OOCASound.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610D5099544090037C2E1 /* OOCASound.m */; };
251610E9099544090037C2E1 /* OOCASoundChannel.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610D6099544090037C2E1 /* OOCASoundChannel.m */; };
251610EA099544090037C2E1 /* OOCAStreamingSound.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610D7099544090037C2E1 /* OOCAStreamingSound.h */; };
251610EB099544090037C2E1 /* OOErrorDescription.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610D8099544090037C2E1 /* OOErrorDescription.h */; };
251610EC099544090037C2E1 /* OOCASoundReferencePoint.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610D9099544090037C2E1 /* OOCASoundReferencePoint.h */; };
251610ED099544090037C2E1 /* OOCASoundInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610DA099544090037C2E1 /* OOCASoundInternal.h */; };
251610EE099544090037C2E1 /* OOCASoundDecoder.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610DB099544090037C2E1 /* OOCASoundDecoder.m */; };
251610EF099544090037C2E1 /* OOErrorDescription.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610DC099544090037C2E1 /* OOErrorDescription.m */; };
251610F2099544190037C2E1 /* VirtualRingBuffer.m in Sources */ = {isa = PBXBuildFile; fileRef = 251610F0099544190037C2E1 /* VirtualRingBuffer.m */; };
251610F3099544190037C2E1 /* VirtualRingBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 251610F1099544190037C2E1 /* VirtualRingBuffer.h */; };
25161153099544390037C2E1 /* AI.m in Sources */ = {isa = PBXBuildFile; fileRef = 25161101099544380037C2E1 /* AI.m */; };
25161158099544390037C2E1 /* AI.h in Headers */ = {isa = PBXBuildFile; fileRef = 25161106099544390037C2E1 /* AI.h */; };
2516115A099544390037C2E1 /* OOTrumble.m in Sources */ = {isa = PBXBuildFile; fileRef = 25161108099544390037C2E1 /* OOTrumble.m */; };
@ -1145,6 +1147,13 @@
1A59FF4117CA26D6000BF0E0 /* oolite-populator.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "oolite-populator.js"; sourceTree = "<group>"; };
1A5AA3220C0098AF0029C78A /* OOOpenGL.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = OOOpenGL.m; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
1A5ABE6A15FBC833006C97DC /* oolite-default-effect-script.js */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.javascript; path = "oolite-default-effect-script.js"; sourceTree = "<group>"; };
1A5D58821825241800C779AE /* ioapi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ioapi.c; sourceTree = "<group>"; usesTabs = 0; };
1A5D58831825241800C779AE /* ioapi.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ioapi.h; sourceTree = "<group>"; };
1A5D58841825241800C779AE /* MiniZip64_info.txt */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = MiniZip64_info.txt; sourceTree = "<group>"; };
1A5D58851825241800C779AE /* unzip.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = unzip.c; sourceTree = "<group>"; };
1A5D58861825241800C779AE /* unzip.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = unzip.h; sourceTree = "<group>"; };
1A5D5891182525DE00C779AE /* NSDataOOExtensions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSDataOOExtensions.h; sourceTree = "<group>"; };
1A5D5892182525DE00C779AE /* NSDataOOExtensions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSDataOOExtensions.m; sourceTree = "<group>"; };
1A5DB1E80BBD8F0000D57389 /* OOConstToString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOConstToString.h; sourceTree = "<group>"; };
1A5DB1E90BBD8F0000D57389 /* OOConstToString.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOConstToString.m; sourceTree = "<group>"; };
1A5DBA9A0BC000DC00D57389 /* OOJavaScriptEngine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOJavaScriptEngine.h; sourceTree = "<group>"; };
@ -1427,6 +1436,24 @@
1A9FCF2115DAC8E100E965D5 /* OOMacSnowLeopardFullScreenController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOMacSnowLeopardFullScreenController.h; sourceTree = "<group>"; };
1A9FCF2215DAC8E100E965D5 /* OOMacSnowLeopardFullScreenController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOMacSnowLeopardFullScreenController.m; sourceTree = "<group>"; };
1A9FCF2515DAC9BC00E965D5 /* GameController+FullScreen.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "GameController+FullScreen.m"; sourceTree = "<group>"; };
1AA085EE182578AF007CCAEB /* OOALBufferedSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOALBufferedSound.h; sourceTree = "<group>"; };
1AA085EF182578AF007CCAEB /* OOALBufferedSound.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOALBufferedSound.m; sourceTree = "<group>"; };
1AA085F2182578AF007CCAEB /* OOALMusic.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOALMusic.h; sourceTree = "<group>"; };
1AA085F3182578AF007CCAEB /* OOALMusic.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOALMusic.m; sourceTree = "<group>"; };
1AA085F4182578AF007CCAEB /* OOALSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOALSound.h; sourceTree = "<group>"; };
1AA085F5182578AF007CCAEB /* OOALSound.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOALSound.m; sourceTree = "<group>"; };
1AA085F6182578AF007CCAEB /* OOALSoundChannel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOALSoundChannel.h; sourceTree = "<group>"; };
1AA085F7182578AF007CCAEB /* OOALSoundChannel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOALSoundChannel.m; sourceTree = "<group>"; };
1AA085F8182578AF007CCAEB /* OOALSoundDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOALSoundDecoder.h; sourceTree = "<group>"; };
1AA085F9182578AF007CCAEB /* OOALSoundDecoder.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOALSoundDecoder.m; sourceTree = "<group>"; };
1AA085FA182578AF007CCAEB /* OOALSoundMixer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOALSoundMixer.h; sourceTree = "<group>"; };
1AA085FB182578AF007CCAEB /* OOALSoundMixer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOALSoundMixer.m; sourceTree = "<group>"; };
1AA085FC182578AF007CCAEB /* OOALStreamedSound.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOALStreamedSound.h; sourceTree = "<group>"; };
1AA085FD182578AF007CCAEB /* OOALStreamedSound.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOALStreamedSound.m; sourceTree = "<group>"; };
1AA0860E182578B8007CCAEB /* OOOpenAL.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOOpenAL.h; sourceTree = "<group>"; };
1AA0860F182578B8007CCAEB /* OOOpenALController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOOpenALController.h; sourceTree = "<group>"; };
1AA08610182578B8007CCAEB /* OOOpenALController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOOpenALController.m; sourceTree = "<group>"; };
1AA0861518257A11007CCAEB /* OpenAL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenAL.framework; path = System/Library/Frameworks/OpenAL.framework; sourceTree = SDKROOT; };
1AA59C6A1780396C007C7373 /* OOJSWormhole.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOJSWormhole.h; sourceTree = "<group>"; };
1AA59C6B1780396C007C7373 /* OOJSWormhole.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOJSWormhole.m; sourceTree = "<group>"; };
1AA7FCA910C2B9BA0058FBED /* OOPlanetDrawable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOPlanetDrawable.h; sourceTree = "<group>"; };
@ -1644,6 +1671,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
1AA0861618257A11007CCAEB /* OpenAL.framework in Frameworks */,
0878FD30086EF845004CB752 /* Carbon.framework in Frameworks */,
0865431C06B8447D000CA0AB /* Cocoa.framework in Frameworks */,
0865431D06B8447D000CA0AB /* OpenGL.framework in Frameworks */,
@ -2170,6 +2198,19 @@
name = "External bundles";
sourceTree = "<group>";
};
1A5D58811825241800C779AE /* MiniZip */ = {
isa = PBXGroup;
children = (
1A5D58821825241800C779AE /* ioapi.c */,
1A5D58831825241800C779AE /* ioapi.h */,
1A5D58841825241800C779AE /* MiniZip64_info.txt */,
1A5D58851825241800C779AE /* unzip.c */,
1A5D58861825241800C779AE /* unzip.h */,
);
name = MiniZip;
path = src/Core/MiniZip;
sourceTree = "<group>";
};
1A5DBA980BC000DC00D57389 /* Scripting */ = {
isa = PBXGroup;
children = (
@ -2335,7 +2376,8 @@
1ACBF06F0D82DF9B00CC005F /* OOSoundSourcePool.h */,
1ACBF0700D82DF9B00CC005F /* OOSoundSourcePool.m */,
1A7B967E0E620C9E00322821 /* OOSoundInternal.h */,
1A8A3D8F0B9B058500AB7625 /* Mac-specific */,
1AA085E81825788E007CCAEB /* OpenAL */,
1A8A3D8F0B9B058500AB7625 /* CoreAudio */,
);
name = Audio;
sourceTree = "<group>";
@ -2737,6 +2779,8 @@
1AEB4919119D5AAA007BD514 /* OORegExpMatcher.m */,
1A062C8711B28D8A00727C1D /* NSObjectOOExtensions.h */,
1A062C8811B28D8A00727C1D /* NSObjectOOExtensions.m */,
1A5D5891182525DE00C779AE /* NSDataOOExtensions.h */,
1A5D5892182525DE00C779AE /* NSDataOOExtensions.m */,
1AF4AF4815B858AA009243BE /* OOWeakSet.h */,
1AF4AF4915B858AA009243BE /* OOWeakSet.m */,
);
@ -2872,7 +2916,7 @@
name = Mathematics;
sourceTree = "<group>";
};
1A8A3D8F0B9B058500AB7625 /* Mac-specific */ = {
1A8A3D8F0B9B058500AB7625 /* CoreAudio */ = {
isa = PBXGroup;
children = (
251610D0099544090037C2E1 /* OOCASound.h */,
@ -2898,10 +2942,34 @@
251610F0099544190037C2E1 /* VirtualRingBuffer.m */,
1A06F2851196E5B100AFA5B4 /* OOCASoundDebugMonitor.h */,
);
name = "Mac-specific";
name = CoreAudio;
path = ../Cocoa;
sourceTree = "<group>";
};
1AA085E81825788E007CCAEB /* OpenAL */ = {
isa = PBXGroup;
children = (
1AA0860E182578B8007CCAEB /* OOOpenAL.h */,
1AA0860F182578B8007CCAEB /* OOOpenALController.h */,
1AA08610182578B8007CCAEB /* OOOpenALController.m */,
1AA085EE182578AF007CCAEB /* OOALBufferedSound.h */,
1AA085EF182578AF007CCAEB /* OOALBufferedSound.m */,
1AA085F2182578AF007CCAEB /* OOALMusic.h */,
1AA085F3182578AF007CCAEB /* OOALMusic.m */,
1AA085F4182578AF007CCAEB /* OOALSound.h */,
1AA085F5182578AF007CCAEB /* OOALSound.m */,
1AA085F6182578AF007CCAEB /* OOALSoundChannel.h */,
1AA085F7182578AF007CCAEB /* OOALSoundChannel.m */,
1AA085F8182578AF007CCAEB /* OOALSoundDecoder.h */,
1AA085F9182578AF007CCAEB /* OOALSoundDecoder.m */,
1AA085FA182578AF007CCAEB /* OOALSoundMixer.h */,
1AA085FB182578AF007CCAEB /* OOALSoundMixer.m */,
1AA085FC182578AF007CCAEB /* OOALStreamedSound.h */,
1AA085FD182578AF007CCAEB /* OOALStreamedSound.m */,
);
name = OpenAL;
sourceTree = "<group>";
};
1AA2E7061191E39600DFBA23 /* Build stuff */ = {
isa = PBXGroup;
children = (
@ -3067,6 +3135,8 @@
29B97323FDCFA39411CA2CEA /* Frameworks */ = {
isa = PBXGroup;
children = (
1AA0861518257A11007CCAEB /* OpenAL.framework */,
1A5D58811825241800C779AE /* MiniZip */,
1AB775FC12CA2E53001478BB /* libjs.xcodeproj */,
1AE3454B12CB77A700FD8C62 /* Ogg.xcodeproj */,
1AE3455112CB77AC00FD8C62 /* Vorbis.xcodeproj */,
@ -3088,16 +3158,7 @@
25F3E6310994F033002F25FD /* legacy_random.h in Headers */,
25F3E63B0994F08A002F25FD /* OOOpenGL.h in Headers */,
25160E2F0995362F0037C2E1 /* OOCocoa.h in Headers */,
251610DD099544090037C2E1 /* OOCABufferedSound.h in Headers */,
251610DE099544090037C2E1 /* OOCASoundMixer.h in Headers */,
251610E0099544090037C2E1 /* OOCASoundChannel.h in Headers */,
251610E3099544090037C2E1 /* OOCASound.h in Headers */,
251610E7099544090037C2E1 /* OOCASoundDecoder.h in Headers */,
251610EA099544090037C2E1 /* OOCAStreamingSound.h in Headers */,
251610EB099544090037C2E1 /* OOErrorDescription.h in Headers */,
251610EC099544090037C2E1 /* OOCASoundReferencePoint.h in Headers */,
251610ED099544090037C2E1 /* OOCASoundInternal.h in Headers */,
251610F3099544190037C2E1 /* VirtualRingBuffer.h in Headers */,
1AA08611182578B8007CCAEB /* OOOpenAL.h in Headers */,
25161158099544390037C2E1 /* AI.h in Headers */,
2516115D099544390037C2E1 /* GameController.h in Headers */,
25161162099544390037C2E1 /* OOTrumble.h in Headers */,
@ -3111,9 +3172,9 @@
2576E7B309B4F418007410F7 /* MyOpenGLView.h in Headers */,
2512833F09BA27C100F43D55 /* Octree.h in Headers */,
2512834209BA27EC00F43D55 /* OOMeshToOctreeConverter.h in Headers */,
1AA08608182578AF007CCAEB /* OOALSoundDecoder.h in Headers */,
2512834609BA281500F43D55 /* CollisionRegion.h in Headers */,
083325DD09DDBCDE00F5B8E4 /* OOColor.h in Headers */,
1A81F70A0A7BAC4D006580AD /* OOCAMusic.h in Headers */,
1A8A37570B960337007D20B8 /* NSMutableDictionaryOOExtensions.h in Headers */,
1A8A394F0B96229C007D20B8 /* NSFileManagerOOExtensions.h in Headers */,
1A8A3A380B962AEF007D20B8 /* NSScannerOOExtensions.h in Headers */,
@ -3129,6 +3190,7 @@
1A94057F0BAF52AD005F6CF3 /* OOQuaternion.h in Headers */,
1A94062B0BAF6170005F6CF3 /* OOBoundingBox.h in Headers */,
1A9406840BAF66D6005F6CF3 /* OOVoxel.h in Headers */,
1AA08604182578AF007CCAEB /* OOALSound.h in Headers */,
1A9406B40BAF67BF005F6CF3 /* OOTriangle.h in Headers */,
1AB01ABE0BB15AED00F1B949 /* OOTextureScaling.h in Headers */,
1AB01BBB0BB16A8A00F1B949 /* OOFastArithmetic.h in Headers */,
@ -3136,6 +3198,7 @@
1A5DB1EA0BBD8F0000D57389 /* OOConstToString.h in Headers */,
1A5DBAA60BC000DC00D57389 /* OOJavaScriptEngine.h in Headers */,
1A5DBAA80BC000DC00D57389 /* OOJSScript.h in Headers */,
1A5D588B1825241800C779AE /* unzip.h in Headers */,
1A5DBAAA0BC000DC00D57389 /* OOPListScript.h in Headers */,
1A5DBAAD0BC000DC00D57389 /* OOScript.h in Headers */,
1A5DBD580BC17F0900D57389 /* NSStringOOExtensions.h in Headers */,
@ -3182,6 +3245,7 @@
1A15049E0C12CA070032F3E8 /* OOProbabilisticTextureManager.h in Headers */,
1AC775E20C2DD4E900ECFF3B /* OODebugGLDrawing.h in Headers */,
1A5E46300C32DACE008104B4 /* OOShaderUniformMethodType.h in Headers */,
1A5D58881825241800C779AE /* ioapi.h in Headers */,
1A7D833A0C40147800E4A5F5 /* OOAsyncQueue.h in Headers */,
1AB2AAFA0C4CE0CC0008CF4E /* OOOXPVerifier.h in Headers */,
1A27DB3B0C4E349F00CB4CE8 /* OOOXPVerifierStageInternal.h in Headers */,
@ -3191,6 +3255,7 @@
1A7D3B9B0C4F7843008EDC33 /* OOCheckDemoShipsPListVerifierStage.h in Headers */,
1A7D3C490C4F818C008EDC33 /* OOCheckEquipmentPListVerifierStage.h in Headers */,
1A7D3D2B0C4F8D02008EDC33 /* OOTextureVerifierStage.h in Headers */,
1AA0860C182578AF007CCAEB /* OOALStreamedSound.h in Headers */,
1A7D41870C516B90008EDC33 /* OOModelVerifierStage.h in Headers */,
1A7D41E20C516E9E008EDC33 /* OOCheckShipDataPListVerifierStage.h in Headers */,
1A6DD1230C57B5BC00A892F4 /* OOPListSchemaVerifier.h in Headers */,
@ -3200,6 +3265,8 @@
1A73712D0C623DAE0097AC37 /* OOJSStation.h in Headers */,
1A7376BE0C64AE330097AC37 /* OOJSSystem.h in Headers */,
1A4FB3350C8DC86800DC8E1F /* OOJSOolite.h in Headers */,
1AA0860A182578AF007CCAEB /* OOALSoundMixer.h in Headers */,
1AA08602182578AF007CCAEB /* OOALMusic.h in Headers */,
1ACEA3490C91507000C7CE97 /* OORoleSet.h in Headers */,
1ACEA6BF0C91DA3E00C7CE97 /* OOJSGlobal.h in Headers */,
1ACEA7280C91DF2800C7CE97 /* OOJSMissionVariables.h in Headers */,
@ -3289,12 +3356,13 @@
1A95C040118A450E002EE302 /* OOConvertCubeMapToLatLong.h in Headers */,
1ACB1D18118DCBC0007B9A1F /* OOConcreteTexture.h in Headers */,
1ACB1D1C118DCE5A007B9A1F /* OOTextureInternal.h in Headers */,
1A06F2861196E5B100AFA5B4 /* OOCASoundDebugMonitor.h in Headers */,
1AEB491A119D5AAA007BD514 /* OORegExpMatcher.h in Headers */,
1A062C8911B28D8A00727C1D /* NSObjectOOExtensions.h in Headers */,
1AABA83E11B941D1003487D5 /* OOPixMapTextureLoader.h in Headers */,
1A11C2B111CFC35000F3EE77 /* OOJSEngineTimeManagement.h in Headers */,
1A143A4811EF22C5001BAB8D /* JAPersistentFileReference.h in Headers */,
1AA08606182578AF007CCAEB /* OOALSoundChannel.h in Headers */,
1AA085FE182578AF007CCAEB /* OOALBufferedSound.h in Headers */,
1AB5E1EF12BD628500C334DD /* OOJoystickManager.h in Headers */,
1A35257212E1FFA900244C9D /* OOConstToJSString.h in Headers */,
1AEF57D312E51DDB00546444 /* OOJSEngineNativeWrappers.h in Headers */,
@ -3321,6 +3389,8 @@
1AD8522517947BD600CBE743 /* OOHPVector.h in Headers */,
1AD8522E17947C9500CBE743 /* OOJSPopulatorDefinition.h in Headers */,
1A9438CF17F84C560011F80B /* OOExplosionCloudEntity.h in Headers */,
1AA08612182578B8007CCAEB /* OOOpenALController.h in Headers */,
1A5D5893182525DE00C779AE /* NSDataOOExtensions.h in Headers */,
1A1F6D0D180AC324002AD52E /* OOWaypointEntity.h in Headers */,
1A1F6D16180AC371002AD52E /* OOJSWaypoint.h in Headers */,
);
@ -3340,6 +3410,7 @@
0865424C06B8447D000CA0AB /* Resources */,
1A5BF29C0916D49800BF238F /* Copy MDImporter */,
1A2CC5F118293E380060285F /* Copy Game Resources */,
1A6D58B6182D5F3600BFB44D /* Generate Manifest */,
1AA2E7471191E4B400DFBA23 /* Copy Schemata */,
1AE8837812EF91880075814F /* Copy Frameworks */,
);
@ -3543,6 +3614,20 @@
shellPath = /bin/sh;
shellScript = "\"$SRCROOT/tools/resource-management/copy-game-resources\" \"$SRCROOT/Resources\" \"$GAME_RESOURCES_DIR\"\n";
};
1A6D58B6182D5F3600BFB44D /* Generate Manifest */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Generate Manifest";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "tools/mkmanifest.sh > \"$GAME_RESOURCES_DIR/manifest.plist\"";
};
1A7E3A06180AC8D400576095 /* Conditionally copy Debug Bundle */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -3601,15 +3686,6 @@
files = (
25F3E6330994F04C002F25FD /* legacy_random.c in Sources */,
25F3E6BD0994F30A002F25FD /* main.m in Sources */,
251610E2099544090037C2E1 /* OOCASoundReferencePoint.m in Sources */,
251610E4099544090037C2E1 /* OOCASoundMixer.m in Sources */,
251610E5099544090037C2E1 /* OOCABufferedSound.m in Sources */,
251610E6099544090037C2E1 /* OOCAStreamingSound.m in Sources */,
251610E8099544090037C2E1 /* OOCASound.m in Sources */,
251610E9099544090037C2E1 /* OOCASoundChannel.m in Sources */,
251610EE099544090037C2E1 /* OOCASoundDecoder.m in Sources */,
251610EF099544090037C2E1 /* OOErrorDescription.m in Sources */,
251610F2099544190037C2E1 /* VirtualRingBuffer.m in Sources */,
25161153099544390037C2E1 /* AI.m in Sources */,
2516115A099544390037C2E1 /* OOTrumble.m in Sources */,
2516115E099544390037C2E1 /* GameController.m in Sources */,
@ -3624,7 +3700,6 @@
1A68A4A51615F4A400D7BB08 /* OOMeshToOctreeConverter.m in Sources */,
2512834709BA281500F43D55 /* CollisionRegion.m in Sources */,
083325DE09DDBCDE00F5B8E4 /* OOColor.m in Sources */,
1A81F7090A7BAC4D006580AD /* OOCAMusic.m in Sources */,
1A8A37560B960337007D20B8 /* NSMutableDictionaryOOExtensions.m in Sources */,
1A8A394E0B96229C007D20B8 /* NSFileManagerOOExtensions.m in Sources */,
1A8A3A390B962AEF007D20B8 /* NSScannerOOExtensions.m in Sources */,
@ -3633,6 +3708,7 @@
1A29967F0B9F064C002D2149 /* OOCache.m in Sources */,
1A9400BE0BAF0ECD005F6CF3 /* OOStringParsing.m in Sources */,
1A9404260BAF3DED005F6CF3 /* OOCollectionExtractors.m in Sources */,
1A5D58871825241800C779AE /* ioapi.c in Sources */,
1A9404670BAF42BF005F6CF3 /* OOPListParsing.m in Sources */,
1A9404A40BAF462D005F6CF3 /* OOVector.m in Sources */,
1A9405390BAF4FA6005F6CF3 /* OOMatrix.m in Sources */,
@ -3645,6 +3721,7 @@
1A5DBAAB0BC000DC00D57389 /* OOPListScript.m in Sources */,
1A5DBAAE0BC000DC00D57389 /* OOScript.m in Sources */,
1A5DBD590BC17F0900D57389 /* NSStringOOExtensions.m in Sources */,
1AA08603182578AF007CCAEB /* OOALMusic.m in Sources */,
1A3AFF200BC4462200B5E2D9 /* OOJSVector.m in Sources */,
1A2A8C160BC65FFD001E00FB /* OOJSEntity.m in Sources */,
1A2A8D3B0BC6765F001E00FB /* EntityOOJavaScriptExtensions.m in Sources */,
@ -3676,6 +3753,7 @@
1A26D0EB0BCF9D3B0073F257 /* OOTextureLoader.m in Sources */,
1A43234F0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m in Sources */,
1ADBA5510BD0F173008FC99C /* OOBasicMaterial.m in Sources */,
1A5D588A1825241800C779AE /* unzip.c in Sources */,
1A2A16680BD10B1200152975 /* OOSingleTextureMaterial.m in Sources */,
1A2A17D70BD1587D00152975 /* OOCPUInfo.m in Sources */,
1A2A1B0A0BD276A900152975 /* OOEntityWithDrawable.m in Sources */,
@ -3701,6 +3779,7 @@
1A736BD40C61E9370097AC37 /* OOJSPlayer.m in Sources */,
1A736C800C61FD220097AC37 /* OOJSCall.m in Sources */,
1A73712E0C623DAE0097AC37 /* OOJSStation.m in Sources */,
1A5D5894182525DE00C779AE /* NSDataOOExtensions.m in Sources */,
1A7376BF0C64AE330097AC37 /* OOJSSystem.m in Sources */,
1A4FB3360C8DC86800DC8E1F /* OOJSOolite.m in Sources */,
1ACEA34A0C91507000C7CE97 /* OORoleSet.m in Sources */,
@ -3709,7 +3788,9 @@
1ACEA7AB0C91E32800C7CE97 /* OOJSMission.m in Sources */,
1A6B1EF10C9AA5C6000717CF /* OOScriptTimer.m in Sources */,
1A6B1F360C9AAA60000717CF /* OOPriorityQueue.m in Sources */,
1AA08613182578B8007CCAEB /* OOOpenALController.m in Sources */,
1A6B228E0C9B40D4000717CF /* OOJSTimer.m in Sources */,
1AA085FF182578AF007CCAEB /* OOALBufferedSound.m in Sources */,
1A6B25EF0C9C2746000717CF /* OOJSClock.m in Sources */,
1A2DA3830CB4D25D00DE6823 /* OOTCPStreamDecoderAbstractionLayer.m in Sources */,
1A2DA3870CB4D27400DE6823 /* OOTCPStreamDecoder.c in Sources */,
@ -3760,8 +3841,11 @@
1AE24374105439B500EAA7F2 /* OOLightParticleEntity.m in Sources */,
1A11273C105994D000DF9D12 /* OOExhaustPlumeEntity.m in Sources */,
1A1F2843105AAB7900ADB8C5 /* OOSparkEntity.m in Sources */,
1AA0860D182578AF007CCAEB /* OOALStreamedSound.m in Sources */,
1AA0860B182578AF007CCAEB /* OOALSoundMixer.m in Sources */,
1A3BA25A106555D100C5C6F3 /* NSNumberOOExtensions.m in Sources */,
1A00C65610663D3700A8737D /* OOProfilingStopwatch.m in Sources */,
1AA08609182578AF007CCAEB /* OOALSoundDecoder.m in Sources */,
1A00C7BB10667D3100A8737D /* OOECMBlastEntity.m in Sources */,
1A00C7E01066814C00A8737D /* OOAsyncWorkManager.m in Sources */,
1A817CFD106D232100AA2F97 /* OOPlasmaShotEntity.m in Sources */,
@ -3783,6 +3867,7 @@
1A3D034B11736EDA005BF5E6 /* OOMaterialConvenienceCreators.m in Sources */,
1AECE9EF11779910003986A8 /* OOPixMap.m in Sources */,
1A8C981D117A380800D8AB7E /* OOCombinedEmissionMapGenerator.m in Sources */,
1AA08605182578AF007CCAEB /* OOALSound.m in Sources */,
1A1F7DB6117B5D8100332757 /* OOMaterialSpecifier.m in Sources */,
1A19783F117F81B10060DB56 /* OOPixMapChannelOperations.m in Sources */,
1A95C041118A450E002EE302 /* OOConvertCubeMapToLatLong.m in Sources */,
@ -3802,6 +3887,7 @@
1A1280F912ECA4ED00B65D9F /* OOJSFont.m in Sources */,
1AE7325112F75D470045513D /* OOLaserShotEntity.m in Sources */,
1A97D77F12FDBB9B0009D74A /* OOQuiriumCascadeEntity.m in Sources */,
1AA08607182578AF007CCAEB /* OOALSoundChannel.m in Sources */,
1A4DF25D12FDC4880027F43D /* OORingEffectEntity.m in Sources */,
1A4DF35412FDF0410027F43D /* OOParticleSystem.m in Sources */,
1A033FB913268ABB006F9DB7 /* OOPDFView.m in Sources */,

View File

@ -1365,7 +1365,12 @@
"wormhole-collapsing-in-mm:ss" = "Collapsing in %02d:%02d";
"oxp-is-incompatible" = "\t“%@” is incompatible with version %@ of Oolite.";
"oxz-lacks-manifest" = "\t“%@” does not have a valid manifest.plist and could not be loaded";
"oxp-manifest-incomplete" = "\tThe manifest.plist for “%@” is missing the required “%@” field";
"oxp-manifest-duplicate" = "\tThe expansion pack “%@” appears to be a duplicate of “%@” and so was not loaded.";
"oxp-conflict" = "\tThe expansion pack “%@” conflicts with “%@” and so was not loaded.";
"oxp-required" = "\tThe expansion pack “%@” was not loaded as it requires “%@” which is not installed.";
"@-is-a-@-from-@" = "%@ is a [21] %@ from %@"; // Character description: "<name> is a {frequent|etc} {offender|fugitive} from <system name>". Never actually visible.
"lowercase-offender" = "offender";
"lowercase-fugitive" = "fugitive";

View File

@ -197,9 +197,12 @@
missile.damage.calc = no; // Debugging of missile damage curves
oxp.conflict = $error;
oxp.duplicate = $error;
oxp.noManifest = $error;
oxp.requirementMissing = $error;
oxp.versionMismatch = $error;
player.ship = no;
player.ship.damage = no;
player.equipmentScript = $scriptDebugOn;
@ -368,9 +371,11 @@
$soundError = $error;
$soundDebug = no;
$soundDebugVerbose = $soundDebug;
sound.buffer = $soundDebugVerbose;
sound.customSounds = $soundDebug;
sound.customSounds.recursion = $soundError; // Circular dependency in customsounds.plist, e.g. [foo] = [bar], [bar] = [foo].
sound.load.success = $soundDebug;
sound.initialization.error = $soundError;
// Mac-specific sound messages
sound.channel.cleanup.success = $soundDebugVerbose;
@ -378,7 +383,6 @@
sound.channel.cleanup.failed.broken = inherit;
sound.channel.cleanup.failed.badState = inherit;
sound.channel.machPortError = $soundError;
sound.initialization.error = $soundError;
sound.mixer.outOfChannels = $soundError;
sound.mixer.inspector.loadFailed = $soundError;
sound.mixer.replacingBrokenChannel = $soundDebug;

View File

@ -44,6 +44,26 @@
<key>LSTypeIsPackage</key>
<true/>
</dict>
<dict>
<key>CFBundleTypeExtensions</key>
<array>
<string>oxz</string>
</array>
<key>CFBundleTypeIconFile</key>
<string>oolite-expansion-document</string>
<key>CFBundleTypeName</key>
<string>Oolite Expansion Pack</string>
<key>CFBundleTypeRole</key>
<string>Viewer</string>
<key>LSHandlerRank</key>
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>org.aegidian.oolite.oxp.compressed</string>
</array>
<key>LSTypeIsPackage</key>
<integer>0</integer>
</dict>
</array>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
@ -86,6 +106,8 @@
</array>
<key>UTTypeDescription</key>
<string>Oolite Saved Game</string>
<key>UTTypeIconFile</key>
<string>oolite-document</string>
<key>UTTypeIdentifier</key>
<string>org.aegidian.oolite.save</string>
<key>UTTypeTagSpecification</key>
@ -100,6 +122,22 @@
<key>UTTypeConformsTo</key>
<array>
<string>public.item</string>
</array>
<key>UTTypeDescription</key>
<string>Oolite Expansion Pack</string>
<key>UTTypeIconFile</key>
<string>oolite-expansion-document</string>
<key>UTTypeIdentifier</key>
<string>org.aegidian.oolite.expansion</string>
<key>UTTypeReferenceURL</key>
<string>http://wiki.alioth.net/index.php/OXP_howto</string>
<key>UTTypeTagSpecification</key>
<dict/>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>org.aegidian.oolite.expansion</string>
<string>com.apple.package</string>
</array>
<key>UTTypeDescription</key>
@ -114,6 +152,26 @@
</array>
</dict>
</dict>
<dict>
<key>UTTypeConformsTo</key>
<array>
<string>org.aegidian.oolite.expansion</string>
<string>com.pkware.zip-archive</string>
</array>
<key>UTTypeDescription</key>
<string>Oolite Expansion Pack</string>
<key>UTTypeIdentifier</key>
<string>org.aegidian.oolite.oxp.compressed</string>
<key>UTTypeReferenceURL</key>
<string></string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
<array>
<string>oxz</string>
</array>
</dict>
</dict>
</array>
</dict>
</plist>

View File

@ -28,8 +28,7 @@ SOFTWARE.
*/
//#import "OOCASoundInternal.h"
#import "OOCocoa.h"
#import "OOSound.h"
#ifndef NDEBUG

View File

@ -57,7 +57,7 @@ _QuaternionDescription
_VectorDescription
_OOStringFromBehaviour
_OOStringFromShaderSetting
_OOSoundRegisterDebugMonitor
# _OOSoundRegisterDebugMonitor # Not implemented in OpenAL builds
_OOJSProfileEnter
_OOJSProfileExit
_OOJSUnreachable

View File

@ -62,7 +62,7 @@ _QuaternionDescription
_VectorDescription
_OOStringFromBehaviour
_OOStringFromShaderSetting
_OOSoundRegisterDebugMonitor
# _OOSoundRegisterDebugMonitor # Not implemented in OpenAL builds
_OOJSProfileEnter
_OOJSProfileExit
_OOJSUnreachable

View File

@ -933,7 +933,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
}
- (void) applyVelocity:(OOTimeDelta)delta_t;
- (void) applyVelocity:(OOTimeDelta)delta_t
{
position = HPvector_add(position, HPvector_multiply_scalar(vectorToHPVector(velocity), delta_t));
}

View File

@ -795,6 +795,7 @@ typedef enum
- (OOWeaponType) weaponForFacing:(OOWeaponFacing)facing;
- (OOWeaponType) currentWeapon;
- (Vector) currentLaserOffset;
- (void) rotateCargo;

View File

@ -4453,7 +4453,14 @@ static GLfloat sBaseMass = 0.0;
if ([ms isEqual:@"INCOMING_MISSILE"])
{
[self playIncomingMissile];
if ([self primaryAggressor] != nil)
{
[self playIncomingMissile:HPVectorToVector([[self primaryAggressor] position])];
}
else
{
[self playIncomingMissile:kZeroVector];
}
[UNIVERSE addMessage:DESC(@"incoming-missile") forCount:4.5];
}
@ -4547,7 +4554,7 @@ static GLfloat sBaseMass = 0.0;
{
firedMissile = [self launchMine:missile];
if (!replacingMissile) [self removeFromPylon:activeMissile];
if (firedMissile != nil) [self playMineLaunched];
if (firedMissile != nil) [self playMineLaunched:[self missileLaunchPosition]];
}
else
{
@ -4558,7 +4565,7 @@ static GLfloat sBaseMass = 0.0;
if (firedMissile != nil)
{
if (!replacingMissile) [self removeFromPylon:activeMissile];
[self playMissileLaunched];
[self playMissileLaunched:[self missileLaunchPosition]];
}
}
@ -4772,6 +4779,12 @@ static GLfloat sBaseMass = 0.0;
}
- (Vector) currentLaserOffset
{
return [self laserPortOffset:currentWeaponFacing];
}
- (BOOL) fireMainWeapon
{
int weapon_to_be_fired = [self currentWeapon];
@ -4783,7 +4796,7 @@ static GLfloat sBaseMass = 0.0;
if (weapon_temp / PLAYER_MAX_WEAPON_TEMP >= WEAPON_COOLING_CUTOUT)
{
[self playWeaponOverheated];
[self playWeaponOverheated:[self currentLaserOffset]];
[UNIVERSE addMessage:DESC(@"weapon-overheat") forCount:3.0];
return NO;
}
@ -4943,7 +4956,7 @@ static GLfloat sBaseMass = 0.0;
- (void) takeEnergyDamage:(double)amount from:(Entity *)ent becauseOf:(Entity *)other
{
HPVector rel_pos;
double d_forward;
double d_forward, d_right, d_up;
BOOL internal_damage = NO; // base chance
OOLog(@"player.ship.damage", @"Player took damage from %@ becauseOf %@", ent, other);
@ -4971,8 +4984,11 @@ static GLfloat sBaseMass = 0.0;
if ([ent isShip]) [(ShipEntity *)ent doScriptEvent:OOJSID("shipAttackedOther") withArgument:self];
d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
[self playShieldHit];
d_right = dot_product(HPVectorToVector(rel_pos), v_right);
d_up = dot_product(HPVectorToVector(rel_pos), v_up);
Vector relative = make_vector(d_right,d_up,d_forward);
[self playShieldHit:relative];
// firing on an innocent ship is an offence
if ([other isShip])
@ -5013,7 +5029,7 @@ static GLfloat sBaseMass = 0.0;
{
internal_damage = ((ranrot_rand() & PLAYER_INTERNAL_DAMAGE_FACTOR) < amount); // base chance of damage to systems
energy -= amount;
[self playDirectHit];
[self playDirectHit:relative];
ship_temperature += (amount / [self heatInsulation]);
}
[self noteTakingDamage:amount from:other type:damageType];
@ -5038,7 +5054,7 @@ static GLfloat sBaseMass = 0.0;
- (void) takeScrapeDamage:(double) amount from:(Entity *) ent
{
HPVector rel_pos;
double d_forward;
double d_forward, d_right, d_up;
BOOL internal_damage = NO; // base chance
if ([self status] == STATUS_DEAD) return;
@ -5055,8 +5071,11 @@ static GLfloat sBaseMass = 0.0;
rel_pos = HPvector_subtract(rel_pos, position);
// rel_pos is now small
d_forward = dot_product(HPVectorToVector(rel_pos), v_forward);
[self playScrapeDamage];
d_right = dot_product(HPVectorToVector(rel_pos), v_right);
d_up = dot_product(HPVectorToVector(rel_pos), v_up);
Vector relative = make_vector(d_right,d_up,d_forward);
[self playScrapeDamage:relative];
if (d_forward >= 0)
{
forward_shield -= amount;

View File

@ -916,7 +916,7 @@ static NSTimeInterval time_last_frame;
{
if ([self fireMainWeapon])
{
[self playLaserHit:[self shipHitByLaser] != nil];
[self playLaserHit:([self shipHitByLaser] != nil) offset:[self currentLaserOffset]];
}
}

View File

@ -24,7 +24,6 @@ MA 02110-1301, USA.
#import "PlayerEntity.h"
@interface PlayerEntity (Sound)
- (void) setUpSound;
@ -107,7 +106,7 @@ MA 02110-1301, USA.
// Warning sounds
- (void) playHostileWarning;
- (void) playAlertConditionRed;
- (void) playIncomingMissile;
- (void) playIncomingMissile:(Vector)missileVector;
- (void) playEnergyLow;
- (void) playDockingDenied;
- (void) playWitchjumpFailure;
@ -118,15 +117,15 @@ MA 02110-1301, USA.
- (void) playFuelLeak;
// Damage sounds
- (void) playShieldHit;
- (void) playDirectHit;
- (void) playScrapeDamage;
- (void) playShieldHit:(Vector)attackVector;
- (void) playDirectHit:(Vector)attackVector;
- (void) playScrapeDamage:(Vector)attackVector;
// Weapon sounds
- (void) playLaserHit:(BOOL)hit;
- (void) playWeaponOverheated;
- (void) playMissileLaunched;
- (void) playMineLaunched;
- (void) playLaserHit:(BOOL)hit offset:(Vector)weaponOffset;
- (void) playWeaponOverheated:(Vector)weaponOffset;
- (void) playMissileLaunched:(Vector)weaponOffset;
- (void) playMineLaunched:(Vector)weaponOffset;
// Miscellaneous sounds
- (void) playEscapePodScooped;

View File

@ -27,6 +27,7 @@ MA 02110-1301, USA.
#import "ResourceManager.h"
#import "Universe.h"
#import "OOSoundSourcePool.h"
#import "OOMaths.h"
// Sizes of sound source pools
@ -51,6 +52,14 @@ static OOSoundSource *sBreakPatternSource;
static OOSoundSourcePool *sBuySellSourcePool;
static OOSoundSource *sAfterburnerSources[2];
const Vector kInterfaceBeepPosition = { 0.0f, -0.2f, 0.5f };
const Vector kInterfaceWarningPosition = { 0.0f, -0.2f, 0.4f };
const Vector kBreakPatternPosition = { 0.0f, 0.0f, 1.0f };
const Vector kEcmPosition = { 0.2f, 0.6f, -0.1f };
const Vector kWitchspacePosition = { 0.0f, -0.3f, -0.3f };
// maybe these should actually track engine positions
const Vector kAfterburner1Position = { -0.1f, 0.0f, -1.0f };
const Vector kAfterburner2Position = { 0.1f, 0.0f, -1.0f };
@implementation PlayerEntity (Sound)
@ -59,9 +68,16 @@ static OOSoundSource *sAfterburnerSources[2];
[self destroySound];
sInterfaceBeepSource = [[OOSoundSource alloc] init];
[sInterfaceBeepSource setPosition:kInterfaceBeepPosition];
sBreakPatternSource = [[OOSoundSource alloc] init];
[sBreakPatternSource setPosition:kBreakPatternPosition];
sEcmSource = [[OOSoundSource alloc] init];
[sEcmSource setPosition:kEcmPosition];
sHyperspaceSoundSource = [[OOSoundSource alloc] init];
[sHyperspaceSoundSource setPosition:kWitchspacePosition];
sBuySellSourcePool = [[OOSoundSourcePool alloc] initWithCount:kBuySellSourcePoolSize minRepeatTime:0.0];
sWarningSoundPool = [[OOSoundSourcePool alloc] initWithCount:kWarningPoolSize minRepeatTime:0.0];
@ -72,7 +88,9 @@ static OOSoundSource *sAfterburnerSources[2];
// Two sources with the same sound are used to simulate looping.
OOSound *afterburnerSound = [ResourceManager ooSoundNamed:@"afterburner1.ogg" inFolder:@"Sounds"];
sAfterburnerSources[0] = [[OOSoundSource alloc] initWithSound:afterburnerSound];
[sAfterburnerSources[0] setPosition:kAfterburner1Position];
sAfterburnerSources[1] = [[OOSoundSource alloc] initWithSound:afterburnerSound];
[sAfterburnerSources[1] setPosition:kAfterburner2Position];
}
@ -340,6 +358,8 @@ static OOSoundSource *sAfterburnerSources[2];
{
if(![sInterfaceBeepSource isPlaying])
{
/* TODO: this should use the scoop position, not the standard
* interface beep position */
[self playInterfaceBeep:@"[scoop]"];
scoopSoundPlayTime = 0.5;
}
@ -484,134 +504,134 @@ static OOSoundSource *sAfterburnerSources[2];
- (void) playHostileWarning
{
[sWarningSoundPool playSoundWithKey:@"[hostile-warning]" priority:1];
[sWarningSoundPool playSoundWithKey:@"[hostile-warning]" priority:1 position:kInterfaceWarningPosition];
}
- (void) playAlertConditionRed
{
[sWarningSoundPool playSoundWithKey:@"[alert-condition-red]" priority:2];
[sWarningSoundPool playSoundWithKey:@"[alert-condition-red]" priority:2 position:kInterfaceWarningPosition];
}
- (void) playIncomingMissile
- (void) playIncomingMissile:(Vector)missileVector
{
[sWarningSoundPool playSoundWithKey:@"[incoming-missile]" priority:3];
[sWarningSoundPool playSoundWithKey:@"[incoming-missile]" priority:3 position:missileVector];
}
- (void) playEnergyLow
{
[sWarningSoundPool playSoundWithKey:@"[energy-low]" priority:0.5];
[sWarningSoundPool playSoundWithKey:@"[energy-low]" priority:0.5 position:kInterfaceWarningPosition];
}
- (void) playDockingDenied
{
[sWarningSoundPool playSoundWithKey:@"[autopilot-denied]" priority:1];
[sWarningSoundPool playSoundWithKey:@"[autopilot-denied]" priority:1 position:kInterfaceWarningPosition];
}
- (void) playWitchjumpFailure
{
[sWarningSoundPool playSoundWithKey:@"[witchdrive-failure]" priority:1.5];
[sWarningSoundPool playSoundWithKey:@"[witchdrive-failure]" priority:1.5 position:kWitchspacePosition];
}
- (void) playWitchjumpMisjump
{
[sWarningSoundPool playSoundWithKey:@"[witchdrive-malfunction]" priority:1.5];
[sWarningSoundPool playSoundWithKey:@"[witchdrive-malfunction]" priority:1.5 position:kWitchspacePosition];
}
- (void) playWitchjumpBlocked
{
[sWarningSoundPool playSoundWithKey:@"[witch-blocked-by-@]" priority:1.3];
[sWarningSoundPool playSoundWithKey:@"[witch-blocked-by-@]" priority:1.3 position:kWitchspacePosition];
}
- (void) playWitchjumpDistanceTooGreat
{
[sWarningSoundPool playSoundWithKey:@"[witch-too-far]" priority:1.3];
[sWarningSoundPool playSoundWithKey:@"[witch-too-far]" priority:1.3 position:kWitchspacePosition];
}
- (void) playWitchjumpInsufficientFuel
{
[sWarningSoundPool playSoundWithKey:@"[witch-no-fuel]" priority:1.3];
[sWarningSoundPool playSoundWithKey:@"[witch-no-fuel]" priority:1.3 position:kWitchspacePosition];
}
- (void) playFuelLeak
{
[sWarningSoundPool playSoundWithKey:@"[fuel-leak]" priority:0.5];
[sWarningSoundPool playSoundWithKey:@"[fuel-leak]" priority:0.5 position:kWitchspacePosition];
}
- (void) playShieldHit
- (void) playShieldHit:(Vector)attackVector
{
[sDamageSoundPool playSoundWithKey:@"[player-hit-by-weapon]"];
[sDamageSoundPool playSoundWithKey:@"[player-hit-by-weapon]" position:attackVector];
}
- (void) playDirectHit
- (void) playDirectHit:(Vector)attackVector
{
[sDamageSoundPool playSoundWithKey:@"[player-direct-hit]"];
[sDamageSoundPool playSoundWithKey:@"[player-direct-hit]" position:attackVector];
}
- (void) playScrapeDamage
- (void) playScrapeDamage:(Vector)attackVector
{
[sDamageSoundPool playSoundWithKey:@"[player-scrape-damage]"];
[sDamageSoundPool playSoundWithKey:@"[player-scrape-damage]" position:attackVector];
}
- (void) playLaserHit:(BOOL)hit
- (void) playLaserHit:(BOOL)hit offset:(Vector)weaponOffset
{
if (hit)
{
[sWeaponSoundPool playSoundWithKey:@"[player-laser-hit]" priority:1 expiryTime:0.05];
[sWeaponSoundPool playSoundWithKey:@"[player-laser-hit]" priority:1.0 expiryTime:0.05 overlap:YES position:weaponOffset];
}
else
{
[sWeaponSoundPool playSoundWithKey:@"[player-laser-miss]" priority:1 expiryTime:0.05];
[sWeaponSoundPool playSoundWithKey:@"[player-laser-miss]" priority:1.0 expiryTime:0.05 overlap:YES position:weaponOffset];
}
}
- (void) playWeaponOverheated
- (void) playWeaponOverheated:(Vector)weaponOffset
{
[sWeaponSoundPool playSoundWithKey:@"[weapon-overheat]" overlap:NO];
[sWeaponSoundPool playSoundWithKey:@"[weapon-overheat]" overlap:NO position:weaponOffset];
}
- (void) playMissileLaunched
- (void) playMissileLaunched:(Vector)weaponOffset
{
[sWeaponSoundPool playSoundWithKey:@"[missile-launched]"];
[sWeaponSoundPool playSoundWithKey:@"[missile-launched]" position:weaponOffset];
}
- (void) playMineLaunched
- (void) playMineLaunched:(Vector)weaponOffset
{
[sWeaponSoundPool playSoundWithKey:@"[mine-launched]"];
[sWeaponSoundPool playSoundWithKey:@"[mine-launched]" position:weaponOffset];
}
- (void) playEscapePodScooped
{
[sMiscSoundPool playSoundWithKey:@"[escape-pod-scooped]"];
[sMiscSoundPool playSoundWithKey:@"[escape-pod-scooped]" position:kInterfaceBeepPosition];
}
- (void) playAegisCloseToPlanet
{
[sMiscSoundPool playSoundWithKey:@"[aegis-planet]"];
[sMiscSoundPool playSoundWithKey:@"[aegis-planet]" position:kInterfaceBeepPosition];
}
- (void) playAegisCloseToStation
{
[sMiscSoundPool playSoundWithKey:@"[aegis-station]"];
[sMiscSoundPool playSoundWithKey:@"[aegis-station]" position:kInterfaceBeepPosition];
}

View File

@ -997,11 +997,13 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
- (BOOL) fireDirectLaserShot:(double)range;
- (BOOL) fireDirectLaserDefensiveShot;
- (BOOL) fireDirectLaserShotAt:(Entity *)my_target;
- (Vector) laserPortOffset:(OOWeaponFacing)direction;
- (BOOL) fireLaserShotInDirection:(OOWeaponFacing)direction;
- (void) adjustMissedShots:(int)delta;
- (int) missedShots;
- (BOOL) firePlasmaShotAtOffset:(double)offset speed:(double)speed color:(OOColor *)color;
- (void) considerFiringMissile:(double)delta_t;
- (Vector) missileLaunchPosition;
- (ShipEntity *) fireMissile;
- (ShipEntity *) fireMissileWithIdentifier:(NSString *) identifier andTarget:(Entity *) target;
- (BOOL) isMissileFlagSet;

View File

@ -10773,15 +10773,9 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
}
- (BOOL) fireLaserShotInDirection:(OOWeaponFacing)direction
- (Vector) laserPortOffset:(OOWeaponFacing)direction
{
double range_limit2 = weaponRange * weaponRange;
GLfloat hit_at_range;
Vector vel = vector_multiply_scalar(v_forward, flightSpeed);
Vector laserPortOffset = kZeroVector;
last_shot_time = [UNIVERSE getTime];
Vector laserPortOffset = kZeroVector;
switch (direction)
{
case WEAPON_FACING_FORWARD:
@ -10801,7 +10795,19 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
laserPortOffset = starboardWeaponOffset;
break;
}
return laserPortOffset;
}
- (BOOL) fireLaserShotInDirection:(OOWeaponFacing)direction
{
double range_limit2 = weaponRange * weaponRange;
GLfloat hit_at_range;
Vector vel = vector_multiply_scalar(v_forward, flightSpeed);
Vector laserPortOffset = [self laserPortOffset:direction];
last_shot_time = [UNIVERSE getTime];
ShipEntity *victim = [UNIVERSE firstShipHitByLaserFromShip:self inDirection:direction offset:laserPortOffset gettingRangeFound:&hit_at_range];
[self setShipHitByLaser:victim];
@ -11053,6 +11059,28 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
}
- (Vector) missileLaunchPosition
{
Vector start;
// default launching position
start.x = 0.0f; // in the middle
start.y = boundingBox.min.y - 4.0f; // 4m below bounding box
start.z = boundingBox.max.z + 1.0f; // 1m ahead of bounding box
// custom launching position
start = [shipinfoDictionary oo_vectorForKey:@"missile_launch_position" defaultValue:start];
if (start.x == 0.0f && start.y == 0.0f && start.z <= 0.0f) // The kZeroVector as start is illegal also.
{
OOLog(@"ship.missileLaunch.invalidPosition", @"***** ERROR: The missile_launch_position defines a position %@ behind the %@. In future versions such missiles may explode on launch because they have to travel through the ship.", VectorDescription(start), self);
start.x = 0.0f;
start.y = boundingBox.min.y - 4.0f;
start.z = boundingBox.max.z + 1.0f;
}
return start;
}
- (ShipEntity *) fireMissile
{
return [self fireMissileWithIdentifier:nil andTarget:[self primaryTarget]];
@ -11071,21 +11099,7 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
if ([UNIVERSE getTime] < missile_launch_time) return nil;
// default launching position
start.x = 0.0f; // in the middle
start.y = boundingBox.min.y - 4.0f; // 4m below bounding box
start.z = boundingBox.max.z + 1.0f; // 1m ahead of bounding box
// custom launching position
start = [shipinfoDictionary oo_vectorForKey:@"missile_launch_position" defaultValue:start];
if (start.x == 0.0f && start.y == 0.0f && start.z <= 0.0f) // The kZeroVector as start is illegal also.
{
OOLog(@"ship.missileLaunch.invalidPosition", @"***** ERROR: The missile_launch_position defines a position %@ behind the %@. In future versions such missiles may explode on launch because they have to travel through the ship.", VectorDescription(start), self);
start.x = 0.0f;
start.y = boundingBox.min.y - 4.0f;
start.z = boundingBox.max.z + 1.0f;
}
start = [self missileLaunchPosition];
double throw_speed = 250.0f;

View File

@ -38,6 +38,7 @@ MA 02110-1301, USA.
#import "OODebugFlags.h"
#import "OOJSFrameCallbacks.h"
#import "OOOpenGLExtensionManager.h"
#import "OOOpenALController.h"
#if OOLITE_MAC_OS_X
#import "JAPersistentFileReference.h"
@ -780,6 +781,7 @@ static NSMutableArray *sMessageStack;
OOLog(@"gameController.exitApp",@".GNUstepDefaults synchronized.");
OOLoggingTerminate();
SDL_Quit();
[[OOOpenALController sharedController] shutdown];
exit(0);
}

View File

@ -29,7 +29,7 @@ SOFTWARE.
#import "OOFunctionAttributes.h"
#import "OOLogging.h"
#import "OOCPUInfo.h"
#import "NSDataOOExtensions.h"
void png_error(png_structp, png_const_charp) NO_RETURN_FUNC;
@ -52,7 +52,7 @@ static void PNGRead(png_structp png, png_bytep bytes, png_size_t size);
- (void)loadTexture
{
// Get data from file
fileData = [[NSData alloc] initWithContentsOfMappedFile:_path];
fileData = [[NSData oo_dataWithOXZFile:_path] retain];
if (fileData == nil) return;
length = [fileData length];

View File

@ -0,0 +1,74 @@
MiniZip - Copyright (c) 1998-2010 - by Gilles Vollant - version 1.1 64 bits from Mathias Svensson
Introduction
---------------------
MiniZip 1.1 is built from MiniZip 1.0 by Gilles Vollant ( http://www.winimage.com/zLibDll/minizip.html )
When adding ZIP64 support into minizip it would result into risk of breaking compatibility with minizip 1.0.
All possible work was done for compatibility.
Background
---------------------
When adding ZIP64 support Mathias Svensson found that Even Rouault have added ZIP64
support for unzip.c into minizip for a open source project called gdal ( http://www.gdal.org/ )
That was used as a starting point. And after that ZIP64 support was added to zip.c
some refactoring and code cleanup was also done.
Changed from MiniZip 1.0 to MiniZip 1.1
---------------------------------------
* Added ZIP64 support for unzip ( by Even Rouault )
* Added ZIP64 support for zip ( by Mathias Svensson )
* Reverted some changed that Even Rouault did.
* Bunch of patches received from Gulles Vollant that he received for MiniZip from various users.
* Added unzip patch for BZIP Compression method (patch create by Daniel Borca)
* Added BZIP Compress method for zip
* Did some refactoring and code cleanup
Credits
Gilles Vollant - Original MiniZip author
Even Rouault - ZIP64 unzip Support
Daniel Borca - BZip Compression method support in unzip
Mathias Svensson - ZIP64 zip support
Mathias Svensson - BZip Compression method support in zip
Resources
ZipLayout http://result42.com/projects/ZipFileLayout
Command line tool for Windows that shows the layout and information of the headers in a zip archive.
Used when debugging and validating the creation of zip files using MiniZip64
ZIP App Note http://www.pkware.com/documents/casestudies/APPNOTE.TXT
Zip File specification
Notes.
* To be able to use BZip compression method in zip64.c or unzip64.c the BZIP2 lib is needed and HAVE_BZIP2 need to be defined.
License
----------------------------------------------------------
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
----------------------------------------------------------

242
src/Core/MiniZip/ioapi.c Normal file
View File

@ -0,0 +1,242 @@
/* ioapi.h -- IO base function header for compress/uncompress .zip
part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt
*/
#if (defined(_WIN32))
#define _CRT_SECURE_NO_WARNINGS
#endif
#if (defined(__APPLE__))
// I/O is always 64-bit on Darwin
#define fopen64 fopen
#define ftello64 ftello
#define fseeko64 fseeko
#endif
#include "ioapi.h"
voidpf call_zopen64 (const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode)
{
if (pfilefunc->zfile_func64.zopen64_file != NULL)
return (*(pfilefunc->zfile_func64.zopen64_file)) (pfilefunc->zfile_func64.opaque,filename,mode);
else
{
return (*(pfilefunc->zopen32_file))(pfilefunc->zfile_func64.opaque,(const char*)filename,mode);
}
}
long call_zseek64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin)
{
if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.zseek64_file)) (pfilefunc->zfile_func64.opaque,filestream,offset,origin);
else
{
uLong offsetTruncated = (uLong)offset;
if (offsetTruncated != offset)
return -1;
else
return (*(pfilefunc->zseek32_file))(pfilefunc->zfile_func64.opaque,filestream,offsetTruncated,origin);
}
}
ZPOS64_T call_ztell64 (const zlib_filefunc64_32_def* pfilefunc,voidpf filestream)
{
if (pfilefunc->zfile_func64.zseek64_file != NULL)
return (*(pfilefunc->zfile_func64.ztell64_file)) (pfilefunc->zfile_func64.opaque,filestream);
else
{
uLong tell_uLong = (*(pfilefunc->ztell32_file))(pfilefunc->zfile_func64.opaque,filestream);
if ((tell_uLong) == ((uLong)-1))
return (ZPOS64_T)-1;
else
return tell_uLong;
}
}
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32)
{
p_filefunc64_32->zfile_func64.zopen64_file = NULL;
p_filefunc64_32->zopen32_file = p_filefunc32->zopen_file;
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
p_filefunc64_32->zfile_func64.zread_file = p_filefunc32->zread_file;
p_filefunc64_32->zfile_func64.zwrite_file = p_filefunc32->zwrite_file;
p_filefunc64_32->zfile_func64.ztell64_file = NULL;
p_filefunc64_32->zfile_func64.zseek64_file = NULL;
p_filefunc64_32->zfile_func64.zclose_file = p_filefunc32->zclose_file;
p_filefunc64_32->zfile_func64.zerror_file = p_filefunc32->zerror_file;
p_filefunc64_32->zfile_func64.opaque = p_filefunc32->opaque;
p_filefunc64_32->zseek32_file = p_filefunc32->zseek_file;
p_filefunc64_32->ztell32_file = p_filefunc32->ztell_file;
}
static voidpf ZCALLBACK fopen_file_func OF((voidpf opaque, const char* filename, int mode));
static uLong ZCALLBACK fread_file_func OF((voidpf opaque, voidpf stream, void* buf, uLong size));
static uLong ZCALLBACK fwrite_file_func OF((voidpf opaque, voidpf stream, const void* buf,uLong size));
static ZPOS64_T ZCALLBACK ftell64_file_func OF((voidpf opaque, voidpf stream));
static long ZCALLBACK fseek64_file_func OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
static int ZCALLBACK fclose_file_func OF((voidpf opaque, voidpf stream));
static int ZCALLBACK ferror_file_func OF((voidpf opaque, voidpf stream));
static voidpf ZCALLBACK fopen_file_func (voidpf opaque, const char* filename, int mode)
{
FILE* file = NULL;
const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename!=NULL) && (mode_fopen != NULL))
file = fopen(filename, mode_fopen);
return file;
}
static voidpf ZCALLBACK fopen64_file_func (voidpf opaque, const void* filename, int mode)
{
FILE* file = NULL;
const char* mode_fopen = NULL;
if ((mode & ZLIB_FILEFUNC_MODE_READWRITEFILTER)==ZLIB_FILEFUNC_MODE_READ)
mode_fopen = "rb";
else
if (mode & ZLIB_FILEFUNC_MODE_EXISTING)
mode_fopen = "r+b";
else
if (mode & ZLIB_FILEFUNC_MODE_CREATE)
mode_fopen = "wb";
if ((filename!=NULL) && (mode_fopen != NULL))
file = fopen64((const char*)filename, mode_fopen);
return file;
}
static uLong ZCALLBACK fread_file_func (voidpf opaque, voidpf stream, void* buf, uLong size)
{
uLong ret;
ret = (uLong)fread(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
static uLong ZCALLBACK fwrite_file_func (voidpf opaque, voidpf stream, const void* buf, uLong size)
{
uLong ret;
ret = (uLong)fwrite(buf, 1, (size_t)size, (FILE *)stream);
return ret;
}
static long ZCALLBACK ftell_file_func (voidpf opaque, voidpf stream)
{
long ret;
ret = ftell((FILE *)stream);
return ret;
}
static ZPOS64_T ZCALLBACK ftell64_file_func (voidpf opaque, voidpf stream)
{
ZPOS64_T ret;
ret = ftello64((FILE *)stream);
return ret;
}
static long ZCALLBACK fseek_file_func (voidpf opaque, voidpf stream, uLong offset, int origin)
{
int fseek_origin=0;
long ret;
switch (origin)
{
case ZLIB_FILEFUNC_SEEK_CUR :
fseek_origin = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END :
fseek_origin = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET :
fseek_origin = SEEK_SET;
break;
default: return -1;
}
ret = 0;
if (fseek((FILE *)stream, offset, fseek_origin) != 0)
ret = -1;
return ret;
}
static long ZCALLBACK fseek64_file_func (voidpf opaque, voidpf stream, ZPOS64_T offset, int origin)
{
int fseek_origin=0;
long ret;
switch (origin)
{
case ZLIB_FILEFUNC_SEEK_CUR :
fseek_origin = SEEK_CUR;
break;
case ZLIB_FILEFUNC_SEEK_END :
fseek_origin = SEEK_END;
break;
case ZLIB_FILEFUNC_SEEK_SET :
fseek_origin = SEEK_SET;
break;
default: return -1;
}
ret = 0;
if(fseeko64((FILE *)stream, offset, fseek_origin) != 0)
ret = -1;
return ret;
}
static int ZCALLBACK fclose_file_func (voidpf opaque, voidpf stream)
{
int ret;
ret = fclose((FILE *)stream);
return ret;
}
static int ZCALLBACK ferror_file_func (voidpf opaque, voidpf stream)
{
int ret;
ret = ferror((FILE *)stream);
return ret;
}
void fill_fopen_filefunc (pzlib_filefunc_def)
zlib_filefunc_def* pzlib_filefunc_def;
{
pzlib_filefunc_def->zopen_file = fopen_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell_file = ftell_file_func;
pzlib_filefunc_def->zseek_file = fseek_file_func;
pzlib_filefunc_def->zclose_file = fclose_file_func;
pzlib_filefunc_def->zerror_file = ferror_file_func;
pzlib_filefunc_def->opaque = NULL;
}
void fill_fopen64_filefunc (zlib_filefunc64_def* pzlib_filefunc_def)
{
pzlib_filefunc_def->zopen64_file = fopen64_file_func;
pzlib_filefunc_def->zread_file = fread_file_func;
pzlib_filefunc_def->zwrite_file = fwrite_file_func;
pzlib_filefunc_def->ztell64_file = ftell64_file_func;
pzlib_filefunc_def->zseek64_file = fseek64_file_func;
pzlib_filefunc_def->zclose_file = fclose_file_func;
pzlib_filefunc_def->zerror_file = ferror_file_func;
pzlib_filefunc_def->opaque = NULL;
}

200
src/Core/MiniZip/ioapi.h Normal file
View File

@ -0,0 +1,200 @@
/* ioapi.h -- IO base function header for compress/uncompress .zip
part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
Modifications for Zip64 support
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt
Changes
Oct-2009 - Defined ZPOS64_T to fpos_t on windows and u_int64_t on linux. (might need to find a better why for this)
Oct-2009 - Change to fseeko64, ftello64 and fopen64 so large files would work on linux.
More if/def section may be needed to support other platforms
Oct-2009 - Defined fxxxx64 calls to normal fopen/ftell/fseek so they would compile on windows.
(but you should use iowin32.c for windows instead)
*/
#ifndef _ZLIBIOAPI64_H
#define _ZLIBIOAPI64_H
#if (!defined(_WIN32)) && (!defined(WIN32))
// Linux needs this to support file operation on files larger then 4+GB
// But might need better if/def to select just the platforms that needs them.
#ifndef __USE_FILE_OFFSET64
#define __USE_FILE_OFFSET64
#endif
#ifndef __USE_LARGEFILE64
#define __USE_LARGEFILE64
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#ifndef _FILE_OFFSET_BIT
#define _FILE_OFFSET_BIT 64
#endif
#endif
#include <stdio.h>
#include <stdlib.h>
#include "zlib.h"
#if defined(USE_FILE32API)
#define fopen64 fopen
#define ftello64 ftell
#define fseeko64 fseek
#else
#ifdef _MSC_VER
#define fopen64 fopen
#if (_MSC_VER >= 1400) && (!(defined(NO_MSCVER_FILE64_FUNC)))
#define ftello64 _ftelli64
#define fseeko64 _fseeki64
#else // old MSC
#define ftello64 ftell
#define fseeko64 fseek
#endif
#endif
#endif
/*
#ifndef ZPOS64_T
#ifdef _WIN32
#define ZPOS64_T fpos_t
#else
#include <stdint.h>
#define ZPOS64_T uint64_t
#endif
#endif
*/
#ifdef HAVE_MINIZIP64_CONF_H
#include "mz64conf.h"
#endif
/* a type choosen by DEFINE */
#ifdef HAVE_64BIT_INT_CUSTOM
typedef 64BIT_INT_CUSTOM_TYPE ZPOS64_T;
#else
#ifdef HAS_STDINT_H
#include "stdint.h"
typedef uint64_t ZPOS64_T;
#else
#if defined(_MSC_VER) || defined(__BORLANDC__)
typedef unsigned __int64 ZPOS64_T;
#else
typedef unsigned long long int ZPOS64_T;
#endif
#endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
#define ZLIB_FILEFUNC_SEEK_CUR (1)
#define ZLIB_FILEFUNC_SEEK_END (2)
#define ZLIB_FILEFUNC_SEEK_SET (0)
#define ZLIB_FILEFUNC_MODE_READ (1)
#define ZLIB_FILEFUNC_MODE_WRITE (2)
#define ZLIB_FILEFUNC_MODE_READWRITEFILTER (3)
#define ZLIB_FILEFUNC_MODE_EXISTING (4)
#define ZLIB_FILEFUNC_MODE_CREATE (8)
#ifndef ZCALLBACK
#if (defined(WIN32) || defined(_WIN32) || defined (WINDOWS) || defined (_WINDOWS)) && defined(CALLBACK) && defined (USEWINDOWS_CALLBACK)
#define ZCALLBACK CALLBACK
#else
#define ZCALLBACK
#endif
#endif
typedef voidpf (ZCALLBACK *open_file_func) OF((voidpf opaque, const char* filename, int mode));
typedef uLong (ZCALLBACK *read_file_func) OF((voidpf opaque, voidpf stream, void* buf, uLong size));
typedef uLong (ZCALLBACK *write_file_func) OF((voidpf opaque, voidpf stream, const void* buf, uLong size));
typedef int (ZCALLBACK *close_file_func) OF((voidpf opaque, voidpf stream));
typedef int (ZCALLBACK *testerror_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *tell_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *seek_file_func) OF((voidpf opaque, voidpf stream, uLong offset, int origin));
/* here is the "old" 32 bits structure structure */
typedef struct zlib_filefunc_def_s
{
open_file_func zopen_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell_file_func ztell_file;
seek_file_func zseek_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
} zlib_filefunc_def;
typedef ZPOS64_T (ZCALLBACK *tell64_file_func) OF((voidpf opaque, voidpf stream));
typedef long (ZCALLBACK *seek64_file_func) OF((voidpf opaque, voidpf stream, ZPOS64_T offset, int origin));
typedef voidpf (ZCALLBACK *open64_file_func) OF((voidpf opaque, const void* filename, int mode));
typedef struct zlib_filefunc64_def_s
{
open64_file_func zopen64_file;
read_file_func zread_file;
write_file_func zwrite_file;
tell64_file_func ztell64_file;
seek64_file_func zseek64_file;
close_file_func zclose_file;
testerror_file_func zerror_file;
voidpf opaque;
} zlib_filefunc64_def;
void fill_fopen64_filefunc OF((zlib_filefunc64_def* pzlib_filefunc_def));
void fill_fopen_filefunc OF((zlib_filefunc_def* pzlib_filefunc_def));
/* now internal definition, only for zip.c and unzip.h */
typedef struct zlib_filefunc64_32_def_s
{
zlib_filefunc64_def zfile_func64;
open_file_func zopen32_file;
tell_file_func ztell32_file;
seek_file_func zseek32_file;
} zlib_filefunc64_32_def;
#define ZREAD64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zread_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
#define ZWRITE64(filefunc,filestream,buf,size) ((*((filefunc).zfile_func64.zwrite_file)) ((filefunc).zfile_func64.opaque,filestream,buf,size))
//#define ZTELL64(filefunc,filestream) ((*((filefunc).ztell64_file)) ((filefunc).opaque,filestream))
//#define ZSEEK64(filefunc,filestream,pos,mode) ((*((filefunc).zseek64_file)) ((filefunc).opaque,filestream,pos,mode))
#define ZCLOSE64(filefunc,filestream) ((*((filefunc).zfile_func64.zclose_file)) ((filefunc).zfile_func64.opaque,filestream))
#define ZERROR64(filefunc,filestream) ((*((filefunc).zfile_func64.zerror_file)) ((filefunc).zfile_func64.opaque,filestream))
voidpf call_zopen64 OF((const zlib_filefunc64_32_def* pfilefunc,const void*filename,int mode));
long call_zseek64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream, ZPOS64_T offset, int origin));
ZPOS64_T call_ztell64 OF((const zlib_filefunc64_32_def* pfilefunc,voidpf filestream));
void fill_zlib_filefunc64_32_def_from_filefunc32(zlib_filefunc64_32_def* p_filefunc64_32,const zlib_filefunc_def* p_filefunc32);
#define ZOPEN64(filefunc,filename,mode) (call_zopen64((&(filefunc)),(filename),(mode)))
#define ZTELL64(filefunc,filestream) (call_ztell64((&(filefunc)),(filestream)))
#define ZSEEK64(filefunc,filestream,pos,mode) (call_zseek64((&(filefunc)),(filestream),(pos),(mode)))
#ifdef __cplusplus
}
#endif
#endif

2128
src/Core/MiniZip/unzip.c Normal file

File diff suppressed because it is too large Load Diff

437
src/Core/MiniZip/unzip.h Normal file
View File

@ -0,0 +1,437 @@
/* unzip.h -- IO for uncompress .zip files using zlib
Version 1.1, February 14h, 2010
part of the MiniZip project - ( http://www.winimage.com/zLibDll/minizip.html )
Copyright (C) 1998-2010 Gilles Vollant (minizip) ( http://www.winimage.com/zLibDll/minizip.html )
Modifications of Unzip for Zip64
Copyright (C) 2007-2008 Even Rouault
Modifications for Zip64 support on both zip and unzip
Copyright (C) 2009-2010 Mathias Svensson ( http://result42.com )
For more info read MiniZip_info.txt
---------------------------------------------------------------------------------
Condition of use and distribution are the same than zlib :
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
---------------------------------------------------------------------------------
Changes
See header of unzip64.c
*/
#ifndef _unz64_H
#define _unz64_H
#ifdef __cplusplus
extern "C" {
#endif
#ifndef _ZLIB_H
#include "zlib.h"
#endif
#ifndef _ZLIBIOAPI_H
#include "ioapi.h"
#endif
#ifdef HAVE_BZIP2
#include "bzlib.h"
#endif
#define Z_BZIP2ED 12
#if defined(STRICTUNZIP) || defined(STRICTZIPUNZIP)
/* like the STRICT of WIN32, we define a pointer that cannot be converted
from (void*) without cast */
typedef struct TagunzFile__ { int unused; } unzFile__;
typedef unzFile__ *unzFile;
#else
typedef voidp unzFile;
#endif
#define UNZ_OK (0)
#define UNZ_END_OF_LIST_OF_FILE (-100)
#define UNZ_ERRNO (Z_ERRNO)
#define UNZ_EOF (0)
#define UNZ_PARAMERROR (-102)
#define UNZ_BADZIPFILE (-103)
#define UNZ_INTERNALERROR (-104)
#define UNZ_CRCERROR (-105)
/* tm_unz contain date/time info */
typedef struct tm_unz_s
{
uInt tm_sec; /* seconds after the minute - [0,59] */
uInt tm_min; /* minutes after the hour - [0,59] */
uInt tm_hour; /* hours since midnight - [0,23] */
uInt tm_mday; /* day of the month - [1,31] */
uInt tm_mon; /* months since January - [0,11] */
uInt tm_year; /* years - [1980..2044] */
} tm_unz;
/* unz_global_info structure contain global data about the ZIPfile
These data comes from the end of central dir */
typedef struct unz_global_info64_s
{
ZPOS64_T number_entry; /* total number of entries in
the central dir on this disk */
uLong size_comment; /* size of the global comment of the zipfile */
} unz_global_info64;
typedef struct unz_global_info_s
{
uLong number_entry; /* total number of entries in
the central dir on this disk */
uLong size_comment; /* size of the global comment of the zipfile */
} unz_global_info;
/* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_info64_s
{
uLong version; /* version made by 2 bytes */
uLong version_needed; /* version needed to extract 2 bytes */
uLong flag; /* general purpose bit flag 2 bytes */
uLong compression_method; /* compression method 2 bytes */
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
uLong crc; /* crc-32 4 bytes */
ZPOS64_T compressed_size; /* compressed size 8 bytes */
ZPOS64_T uncompressed_size; /* uncompressed size 8 bytes */
uLong size_filename; /* filename length 2 bytes */
uLong size_file_extra; /* extra field length 2 bytes */
uLong size_file_comment; /* file comment length 2 bytes */
uLong disk_num_start; /* disk number start 2 bytes */
uLong internal_fa; /* internal file attributes 2 bytes */
uLong external_fa; /* external file attributes 4 bytes */
tm_unz tmu_date;
} unz_file_info64;
typedef struct unz_file_info_s
{
uLong version; /* version made by 2 bytes */
uLong version_needed; /* version needed to extract 2 bytes */
uLong flag; /* general purpose bit flag 2 bytes */
uLong compression_method; /* compression method 2 bytes */
uLong dosDate; /* last mod file date in Dos fmt 4 bytes */
uLong crc; /* crc-32 4 bytes */
uLong compressed_size; /* compressed size 4 bytes */
uLong uncompressed_size; /* uncompressed size 4 bytes */
uLong size_filename; /* filename length 2 bytes */
uLong size_file_extra; /* extra field length 2 bytes */
uLong size_file_comment; /* file comment length 2 bytes */
uLong disk_num_start; /* disk number start 2 bytes */
uLong internal_fa; /* internal file attributes 2 bytes */
uLong external_fa; /* external file attributes 4 bytes */
tm_unz tmu_date;
} unz_file_info;
extern int ZEXPORT unzStringFileNameCompare OF ((const char* fileName1,
const char* fileName2,
int iCaseSensitivity));
/*
Compare two filename (fileName1,fileName2).
If iCaseSenisivity = 1, comparision is case sensitivity (like strcmp)
If iCaseSenisivity = 2, comparision is not case sensitivity (like strcmpi
or strcasecmp)
If iCaseSenisivity = 0, case sensitivity is defaut of your operating system
(like 1 on Unix, 2 on Windows)
*/
extern unzFile ZEXPORT unzOpen OF((const char *path));
extern unzFile ZEXPORT unzOpen64 OF((const void *path));
/*
Open a Zip file. path contain the full pathname (by example,
on a Windows XP computer "c:\\zlib\\zlib113.zip" or on an Unix computer
"zlib/zlib113.zip".
If the zipfile cannot be opened (file don't exist or in not valid), the
return value is NULL.
Else, the return value is a unzFile Handle, usable with other function
of this unzip package.
the "64" function take a const void* pointer, because the path is just the
value passed to the open64_file_func callback.
Under Windows, if UNICODE is defined, using fill_fopen64_filefunc, the path
is a pointer to a wide unicode string (LPCTSTR is LPCWSTR), so const char*
does not describe the reality
*/
extern unzFile ZEXPORT unzOpen2 OF((const char *path,
zlib_filefunc_def* pzlib_filefunc_def));
/*
Open a Zip file, like unzOpen, but provide a set of file low level API
for read/write the zip file (see ioapi.h)
*/
extern unzFile ZEXPORT unzOpen2_64 OF((const void *path,
zlib_filefunc64_def* pzlib_filefunc_def));
/*
Open a Zip file, like unz64Open, but provide a set of file low level API
for read/write the zip file (see ioapi.h)
*/
extern int ZEXPORT unzClose OF((unzFile file));
/*
Close a ZipFile opened with unzipOpen.
If there is files inside the .Zip opened with unzOpenCurrentFile (see later),
these files MUST be closed with unzipCloseCurrentFile before call unzipClose.
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalInfo OF((unzFile file,
unz_global_info *pglobal_info));
extern int ZEXPORT unzGetGlobalInfo64 OF((unzFile file,
unz_global_info64 *pglobal_info));
/*
Write info about the ZipFile in the *pglobal_info structure.
No preparation of the structure is needed
return UNZ_OK if there is no problem. */
extern int ZEXPORT unzGetGlobalComment OF((unzFile file,
char *szComment,
uLong uSizeBuf));
/*
Get the global comment string of the ZipFile, in the szComment buffer.
uSizeBuf is the size of the szComment buffer.
return the number of byte copied or an error code <0
*/
/***************************************************************************/
/* Unzip package allow you browse the directory of the zipfile */
extern int ZEXPORT unzGoToFirstFile OF((unzFile file));
/*
Set the current file of the zipfile to the first file.
return UNZ_OK if there is no problem
*/
extern int ZEXPORT unzGoToNextFile OF((unzFile file));
/*
Set the current file of the zipfile to the next file.
return UNZ_OK if there is no problem
return UNZ_END_OF_LIST_OF_FILE if the actual file was the latest.
*/
extern int ZEXPORT unzLocateFile OF((unzFile file,
const char *szFileName,
int iCaseSensitivity));
/*
Try locate the file szFileName in the zipfile.
For the iCaseSensitivity signification, see unzStringFileNameCompare
return value :
UNZ_OK if the file is found. It becomes the current file.
UNZ_END_OF_LIST_OF_FILE if the file is not found
*/
/* ****************************************** */
/* Ryan supplied functions */
/* unz_file_info contain information about a file in the zipfile */
typedef struct unz_file_pos_s
{
uLong pos_in_zip_directory; /* offset in zip file directory */
uLong num_of_file; /* # of file */
} unz_file_pos;
extern int ZEXPORT unzGetFilePos(
unzFile file,
unz_file_pos* file_pos);
extern int ZEXPORT unzGoToFilePos(
unzFile file,
unz_file_pos* file_pos);
typedef struct unz64_file_pos_s
{
ZPOS64_T pos_in_zip_directory; /* offset in zip file directory */
ZPOS64_T num_of_file; /* # of file */
} unz64_file_pos;
extern int ZEXPORT unzGetFilePos64(
unzFile file,
unz64_file_pos* file_pos);
extern int ZEXPORT unzGoToFilePos64(
unzFile file,
const unz64_file_pos* file_pos);
/* ****************************************** */
extern int ZEXPORT unzGetCurrentFileInfo64 OF((unzFile file,
unz_file_info64 *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize));
extern int ZEXPORT unzGetCurrentFileInfo OF((unzFile file,
unz_file_info *pfile_info,
char *szFileName,
uLong fileNameBufferSize,
void *extraField,
uLong extraFieldBufferSize,
char *szComment,
uLong commentBufferSize));
/*
Get Info about the current file
if pfile_info!=NULL, the *pfile_info structure will contain somes info about
the current file
if szFileName!=NULL, the filemane string will be copied in szFileName
(fileNameBufferSize is the size of the buffer)
if extraField!=NULL, the extra field information will be copied in extraField
(extraFieldBufferSize is the size of the buffer).
This is the Central-header version of the extra field
if szComment!=NULL, the comment string of the file will be copied in szComment
(commentBufferSize is the size of the buffer)
*/
/** Addition for GDAL : START */
extern ZPOS64_T ZEXPORT unzGetCurrentFileZStreamPos64 OF((unzFile file));
/** Addition for GDAL : END */
/***************************************************************************/
/* for reading the content of the current zipfile, you can open it, read data
from it, and close it (you can close it before reading all the file)
*/
extern int ZEXPORT unzOpenCurrentFile OF((unzFile file));
/*
Open for reading data the current file in the zipfile.
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFilePassword OF((unzFile file,
const char* password));
/*
Open for reading data the current file in the zipfile.
password is a crypting password
If there is no error, the return value is UNZ_OK.
*/
extern int ZEXPORT unzOpenCurrentFile2 OF((unzFile file,
int* method,
int* level,
int raw));
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
*method will receive method of compression, *level will receive level of
compression
note : you can set level parameter as NULL (if you did not want known level,
but you CANNOT set method parameter as NULL
*/
extern int ZEXPORT unzOpenCurrentFile3 OF((unzFile file,
int* method,
int* level,
int raw,
const char* password));
/*
Same than unzOpenCurrentFile, but open for read raw the file (not uncompress)
if raw==1
*method will receive method of compression, *level will receive level of
compression
note : you can set level parameter as NULL (if you did not want known level,
but you CANNOT set method parameter as NULL
*/
extern int ZEXPORT unzCloseCurrentFile OF((unzFile file));
/*
Close the file in zip opened with unzOpenCurrentFile
Return UNZ_CRCERROR if all the file was read but the CRC is not good
*/
extern int ZEXPORT unzReadCurrentFile OF((unzFile file,
voidp buf,
unsigned len));
/*
Read bytes from the current file (opened by unzOpenCurrentFile)
buf contain buffer where data must be copied
len the size of buf.
return the number of byte copied if somes bytes are copied
return 0 if the end of file was reached
return <0 with error code if there is an error
(UNZ_ERRNO for IO error, or zLib error for uncompress error)
*/
extern z_off_t ZEXPORT unztell OF((unzFile file));
extern ZPOS64_T ZEXPORT unztell64 OF((unzFile file));
/*
Give the current position in uncompressed data
*/
extern int ZEXPORT unzeof OF((unzFile file));
/*
return 1 if the end of file was reached, 0 elsewhere
*/
extern int ZEXPORT unzGetLocalExtrafield OF((unzFile file,
voidp buf,
unsigned len));
/*
Read extra field from the current file (opened by unzOpenCurrentFile)
This is the local-header version of the extra field (sometimes, there is
more info in the local-header version than in the central-header)
if buf==NULL, it return the size of the local extra field
if buf!=NULL, len is the size of the buffer, the extra header is copied in
buf.
the return value is the number of bytes copied in buf, or (if <0)
the error code
*/
/***************************************************************************/
/* Get the current file offset */
extern ZPOS64_T ZEXPORT unzGetOffset64 (unzFile file);
extern uLong ZEXPORT unzGetOffset (unzFile file);
/* Set the current file offset */
extern int ZEXPORT unzSetOffset64 (unzFile file, ZPOS64_T pos);
extern int ZEXPORT unzSetOffset (unzFile file, uLong pos);
#ifdef __cplusplus
}
#endif
#endif /* _unz64_H */

View File

@ -0,0 +1,37 @@
/*
NSDataOOExtensions.h
Extensions to NSData.
Copyright (C) 2008-2013 Jens Ayton and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOCocoa.h"
@interface NSData (OOExtensions)
+ (instancetype) oo_dataWithOXZFile:(NSString *)path;
@end

View File

@ -0,0 +1,166 @@
/*
NSDataOOExtensions.m
Extensions to NSData.
Copyright (C) 2008-2013 Jens Ayton and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOCocoa.h"
#import "unzip.h"
#define ZIP_BUFFER_SIZE 8192
@implementation NSData (OOExtensions)
+ (instancetype) oo_dataWithOXZFile:(NSString *)path
{
unsigned i, cl;
NSArray *components = [path pathComponents];
cl = [components count];
for (i = 0 ; i < cl ; i++)
{
NSString *component = [components objectAtIndex:i];
if ([[[component pathExtension] lowercaseString] isEqualToString:@"oxz"])
{
break;
}
}
// if i == cl then the path is entirely uncompressed
if (i == cl)
{
/* -initWithContentsOfMappedFile fails quietly under OS X if there's no file,
but GNUstep complains. */
#if OOLITE_MAC_OS_X
return [[[NSData alloc] initWithContentsOfMappedFile:path] autorelease];
#else
NSFileManager *fmgr = [NSFileManager defaultManager];
BOOL dir;
if ([fmgr fileExistsAtPath:path isDirectory:&dir])
{
if (!dir)
{
if ([[fmgr fileAttributesAtPath:path traverseLink:NO] fileSize] == 0)
{
OOLog(kOOLogFileNotFound, @"Expected file but found empty file at %@", path);
}
else
{
return [[[NSData alloc] initWithContentsOfMappedFile:path] autorelease];
}
}
else
{
OOLog(kOOLogFileNotFound, @"Expected file but found directory at %@", path);
}
}
return nil;
#endif
}
// otherwise components 0..i are the OXZ path, and i+1..n are the
// path inside the OXZ
NSRange range;
range.location = 0; range.length = i+1;
NSString *zipFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
range.location = i+1; range.length = cl-(i+1);
NSString *containedFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
unzFile uf = NULL;
const char* zipname = [zipFile UTF8String];
if (zipname != NULL)
{
uf = unzOpen64(zipname);
}
if (uf == NULL)
{
OOLog(kOOLogFileNotFound, @"Could not unzip OXZ at %@", zipFile);
return nil;
}
const char* filename = [containedFile UTF8String];
// unzLocateFile(*, *, 1) = case-sensitive extract
if (unzLocateFile(uf, filename, 1) != UNZ_OK)
{
unzClose(uf);
/* Much of the time this function is called with the
* expectation that the file may not necessarily exist -
* e.g. on plist merges, config scans, etc. So don't add log
* entries for this failure mode */
// OOLog(kOOLogFileNotFound, @"Could not find %@ within OXZ at %@", containedFile, zipFile);
return nil;
}
int err = UNZ_OK;
unz_file_info64 file_info = {0};
err = unzGetCurrentFileInfo64(uf, &file_info, NULL, 0, NULL, 0, NULL, 0);
if (err != UNZ_OK)
{
unzClose(uf);
OOLog(kOOLogFileNotFound, @"Could not get properties of %@ within OXZ at %@", containedFile, zipFile);
return nil;
}
err = unzOpenCurrentFile(uf);
if (err != UNZ_OK)
{
unzClose(uf);
OOLog(kOOLogFileNotFound, @"Could not read %@ within OXZ at %@", containedFile, zipFile);
return nil;
}
NSMutableData *tmp = [NSMutableData dataWithCapacity:file_info.uncompressed_size];
void *buf = (void*)malloc(ZIP_BUFFER_SIZE);
do
{
err = unzReadCurrentFile(uf, buf, ZIP_BUFFER_SIZE);
if (err < 0)
{
OOLog(kOOLogFileNotFound, @"Could not read %@ within OXZ at %@ (err %d)", containedFile, zipFile, err);
break;
}
if (err == 0)
{
break;
}
[tmp appendBytes:buf length:err];
}
while (err > 0);
free(buf);
err = unzCloseCurrentFile(uf);
if (err != UNZ_OK)
{
unzClose(uf);
OOLog(kOOLogFileNotFound, @"Could not close %@ within OXZ at %@", containedFile, zipFile);
return nil;
}
unzClose(uf);
return [[tmp retain] autorelease];
}
@end

View File

@ -4,7 +4,7 @@ NSFileManagerOOExtensions.h
This extends NSFileManager and adds some methods to insulate the
main oolite code from the gory details of creating/chdiring to the
commander save directory.
commander save directory, as well as handling OXZ inspection
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
@ -54,6 +54,9 @@ MA 02110-1301, USA.
- (BOOL) chdirToSnapshotPath;
#endif
// this also checks inside OXZ files; always returns NO for directories
- (BOOL) oo_oxzFileExistsAtPath:(NSString *)path;
@end

View File

@ -31,7 +31,7 @@ MA 02110-1301, USA.
#import "OOPListParsing.h"
#import "GameController.h"
#import "NSFileManagerOOExtensions.h"
#import "unzip.h"
@implementation NSFileManager (OOExtensions)
@ -227,6 +227,77 @@ MA 02110-1301, USA.
}
#endif
- (BOOL) oo_oxzFileExistsAtPath:(NSString *)path
{
unsigned i, cl;
NSArray *components = [path pathComponents];
cl = [components count];
for (i = 0 ; i < cl ; i++)
{
NSString *component = [components objectAtIndex:i];
if ([[[component pathExtension] lowercaseString] isEqualToString:@"oxz"])
{
break;
}
}
// if i == cl then the path is entirely uncompressed
if (i == cl)
{
BOOL directory = NO;
BOOL result = [self fileExistsAtPath:path isDirectory:&directory];
if (directory)
{
return NO;
}
return result;
}
NSRange range;
range.location = 0; range.length = i+1;
NSString *zipFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
range.location = i+1; range.length = cl-(i+1);
NSString *containedFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
unzFile uf = NULL;
const char* zipname = [zipFile cStringUsingEncoding:NSUTF8StringEncoding];
if (zipname != NULL)
{
uf = unzOpen64(zipname);
}
if (uf == NULL)
{
// no such zip file
return NO;
}
const char* filename = [containedFile cStringUsingEncoding:NSUTF8StringEncoding];
// unzLocateFile(*, *, 1) = case-sensitive extract
BOOL result = YES;
if (unzLocateFile(uf, filename, 1) != UNZ_OK)
{
result = NO;
}
else
{
int err = UNZ_OK;
unz_file_info64 file_info = {0};
err = unzGetCurrentFileInfo64(uf, &file_info, NULL, 0, NULL, 0, NULL, 0);
if (err != UNZ_OK)
{
result = NO;
}
else
{
}
}
unzClose(uf);
return result;
}
@end

View File

@ -23,6 +23,7 @@ MA 02110-1301, USA.
*/
#import "NSStringOOExtensions.h"
#import "NSDataOOExtensions.h"
#import "OOCocoa.h"
@ -38,7 +39,7 @@ MA 02110-1301, USA.
const uint8_t *effectiveBytes = NULL;
size_t effectiveLength = 0;
data = [[NSData alloc] initWithContentsOfFile:path];
data = [[NSData oo_dataWithOXZFile:path] retain];
if (data == nil) OK = NO;
if (OK)

View File

@ -0,0 +1,43 @@
/*
OOALBufferedSound.h
OOALBufferedSound - OpenAL sound implementation for Oolite.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOSound.h"
#import "OOALSoundDecoder.h"
@interface OOALBufferedSound: OOSound
{
@private
char *_buffer;
size_t _size;
double _sampleRate;
NSString *_name;
BOOL _stereo;
}
- (id)initWithDecoder:(OOALSoundDecoder *)inDecoder;
@end

View File

@ -0,0 +1,103 @@
/*
OOALBufferedSound.m
OOALBufferedSound - OpenAL sound implementation for Oolite.
Copyright (C) 2005-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOALBufferedSound.h"
#import "OOALSoundDecoder.h"
@implementation OOALBufferedSound
- (void)dealloc
{
free(_buffer);
_buffer = NULL;
[super dealloc];
}
- (NSString *)name
{
return _name;
}
- (id)initWithDecoder:(OOALSoundDecoder *)inDecoder
{
BOOL OK = YES;
[OOSound setUp];
if (![OOSound isSoundOK] || nil == inDecoder) OK = NO;
if (OK)
{
self = [super init];
if (nil == self) OK = NO;
}
if (OK)
{
_name = [[inDecoder name] copy];
_sampleRate = [inDecoder sampleRate];
OK = [inDecoder readCreatingBuffer:&_buffer withFrameCount:&_size];
_stereo = [inDecoder isStereo];
}
if (!OK)
{
[self release];
self = nil;
}
return self;
}
- (ALuint) soundBuffer
{
ALuint buffer;
ALint error;
OOAL(alGenBuffers(1,&buffer));
if ((error = alGetError()) != AL_NO_ERROR)
{
OOLog(kOOLogSoundLoadingError,@"Could not create OpenAL buffer");
return 0;
}
else
{
if (!_stereo)
{
alBufferData(buffer,AL_FORMAT_MONO16,_buffer,_size,_sampleRate);
}
else
{
alBufferData(buffer,AL_FORMAT_STEREO16,_buffer,_size,_sampleRate);
}
return buffer;
}
}
@end

46
src/Core/OOALMusic.h Normal file
View File

@ -0,0 +1,46 @@
/*
OOALMusic.h
Subclass of OOSound with additional controls specific to music playback. Only
one instance of OOMusic may be playing at a time.
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2005-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "OOALSound.h"
@interface OOMusic: OOSound
{
@private
OOSound *sound;
}
- (void) playLooped:(BOOL)looped;
- (void) stop;
- (BOOL) isPlaying;
@end

108
src/Core/OOALMusic.m Normal file
View File

@ -0,0 +1,108 @@
/*
OOALMusic.m
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2005-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOALMusic.h"
#import "OOSoundSource.h"
static OOMusic *sPlayingMusic = nil;
static OOSoundSource *sMusicSource = nil;
@implementation OOMusic
+ (id)allocWithZone:(NSZone *)inZone
{
return NSAllocateObject([OOMusic class], 0, inZone);
}
- (void)dealloc
{
if (sPlayingMusic == self) [self stop];
[sound release];
[super dealloc];
}
- (id)initWithContentsOfFile:(NSString *)inPath
{
self = [super init];
if (nil != self)
{
sound = [[OOSound alloc] initWithContentsOfFile:inPath];
if (nil == sound)
{
[self release];
self = nil;
}
}
return self;
}
- (NSString *)name
{
return [sound name];
}
- (void)playLooped:(BOOL)inLoop
{
if (sPlayingMusic != self)
{
if (nil == sMusicSource)
{
sMusicSource = [[OOSoundSource alloc] init];
}
[sMusicSource stop];
[sMusicSource setLoop:inLoop];
[sMusicSource setSound:sound];
[sMusicSource play];
sPlayingMusic = self;
}
}
- (BOOL)isPlaying
{
return sPlayingMusic == self && [sMusicSource isPlaying];
}
- (void)stop
{
if (sPlayingMusic == self)
{
sPlayingMusic = nil;
[sMusicSource stop];
}
}
@end

48
src/Core/OOALSound.h Normal file
View File

@ -0,0 +1,48 @@
/*
OOALSound.h
OOALSound - OpenAL sound implementation for Oolite.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "OOOpenALController.h"
@interface OOSound: NSObject
+ (BOOL) setUp;
+ (void) update;
+ (void) setMasterVolume:(float) fraction;
+ (float) masterVolume;
- (id) initWithContentsOfFile:(NSString *)path;
- (NSString *)name;
+ (BOOL) isSoundOK;
- (ALuint) soundBuffer;
- (BOOL) soundIncomplete;
- (void) rewind;
@end

176
src/Core/OOALSound.m Normal file
View File

@ -0,0 +1,176 @@
/*
OOALSound.m
OOALSound - OpenAL sound implementation for Oolite.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOALSound.h"
#import "OOLogging.h"
#import "OOCollectionExtractors.h"
#import "OOMaths.h"
#import "OOALSoundDecoder.h"
#import "OOOpenALController.h"
#import "OOALBufferedSound.h"
#import "OOALStreamedSound.h"
#import "OOALSoundMixer.h"
#define KEY_VOLUME_CONTROL @"volume_control"
static const size_t kMaxBufferedSoundSize = 1 << 20; // 1 MB
static BOOL sIsSetUp = NO;
static BOOL sIsSoundOK = NO;
@implementation OOSound
+ (BOOL) setUp
{
if (!sIsSetUp)
{
sIsSetUp = YES;
OOOpenALController* controller = [OOOpenALController sharedController];
if (controller != nil)
{
sIsSoundOK = YES;
}
}
return sIsSoundOK;
}
+ (void) setMasterVolume:(float) fraction
{
if (!sIsSetUp && ![self setUp])
return;
fraction = OOClamp_0_1_f(fraction);
OOOpenALController *controller = [OOOpenALController sharedController];
if (fraction != [controller masterVolume])
{
[controller setMasterVolume:fraction];
[[NSUserDefaults standardUserDefaults] setFloat:[controller masterVolume] forKey:KEY_VOLUME_CONTROL];
}
}
+ (float) masterVolume
{
if (!sIsSetUp && ![self setUp] )
return 0.0;
OOOpenALController *controller = [OOOpenALController sharedController];
return [controller masterVolume];
}
- (id) init
{
if (!sIsSetUp) [OOSound setUp];
return [super init];
}
- (id) initWithContentsOfFile:(NSString *)path
{
[self release];
if (!sIsSetUp && ![OOSound setUp]) return nil;
OOALSoundDecoder *decoder;
decoder = [[OOALSoundDecoder alloc] initWithPath:path];
if (nil == decoder) return nil;
if ([decoder sizeAsBuffer] <= kMaxBufferedSoundSize)
{
self = [[OOALBufferedSound alloc] initWithDecoder:decoder];
}
else
{
self = [[OOALStreamedSound alloc] initWithDecoder:decoder];
}
[decoder release];
if (nil != self)
{
#ifndef NDEBUG
OOLog(kOOLogSoundLoadingSuccess, @"Loaded sound %@", path);
#endif
}
else
{
OOLog(kOOLogSoundLoadingError, @"Failed to load sound \"%@\"", path);
}
return self;
}
- (id)initWithDecoder:(OOALSoundDecoder *)inDecoder
{
[self release];
return nil;
}
- (NSString *)name
{
OOLogGenericSubclassResponsibility();
return @"";
}
+ (void) update
{
OOSoundMixer * mixer = [OOSoundMixer sharedMixer];
if( sIsSoundOK && mixer)
[mixer update];
}
+ (BOOL) isSoundOK
{
return sIsSoundOK;
}
- (ALuint) soundBuffer
{
OOLogGenericSubclassResponsibility();
return 0;
}
- (BOOL) soundIncomplete
{
return NO;
}
- (void) rewind
{
// doesn't need to do anything on seekable FDs
}
@end

View File

@ -0,0 +1,76 @@
/*
OOALSoundChannel.h
A channel for audio playback.
This class is an implementation detail. Do not use it directly; use an
OOSoundSource to play an OOSound.
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2006-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import <Foundation/Foundation.h>
#import "OOOpenALController.h"
#import "OOMaths.h"
@class OOSound;
@interface OOSoundChannel: NSObject
{
OOSoundChannel *_next;
id _delegate;
OOSound *_sound;
ALuint _buffer;
ALuint _lastBuffer;
BOOL _bigSound;
ALuint _source;
BOOL _playing;
BOOL _loop;
}
- (void) update;
- (void) setDelegate:(id)delegate;
// Unretained pointer used to maintain simple stack
- (OOSoundChannel *) next;
- (void) setNext:(OOSoundChannel *)next;
// set sound position relative to listener
- (void) setPosition:(Vector) vector;
- (void) setGain:(float) gain;
- (BOOL) playSound:(OOSound *)sound looped:(BOOL)loop;
- (void)stop;
- (OOSound *)sound;
@end
@interface NSObject(OOSoundChannelDelegate)
- (void)channel:(OOSoundChannel *)inChannel didFinishPlayingSound:(OOSound *)inSound;
@end

247
src/Core/OOALSoundChannel.m Normal file
View File

@ -0,0 +1,247 @@
/*
OOALSoundChannel.m
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2006-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOALSoundChannel.h"
#import "OOALSound.h"
#import "OOLogging.h"
#import "OOMaths.h"
@interface OOSoundChannel (Private)
- (BOOL) enqueueBuffer:(OOSound *)sound;
- (void) hasStopped;
- (void) getNextSoundBuffer;
@end
@implementation OOSoundChannel
- (id) init
{
if ((self = [super init]))
{
ALuint error;
OOAL(alGenSources(1,&_source));
if ((error = alGetError()) != AL_NO_ERROR)
{
OOLog(kOOLogSoundInitError, @"Could not create OpenAL source");
[self release];
self = nil;
}
// sources are all relative to listener, defaulting to zero vector
OOAL(alSourcei(_source, AL_SOURCE_RELATIVE, AL_TRUE));
OOAL(alSource3f(_source, AL_POSITION, 0.0f, 0.0f, 0.0f));
}
return self;
}
- (void) dealloc
{
[self hasStopped]; // make sure buffers are dequeued and deleted
OOAL(alDeleteSources(1, &_source));
[super dealloc];
}
- (void) update
{
// Check if we've reached the end of a sound.
if (_sound != nil)
{
ALint check;
OOAL(alGetSourcei(_source,AL_SOURCE_STATE,&check));
if (check == AL_STOPPED)
{
[self hasStopped];
}
else if ([_sound soundIncomplete]) // streaming and not finished loading
{
OOLog(@"sound.buffer", @"Incomplete, trying next for %@", [_sound name]);
[self getNextSoundBuffer];
}
else if (_loop)
{
OOLog(@"sound.buffer", @"Looping, trying restart for %@", [_sound name]);
// sound is complete, but needs to be looped, so start it again
[_sound rewind];
[self getNextSoundBuffer];
}
}
}
- (void) getNextSoundBuffer
{
if (!_bigSound)
{
// we've only loaded one buffer so far
_bigSound = YES;
_lastBuffer = _buffer;
[self enqueueBuffer:_sound];
}
else
{
// _lastBuffer has something in it, so only queue up
// another one if we've finished with that
ALint processed = 0;
OOAL(alGetSourcei(_source, AL_BUFFERS_PROCESSED, &processed));
if (processed > 0) // slot free
{
// dequeue and delete lastBuffer
ALuint buffer;
OOAL(alSourceUnqueueBuffers(_source, 1, &buffer));
assert(buffer == _lastBuffer);
OOAL(alDeleteBuffers(1,&_lastBuffer));
// shuffle along, and grab the next bit
_lastBuffer = _buffer;
[self enqueueBuffer:_sound];
}
}
}
- (void) setDelegate:(id)delegate
{
_delegate = delegate;
}
- (OOSoundChannel *) next
{
return _next;
}
- (void) setNext:(OOSoundChannel *)next
{
_next = next;
}
- (void) setPosition:(Vector) vector
{
OOAL(alSource3f(_source, AL_POSITION, vector.x, vector.y, vector.z));
}
- (void) setGain:(float) gain
{
OOAL(alSourcef(_source, AL_GAIN, gain));
}
- (BOOL) playSound:(OOSound *)sound looped:(BOOL)loop
{
if (sound == nil) return NO;
if (_sound != nil) [self stop];
_loop = loop;
_bigSound = NO;
[sound rewind];
if ([self enqueueBuffer:sound])
{
_sound = [sound retain];
return YES;
}
else
{
return NO;
}
}
- (void) stop
{
if (_sound != nil)
{
OOAL(alSourceStop(_source));
[self hasStopped];
}
}
- (void) hasStopped
{
OOAL(alDeleteBuffers(1,&_buffer));
if (_bigSound)
{
// then we have two buffers to cleanup
OOAL(alDeleteBuffers(1,&_lastBuffer));
}
_bigSound = NO;
ALint queued;
OOAL(alGetSourcei(_source, AL_BUFFERS_QUEUED, &queued));
while (queued--)
{
ALuint buffer;
OOAL(alSourceUnqueueBuffers(_source, 1, &buffer));
}
OOSound *sound = _sound;
_sound = nil;
if (nil != _delegate && [_delegate respondsToSelector:@selector(channel:didFinishPlayingSound:)])
{
[_delegate channel:self didFinishPlayingSound:sound];
}
[sound release];
}
- (BOOL) enqueueBuffer:(OOSound *)sound
{
// get sound data
_buffer = [sound soundBuffer];
// bind sound data to buffer
OOAL(alSourceQueueBuffers(_source, 1, &_buffer));
ALuint error;
if ((error = alGetError()) != AL_NO_ERROR)
{
OOLog(@"ov.debug",@"Error %d queueing buffers",error);
return NO;
}
OOAL(alSourcePlay(_source));
if ((error = alGetError()) != AL_NO_ERROR)
{
OOLog(@"ov.debug",@"Error %d playing source",error);
return NO;
}
return YES;
}
- (OOSound *)sound
{
return _sound;
}
@end

View File

@ -0,0 +1,60 @@
/*
OOALSoundDecoder.h
Class responsible for converting a sound to a PCM buffer for playback. This
class is an implementation detail. Do not use it directly; use OOSound to
load sounds.
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2005-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import <Foundation/Foundation.h>
#define OOAL_STREAM_CHUNK_SIZE (sizeof(char) * 409600)
@interface OOALSoundDecoder: NSObject
- (id)initWithPath:(NSString *)inPath;
+ (OOALSoundDecoder *)codecWithPath:(NSString *)inPath;
// Full-buffer reading.
- (BOOL)readCreatingBuffer:(char **)outBuffer withFrameCount:(size_t *)outSize;
// Stream reading.
- (size_t)streamToBuffer:(char *)buffer;
// Returns the size of the data -readMonoCreatingBuffer:withFrameCount: will create.
- (size_t)sizeAsBuffer;
- (BOOL)isStereo;
- (long)sampleRate;
// For streaming
- (void) reset;
- (NSString *)name;
@end

514
src/Core/OOALSoundDecoder.m Normal file
View File

@ -0,0 +1,514 @@
/*
OOALSoundDecoder.m
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2005-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOALSoundDecoder.h"
#import "NSDataOOExtensions.h"
#import <vorbis/vorbisfile.h>
#import "OOLogging.h"
#import "unzip.h"
enum
{
kMaxDecodeSize = 1 << 20 // 2^20 frames = 4 MB
};
static size_t OOReadOXZVorbis (void *ptr, size_t size, size_t nmemb, void *datasource);
static int OOCloseOXZVorbis (void *datasource);
// not practical to implement these
//static int OOSeekOXZVorbis (void *datasource, ogg_int64_t offset, int whence);
//static long OOTellOXZVorbis (void *datasource);
@interface OOALSoundVorbisCodec: OOALSoundDecoder
{
OggVorbis_File _vf;
NSString *_name;
BOOL _readStarted;
BOOL _seekableStream;
@public
unzFile uf;
}
- (NSDictionary *)comments;
@end
@implementation OOALSoundDecoder
- (id)initWithPath:(NSString *)inPath
{
[self release];
self = nil;
if ([[inPath pathExtension] isEqual:@"ogg"])
{
self = [[OOALSoundVorbisCodec alloc] initWithPath:inPath];
}
return self;
}
+ (OOALSoundDecoder *)codecWithPath:(NSString *)inPath
{
if ([[inPath pathExtension] isEqual:@"ogg"])
{
return [[[OOALSoundVorbisCodec alloc] initWithPath:inPath] autorelease];
}
return nil;
}
- (size_t)streamToBuffer:(char *)ioBuffer
{
return 0;
}
- (BOOL)readCreatingBuffer:(char **)outBuffer withFrameCount:(size_t *)outSize
{
if (NULL != outBuffer) *outBuffer = NULL;
if (NULL != outSize) *outSize = 0;
return NO;
}
- (size_t)sizeAsBuffer
{
return 0;
}
- (BOOL)isStereo
{
return NO;
}
- (long)sampleRate
{
return 0;
}
- (void) reset
{
// nothing
}
- (NSString *)name
{
return @"";
}
@end
@implementation OOALSoundVorbisCodec
- (id)initWithPath:(NSString *)path
{
if ((self = [super init]))
{
BOOL OK = NO;
_name = [[path lastPathComponent] retain];
unsigned i, cl;
NSArray *components = [path pathComponents];
cl = [components count];
for (i = 0 ; i < cl ; i++)
{
NSString *component = [components objectAtIndex:i];
if ([[[component pathExtension] lowercaseString] isEqualToString:@"oxz"])
{
break;
}
}
// if i == cl then the path is entirely uncompressed
if (i == cl)
{
/* Get vorbis data from a standard file stream */
int err;
FILE *file;
_seekableStream = YES;
if (nil != path)
{
file = fopen([path UTF8String], "rb");
if (NULL != file)
{
err = ov_open_callbacks(file, &_vf, NULL, 0, OV_CALLBACKS_DEFAULT);
if (0 == err)
{
OK = YES;
}
}
}
if (!OK)
{
[self release];
self = nil;
}
}
else
{
_seekableStream = NO;
NSRange range;
range.location = 0; range.length = i+1;
NSString *zipFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
range.location = i+1; range.length = cl-(i+1);
NSString *containedFile = [NSString pathWithComponents:[components subarrayWithRange:range]];
const char* zipname = [zipFile UTF8String];
if (zipname != NULL)
{
uf = unzOpen64(zipname);
}
if (uf == NULL)
{
OOLog(kOOLogFileNotFound, @"Could not unzip OXZ at %@", zipFile);
[self release];
self = nil;
}
else
{
const char* filename = [containedFile UTF8String];
// unzLocateFile(*, *, 1) = case-sensitive extract
if (unzLocateFile(uf, filename, 1) != UNZ_OK)
{
unzClose(uf);
[self release];
self = nil;
}
else
{
int err = UNZ_OK;
unz_file_info64 file_info = {0};
err = unzGetCurrentFileInfo64(uf, &file_info, NULL, 0, NULL, 0, NULL, 0);
if (err != UNZ_OK)
{
unzClose(uf);
OOLog(kOOLogFileNotFound, @"Could not get properties of %@ within OXZ at %@", containedFile, zipFile);
[self release];
self = nil;
}
else
{
err = unzOpenCurrentFile(uf);
if (err != UNZ_OK)
{
unzClose(uf);
OOLog(kOOLogFileNotFound, @"Could not read %@ within OXZ at %@", containedFile, zipFile);
[self release];
self = nil;
}
else
{
ov_callbacks _callbacks = {
OOReadOXZVorbis, // read sequentially
NULL, // no seek
OOCloseOXZVorbis, // close file
NULL, // no tell
};
err = ov_open_callbacks(self, &_vf, NULL, 0, _callbacks);
if (0 == err)
{
OK = YES;
_readStarted = NO;
}
if (!OK)
{
unzClose(uf);
[self release];
self = nil;
}
}
}
}
}
}
}
return self;
}
- (void)dealloc
{
[_name release];
ov_clear(&_vf);
unzClose(uf);
[super dealloc];
}
- (NSDictionary *)comments
{
vorbis_comment *comments;
unsigned i, count;
NSMutableDictionary *result = nil;
NSString *comment, *key, *value;
NSRange range;
comments = ov_comment(&_vf, -1);
if (NULL != comments)
{
count = comments->comments;
if (0 != count)
{
result = [NSMutableDictionary dictionaryWithCapacity:count];
for (i = 0; i != count; ++i)
{
comment = [[NSString alloc] initWithBytesNoCopy:comments->user_comments[i] length:comments->comment_lengths[i] encoding:NSUTF8StringEncoding freeWhenDone:NO];
range = [comment rangeOfString:@"="];
if (0 != range.length)
{
key = [comment substringToIndex:range.location];
value = [comment substringFromIndex:range.location + 1];
}
else
{
key = comment;
value = @"";
}
[result setObject:value forKey:key];
[comment release];
}
}
}
return result;
}
- (BOOL)readCreatingBuffer:(char **)outBuffer withFrameCount:(size_t *)outSize
{
char *buffer = NULL, *dst;
size_t sizeInFrames = 0;
int remaining;
long framesRead;
// 16-bit samples, either two or one track
int frameSize = [self isStereo] ? 4 : 2;
ogg_int64_t totalSizeInFrames;
BOOL OK = YES;
if (NULL != outBuffer) *outBuffer = NULL;
if (NULL != outSize) *outSize = 0;
if (NULL == outBuffer || NULL == outSize) OK = NO;
if (OK)
{
totalSizeInFrames = ov_pcm_total(&_vf, -1);
assert ((uint64_t)totalSizeInFrames < (uint64_t)SIZE_MAX); // Should have been checked by caller
sizeInFrames = (size_t)totalSizeInFrames;
}
if (OK)
{
buffer = malloc(sizeof (char) * frameSize * sizeInFrames);
if (!buffer) OK = NO;
}
if (OK && sizeInFrames)
{
remaining = (int)MIN(frameSize * sizeInFrames, (size_t)INT_MAX);
dst = buffer;
char pcmout[4096];
do
{
int toRead = sizeof(pcmout);
if (remaining < toRead)
{
toRead = remaining;
}
framesRead = ov_read(&_vf, pcmout, toRead, 0, 2, 1, NULL);
if (framesRead <= 0)
{
if (OV_HOLE == framesRead) continue;
//else:
break;
}
memcpy(dst, &pcmout, sizeof (char) * framesRead);
remaining -= framesRead;
dst += framesRead;
} while (0 < remaining);
sizeInFrames -= remaining; // In case we stopped at an error
}
if (OK)
{
*outBuffer = buffer;
*outSize = sizeInFrames*frameSize;
}
else
{
if (buffer) free(buffer);
}
return OK;
}
- (size_t)streamToBuffer:(char *)buffer
{
int remaining = OOAL_STREAM_CHUNK_SIZE;
size_t streamed = 0;
long framesRead;
char *dst = buffer;
char pcmout[4096];
_readStarted = YES;
do
{
int toRead = sizeof(pcmout);
if (remaining < toRead)
{
toRead = remaining;
}
framesRead = ov_read(&_vf, pcmout, toRead, 0, 2, 1, NULL);
if (framesRead <= 0)
{
if (OV_HOLE == framesRead) continue;
//else:
break;
}
memcpy(dst, &pcmout, sizeof (char) * framesRead);
remaining -= sizeof(char) * framesRead;
dst += sizeof(char) * framesRead;
streamed += sizeof(char) * framesRead;
} while (0 < remaining);
return streamed;
}
- (size_t)sizeAsBuffer
{
ogg_int64_t size;
size = ov_pcm_total(&_vf, -1);
size *= sizeof(char) * ([self isStereo] ? 4 : 2);
if ((uint64_t)SIZE_MAX < (uint64_t)size) size = (ogg_int64_t)SIZE_MAX;
return (size_t)size;
}
- (BOOL)isStereo
{
return 1 < ov_info(&_vf, -1)->channels;
}
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p>{\"%@\", comments=%@}", [self className], self, _name, [self comments]];
}
- (long)sampleRate
{
return ov_info(&_vf, -1)->rate;
}
- (void) reset
{
if (!_readStarted)
{
return; // don't need to do anything
}
if (_seekableStream)
{
ov_pcm_seek(&_vf, 0);
return;
}
// reset current file pointer in OXZ
unzOpenCurrentFile(uf);
// reopen OGG streamer
ov_clear(&_vf);
ov_callbacks _callbacks = {
OOReadOXZVorbis, // read sequentially
NULL, // no seek
OOCloseOXZVorbis, // close file
NULL, // no tell
};
ov_open_callbacks(self, &_vf, NULL, 0, _callbacks);
_readStarted = NO;
}
- (NSString *)name
{
return [[_name retain] autorelease];
}
@end
static size_t OOReadOXZVorbis (void *ptr, size_t size, size_t nmemb, void *datasource)
{
OOALSoundVorbisCodec *src = (OOALSoundVorbisCodec *)datasource;
size_t toRead = size*nmemb;
void *buf = (void*)malloc(toRead);
int err = UNZ_OK;
err = unzReadCurrentFile(src->uf, buf, toRead);
// OOLog(@"sound.replay",@"Read %d blocks, got %d",toRead,err);
if (err > 0)
{
memcpy(ptr, buf, err);
}
if (err < 0)
{
return OV_EREAD;
}
return err;
}
static int OOCloseOXZVorbis (void *datasource)
{
// doing this prevents replaying
// OOALSoundVorbisCodec *src = (OOALSoundVorbisCodec *)datasource;
// unzClose(src->uf);
return 0;
}

61
src/Core/OOALSoundMixer.h Normal file
View File

@ -0,0 +1,61 @@
/*
OOALSoundMixer.h
Class responsible for managing and mixing sound channels. This class is an
implementation detail. Do not use it directly; use an OOSoundSource to play an
OOSound.
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2006-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import <Foundation/Foundation.h>
@class OOSoundChannel;
enum
{
kMixerGeneralChannels = 32
};
@interface OOSoundMixer: NSObject
{
OOSoundChannel *_channels[kMixerGeneralChannels];
OOSoundChannel *_freeList;
uint32_t _maxChannels;
uint32_t _playMask;
}
// Singleton accessor
+ (id) sharedMixer;
- (void) update;
- (OOSoundChannel *) popChannel;
- (void) pushChannel:(OOSoundChannel *)channel;
@end

177
src/Core/OOALSoundMixer.m Normal file
View File

@ -0,0 +1,177 @@
/*
OOALSoundMixer.m
OOALSound - OpenAL sound implementation for Oolite.
Copyright (C) 2006-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#include <assert.h>
#import "OOALSoundMixer.h"
#import "OOCocoa.h"
#import "OOALSound.h"
#import "OOALSoundChannel.h"
static OOSoundMixer *sSingleton = nil;
@implementation OOSoundMixer
+ (id) sharedMixer
{
if (nil == sSingleton)
{
[[self alloc] init];
}
return sSingleton;
}
- (id) init
{
BOOL OK = YES;
uint32_t idx = 0, count = kMixerGeneralChannels;
OOSoundChannel *channel;
if (!(self = [super init])) return nil;
if (![OOSound setUp]) OK = NO;
if (OK)
{
// Allocate channels
do
{
channel = [[OOSoundChannel alloc] init];
if (nil != channel)
{
_channels[idx++] = channel;
[self pushChannel:channel];
}
} while (--count);
}
if (!OK)
{
[super release];
// static analyser complains about this next line; probably nothing - CIM
self = nil;
}
else
{
sSingleton = self;
}
return sSingleton;
}
// only to be called at app shutdown by OOOpenALController::shutdown
- (void) shutdown
{
uint32_t i;
for (i = 0; i < kMixerGeneralChannels; ++i)
{
DESTROY(_channels[i]);
}
}
- (void) update
{
uint32_t i;
for (i = 0; i < kMixerGeneralChannels; ++i)
{
[_channels[i] update];
}
}
- (OOSoundChannel *) popChannel
{
OOSoundChannel *channel = _freeList;
_freeList = [channel next];
[channel setNext:nil];
return channel;
}
- (void) pushChannel:(OOSoundChannel *)channel
{
assert(channel != nil);
[channel setNext:_freeList];
_freeList = channel;
}
@end
@implementation OOSoundMixer (Singleton)
/* Canonical singleton boilerplate.
See Cocoa Fundamentals Guide: Creating a Singleton Instance.
See also +sharedMixer above.
NOTE: assumes single-threaded access.
*/
+ (id)allocWithZone:(NSZone *)inZone
{
if (sSingleton == nil)
{
sSingleton = [super allocWithZone:inZone];
return sSingleton;
}
return nil;
}
- (id)copyWithZone:(NSZone *)inZone
{
return self;
}
- (id)retain
{
return self;
}
- (NSUInteger)retainCount
{
return UINT_MAX;
}
- (void)release
{}
- (id)autorelease
{
return self;
}
@end

View File

@ -0,0 +1,45 @@
/*
OOALStreamedSound.h
OOALStreamedSound - OpenAL sound implementation for Oolite.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOSound.h"
#import "OOALSoundDecoder.h"
@interface OOALStreamedSound: OOSound
{
@private
char *_buffer;
size_t _size;
double _sampleRate;
NSString *_name;
BOOL _stereo;
OOALSoundDecoder *decoder;
BOOL _reachedEnd;
}
- (id)initWithDecoder:(OOALSoundDecoder *)inDecoder;
@end

View File

@ -0,0 +1,127 @@
/*
OOALStreamedSound.m
OOALStreamedSound - OpenAL sound implementation for Oolite.
Copyright (C) 2005-2013 Jens Ayton
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/
#import "OOALStreamedSound.h"
#import "OOALSoundDecoder.h"
@implementation OOALStreamedSound
- (void)dealloc
{
free(_buffer);
_buffer = NULL;
[decoder release];
[super dealloc];
}
- (NSString *)name
{
return _name;
}
- (id)initWithDecoder:(OOALSoundDecoder *)inDecoder
{
BOOL OK = YES;
[OOSound setUp];
if (![OOSound isSoundOK] || nil == inDecoder) OK = NO;
if (OK)
{
self = [super init];
if (nil == self) OK = NO;
}
if (OK)
{
_name = [[inDecoder name] copy];
_sampleRate = [inDecoder sampleRate];
_stereo = [inDecoder isStereo];
_reachedEnd = NO;
_buffer = malloc(OOAL_STREAM_CHUNK_SIZE);
decoder = [inDecoder retain];
[self rewind];
}
if (!OK)
{
[self release];
self = nil;
}
return self;
}
- (void) rewind
{
[decoder reset];
_reachedEnd = NO;
}
- (BOOL) soundIncomplete
{
return !_reachedEnd;
}
- (ALuint) soundBuffer
{
size_t transferred = [decoder streamToBuffer:_buffer];
if (transferred < OOAL_STREAM_CHUNK_SIZE)
{
// otherwise keep going
_reachedEnd = YES;
}
ALuint buffer;
ALint error;
OOAL(alGenBuffers(1,&buffer));
if ((error = alGetError()) != AL_NO_ERROR)
{
OOLog(kOOLogSoundLoadingError,@"Could not create OpenAL buffer");
return 0;
}
else
{
if (!_stereo)
{
alBufferData(buffer,AL_FORMAT_MONO16,_buffer,transferred,_sampleRate);
}
else
{
alBufferData(buffer,AL_FORMAT_STEREO16,_buffer,transferred,_sampleRate);
}
return buffer;
}
}
@end

View File

@ -32,6 +32,7 @@ SOFTWARE.
#import "Universe.h"
#import "OOStellarBody.h"
#import "OOJavaScriptEngine.h"
#import "OOSound.h"
static NSString *AdditionalLogHeaderInfo(void);
@ -99,6 +100,10 @@ void OOPrintLogHeader(void)
NSArray *featureStrings = [NSArray arrayWithObjects:
// User features
#if OOLITE_OPENAL
@"OpenAL",
#endif
#if OO_SHADERS
@"GLSL shaders",
#endif
@ -107,14 +112,6 @@ void OOPrintLogHeader(void)
@"new planets",
#endif
#if OOLITE_MAC_OS_X || defined(HAVE_LIBESPEAK)
@"spoken messages",
#endif
#if MASS_DEPENDENT_FUEL_PRICES
@"mass/fuel pricing",
#endif
// Debug features
#if OO_CHECK_GL_HEAVY
@"heavy OpenGL error checking",

40
src/Core/OOOpenAL.h Normal file
View File

@ -0,0 +1,40 @@
/*
OOOpenAL.h
Platform-independent access to OpenAL headers and AL utilities
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOCocoa.h"
#if OOLITE_MAC_OS_X
#import <OpenAL/al.h>
#import <OpenAL/alc.h>
#else
#include <AL/al.h>
#include <AL/alc.h>
#endif
// alGetError should always be called before openAL calls to reset the
// error stack
#define OOAL(cmd) do { alGetError(); cmd; } while (0)

View File

@ -0,0 +1,49 @@
/*
OOOpenALController.h
Singleton controller for Open AL interfaces
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOOpenAL.h"
static NSString * const kOOLogSoundInitError = @"sound.initialization.error";
static NSString * const kOOLogSoundLoadingSuccess = @"sound.load.success";
static NSString * const kOOLogSoundLoadingError = @"sound.load.error";
@interface OOOpenALController : NSObject
{
@private
ALCdevice *device;
ALCcontext *context;
}
+ (OOOpenALController *) sharedController;
- (void) setMasterVolume:(ALfloat) fraction;
- (ALfloat) masterVolume;
- (void) shutdown;
@end

View File

@ -0,0 +1,95 @@
/*
OOOpenALController.m
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOOpenALController.h"
#import "OOLogging.h"
#import "OOALSoundMixer.h"
static id sSingleton = nil;
@implementation OOOpenALController
+ (OOOpenALController *) sharedController
{
if (sSingleton == nil)
{
sSingleton = [[self alloc] init];
}
return sSingleton;
}
- (id) init
{
self = [super init];
if (self != nil)
{
ALuint error;
device = alcOpenDevice(NULL); // default device
if (!device)
{
OOLog(kOOLogSoundInitError,@"Failed to open default sound device");
return nil;
}
context = alcCreateContext(device,NULL); // default context
if (!alcMakeContextCurrent(context))
{
OOLog(kOOLogSoundInitError,@"Failed to create default sound context");
return nil;
}
if ((error = alGetError()) != AL_NO_ERROR)
{
OOLog(kOOLogSoundInitError,@"Error %d creating sound context",error);
}
OOAL(alDistanceModel(AL_NONE));
}
return self;
}
- (void) setMasterVolume:(ALfloat) fraction
{
OOAL(alListenerf(AL_GAIN,fraction));
}
- (ALfloat) masterVolume
{
ALfloat fraction = 0.0;
OOAL(alGetListenerf(AL_GAIN,&fraction));
return fraction;
}
// only to be called at app shutdown
// is there a better way to handle this?
- (void) shutdown
{
[[OOSoundMixer sharedMixer] shutdown];
OOAL(alcMakeContextCurrent(NULL));
OOAL(alcDestroyContext(context));
OOAL(alcCloseDevice(device));
}
@end

View File

@ -26,6 +26,7 @@ MA 02110-1301, USA.
#import "OOPListParsing.h"
#import "OOLogging.h"
#import "OOStringParsing.h"
#import "NSDataOOExtensions.h"
#include <ctype.h>
#include <string.h>
@ -171,6 +172,9 @@ static NSData *ChangeDTDIfApplicable(NSData *data)
*/
static NSData *CopyDataFromFile(NSString *path)
{
return [[NSData oo_dataWithOXZFile:path] retain];
#if 0
// without OXZ extension. Code to be deleted once everything is working
#if OOLITE_MAC_OS_X
return [[NSData alloc] initWithContentsOfMappedFile:path];
#else
@ -191,6 +195,7 @@ static NSData *CopyDataFromFile(NSString *path)
return nil;
#endif
#endif
}
// Wrappers which ensure that the plist contains the right type of object.
NSDictionary *OODictionaryFromData(NSData *data, NSString *whereFrom)

View File

@ -43,7 +43,13 @@ MA 02110-1301, USA.
#import "OOCocoa.h"
#define OOLITE_OPENAL 1
#if OOLITE_OPENAL
#import "OOALSound.h"
#import "OOALMusic.h"
#import "OOBasicSoundReferencePoint.h"
#else
#if OOLITE_SDL
#import "OOSDLSound.h"
#import "SDLMusic.h"
@ -53,5 +59,6 @@ MA 02110-1301, USA.
#import "OOCAMusic.h"
#import "OOCASoundReferencePoint.h"
#endif
#endif
#import "OOSoundSource.h"

View File

@ -1,6 +1,14 @@
#import "OOSound.h"
#if OOLITE_SDL
#if OOLITE_OPENAL
#import "OOALSoundMixer.h"
#import "OOALSoundChannel.h"
#define OOSoundAcquireLock() do {} while(0)
#define OOSoundReleaseLock() do {} while(0)
#elif OOLITE_SDL
#import "OOSDLSoundMixer.h"
#import "OOSDLSoundChannel.h"

View File

@ -44,6 +44,9 @@ OUT OF OR
BOOL _loop;
uint8_t _repeatCount,
_remainingCount;
Vector _position;
BOOL _positional;
float _gain;
}
+ (instancetype) sourceWithSound:(OOSound *)inSound;
@ -69,9 +72,15 @@ OUT OF OR
- (void) playSound:(OOSound *)inSound repeatCount:(uint8_t)inCount;
- (void) playOrRepeatSound:(OOSound *)inSound;
// Positional audio attributes are ignored in this implementation
// Positional audio attributes are used in this implementation
- (void) setPositional:(BOOL)inPositional;
- (BOOL) positional;
- (void) setPosition:(Vector)inPosition;
- (Vector) position;
- (void) setGain:(float)gain;
- (float) gain;
// *Advanced* positional audio attributes are ignored in this implementation
- (void) setVelocity:(Vector)inVelocity;
- (void) setOrientation:(Vector)inOrientation;
- (void) setConeAngle:(float)inAngle;

View File

@ -27,7 +27,7 @@ SOFTWARE.
#import "OOSoundInternal.h"
#import "OOLogging.h"
#import "OOMaths.h"
static NSMutableSet *sPlayingSoundSources;
@ -40,6 +40,18 @@ static NSMutableSet *sPlayingSoundSources;
}
- (id) init
{
self = [super init];
if (!self) return nil;
_positional = NO;
_position = kZeroVector;
_gain = 1.0;
return self;
}
- (id) initWithSound:(OOSound *)inSound
{
self = [self init];
@ -133,6 +145,8 @@ static NSMutableSet *sPlayingSoundSources;
{
_remainingCount = [self repeatCount];
[_channel setDelegate:self];
[_channel setPosition:_position];
[_channel setGain:_gain];
[_channel playSound:[self sound] looped:[self loop]];
[self retain];
}
@ -211,16 +225,64 @@ static NSMutableSet *sPlayingSoundSources;
- (void) setPositional:(BOOL)inPositional
{
if (inPositional)
{
_positional = YES;
}
else
{
/* OpenAL doesn't easily do non-positional sounds beyond the
* stereo/mono distinction, but setting the position to the
* zero vector is probably close enough */
_positional = NO;
[self setPosition:kZeroVector];
}
}
- (BOOL) positional
{
return _positional;
}
- (void) setPosition:(Vector)inPosition
{
_position = inPosition;
if (inPosition.x != 0.0 || inPosition.y != 0.0 || inPosition.z != 0.0)
{
_positional = YES;
}
if (_channel)
{
[_channel setPosition:_position];
}
}
- (Vector) position
{
return _position;
}
- (void) setGain:(float)gain
{
_gain = gain;
if (_channel)
{
[_channel setGain:_gain];
}
}
- (float) gain
{
return _gain;
}
/* Following not yet implemented */
- (void) setVelocity:(Vector)inVelocity
{

View File

@ -35,7 +35,7 @@ SOFTWARE.
#import <Foundation/Foundation.h>
#import "OOTypes.h"
#import "OOMaths.h"
@interface OOSoundSourcePool: NSObject
{
@ -52,6 +52,12 @@ SOFTWARE.
+ (instancetype) poolWithCount:(uint8_t)count minRepeatTime:(OOTimeDelta)minRepeat;
- (id) initWithCount:(uint8_t)count minRepeatTime:(OOTimeDelta)minRepeat;
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
expiryTime:(OOTimeDelta)expiryTime
overlap:(BOOL)overlap
position:(Vector)position;
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
expiryTime:(OOTimeDelta)expiryTime;
@ -59,9 +65,17 @@ SOFTWARE.
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority; // expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
position:(Vector)position; // expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key
position:(Vector)position; // expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key; // priority: 1.0, expiryTime:0.1 +/- 0.5
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap; // if overlap == NO it waits for key to finish before playing key again
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap position:(Vector)position;
@end

View File

@ -103,6 +103,7 @@ typedef struct OOSoundSourcePoolElement
priority:(float)priority
expiryTime:(OOTimeDelta)expiryTime
overlap:(BOOL)overlap
position:(Vector)position
{
uint8_t slot;
OOTimeAbsolute now, absExpiryTime;
@ -137,6 +138,7 @@ typedef struct OOSoundSourcePoolElement
if (!overlap) _reserved = slot;
// Play and store metadata
[element->source setPosition:position];
[element->source playSound:sound];
element->expiryTime = absExpiryTime;
element->priority = priority;
@ -159,7 +161,20 @@ typedef struct OOSoundSourcePoolElement
[self playSoundWithKey:key
priority:priority
expiryTime:expiryTime
overlap:YES];
overlap:YES
position:kZeroVector];
}
- (void) playSoundWithKey:(NSString *)key
priority:(float)priority
position:(Vector)position
{
[self playSoundWithKey:key
priority:priority
expiryTime:0.5 + randf() * 0.1
overlap:YES
position:position];
}
@ -178,14 +193,32 @@ typedef struct OOSoundSourcePoolElement
}
- (void) playSoundWithKey:(NSString *)key position:(Vector)position
{
[self playSoundWithKey:key priority:1.0 position:position];
}
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap
{
[self playSoundWithKey:key
priority:1.0
expiryTime:0.5
overlap:overlap];
overlap:overlap
position:kZeroVector];
}
- (void) playSoundWithKey:(NSString *)key overlap:(BOOL)overlap position:(Vector)position
{
[self playSoundWithKey:key
priority:1.0
expiryTime:0.5
overlap:overlap
position:position];
}
@end

View File

@ -29,6 +29,7 @@ MA 02110-1301, USA.
#import "ResourceManager.h"
#import "OOSound.h"
#import "OOStringParsing.h"
#import "OOMaths.h"
static void InitTrumbleSounds(void);
@ -987,7 +988,12 @@ static void InitTrumbleSounds(void)
static void PlayTrumbleIdle(void)
{
// Only play idle sound if no trumble is making noise.
if (![sTrumbleSoundSource isPlaying]) [sTrumbleSoundSource playSound:sTrumbleIdleSound];
if (![sTrumbleSoundSource isPlaying])
{
// trumble sound from random direction - where's it gone now?
[sTrumbleSoundSource setPosition:OORandomUnitVector()];
[sTrumbleSoundSource playSound:sTrumbleIdleSound];
}
}
@ -996,6 +1002,8 @@ static void PlayTrumbleSqueal(void)
// Play squeal sound if no trumble is currently squealing, but trumping idle sound.
if (![sTrumbleSoundSource isPlaying] || [sTrumbleSoundSource sound] == sTrumbleIdleSound)
{
// trumble sound from random direction - where's it gone now?
[sTrumbleSoundSource setPosition:OORandomUnitVector()];
[sTrumbleSoundSource playSound:sTrumbleSqealSound];
}
}

View File

@ -26,7 +26,7 @@ MA 02110-1301, USA.
#import "OOCocoa.h"
#import "OOOpenGL.h"
#import "NSFileManagerOOExtensions.h"
@class OOSound, OOMusic;

View File

@ -50,6 +50,33 @@ static NSString * const kOOCacheKeySearchPaths = @"search paths";
static NSString * const kOOCacheKeyModificationDates = @"modification dates";
static NSString * const kOOManifestIdentifier = @"identifier";
static NSString * const kOOManifestVersion = @"version";
static NSString * const kOOManifestRequiredOoliteVersion= @"required_oolite_version";
static NSString * const kOOManifestMaximumOoliteVersion = @"maximum_oolite_version";
static NSString * const kOOManifestTitle = @"title";
static NSString * const kOOManifestRequiresOXPs = @"requires_oxps";
static NSString * const kOOManifestConflictOXPs = @"conflict_oxps";
// this property is not contained in the manifest.plist but is
// calculated by Oolite
static NSString * const kOOManifestFilePath = @"file_path";
// following manifest.plist properties not yet implemented
static NSString * const kOOManifestDescription = @"description";
static NSString * const kOOManifestCategory = @"category";
static NSString * const kOOManifestTags = @"tags";
static NSString * const kOOManifestAuthor = @"author";
static NSString * const kOOManifestLicense = @"license";
static NSString * const kOOManifestOptionalOXPs = @"optional_oxps";
static NSString * const kOOManifestDownloadURL = @"download_url";
static NSString * const kOOManifestInformationURL = @"information_url";
// properties for within requires/optional/conflicts entries
static NSString * const kOOManifestRelationIdentifier = @"identifier";
static NSString * const kOOManifestRelationVersion = @"version";
static NSString * const kOOManifestRelationMaxVersion = @"maximum_version";
static NSString * const kOOManifestRelationDescription = @"description";
extern NSDictionary* ParseOOSScripts(NSString* script);
@ -57,7 +84,11 @@ extern NSDictionary* ParseOOSScripts(NSString* script);
+ (void) checkOXPMessagesInPath:(NSString *)path;
+ (void) checkPotentialPath:(NSString *)path :(NSMutableArray *)searchPaths;
+ (BOOL) areRequirementsFulfilled:(NSDictionary*)requirements forOXP:(NSString *)path;
+ (BOOL) validateManifest:(NSDictionary*)manifest forOXP:(NSString *)path;
+ (BOOL) areRequirementsFulfilled:(NSDictionary*)requirements forOXP:(NSString *)path andFile:(NSString *)file;
+ (void) filterSearchPathsForConflicts:(NSMutableArray *)searchPaths;
+ (BOOL) filterSearchPathsForRequirements:(NSMutableArray *)searchPaths;
+ (BOOL) matchVersions:(NSDictionary *)rangeDict withVersion:(NSString *)version;
+ (void) addErrorWithKey:(NSString *)descriptionKey param1:(id)param1 param2:(id)param2;
+ (void) checkCacheUpToDateForPaths:(NSArray *)searchPaths;
+ (void) logPaths;
@ -77,6 +108,7 @@ static NSMutableArray *sErrors;
//
static NSMutableDictionary *sSoundCache;
static NSMutableDictionary *sStringCache;
static NSMutableDictionary *sOXPManifests;
@implementation ResourceManager
@ -191,7 +223,12 @@ static NSMutableDictionary *sStringCache;
}
}
sSearchPaths = [existingRootPaths mutableCopy];
// validate default search paths
sSearchPaths = [NSMutableArray new];
foreach(path, existingRootPaths)
{
[self checkPotentialPath:path :sSearchPaths];
}
// Iterate over root paths.
for (pathEnum = [existingRootPaths objectEnumerator]; (root = [pathEnum nextObject]); )
@ -203,18 +240,30 @@ static NSMutableDictionary *sStringCache;
{
// Check if it's a directory.
path = [root stringByAppendingPathComponent:subPath];
if ([fmgr fileExistsAtPath:path isDirectory:&isDirectory] && isDirectory)
if ([fmgr fileExistsAtPath:path isDirectory:&isDirectory])
{
// If it is, is it an OXP?.
if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxp"])
if (isDirectory)
{
[self checkPotentialPath:path :sSearchPaths];
if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
// If it is, is it an OXP?.
if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxp"])
{
[self checkPotentialPath:path :sSearchPaths];
if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
}
else
{
// If not, don't search subdirectories.
[dirEnum skipDescendents];
}
}
else
{
// If not, don't search subdirectories.
[dirEnum skipDescendents];
// If not a directory, is it an OXZ?
if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
{
[self checkPotentialPath:path :sSearchPaths];
if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
}
}
}
}
@ -226,6 +275,26 @@ static NSMutableDictionary *sStringCache;
[self checkPotentialPath:path :sSearchPaths];
if ([sSearchPaths containsObject:path]) [self checkOXPMessagesInPath:path];
}
/* This is a conservative filter. It probably gets rid of more
* OXPs than it technically needs to in certain situations with
* dependency chains, but really any conflict here needs to be
* resolved by the user rather than Oolite. The point is to avoid
* loading OXPs which we shouldn't; if doing so takes out other
* OXPs which would have been safe, that's not important. */
[self filterSearchPathsForConflicts:sSearchPaths];
/* This one needs to be run repeatedly to be sure. Take the chain
* A depends on B depends on C. A and B are installed. A is
* checked first, and depends on B, which is thought to be
* okay. So A is kept. Then B is checked and removed. A must then
* be rechecked. This function therefore is run repeatedly until a
* run of it removes no further items.
*
* There may well be more elegant and efficient ways to do this
* but this is already fast enough for most purposes.
*/
while (![self filterSearchPathsForRequirements:sSearchPaths]) {}
[self checkCacheUpToDateForPaths:sSearchPaths];
return sSearchPaths;
@ -329,26 +398,123 @@ static NSMutableDictionary *sStringCache;
}
// Given a path to an assumed OXP (or other location where files are permissible), check for a requires.plist and add to search paths if acceptable.
// Given a path to an assumed OXP (or other location where files are permissible), check for a requires.plist or manifest.plist and add to search paths if acceptable.
+ (void)checkPotentialPath:(NSString *)path :(NSMutableArray *)searchPaths
{
NSDictionary *requirements = nil;
BOOL requirementsMet;
requirements = OODictionaryFromFile([path stringByAppendingPathComponent:@"requires.plist"]);
requirementsMet = [self areRequirementsFulfilled:requirements forOXP:path];
if (requirementsMet) [searchPaths addObject:path];
else if (EXPECT_NOT(![UNIVERSE strict]))
NSDictionary *manifest = nil;
BOOL requirementsMet = YES;
if (![[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
{
// OXZ format ignores requires.plist
requirements = OODictionaryFromFile([path stringByAppendingPathComponent:@"requires.plist"]);
requirementsMet = [self areRequirementsFulfilled:requirements forOXP:path andFile:@"requires.plist"];
}
if (!requirementsMet)
{
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
OOLog(@"oxp.versionMismatch", @"OXP %@ is incompatible with version %@ of Oolite.", path, version);
[self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
return;
}
manifest = OODictionaryFromFile([path stringByAppendingPathComponent:@"manifest.plist"]);
if (manifest == nil)
{
if ([[[path pathExtension] lowercaseString] isEqualToString:@"oxz"])
{
OOLog(@"oxp.noManifest", @"OXZ %@ has no manifest.plist", path);
[self addErrorWithKey:@"oxz-lacks-manifest" param1:[path lastPathComponent] param2:nil];
return;
}
}
else
{
requirementsMet = [self validateManifest:manifest forOXP:path];
}
if (requirementsMet)
{
[searchPaths addObject:path];
}
}
+ (BOOL) areRequirementsFulfilled:(NSDictionary*)requirements forOXP:(NSString *)path
+ (BOOL) validateManifest:(NSDictionary*)manifest forOXP:(NSString *)path
{
if (sOXPManifests == nil)
{
sOXPManifests = [[NSMutableDictionary alloc] initWithCapacity:32];
}
BOOL OK = YES;
NSString *identifier = [manifest oo_stringForKey:kOOManifestIdentifier defaultValue:nil];
NSString *version = [manifest oo_stringForKey:kOOManifestVersion defaultValue:nil];
NSString *required = [manifest oo_stringForKey:kOOManifestRequiredOoliteVersion defaultValue:nil];
NSString *title = [manifest oo_stringForKey:kOOManifestTitle defaultValue:nil];
if (identifier == nil)
{
OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestIdentifier);
[self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestIdentifier];
OK = NO;
}
if (version == nil)
{
OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestVersion);
[self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestVersion];
OK = NO;
}
if (required == nil)
{
OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestRequiredOoliteVersion);
[self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestRequiredOoliteVersion];
OK = NO;
}
if (title == nil)
{
OOLog(@"oxp.noManifest", @"OXZ %@ manifest.plist has no '%@' field.", path, kOOManifestTitle);
[self addErrorWithKey:@"oxp-manifest-incomplete" param1:title param2:kOOManifestTitle];
OK = NO;
}
if (!OK)
{
return NO;
}
NSString *maxRequired = [manifest oo_stringForKey:kOOManifestMaximumOoliteVersion defaultValue:nil];
if (maxRequired == nil)
{
OK = [self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", nil] forOXP:title andFile:@"manifest.plist"];
}
else
{
OK = [self areRequirementsFulfilled:[NSDictionary dictionaryWithObjectsAndKeys:required, @"version", maxRequired, @"max_version", nil] forOXP:title andFile:@"manifest.plist"];
}
if (!OK)
{
NSString *version = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
OOLog(@"oxp.versionMismatch", @"OXP %@ is incompatible with version %@ of Oolite.", path, version);
[self addErrorWithKey:@"oxp-is-incompatible" param1:[path lastPathComponent] param2:version];
return NO;
}
NSDictionary *duplicate = [sOXPManifests objectForKey:identifier];
if (duplicate != nil)
{
OOLog(@"oxp.duplicate", @"OXP %@ has the same identifier (%@) as %@ which has already been loaded.",path,identifier,[duplicate oo_stringForKey:kOOManifestFilePath]);
[self addErrorWithKey:@"oxp-manifest-duplicate" param1:path param2:[duplicate oo_stringForKey:kOOManifestFilePath]];
return NO;
}
NSMutableDictionary *mData = [NSMutableDictionary dictionaryWithDictionary:manifest];
[mData setObject:path forKey:kOOManifestFilePath];
// add an extra key
[sOXPManifests setObject:mData forKey:identifier];
return YES;
}
+ (BOOL) areRequirementsFulfilled:(NSDictionary*)requirements forOXP:(NSString *)path andFile:(NSString *)file
{
BOOL OK = YES;
NSString *requiredVersion = nil;
@ -380,7 +546,7 @@ static NSMutableDictionary *sStringCache;
}
else
{
OOLog(@"requirements.wrongType", @"Expected requires.plist entry \"%@\" to be string, but got %@ in OXP %@.", @"version", [requirements class], [path lastPathComponent]);
OOLog(@"requirements.wrongType", @"Expected %@ entry \"%@\" to be string, but got %@ in OXP %@.", file, @"version", [requirements class], [path lastPathComponent]);
OK = NO;
}
}
@ -401,7 +567,7 @@ static NSMutableDictionary *sStringCache;
}
else
{
OOLog(@"requirements.wrongType", @"Expected requires.plist entry \"%@\" to be string, but got %@ in OXP %@.", @"max_version", [requirements class], [path lastPathComponent]);
OOLog(@"requirements.wrongType", @"Expected %@ entry \"%@\" to be string, but got %@ in OXP %@.", file, @"max_version", [requirements class], [path lastPathComponent]);
OK = NO;
}
}
@ -418,6 +584,140 @@ static NSMutableDictionary *sStringCache;
}
+ (void) filterSearchPathsForConflicts:(NSMutableArray *)searchPaths
{
NSDictionary *manifest = nil;
NSDictionary *conflicting = nil;
NSDictionary *conflictManifest = nil;
NSString *identifier = nil;
NSString *conflictID = nil;
NSArray *identifiers = [sOXPManifests allKeys];
NSArray *conflicts = nil;
// take a copy because we'll mutate the original
// foreach identified add-on
foreach (identifier, identifiers)
{
manifest = [sOXPManifests objectForKey:identifier];
if (manifest != nil)
{
conflicts = [manifest oo_arrayForKey:kOOManifestConflictOXPs defaultValue:nil];
// if it has a non-empty conflict_oxps list
if (conflicts != nil && [conflicts count] > 0)
{
// iterate over that list
foreach (conflicting, conflicts)
{
conflictID = [conflicting oo_stringForKey:kOOManifestRelationIdentifier];
conflictManifest = [sOXPManifests objectForKey:conflictID];
// if the other OXP is in the list
if (conflictManifest != nil)
{
// then check versions
if ([self matchVersions:conflicting withVersion:[conflictManifest oo_stringForKey:kOOManifestVersion]])
{
// then we have a conflict, so remove this path
[self addErrorWithKey:@"oxp-conflict" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[conflictManifest oo_stringForKey:kOOManifestTitle]];
OOLog(@"oxp.conflict",@"OXP %@ conflicts with %@ and was removed from the loading list",[[manifest oo_stringForKey:kOOManifestFilePath] lastPathComponent],[[conflictManifest oo_stringForKey:kOOManifestFilePath] lastPathComponent]);
[searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
[sOXPManifests removeObjectForKey:identifier];
break;
}
}
}
}
}
}
}
+ (BOOL) filterSearchPathsForRequirements:(NSMutableArray *)searchPaths
{
NSDictionary *manifest = nil;
NSDictionary *required = nil;
NSDictionary *requiredManifest = nil;
NSString *identifier = nil;
NSString *requiredID = nil;
NSArray *identifiers = [sOXPManifests allKeys];
NSArray *requireds = nil;
BOOL allMet = YES;
// take a copy because we'll mutate the original
// foreach identified add-on
foreach (identifier, identifiers)
{
manifest = [sOXPManifests objectForKey:identifier];
if (manifest != nil)
{
requireds = [manifest oo_arrayForKey:kOOManifestRequiresOXPs defaultValue:nil];
// if it has a non-empty required_oxps list
if (requireds != nil && [requireds count] > 0)
{
// iterate over that list
foreach (required, requireds)
{
requiredID = [required oo_stringForKey:kOOManifestRelationIdentifier];
requiredManifest = [sOXPManifests objectForKey:requiredID];
// if the other OXP is in the list
BOOL requirementsMet = NO;
if (requiredManifest != nil)
{
// then check versions
if ([self matchVersions:required withVersion:[requiredManifest oo_stringForKey:kOOManifestVersion]])
{
requirementsMet = YES;
}
}
if (!requirementsMet)
{
// then we have a missing requirement, so remove this path
[self addErrorWithKey:@"oxp-required" param1:[manifest oo_stringForKey:kOOManifestTitle] param2:[required oo_stringForKey:kOOManifestRelationDescription defaultValue:[required oo_stringForKey:kOOManifestRelationIdentifier]]];
OOLog(@"oxp.requirementMissing",@"OXP %@ had unmet requirements and was removed from the loading list",[[manifest oo_stringForKey:kOOManifestFilePath] lastPathComponent]);
[searchPaths removeObject:[manifest oo_stringForKey:kOOManifestFilePath]];
[sOXPManifests removeObjectForKey:identifier];
allMet = NO;
break;
}
}
}
}
}
return allMet;
}
+ (BOOL) matchVersions:(NSDictionary *)rangeDict withVersion:(NSString *)version
{
NSString *minimum = [rangeDict oo_stringForKey:kOOManifestRelationVersion defaultValue:nil];
NSString *maximum = [rangeDict oo_stringForKey:kOOManifestRelationMaxVersion defaultValue:nil];
NSArray *isVersionComponents = ComponentsFromVersionString(version);
NSArray *reqVersionComponents = nil;
if (minimum != nil)
{
reqVersionComponents = ComponentsFromVersionString(minimum);
if (NSOrderedAscending == CompareVersions(isVersionComponents, reqVersionComponents))
{
// earlier than minimum version
return NO;
}
}
if (maximum != nil)
{
reqVersionComponents = ComponentsFromVersionString(maximum);
if (NSOrderedDescending == CompareVersions(isVersionComponents, reqVersionComponents))
{
// later than maximum version
return NO;
}
}
// either version was okay, or no version info so an unconditional match
return YES;
}
+ (void) addErrorWithKey:(NSString *)descriptionKey param1:(id)param1 param2:(id)param2
{
if (descriptionKey != nil)
@ -961,14 +1261,14 @@ static NSString *LogClassKeyRoot(NSString *key)
for (pathEnum = [[ResourceManager paths] reverseObjectEnumerator]; (path = [pathEnum nextObject]); )
{
filePath = [[path stringByAppendingPathComponent:folderName] stringByAppendingPathComponent:fileName];
if ([fmgr fileExistsAtPath:filePath])
if ([fmgr oo_oxzFileExistsAtPath:filePath])
{
result = filePath;
break;
}
filePath = [path stringByAppendingPathComponent:fileName];
if ([fmgr fileExistsAtPath:filePath])
if ([fmgr oo_oxzFileExistsAtPath:filePath])
{
result = filePath;
break;
@ -1266,6 +1566,8 @@ static NSString *LogClassKeyRoot(NSString *key)
sSoundCache = nil;
[sStringCache release];
sStringCache = nil;
[sOXPManifests release];
sOXPManifests = nil;
}
@end

View File

@ -23,6 +23,7 @@ MA 02110-1301, USA.
*/
#import "OOJSSound.h"
#import "OOJSVector.h"
#import "OOJavaScriptEngine.h"
#import "OOSound.h"
#import "ResourceManager.h"
@ -64,7 +65,10 @@ enum
kSoundSource_sound,
kSoundSource_isPlaying,
kSoundSource_loop,
kSoundSource_repeatCount
kSoundSource_position,
kSoundSource_positional,
kSoundSource_repeatCount,
kSoundSource_volume
};
@ -73,8 +77,11 @@ static JSPropertySpec sSoundSourceProperties[] =
// JS name ID flags
{ "isPlaying", kSoundSource_isPlaying, OOJS_PROP_READONLY_CB },
{ "loop", kSoundSource_loop, OOJS_PROP_READWRITE_CB },
{ "position", kSoundSource_position, OOJS_PROP_READWRITE_CB },
{ "positional", kSoundSource_positional, OOJS_PROP_READWRITE_CB },
{ "repeatCount", kSoundSource_repeatCount, OOJS_PROP_READWRITE_CB },
{ "sound", kSoundSource_sound, OOJS_PROP_READWRITE_CB },
{ "volume", kSoundSource_volume, OOJS_PROP_READWRITE_CB },
{ 0 }
};
@ -148,7 +155,18 @@ static JSBool SoundSourceGetProperty(JSContext *context, JSObject *this, jsid pr
case kSoundSource_repeatCount:
*value = INT_TO_JSVAL([soundSource repeatCount]);
return YES;
case kSoundSource_position:
return VectorToJSValue(context, [soundSource position], value);
case kSoundSource_positional:
*value = OOJSValueFromBOOL([soundSource positional]);
return YES;
case kSoundSource_volume:
return JS_NewNumberValue(context, [soundSource gain], value);
default:
OOJSReportBadPropertySelector(context, this, propID, sSoundSourceProperties);
return NO;
@ -167,7 +185,9 @@ static JSBool SoundSourceSetProperty(JSContext *context, JSObject *this, jsid pr
OOSoundSource *soundSource = nil;
int32 iValue;
JSBool bValue;
Vector vValue;
double fValue;
if (!JSSoundSourceGetSoundSource(context, this, &soundSource)) return NO;
switch (JSID_TO_INT(propID))
@ -195,6 +215,32 @@ static JSBool SoundSourceSetProperty(JSContext *context, JSObject *this, jsid pr
}
break;
case kSoundSource_position:
if (JSValueToVector(context, *value, &vValue))
{
[soundSource setPosition:vValue];
return YES;
}
break;
case kSoundSource_positional:
if (JS_ValueToBoolean(context, *value, &bValue))
{
[soundSource setPositional:bValue];
return YES;
}
break;
case kSoundSource_volume:
if (JS_ValueToNumber(context, *value, &fValue))
{
fValue = OOClamp_0_max_d(fValue, 1);
[soundSource setGain:fValue];
return YES;
}
break;
default:
OOJSReportBadPropertySelector(context, this, propID, sSoundSourceProperties);
return NO;

View File

@ -68,11 +68,11 @@ static NSString * const kOOLogLoadScriptNone = @"script.load.none";
if (result == nil)
{
filePath = [path stringByAppendingPathComponent:@"script.js"];
if ([fmgr fileExistsAtPath:filePath]) foundScript = YES;
if ([fmgr oo_oxzFileExistsAtPath:filePath]) foundScript = YES;
else
{
filePath = [path stringByAppendingPathComponent:@"script.es"];
if ([fmgr fileExistsAtPath:filePath]) foundScript = YES;
if ([fmgr oo_oxzFileExistsAtPath:filePath]) foundScript = YES;
}
if (foundScript)
{
@ -95,7 +95,7 @@ static NSString * const kOOLogLoadScriptNone = @"script.load.none";
if (result == nil)
{
filePath = [path stringByAppendingPathComponent:@"script.plist"];
if ([fmgr fileExistsAtPath:filePath])
if ([fmgr oo_oxzFileExistsAtPath:filePath])
{
foundScript = YES;
OOLog(kOOLogLoadScriptPList, @"Trying to load property list script %@", filePath);
@ -157,8 +157,8 @@ static NSString * const kOOLogLoadScriptNone = @"script.load.none";
+ (NSArray *)scriptsFromFileAtPath:(NSString *)filePath
{
BOOL directory;
if (![[NSFileManager defaultManager] fileExistsAtPath:filePath isDirectory:&directory] || directory) return nil;
// oo_oxzFile always returns false for directories
if (![[NSFileManager defaultManager] oo_oxzFileExistsAtPath:filePath]) return nil;
NSString *extension = [[filePath pathExtension] lowercaseString];

View File

@ -27,7 +27,7 @@ SOFTWARE.
#import "OOSDLConcreteSound.h"
#import "OOLogging.h"
#import "NSDataOOExtensions.h"
@implementation OOSDLConcreteSound
@ -35,7 +35,10 @@ SOFTWARE.
{
if ((self = [super init]))
{
_chunk = Mix_LoadWAV([path UTF8String]);
NSData *fileData = [NSData oo_dataWithOXZFile:path];
SDL_RWops *soundData = SDL_RWFromConstMem([fileData bytes],[fileData length]);
_chunk = Mix_LoadWAV_RW(soundData, 0);
SDL_RWclose(soundData);
if (_chunk != NULL)
{

27
tools/mkmanifest.sh Executable file
View File

@ -0,0 +1,27 @@
#! /bin/sh
OOLITE_VERSION_FILE="src/Cocoa/oolite-version.xcconfig"
if [ $# -ge 1 ]; then
cd $1
if [ $? ]; then
exit $?
fi
fi
# Extract definition of $OOLITE_VERSION from the xcconfig
. $OOLITE_VERSION_FILE
echo "{"
echo " title = \"Oolite core\";"
echo " identifier = \"org.oolite.oolite\";"
echo " "
echo " version = \"$OOLITE_VERSION\";"
echo " required_oolite_version = \"$OOLITE_VERSION\";"
echo " "
echo " license = \"GPL 2+ / CC-BY-NC-SA 3.0 - see LICENSE.TXT for details\";"
echo " author = \"Giles Williams, Jens Ayton and contributors\";"
echo " information_url = \"http://www.oolite.org/\";"
echo "}"