Bumped version number to 1.69.2. Removed support for deprecated shader features. Added caching of GL texture names to avoid expensive glGenTextures()/glDeleteTextures() call. Set texture cache size to something sensible (50 at the moment), but textures are being leaked. Fixed loss-of-precision bug in OOCollectionExtractors' double methods. Added collection extractor methods for vectors, quaternions, and non-negative floats/doubles. Switched on -Werror for OS X build.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@1088 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2007-07-17 10:42:36 +00:00
parent 569b690990
commit a3cee138b8
42 changed files with 672 additions and 435 deletions

View File

@ -390,8 +390,8 @@
1A9406850BAF66D6005F6CF3 /* OOVoxel.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9406830BAF66D6005F6CF3 /* OOVoxel.m */; settings = {COMPILER_FLAGS = "-O3 -falign-loops=32 -falign-loops-max-skip=31 -falign-functions=32"; }; }; 1A9406850BAF66D6005F6CF3 /* OOVoxel.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9406830BAF66D6005F6CF3 /* OOVoxel.m */; settings = {COMPILER_FLAGS = "-O3 -falign-loops=32 -falign-loops-max-skip=31 -falign-functions=32"; }; };
1A9406B40BAF67BF005F6CF3 /* OOTriangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9406B20BAF67BF005F6CF3 /* OOTriangle.h */; }; 1A9406B40BAF67BF005F6CF3 /* OOTriangle.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9406B20BAF67BF005F6CF3 /* OOTriangle.h */; };
1A9406B50BAF67BF005F6CF3 /* OOTriangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9406B30BAF67BF005F6CF3 /* OOTriangle.m */; settings = {COMPILER_FLAGS = "-O3 -falign-loops=32 -falign-loops-max-skip=31 -falign-functions=32"; }; }; 1A9406B50BAF67BF005F6CF3 /* OOTriangle.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A9406B30BAF67BF005F6CF3 /* OOTriangle.m */; settings = {COMPILER_FLAGS = "-O3 -falign-loops=32 -falign-loops-max-skip=31 -falign-functions=32"; }; };
1A95338B0C02089E004EBB58 /* material-defaults.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1A9533890C02089E004EBB58 /* material-defaults.plist */; }; 1A95338B0C02089E004EBB58 /* material-defaults.plist in Copy Config */ = {isa = PBXBuildFile; fileRef = 1A9533890C02089E004EBB58 /* material-defaults.plist */; };
1A95338C0C02089E004EBB58 /* planetinfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 1A95338A0C02089E004EBB58 /* planetinfo.plist */; }; 1A95338C0C02089E004EBB58 /* planetinfo.plist in Copy Config */ = {isa = PBXBuildFile; fileRef = 1A95338A0C02089E004EBB58 /* planetinfo.plist */; };
1AB01ABE0BB15AED00F1B949 /* OOTextureScaling.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB01ABC0BB15AED00F1B949 /* OOTextureScaling.h */; }; 1AB01ABE0BB15AED00F1B949 /* OOTextureScaling.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB01ABC0BB15AED00F1B949 /* OOTextureScaling.h */; };
1AB01B5F0BB1639600F1B949 /* OOTextureScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AB01ABD0BB15AED00F1B949 /* OOTextureScaling.m */; }; 1AB01B5F0BB1639600F1B949 /* OOTextureScaling.m in Sources */ = {isa = PBXBuildFile; fileRef = 1AB01ABD0BB15AED00F1B949 /* OOTextureScaling.m */; };
1AB01BBB0BB16A8A00F1B949 /* OOFastArithmetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB01BB90BB16A8A00F1B949 /* OOFastArithmetic.h */; }; 1AB01BBB0BB16A8A00F1B949 /* OOFastArithmetic.h in Headers */ = {isa = PBXBuildFile; fileRef = 1AB01BB90BB16A8A00F1B949 /* OOFastArithmetic.h */; };
@ -568,6 +568,8 @@
dstPath = Config; dstPath = Config;
dstSubfolderSpec = 7; dstSubfolderSpec = 7;
files = ( files = (
1A95338B0C02089E004EBB58 /* material-defaults.plist in Copy Config */,
1A95338C0C02089E004EBB58 /* planetinfo.plist in Copy Config */,
1AD0C3300C463FCC0070BD23 /* autoAImap.plist in Copy Config */, 1AD0C3300C463FCC0070BD23 /* autoAImap.plist in Copy Config */,
1A3591830C1C382700E52220 /* nebulatextures.plist in Copy Config */, 1A3591830C1C382700E52220 /* nebulatextures.plist in Copy Config */,
1A3591840C1C382700E52220 /* startextures.plist in Copy Config */, 1A3591840C1C382700E52220 /* startextures.plist in Copy Config */,
@ -872,7 +874,7 @@
083325DC09DDBCDE00F5B8E4 /* OOColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOColor.m; sourceTree = "<group>"; }; 083325DC09DDBCDE00F5B8E4 /* OOColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOColor.m; sourceTree = "<group>"; };
083DB4D30A70E51E00B419B2 /* OOBrain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOBrain.h; sourceTree = "<group>"; }; 083DB4D30A70E51E00B419B2 /* OOBrain.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOBrain.h; sourceTree = "<group>"; };
083DB4D40A70E51E00B419B2 /* OOBrain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOBrain.m; sourceTree = "<group>"; }; 083DB4D40A70E51E00B419B2 /* OOBrain.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOBrain.m; sourceTree = "<group>"; };
0865432206B8447D000CA0AB /* Oolite.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Oolite.app; sourceTree = BUILT_PRODUCTS_DIR; }; 0865432206B8447D000CA0AB /* OoliteDev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OoliteDev.app; sourceTree = BUILT_PRODUCTS_DIR; };
0878FD2F086EF845004CB752 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; }; 0878FD2F086EF845004CB752 /* Carbon.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Carbon.framework; path = /System/Library/Frameworks/Carbon.framework; sourceTree = "<absolute>"; };
1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; }; 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = "<absolute>"; };
1A08317C0C2EED9700E3AE25 /* debugLogMessageClassesMenu.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = debugLogMessageClassesMenu.plist; sourceTree = "<group>"; }; 1A08317C0C2EED9700E3AE25 /* debugLogMessageClassesMenu.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist; path = debugLogMessageClassesMenu.plist; sourceTree = "<group>"; };
@ -1197,10 +1199,6 @@
1A5E462D0C32DACE008104B4 /* OOShaderUniformMethodType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOShaderUniformMethodType.m; sourceTree = "<group>"; }; 1A5E462D0C32DACE008104B4 /* OOShaderUniformMethodType.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOShaderUniformMethodType.m; sourceTree = "<group>"; };
1A5E462E0C32DACE008104B4 /* OOShaderUniformMethodType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOShaderUniformMethodType.h; sourceTree = "<group>"; }; 1A5E462E0C32DACE008104B4 /* OOShaderUniformMethodType.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOShaderUniformMethodType.h; sourceTree = "<group>"; };
1A67050E0C4904ED002551AA /* oolite-cloaking-device.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "oolite-cloaking-device.js"; sourceTree = "<group>"; }; 1A67050E0C4904ED002551AA /* oolite-cloaking-device.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = "oolite-cloaking-device.js"; sourceTree = "<group>"; };
1A71D85A0BCA88AA00CD5C13 /* OOPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOPlayer.h; sourceTree = "<group>"; };
1A71D85B0BCA88AA00CD5C13 /* OOPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOPlayer.m; sourceTree = "<group>"; };
1A71D89F0BCA8B6500CD5C13 /* OOLocalPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOLocalPlayer.h; sourceTree = "<group>"; };
1A71D8A00BCA8B6500CD5C13 /* OOLocalPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOLocalPlayer.m; sourceTree = "<group>"; };
1A71E6F30BCE340C00CD5C13 /* libpng.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpng.a; sourceTree = BUILT_PRODUCTS_DIR; }; 1A71E6F30BCE340C00CD5C13 /* libpng.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libpng.a; sourceTree = BUILT_PRODUCTS_DIR; };
1A71E7030BCE34CF00CD5C13 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pngconf.h; sourceTree = "<group>"; }; 1A71E7030BCE34CF00CD5C13 /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = pngconf.h; sourceTree = "<group>"; };
1A71E7040BCE34CF00CD5C13 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pngmem.c; sourceTree = "<group>"; }; 1A71E7040BCE34CF00CD5C13 /* pngmem.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pngmem.c; sourceTree = "<group>"; };
@ -1466,7 +1464,7 @@
19C28FACFE9D520D11CA2CBB /* Products */ = { 19C28FACFE9D520D11CA2CBB /* Products */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
0865432206B8447D000CA0AB /* Oolite.app */, 0865432206B8447D000CA0AB /* OoliteDev.app */,
1A71E6F30BCE340C00CD5C13 /* libpng.a */, 1A71E6F30BCE340C00CD5C13 /* libpng.a */,
); );
name = Products; name = Products;
@ -1887,17 +1885,6 @@
path = Materials; path = Materials;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
1A71E5230BCD7C4E00CD5C13 /* Player refactoring */ = {
isa = PBXGroup;
children = (
1A71D85A0BCA88AA00CD5C13 /* OOPlayer.h */,
1A71D85B0BCA88AA00CD5C13 /* OOPlayer.m */,
1A71D89F0BCA8B6500CD5C13 /* OOLocalPlayer.h */,
1A71D8A00BCA8B6500CD5C13 /* OOLocalPlayer.m */,
);
name = "Player refactoring";
sourceTree = "<group>";
};
1A71E6FB0BCE345800CD5C13 /* libpng */ = { 1A71E6FB0BCE345800CD5C13 /* libpng */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
@ -1982,7 +1969,6 @@
25161110099544390037C2E1 /* OOTrumble.h */, 25161110099544390037C2E1 /* OOTrumble.h */,
25161108099544390037C2E1 /* OOTrumble.m */, 25161108099544390037C2E1 /* OOTrumble.m */,
1A2A1B020BD2768300152975 /* Graphics */, 1A2A1B020BD2768300152975 /* Graphics */,
1A71E5230BCD7C4E00CD5C13 /* Player refactoring */,
1A5DBA980BC000DC00D57389 /* Scripting */, 1A5DBA980BC000DC00D57389 /* Scripting */,
); );
name = Source; name = Source;
@ -2534,7 +2520,7 @@
name = Oolite; name = Oolite;
productInstallPath = "$(HOME)/Applications"; productInstallPath = "$(HOME)/Applications";
productName = Oolite; productName = Oolite;
productReference = 0865432206B8447D000CA0AB /* Oolite.app */; productReference = 0865432206B8447D000CA0AB /* OoliteDev.app */;
productType = "com.apple.product-type.application"; productType = "com.apple.product-type.application";
}; };
1A71E6F20BCE340C00CD5C13 /* libpng-custom */ = { 1A71E6F20BCE340C00CD5C13 /* libpng-custom */ = {
@ -2598,8 +2584,6 @@
25F3E8A80994FE65002F25FD /* oolite-expansion-document.icns in Resources */, 25F3E8A80994FE65002F25FD /* oolite-expansion-document.icns in Resources */,
25F3E8A90994FE65002F25FD /* oolite-icon.icns in Resources */, 25F3E8A90994FE65002F25FD /* oolite-icon.icns in Resources */,
25F3E8B40994FE9B002F25FD /* InfoPlist.strings in Resources */, 25F3E8B40994FE9B002F25FD /* InfoPlist.strings in Resources */,
1A95338B0C02089E004EBB58 /* material-defaults.plist in Resources */,
1A95338C0C02089E004EBB58 /* planetinfo.plist in Resources */,
1A358CE20C1AB80D00E52220 /* ReadMe.rtfd in Resources */, 1A358CE20C1AB80D00E52220 /* ReadMe.rtfd in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -2824,6 +2808,7 @@
GCC_PREPROCESSOR_DEFINITIONS = XP_UNIX; GCC_PREPROCESSOR_DEFINITIONS = XP_UNIX;
GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = OO_DEBUG; GCC_PREPROCESSOR_DEFINITIONS_NOT_USED_IN_PRECOMPS = OO_DEBUG;
GCC_REUSE_STRINGS = YES; GCC_REUSE_STRINGS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(HEADER_SEARCH_PATHS_QUOTED_1)", "$(HEADER_SEARCH_PATHS_QUOTED_1)",
"$(HEADER_SEARCH_PATHS_QUOTED_2)", "$(HEADER_SEARCH_PATHS_QUOTED_2)",
@ -2877,6 +2862,7 @@
OOLOG_NO_FILE_NAME, OOLOG_NO_FILE_NAME,
); );
GCC_REUSE_STRINGS = YES; GCC_REUSE_STRINGS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(HEADER_SEARCH_PATHS_QUOTED_1)", "$(HEADER_SEARCH_PATHS_QUOTED_1)",
"$(HEADER_SEARCH_PATHS_QUOTED_2)", "$(HEADER_SEARCH_PATHS_QUOTED_2)",
@ -2980,6 +2966,7 @@
"OO_SMART_CRASH_REPORT_INSTALL=1", "OO_SMART_CRASH_REPORT_INSTALL=1",
); );
GCC_REUSE_STRINGS = YES; GCC_REUSE_STRINGS = YES;
GCC_TREAT_WARNINGS_AS_ERRORS = YES;
HEADER_SEARCH_PATHS = ( HEADER_SEARCH_PATHS = (
"$(HEADER_SEARCH_PATHS_QUOTED_1)", "$(HEADER_SEARCH_PATHS_QUOTED_1)",
"$(HEADER_SEARCH_PATHS_QUOTED_2)", "$(HEADER_SEARCH_PATHS_QUOTED_2)",

View File

@ -39,7 +39,7 @@
key_snapshot = "*"; key_snapshot = "*";
key_docking_music = "s"; key_docking_music = "s";
kay_advanced_nav_array = "^"; key_advanced_nav_array = "^";
key_map_home = 302; // Home key_map_home = 302; // Home
key_map_info = "i"; key_map_info = "i";

View File

@ -278,6 +278,8 @@
texture.dealloc = $textureDebug; texture.dealloc = $textureDebug;
texture.upload = $textureDebug; texture.upload = $textureDebug;
textureCache = $textureDebug;
textureLoader.asyncLoad = $textureDebug; textureLoader.asyncLoad = $textureDebug;
textureLoader.asyncLoad.done = inherit; textureLoader.asyncLoad.done = inherit;
textureLoader.asyncLoad.exception = $error; textureLoader.asyncLoad.exception = $error;

View File

@ -424,6 +424,8 @@
<string>inherit</string> <string>inherit</string>
<key>texture.upload</key> <key>texture.upload</key>
<string>$textureDebug</string> <string>$textureDebug</string>
<key>textureCache</key>
<string>$textureDebug</string>
<key>textureLoader.asyncLoad</key> <key>textureLoader.asyncLoad</key>
<string>$textureDebug</string> <string>$textureDebug</string>
<key>textureLoader.asyncLoad.done</key> <key>textureLoader.asyncLoad.done</key>

View File

@ -5,18 +5,6 @@
*/ */
{ {
// Default shader uniform bindings for ship entities.
"ship-default-bindings" =
{
"engine_level" = { type = "binding"; value = "speedFactor"; };
"laser_heat_level" = { type = "binding"; value = "laserHeatLevel"; clamped = "YES"; };
"hull_heat_level" = { type = "binding"; value = "hullHeatLevel"; };
"entity_personality" = { type = "binding"; value = "entityPersonality"; };
"entity_personality_int" = { type = "binding"; value = "entityPersonalityInt"; };
"time" = { type = "binding"; value = "universalTime"; };
};
// Macros prepended to shader source code for ship entities. // Macros prepended to shader source code for ship entities.
"ship-prefix-macros" = "ship-prefix-macros" =
{ {

View File

@ -1,6 +1,6 @@
/* Localized versions of Info.plist keys */ /* Localized versions of Info.plist keys */
CFBundleName = "Oolite"; CFBundleName = "Oolite";
CFBundleShortVersionString = "Oolite version 1.69.1"; CFBundleShortVersionString = "Oolite version 1.69.2";
CFBundleGetInfoString = "Oolite version 1.69.1, © 2003-2007 Giles Williams and contributors."; CFBundleGetInfoString = "Oolite version 1.69.2, © 2003-2007 Giles Williams and contributors.";
NSHumanReadableCopyright = "Copyright 2003-2007 Giles Williams and contributors."; NSHumanReadableCopyright = "Copyright 2003-2007 Giles Williams and contributors.";

View File

@ -29,7 +29,7 @@ this.name = "oolite-cloaking-device";
this.author = "Jens Ayton"; this.author = "Jens Ayton";
this.copyright = "(C) 2007 the Oolite team."; this.copyright = "(C) 2007 the Oolite team.";
this.description = "Cloaking device mission in galaxy 5."; this.description = "Cloaking device mission in galaxy 5.";
this.version = "1.69.1"; this.version = "1.69.2";
this.willExitWitchSpace = function() this.willExitWitchSpace = function()

View File

@ -1,7 +1,7 @@
{ {
"!metadata!" = { "!metadata!" = {
// NOTE: metadata tagging syntax is not backwards compatible with versions of Oolite prior to 1.68. // NOTE: metadata tagging syntax is not backwards compatible with versions of Oolite prior to 1.68.
version = "1.69.1"; version = "1.69.2";
description = "Oolite built-in world scripts."; description = "Oolite built-in world scripts.";
}; };

View File

@ -48,7 +48,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>Ool8</string> <string>Ool8</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.69.1</string> <string>1.69.2</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>
@ -97,6 +97,6 @@
<key>SmartCrashReports_EmailTicket</key> <key>SmartCrashReports_EmailTicket</key>
<string>SCR-A36F37AFFD</string> <string>SCR-A36F37AFFD</string>
<key>SmartCrashReports_CommentsTemplate</key> <key>SmartCrashReports_CommentsTemplate</key>
<string>Please paste the contents of the run log (in your home folder, open Libray, then Logs, then Oolite, then Latest.log) here.</string> <string>Please paste the last few lines of the run log here (in your home folder, open Library, then Logs, then Oolite, then Latest.log). If a large portion of the log appears relevant, consider sending a bug report by e-mail to oolite.bug.reports@gmail.com instead; please include the crash log if you do (Library, Logs, CrashReporter, Oolite.crash.log).</string>
</dict> </dict>
</plist> </plist>

View File

@ -48,7 +48,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>Ool8</string> <string>Ool8</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.69.1</string> <string>1.69.2</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@ -48,7 +48,7 @@
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>Ool8</string> <string>Ool8</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.69.1</string> <string>1.69.2</string>
<key>NSMainNibFile</key> <key>NSMainNibFile</key>
<string>MainMenu</string> <string>MainMenu</string>
<key>NSPrincipalClass</key> <key>NSPrincipalClass</key>

View File

@ -70,7 +70,7 @@ typedef struct
} Frame; } Frame;
@interface Entity: NSObject <OOWeakReferenceSupport> @interface Entity: OOWeakRefObject
{ {
// the base object for ships/stations/anything actually // the base object for ships/stations/anything actually
////////////////////////////////////////////////////// //////////////////////////////////////////////////////
@ -153,8 +153,6 @@ typedef struct
OOUniversalID owner; OOUniversalID owner;
OOWeakReference *weakSelf;
OOTimeAbsolute spawnTime; OOTimeAbsolute spawnTime;
} }

View File

@ -86,26 +86,11 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
[collidingEntities release]; [collidingEntities release];
[trackLock release]; [trackLock release];
[collisionRegion release]; [collisionRegion release];
[weakSelf weakRefDrop];
[super dealloc]; [super dealloc];
} }
- (id)weakRetain
{
if (weakSelf == nil) weakSelf = [OOWeakReference weakRefWithObject:self];
return [weakSelf retain];
}
- (void)weakRefDied:(OOWeakReference *)weakRef
{
assert(weakRef == weakSelf);
weakSelf = nil;
}
- (NSString *)description - (NSString *)description
{ {
return [NSString stringWithFormat:@"<%@ %p>{%u position=%@ scanClass=%@ status=%@}", [self class], self, [self universalID], VectorDescription([self position]), ScanClassToString([self scanClass]), EntityStatusToString([self status])]; return [NSString stringWithFormat:@"<%@ %p>{%u position=%@ scanClass=%@ status=%@}", [self class], self, [self universalID], VectorDescription([self position]), ScanClassToString([self scanClass]), EntityStatusToString([self status])];
@ -1032,7 +1017,7 @@ static NSString * const kOOLogEntityUpdateError = @"entity.linkedList.update.
- (void)subEntityReallyDied:(ShipEntity *)sub - (void)subEntityReallyDied:(ShipEntity *)sub
{ {
OOLog(@"entity.bug", @"%s called for non-ship entity %@ by %@", self, sub); OOLog(@"entity.bug", @"%s called for non-ship entity %@ by %@", __FUNCTION__, self, sub);
} }

View File

@ -217,7 +217,7 @@ typedef enum
OOTexture *missionBackgroundTexture; OOTexture *missionBackgroundTexture;
NSMutableDictionary *extra_equipment; NSMutableDictionary *extra_equipment; // TODO: this seems to be a dictionary whose values are all [NSNumber numberWithBool:YES]. Should be a set; remember to convert to dictionary for savinh.
BOOL found_equipment; BOOL found_equipment;
NSMutableDictionary *reputation; NSMutableDictionary *reputation;
@ -378,7 +378,7 @@ typedef enum
OOKeyCode key_snapshot; OOKeyCode key_snapshot;
OOKeyCode key_docking_music; OOKeyCode key_docking_music;
OOKeyCode kay_advanced_nav_array; OOKeyCode key_advanced_nav_array;
OOKeyCode key_map_home; OOKeyCode key_map_home;
OOKeyCode key_map_info; OOKeyCode key_map_info;

View File

@ -994,20 +994,17 @@ static PlayerEntity *sSharedPlayer = nil;
// set things from dictionary from here out // set things from dictionary from here out
maxFlightSpeed = [shipDict doubleForKey:@"max_flight_speed" defaultValue:160.0f]; maxFlightSpeed = [shipDict floatForKey:@"max_flight_speed" defaultValue:160.0f];
max_flight_roll = [shipDict doubleForKey:@"max_flight_roll" defaultValue:2.0f]; max_flight_roll = [shipDict floatForKey:@"max_flight_roll" defaultValue:2.0f];
max_flight_pitch = [shipDict doubleForKey:@"max_flight_pitch" defaultValue:1.0f]; max_flight_pitch = [shipDict floatForKey:@"max_flight_pitch" defaultValue:1.0f];
max_flight_yaw = [shipDict doubleForKey:@"max_flight_yaw" defaultValue:max_flight_pitch]; // Note by default yaw == pitch max_flight_yaw = [shipDict floatForKey:@"max_flight_yaw" defaultValue:max_flight_pitch]; // Note by default yaw == pitch
// set control factors.. // set control factors..
roll_delta = 2.0 * max_flight_roll; roll_delta = 2.0 * max_flight_roll;
pitch_delta = 2.0 * max_flight_pitch; pitch_delta = 2.0 * max_flight_pitch;
yaw_delta = 2.0 * max_flight_yaw; yaw_delta = 2.0 * max_flight_yaw;
if ([shipDict objectForKey:@"thrust"]) thrust = [shipDict floatForKey:@"thrust" defaultValue:thrust];
{
thrust = [(NSNumber *)[shipDict objectForKey:@"thrust"] doubleValue];
}
maxEnergy = [shipDict floatForKey:@"max_energy" defaultValue:maxEnergy]; maxEnergy = [shipDict floatForKey:@"max_energy" defaultValue:maxEnergy];
energy_recharge_rate = [shipDict floatForKey:@"energy_recharge_rate" defaultValue:energy_recharge_rate]; energy_recharge_rate = [shipDict floatForKey:@"energy_recharge_rate" defaultValue:energy_recharge_rate];
@ -1033,7 +1030,6 @@ static PlayerEntity *sSharedPlayer = nil;
shadersDictionary:[shipDict dictionaryForKey:@"shaders"] shadersDictionary:[shipDict dictionaryForKey:@"shaders"]
smooth:[shipDict boolForKey:@"smooth" defaultValue:NO] smooth:[shipDict boolForKey:@"smooth" defaultValue:NO]
shaderMacros:DefaultShipShaderMacros() shaderMacros:DefaultShipShaderMacros()
defaultBindings:DefaultShipShaderBindings()
shaderBindingTarget:self]; shaderBindingTarget:self];
[self setMesh:mesh]; [self setMesh:mesh];
} }
@ -1093,15 +1089,12 @@ static PlayerEntity *sSharedPlayer = nil;
ScanVectorFromString([shipDict stringForKey:@"view_position_aft"], &aftViewOffset); ScanVectorFromString([shipDict stringForKey:@"view_position_aft"], &aftViewOffset);
ScanVectorFromString([shipDict stringForKey:@"view_position_port"], &portViewOffset); ScanVectorFromString([shipDict stringForKey:@"view_position_port"], &portViewOffset);
ScanVectorFromString([shipDict stringForKey:@"view_position_starboard"], &starboardViewOffset); ScanVectorFromString([shipDict stringForKey:@"view_position_starboard"], &starboardViewOffset);
if ([shipDict objectForKey:@"custom_views"]) NSArray *customViews = [shipDict arrayForKey:@"custom_views"];
if (customViews != nil)
{ {
NSObject* obj = [shipDict objectForKey:@"custom_views"]; [custom_views release];
if ([obj isKindOfClass:[NSArray class]]) custom_views = [customViews mutableCopy]; // FIXME: This is mutable because it's used as a queue rather than using an index. Silly, fix. -- Ahruman
{
[custom_views release];
custom_views = [[NSMutableArray arrayWithArray:(NSArray*)obj] retain];
}
} }
// set weapon offsets // set weapon offsets
@ -1467,7 +1460,7 @@ double scoopSoundPlayTime = 0.0;
BOOL go = YES; BOOL go = YES;
// check nearby masses // check nearby masses
ShipEntity* blocker = (ShipEntity*)[UNIVERSE entityForUniversalID:[self checkShipsInVicinityForWitchJumpExit]]; ShipEntity* blocker = [UNIVERSE entityForUniversalID:[self checkShipsInVicinityForWitchJumpExit]];
if (blocker) if (blocker)
{ {
[UNIVERSE clearPreviousMessage]; [UNIVERSE clearPreviousMessage];
@ -1566,7 +1559,7 @@ double scoopSoundPlayTime = 0.0;
{ {
if (missile_status == MISSILE_STATUS_TARGET_LOCKED) if (missile_status == MISSILE_STATUS_TARGET_LOCKED)
{ {
ShipEntity* e = (ShipEntity*)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity* e = [UNIVERSE entityForUniversalID:primaryTarget];
if ((e == nil)||(e->zero_distance > SCANNER_MAX_RANGE2)|| if ((e == nil)||(e->zero_distance > SCANNER_MAX_RANGE2)||
((e->isShip)&&([e isCloaked]))|| // checks for cloaked ships ((e->isShip)&&([e isCloaked]))|| // checks for cloaked ships
((e->isShip)&&(!has_military_scanner_filter)&&([e isJammingScanning]))) // checks for activated jammer ((e->isShip)&&(!has_military_scanner_filter)&&([e isJammingScanning]))) // checks for activated jammer
@ -1831,7 +1824,7 @@ double scoopSoundPlayTime = 0.0;
if ((status == STATUS_ESCAPE_SEQUENCE)&&(shot_time > ESCAPE_SEQUENCE_TIME)) if ((status == STATUS_ESCAPE_SEQUENCE)&&(shot_time > ESCAPE_SEQUENCE_TIME))
{ {
[(ShipEntity *)[UNIVERSE entityForUniversalID:found_target] becomeExplosion]; // blow up the doppelganger [[UNIVERSE entityForUniversalID:found_target] becomeExplosion]; // blow up the doppelganger
[self setTargetToStation]; [self setTargetToStation];
if ([self primaryTarget]) if ([self primaryTarget])
{ {
@ -2362,9 +2355,9 @@ double scoopSoundPlayTime = 0.0;
else else
{ {
nextBeaconID = [[UNIVERSE firstBeacon] universalID]; nextBeaconID = [[UNIVERSE firstBeacon] universalID];
while ((nextBeaconID != NO_TARGET)&&[(ShipEntity*)[UNIVERSE entityForUniversalID:nextBeaconID] isJammingScanning]) while ((nextBeaconID != NO_TARGET)&&[[UNIVERSE entityForUniversalID:nextBeaconID] isJammingScanning])
{ {
nextBeaconID = [(ShipEntity*)[UNIVERSE entityForUniversalID:nextBeaconID] nextBeaconID]; nextBeaconID = [[UNIVERSE entityForUniversalID:nextBeaconID] nextBeaconID];
} }
if (nextBeaconID != NO_TARGET) if (nextBeaconID != NO_TARGET)
@ -2375,9 +2368,9 @@ double scoopSoundPlayTime = 0.0;
break; break;
case COMPASS_MODE_TARGET: case COMPASS_MODE_TARGET:
nextBeaconID = [[UNIVERSE firstBeacon] universalID]; nextBeaconID = [[UNIVERSE firstBeacon] universalID];
while ((nextBeaconID != NO_TARGET)&&[(ShipEntity*)[UNIVERSE entityForUniversalID:nextBeaconID] isJammingScanning]) while ((nextBeaconID != NO_TARGET)&&[[UNIVERSE entityForUniversalID:nextBeaconID] isJammingScanning])
{ {
nextBeaconID = [(ShipEntity*)[UNIVERSE entityForUniversalID:nextBeaconID] nextBeaconID]; nextBeaconID = [[UNIVERSE entityForUniversalID:nextBeaconID] nextBeaconID];
} }
if (nextBeaconID != NO_TARGET) if (nextBeaconID != NO_TARGET)
@ -2388,8 +2381,8 @@ double scoopSoundPlayTime = 0.0;
case COMPASS_MODE_BEACONS: case COMPASS_MODE_BEACONS:
do do
{ {
nextBeaconID = [(ShipEntity*)[UNIVERSE entityForUniversalID:nextBeaconID] nextBeaconID]; nextBeaconID = [[UNIVERSE entityForUniversalID:nextBeaconID] nextBeaconID];
} while ((nextBeaconID != NO_TARGET)&&[(ShipEntity*)[UNIVERSE entityForUniversalID:nextBeaconID] isJammingScanning]); } while ((nextBeaconID != NO_TARGET)&&[[UNIVERSE entityForUniversalID:nextBeaconID] isJammingScanning]);
if (nextBeaconID == NO_TARGET) if (nextBeaconID == NO_TARGET)
[self setCompassMode:COMPASS_MODE_PLANET]; [self setCompassMode:COMPASS_MODE_PLANET];
@ -6031,7 +6024,7 @@ OOSound* burnersound;
if (++target_memory_index >= PLAYER_TARGET_MEMORY_SIZE) if (++target_memory_index >= PLAYER_TARGET_MEMORY_SIZE)
target_memory_index -= PLAYER_TARGET_MEMORY_SIZE; target_memory_index -= PLAYER_TARGET_MEMORY_SIZE;
int targ_id = target_memory[target_memory_index]; int targ_id = target_memory[target_memory_index];
ShipEntity* potential_target = (ShipEntity*)[UNIVERSE entityForUniversalID: targ_id]; ShipEntity* potential_target = [UNIVERSE entityForUniversalID: targ_id];
if ((potential_target)&&(potential_target->isShip)) if ((potential_target)&&(potential_target->isShip))
{ {
@ -6058,7 +6051,7 @@ OOSound* burnersound;
if (--target_memory_index < 0) if (--target_memory_index < 0)
target_memory_index += PLAYER_TARGET_MEMORY_SIZE; target_memory_index += PLAYER_TARGET_MEMORY_SIZE;
int targ_id = target_memory[target_memory_index]; int targ_id = target_memory[target_memory_index];
ShipEntity* potential_target = (ShipEntity*)[UNIVERSE entityForUniversalID: targ_id]; ShipEntity* potential_target = [UNIVERSE entityForUniversalID: targ_id];
if ((potential_target)&&(potential_target->isShip)) if ((potential_target)&&(potential_target->isShip))
{ {

View File

@ -59,34 +59,38 @@ static NSString * const kOOLogFlightTrainingBeacons = @"beacon.list.flightTrain
// pre-process kdic - replace any strings with an integer representing the ASCII value of the first character // pre-process kdic - replace any strings with an integer representing the ASCII value of the first character
unsigned i; unsigned i;
NSArray* keys = [kdic allKeys]; NSArray *keys = nil;
id key = nil, value = nil;
int iValue;
unsigned char keychar;
NSString *keystring = nil;
keys = [kdic allKeys];
for (i = 0; i < [keys count]; i++) for (i = 0; i < [keys count]; i++)
{ {
id key = [keys objectAtIndex:i]; key = [keys objectAtIndex:i];
id value = [kdic objectForKey: key]; value = [kdic objectForKey: key];
int iValue = [value intValue]; iValue = [value intValue];
// for '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' - we want to interpret those as strings - not numbers // for '0' '1' '2' '3' '4' '5' '6' '7' '8' '9' - we want to interpret those as strings - not numbers
// alphabetical characters and symbols will return an intValue of 0. // alphabetical characters and symbols will return an intValue of 0.
if ([value isKindOfClass:[NSString class]] && (iValue < 10)) if ([value isKindOfClass:[NSString class]] && (iValue < 10))
{ {
char keychar; keystring = value;
NSString *keystring = value;
if ([keystring length] == 1 || (iValue == 0 && [keystring length] != 0)) if ([keystring length] == 1 || (iValue == 0 && [keystring length] != 0))
{ {
keychar = [keystring characterAtIndex: 0] & 0x00ff; // uses lower byte of unichar keychar = [keystring characterAtIndex: 0] & 0x00ff; // uses lower byte of unichar
} }
else if (iValue <= 0xFF) keychar = iValue; else if (iValue <= 0xFF) keychar = iValue;
[kdic setObject:[NSNumber numberWithInt:(int)keychar] forKey:key]; [kdic setObject:[NSNumber numberWithUnsignedChar:keychar] forKey:key];
} }
} }
// set default keys... // set default keys.
#define LOAD_KEY_SETTING(name, default) name = [kdic intForKey:@#name defaultValue:default] #define LOAD_KEY_SETTING(name, default) name = [kdic unsignedShortForKey:@#name defaultValue:default]
LOAD_KEY_SETTING(key_roll_left, gvArrowKeyLeft ); LOAD_KEY_SETTING(key_roll_left, gvArrowKeyLeft );
LOAD_KEY_SETTING(key_roll_right, gvArrowKeyRight ); LOAD_KEY_SETTING(key_roll_right, gvArrowKeyRight );
@ -128,7 +132,7 @@ static NSString * const kOOLogFlightTrainingBeacons = @"beacon.list.flightTrain
LOAD_KEY_SETTING(key_snapshot, '*' ); LOAD_KEY_SETTING(key_snapshot, '*' );
LOAD_KEY_SETTING(key_docking_music, 's' ); LOAD_KEY_SETTING(key_docking_music, 's' );
LOAD_KEY_SETTING(kay_advanced_nav_array, '^' ); LOAD_KEY_SETTING(key_advanced_nav_array, '^' );
LOAD_KEY_SETTING(key_map_home, gvHomeKey ); LOAD_KEY_SETTING(key_map_home, gvHomeKey );
LOAD_KEY_SETTING(key_map_info, 'i' ); LOAD_KEY_SETTING(key_map_info, 'i' );
@ -1475,7 +1479,7 @@ static BOOL spacePressed;
switch (gui_screen) switch (gui_screen)
{ {
case GUI_SCREEN_LONG_RANGE_CHART : case GUI_SCREEN_LONG_RANGE_CHART :
if ([gameView isDown:kay_advanced_nav_array]) // '^' key if ([gameView isDown:key_advanced_nav_array]) // '^' key
{ {
if (!pling_pressed) if (!pling_pressed)
{ {

View File

@ -108,17 +108,17 @@ MA 02110-1301, USA.
//scripting //scripting
NSArray *launch_actions; NSArray *launch_actions;
NSArray *script_actions; NSArray *script_actions; // used by cargo-containers with CARGO_SCRIPT_ACTION when you scoop them, used by Stations when you dock with them, used during custom system set up too
NSArray *death_actions; NSArray *death_actions;
//docking instructions //docking instructions
NSDictionary *dockingInstructions; NSDictionary *dockingInstructions;
int escort_ids[MAX_ESCORTS]; // replaces the mutable array OOUniversalID escort_ids[MAX_ESCORTS]; // replaces the mutable array
int escortCount; // initially, number of escorts to set up, later number of escorts available unsigned escortCount; // initially, number of escorts to set up, later number of escorts available
int groupID; // id of group leader int groupID; // id of group leader
int last_escort_target; // last target an escort was deployed after OOUniversalID last_escort_target; // last target an escort was deployed after
int found_hostiles; // number of hostiles found unsigned found_hostiles; // number of hostiles found
OOColor *laser_color; OOColor *laser_color;
@ -225,11 +225,12 @@ MA 02110-1301, USA.
// navigation // navigation
GLfloat flightSpeed; // current speed GLfloat flightSpeed; // current speed
GLfloat flightRoll; // current roll rate GLfloat flightRoll; // current roll rate
GLfloat flightPitch; // current pitch rate GLfloat flightPitch; // current pitch rate
GLfloat flightYaw; // current yaw rate GLfloat flightYaw; // current yaw rate
GLfloat pitch_tolerance; float accuracy;
float pitch_tolerance;
OOAegisStatus aegis_status; // set to YES when within the station's protective zone OOAegisStatus aegis_status; // set to YES when within the station's protective zone
@ -269,12 +270,12 @@ MA 02110-1301, USA.
// for advanced scanning etc. // for advanced scanning etc.
ShipEntity* scanned_ships[MAX_SCAN_NUMBER + 1]; ShipEntity* scanned_ships[MAX_SCAN_NUMBER + 1];
GLfloat distance2_scanned_ships[MAX_SCAN_NUMBER + 1]; GLfloat distance2_scanned_ships[MAX_SCAN_NUMBER + 1];
int n_scanned_ships; unsigned n_scanned_ships;
// advanced navigation // advanced navigation
Vector navpoints[32]; Vector navpoints[32];
int next_navpoint_index; unsigned next_navpoint_index;
int number_of_navpoints; unsigned number_of_navpoints;
// Collision detection // Collision detection
Octree *octree; Octree *octree;
@ -367,8 +368,8 @@ MA 02110-1301, USA.
- (int) groupID; - (int) groupID;
- (void) setGroupID:(int) value; - (void) setGroupID:(int) value;
- (int) escortCount; - (unsigned) escortCount;
- (void) setEscortCount:(int) value; - (void) setEscortCount:(unsigned) value;
- (ShipEntity *) proximity_alert; - (ShipEntity *) proximity_alert;
- (void) setProximity_alert:(ShipEntity*) other; - (void) setProximity_alert:(ShipEntity*) other;
@ -621,5 +622,4 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role);
BOOL ship_canCollide (ShipEntity* ship); BOOL ship_canCollide (ShipEntity* ship);
NSDictionary *DefaultShipShaderBindings(void);
NSDictionary *DefaultShipShaderMacros(void); NSDictionary *DefaultShipShaderMacros(void);

View File

@ -108,6 +108,7 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
{ {
NSDictionary *shipDict = dict; NSDictionary *shipDict = dict;
unsigned i; unsigned i;
PlayerEntity *player = [PlayerEntity sharedPlayer];
// Does this positional stuff need setting up here? // Does this positional stuff need setting up here?
// Either way, having four representations of orientation is dumb. Needs fixing. --Ahruman // Either way, having four representations of orientation is dumb. Needs fixing. --Ahruman
@ -140,24 +141,23 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
shipDict = shipinfoDictionary; // TEMP: ensure no mutation shipDict = shipinfoDictionary; // TEMP: ensure no mutation
// set things from dictionary from here out // set things from dictionary from here out
maxFlightSpeed = [shipDict doubleForKey:@"max_flight_speed"]; maxFlightSpeed = [shipDict floatForKey:@"max_flight_speed"];
max_flight_roll = [shipDict doubleForKey:@"max_flight_roll"]; max_flight_roll = [shipDict floatForKey:@"max_flight_roll"];
max_flight_pitch = [shipDict doubleForKey:@"max_flight_pitch"]; max_flight_pitch = [shipDict floatForKey:@"max_flight_pitch"];
max_flight_yaw = [shipDict doubleForKey:@"max_flight_yaw" defaultValue:max_flight_pitch]; // Note by default yaw == pitch max_flight_yaw = [shipDict floatForKey:@"max_flight_yaw" defaultValue:max_flight_pitch]; // Note by default yaw == pitch
thrust = [shipDict doubleForKey:@"thrust" defaultValue:thrust]; thrust = [shipDict floatForKey:@"thrust"];
// This was integer percentages, made it floating point... I don't see any reason to limit the value's precision. -- Ahruman accuracy = [shipDict floatForKey:@"accuracy" defaultValue:-100.0f]; // Out-of-range default
float accuracy = [shipDict doubleForKey:@"accuracy" defaultValue:-100]; // Out-of-range default
if (accuracy >= -5.0f && accuracy <= 10.0f) if (accuracy >= -5.0f && accuracy <= 10.0f)
{ {
pitch_tolerance = 0.01 * (85.0f + accuracy); pitch_tolerance = 0.01 * (85.0f + accuracy);
} }
else else
{ {
// TODO: reimplement with randf(), or maybe bellf(). -- Ahruman pitch_tolerance = 0.01 * (80 + (randf() * 15.0f));
pitch_tolerance = 0.01 * (80 +(ranrot_rand() & 15));
} }
if (accuracy < 1.0f) accuracy = 1.0f;
maxEnergy = [shipDict floatForKey:@"max_energy"]; maxEnergy = [shipDict floatForKey:@"max_energy"];
energy_recharge_rate = [shipDict floatForKey:@"energy_recharge_rate"]; energy_recharge_rate = [shipDict floatForKey:@"energy_recharge_rate"];
@ -165,8 +165,8 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
forward_weapon_type = StringToWeaponType([shipDict stringForKey:@"forward_weapon_type" defaultValue:@"WEAPON_NONE"]); forward_weapon_type = StringToWeaponType([shipDict stringForKey:@"forward_weapon_type" defaultValue:@"WEAPON_NONE"]);
aft_weapon_type = StringToWeaponType([shipDict stringForKey:@"aft_weapon_type" defaultValue:@"WEAPON_NONE"]); aft_weapon_type = StringToWeaponType([shipDict stringForKey:@"aft_weapon_type" defaultValue:@"WEAPON_NONE"]);
weapon_energy = [shipDict doubleForKey:@"weapon_energy"]; weapon_energy = [shipDict floatForKey:@"weapon_energy"];
scannerRange = [shipDict doubleForKey:@"scanner_range" defaultValue:25600.0]; scannerRange = [shipDict floatForKey:@"scanner_range" defaultValue:25600.0];
missiles = [shipDict intForKey:@"missiles"]; missiles = [shipDict intForKey:@"missiles"];
// upgrades: // upgrades:
@ -248,9 +248,8 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
OOMesh *mesh = [OOMesh meshWithName:modelName OOMesh *mesh = [OOMesh meshWithName:modelName
materialDictionary:[shipDict dictionaryForKey:@"materials"] materialDictionary:[shipDict dictionaryForKey:@"materials"]
shadersDictionary:[shipDict dictionaryForKey:@"shaders"] shadersDictionary:[shipDict dictionaryForKey:@"shaders"]
smooth:[shipDict boolForKey:@"smooth" defaultValue:NO] smooth:[shipDict boolForKey:@"smooth"]
shaderMacros:DefaultShipShaderMacros() shaderMacros:DefaultShipShaderMacros()
defaultBindings:DefaultShipShaderBindings()
shaderBindingTarget:self]; shaderBindingTarget:self];
[self setMesh:mesh]; [self setMesh:mesh];
} }
@ -274,7 +273,7 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
[exhaust release]; [exhaust release];
} }
is_hulk = [shipDict boolForKey:@"is_hulk" defaultValue:NO]; is_hulk = [shipDict boolForKey:@"is_hulk"];
NSArray *subs = [shipDict arrayForKey:@"subentities"]; NSArray *subs = [shipDict arrayForKey:@"subentities"];
for (i = 0; i < [subs count]; i++) for (i = 0; i < [subs count]; i++)
@ -348,24 +347,23 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
if (color == nil) color = [OOColor redColor]; if (color == nil) color = [OOColor redColor];
[self setLaserColor:color]; [self setLaserColor:color];
// scan class // scan class. NOTE: non-standard capitalization is documented and entrenched.
scanClass = StringToScanClass([shipDict objectForKey:@"scanClass"]); scanClass = StringToScanClass([shipDict objectForKey:@"scanClass"]);
// scripting // scripting
// TODO: use OOScript here. -- Ahruman // TODO: use OOScript here. -- Ahruman
launch_actions = [[shipDict arrayForKey:KEY_LAUNCH_ACTIONS] copy]; launch_actions = [[shipDict arrayForKey:@"launch_actions"] copy];
script_actions = [[shipDict arrayForKey:KEY_SCRIPT_ACTIONS] copy]; script_actions = [[shipDict arrayForKey:@"script_actions"] copy];
death_actions = [[shipDict arrayForKey:KEY_DEATH_ACTIONS] copy]; death_actions = [[shipDict arrayForKey:@"death_actions"] copy];
NSArray *setUpActions = [shipDict arrayForKey:KEY_SETUP_ACTIONS]; NSArray *setUpActions = [shipDict arrayForKey:@"setup_actions"];
if (setUpActions != nil) if (setUpActions != nil)
{ {
PlayerEntity* player = [PlayerEntity sharedPlayer];
[player setScriptTarget:self]; [player setScriptTarget:self];
[player scriptActions:setUpActions forTarget:self]; [player scriptActions:setUpActions forTarget:self];
} }
// escorts // escorts
escortCount = [shipDict intForKey:@"escorts"]; escortCount = [shipDict unsignedIntForKey:@"escorts"];
escortsAreSetUp = (escortCount == 0); escortsAreSetUp = (escortCount == 0);
// beacons // beacons
@ -381,7 +379,7 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
// //
if ([shipDict objectForKey:@"track_contacts"]) if ([shipDict objectForKey:@"track_contacts"])
{ {
[self setTrackCloseContacts:[[shipDict objectForKey:@"track_contacts"] boolValue]]; [self setTrackCloseContacts:[shipDict boolForKey:@"track_contacts"]];
// DEBUG.... // DEBUG....
[self setReportAImessages:YES]; [self setReportAImessages:YES];
} }
@ -392,7 +390,7 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
// set weapon offsets // set weapon offsets
[self setDefaultWeaponOffsets]; [self setDefaultWeaponOffsets];
//
ScanVectorFromString([shipDict objectForKey:@"weapon_position_forward"], &forwardWeaponOffset); ScanVectorFromString([shipDict objectForKey:@"weapon_position_forward"], &forwardWeaponOffset);
ScanVectorFromString([shipDict objectForKey:@"weapon_position_aft"], &aftWeaponOffset); ScanVectorFromString([shipDict objectForKey:@"weapon_position_aft"], &aftWeaponOffset);
ScanVectorFromString([shipDict objectForKey:@"weapon_position_port"], &portWeaponOffset); ScanVectorFromString([shipDict objectForKey:@"weapon_position_port"], &portWeaponOffset);
@ -401,10 +399,10 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
// fuel scoop destination position (where cargo gets sucked into) // fuel scoop destination position (where cargo gets sucked into)
tractor_position = kZeroVector; tractor_position = kZeroVector;
ScanVectorFromString([shipDict objectForKey:@"scoop_position"], &tractor_position); ScanVectorFromString([shipDict objectForKey:@"scoop_position"], &tractor_position);
// ship skin insulation factor (1.0 is normal) // ship skin insulation factor (1.0 is normal)
heat_insulation = [shipDict doubleForKey:@"heat_insulation" defaultValue:1.0]; heat_insulation = [shipDict doubleForKey:@"heat_insulation" defaultValue:1.0];
// crew and passengers // crew and passengers
NSDictionary* cdict = [[UNIVERSE characters] objectForKey:[shipDict stringForKey:@"pilot"]]; NSDictionary* cdict = [[UNIVERSE characters] objectForKey:[shipDict stringForKey:@"pilot"]];
if (cdict != nil) if (cdict != nil)
@ -675,23 +673,24 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
{ {
NSString *escortRole = @"escort"; NSString *escortRole = @"escort";
NSString *escortShipKey = nil; NSString *escortShipKey = nil;
// FIXME: should look for substring, or in more sensible role manager
if ([roles isEqual:@"trader"]) if ([roles isEqual:@"trader"])
escortRole = @"escort"; escortRole = @"escort";
if ([roles isEqual:@"police"]) if ([roles isEqual:@"police"])
escortRole = @"wingman"; escortRole = @"wingman";
if ([shipinfoDictionary objectForKey:@"escort-role"]) if ([shipinfoDictionary objectForKey:@"escort-role"])
{ {
escortRole = (NSString*)[shipinfoDictionary objectForKey:@"escort-role"]; escortRole = [shipinfoDictionary stringForKey:@"escort-role"];
if (![[UNIVERSE newShipWithRole:escortRole] autorelease]) if (![[UNIVERSE newShipWithRole:escortRole] autorelease])
escortRole = @"escort"; escortRole = @"escort";
} }
if ([shipinfoDictionary objectForKey:@"escort-ship"]) if ([shipinfoDictionary objectForKey:@"escort-ship"])
{ {
escortShipKey = (NSString*)[shipinfoDictionary objectForKey:@"escort-ship"]; escortShipKey = [shipinfoDictionary stringForKey:@"escort-ship"];
if (![[UNIVERSE newShipWithName:escortShipKey] autorelease]) if (![[UNIVERSE newShipWithName:escortShipKey] autorelease])
escortShipKey = nil; escortShipKey = nil;
} }
@ -699,47 +698,48 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
while (escortCount > 0) while (escortCount > 0)
{ {
Vector ex_pos = [self coordinatesForEscortPosition:escortCount - 1]; Vector ex_pos = [self coordinatesForEscortPosition:escortCount - 1];
ShipEntity *escorter; ShipEntity *escorter = nil;
if (escortShipKey) if (escortShipKey)
escorter = [UNIVERSE newShipWithName:escortShipKey]; // retained escorter = [UNIVERSE newShipWithName:escortShipKey]; // retained
else else
escorter = [UNIVERSE newShipWithRole:escortRole]; // retained escorter = [UNIVERSE newShipWithRole:escortRole]; // retained
if (!escorter) break; if (!escorter) break;
if (![escorter crew]) if (![escorter crew])
{
[escorter setCrew:[NSArray arrayWithObject: [escorter setCrew:[NSArray arrayWithObject:
[OOCharacter randomCharacterWithRole: @"hunter" [OOCharacter randomCharacterWithRole: @"hunter"
andOriginalSystem: [UNIVERSE systemSeed]]]]; andOriginalSystem: [UNIVERSE systemSeed]]]];
}
// spread them around a little randomly // spread them around a little randomly
double dd = escorter->collision_radius; double dd = escorter->collision_radius;
ex_pos.x += dd * 6.0 * (randf() - 0.5); ex_pos.x += dd * 6.0 * (randf() - 0.5);
ex_pos.y += dd * 6.0 * (randf() - 0.5); ex_pos.y += dd * 6.0 * (randf() - 0.5);
ex_pos.z += dd * 6.0 * (randf() - 0.5); ex_pos.z += dd * 6.0 * (randf() - 0.5);
[escorter setScanClass: CLASS_NEUTRAL]; [escorter setScanClass: CLASS_NEUTRAL];
[escorter setPosition:ex_pos]; [escorter setPosition:ex_pos];
[escorter setStatus:STATUS_IN_FLIGHT]; [escorter setStatus:STATUS_IN_FLIGHT];
[escorter setRoles:escortRole]; [escorter setRoles:escortRole];
[escorter setScanClass:scanClass]; // you are the same as I [escorter setScanClass:scanClass]; // you are the same as I
[UNIVERSE addEntity:escorter]; [UNIVERSE addEntity:escorter];
[[escorter getAI] setStateMachine:@"escortAI.plist"]; // must happen after adding to the UNIVERSE! [[escorter getAI] setStateMachine:@"escortAI.plist"]; // must happen after adding to the UNIVERSE!
[escorter setGroupID:universalID]; [escorter setGroupID:universalID];
[self setGroupID:universalID]; // make self part of same group [self setGroupID:universalID]; // make self part of same group
[escorter setOwner: self]; // make self group leader [escorter setOwner: self]; // make self group leader
[[escorter getAI] setState:@"FLYING_ESCORT"]; // begin immediately [[escorter getAI] setState:@"FLYING_ESCORT"]; // begin immediately
if (bounty) if (bounty)
{ {
int extra = 1 | (ranrot_rand() & 15); int extra = 1 | (ranrot_rand() & 15);
@ -750,7 +750,7 @@ static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.change
{ {
[escorter setBounty:0]; [escorter setBounty:0];
} }
[escorter release]; [escorter release];
escortCount--; escortCount--;
} }
@ -1059,7 +1059,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
{ {
if (bounty > 0) if (bounty > 0)
bounty = 0; bounty = 0;
ShipEntity* target = (ShipEntity*)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity* target = [UNIVERSE entityForUniversalID:primaryTarget];
if ((target)&&(target->scanClass == CLASS_POLICE)) if ((target)&&(target->scanClass == CLASS_POLICE))
{ {
primaryTarget = NO_TARGET; primaryTarget = NO_TARGET;
@ -1077,7 +1077,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
for (contactEnum = [closeContactsInfo keyEnumerator]; (other_key = [contactEnum nextObject]); ) for (contactEnum = [closeContactsInfo keyEnumerator]; (other_key = [contactEnum nextObject]); )
{ {
ShipEntity* other = (ShipEntity*)[UNIVERSE entityForUniversalID:[other_key intValue]]; ShipEntity* other = [UNIVERSE entityForUniversalID:[other_key intValue]];
if ((other != nil) && (other->isShip)) if ((other != nil) && (other->isShip))
{ {
if (distance2(position, other->position) > collision_radius * collision_radius) // moved beyond our sphere! if (distance2(position, other->position) > collision_radius * collision_radius) // moved beyond our sphere!
@ -1430,16 +1430,13 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
// update destination position for escorts // update destination position for escorts
if (escortCount > 0) if (escortCount > 0)
{ {
int i; unsigned i;
for (i = 0; i < escortCount; i++) for (i = 0; i < escortCount; i++)
{ {
ShipEntity *escorter = (ShipEntity *)[UNIVERSE entityForUniversalID:escort_ids[i]]; ShipEntity *escorter = [UNIVERSE entityForUniversalID:escort_ids[i]];
// check it's still an escort ship // check it's still an escort ship
BOOL escorter_okay = YES; BOOL escorter_okay = (escorter != nil) && escorter->isShip;
if (!escorter)
escorter_okay = NO;
else
escorter_okay = escorter->isShip;
if (escorter_okay) if (escorter_okay)
[escorter setDestination:[self coordinatesForEscortPosition:i]]; // update its destination [escorter setDestination:[self coordinatesForEscortPosition:i]]; // update its destination
else else
@ -1741,7 +1738,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
// //
BOOL isUsingAfterburner = canBurn && (flightSpeed > maxFlightSpeed); BOOL isUsingAfterburner = canBurn && (flightSpeed > maxFlightSpeed);
double slow_down_range = weaponRange * COMBAT_WEAPON_RANGE_FACTOR * ((isUsingAfterburner)? 3.0 * AFTERBURNER_FACTOR : 1.0); double slow_down_range = weaponRange * COMBAT_WEAPON_RANGE_FACTOR * ((isUsingAfterburner)? 3.0 * AFTERBURNER_FACTOR : 1.0);
ShipEntity* target = (ShipEntity*)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity* target = [UNIVERSE entityForUniversalID:primaryTarget];
double target_speed = [target speed]; double target_speed = [target speed];
double distance = [self rangeToDestination]; double distance = [self rangeToDestination];
if (range < slow_down_range) if (range < slow_down_range)
@ -1875,7 +1872,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
// //
BOOL isUsingAfterburner = canBurn && (flightSpeed > maxFlightSpeed); BOOL isUsingAfterburner = canBurn && (flightSpeed > maxFlightSpeed);
double slow_down_range = weaponRange * COMBAT_WEAPON_RANGE_FACTOR * ((isUsingAfterburner)? 3.0 * AFTERBURNER_FACTOR : 1.0); double slow_down_range = weaponRange * COMBAT_WEAPON_RANGE_FACTOR * ((isUsingAfterburner)? 3.0 * AFTERBURNER_FACTOR : 1.0);
ShipEntity* target = (ShipEntity*)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity* target = [UNIVERSE entityForUniversalID:primaryTarget];
double target_speed = [target speed]; double target_speed = [target speed];
if (range <= slow_down_range) if (range <= slow_down_range)
desired_speed = OOMax_d(target_speed, 0.25 * maxFlightSpeed); // within the weapon's range match speed desired_speed = OOMax_d(target_speed, 0.25 * maxFlightSpeed); // within the weapon's range match speed
@ -2039,7 +2036,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
- (void) behaviour_formation_form_up:(double) delta_t - (void) behaviour_formation_form_up:(double) delta_t
{ {
// get updated destination from owner // get updated destination from owner
ShipEntity* leadShip = (ShipEntity *)[UNIVERSE entityForUniversalID:owner]; ShipEntity* leadShip = [UNIVERSE entityForUniversalID:owner];
double distance = [self rangeToDestination]; double distance = [self rangeToDestination];
double eta = (distance - desired_range) / flightSpeed; double eta = (distance - desired_range) / flightSpeed;
if ((eta < 5.0)&&(leadShip)&&(leadShip->isShip)) if ((eta < 5.0)&&(leadShip)&&(leadShip->isShip))
@ -2691,13 +2688,13 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
} }
- (int) escortCount - (unsigned) escortCount
{ {
return escortCount; return escortCount;
} }
- (void) setEscortCount:(int) value - (void) setEscortCount:(unsigned) value
{ {
escortCount = value; escortCount = value;
escortsAreSetUp = (escortCount == 0); escortsAreSetUp = (escortCount == 0);
@ -2706,7 +2703,7 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
- (ShipEntity*) proximity_alert - (ShipEntity*) proximity_alert
{ {
return (ShipEntity*)[UNIVERSE entityForUniversalID:proximity_alert]; return [UNIVERSE entityForUniversalID:proximity_alert];
} }
@ -2739,7 +2736,7 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
if (behaviour == BEHAVIOUR_AVOID_COLLISION) // already avoiding something if (behaviour == BEHAVIOUR_AVOID_COLLISION) // already avoiding something
{ {
ShipEntity* prox = (ShipEntity*)[UNIVERSE entityForUniversalID:proximity_alert]; ShipEntity* prox = [UNIVERSE entityForUniversalID:proximity_alert];
if ((prox)&&(prox != other)) if ((prox)&&(prox != other))
{ {
// check which subtends the greatest angle // check which subtends the greatest angle
@ -3461,7 +3458,7 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
case CARGO_FLAG_FULL_UNIFORM : case CARGO_FLAG_FULL_UNIFORM :
{ {
NSString* commodity_name = (NSString*)[shipinfoDictionary objectForKey:@"cargo_carried"]; NSString* commodity_name = [shipinfoDictionary stringForKey:@"cargo_carried"];
jetsam = [UNIVERSE getContainersOfCommodity:commodity_name :cargo_to_go]; jetsam = [UNIVERSE getContainersOfCommodity:commodity_name :cargo_to_go];
} }
break; break;
@ -4571,8 +4568,6 @@ BOOL class_masslocks(int some_class)
double stick_roll = 0.0; //desired roll and pitch double stick_roll = 0.0; //desired roll and pitch
double stick_pitch = 0.0; double stick_pitch = 0.0;
double tolerance1 = pitch_tolerance;
relPos = vector_subtract(target->position, position); relPos = vector_subtract(target->position, position);
range2 = magnitude2(relPos); range2 = magnitude2(relPos);
@ -4590,7 +4585,7 @@ BOOL class_masslocks(int some_class)
if (pitching_over) if (pitching_over)
pitching_over = (stick_pitch != 0.0); pitching_over = (stick_pitch != 0.0);
if ((d_forward < -tolerance1) && (!pitching_over)) if ((d_forward < -pitch_tolerance) && (!pitching_over))
{ {
pitching_over = YES; pitching_over = YES;
if (d_up >= 0) if (d_up >= 0)
@ -4866,14 +4861,10 @@ BOOL class_masslocks(int some_class)
// set the values for the forward weapon // set the values for the forward weapon
// //
[self setWeaponDataFromType:forward_weapon_type]; [self setWeaponDataFromType:forward_weapon_type];
//
if (shot_time < weapon_recharge_rate) if (shot_time < weapon_recharge_rate)
return NO; return NO;
int accuracy = 1;
if ([shipinfoDictionary objectForKey:@"accuracy"])
accuracy = [(NSNumber *)[shipinfoDictionary objectForKey:@"accuracy"] intValue];
if (accuracy < 1)
accuracy = 1;
if (range > randf() * weaponRange * accuracy) if (range > randf() * weaponRange * accuracy)
return NO; return NO;
if (range > weaponRange) if (range > weaponRange)
@ -5073,7 +5064,7 @@ BOOL class_masslocks(int some_class)
shot = [[ParticleEntity alloc] initLaserFromSubentity:self view:direction]; // alloc retains! shot = [[ParticleEntity alloc] initLaserFromSubentity:self view:direction]; // alloc retains!
[shot setColor:laser_color]; [shot setColor:laser_color];
[shot setScanClass: CLASS_NO_DRAW]; [shot setScanClass: CLASS_NO_DRAW];
ShipEntity *victim = (ShipEntity*)[UNIVERSE entityForUniversalID:target_laser_hit]; ShipEntity *victim = [UNIVERSE entityForUniversalID:target_laser_hit];
if ((victim)&&(victim->isShip)) if ((victim)&&(victim->isShip))
{ {
ShipEntity* subent = victim->subentity_taking_damage; ShipEntity* subent = victim->subentity_taking_damage;
@ -5145,7 +5136,7 @@ BOOL class_masslocks(int some_class)
[shot setPosition: position]; [shot setPosition: position];
[shot setOrientation: q_laser]; [shot setOrientation: q_laser];
[shot setVelocity: vel]; [shot setVelocity: vel];
ShipEntity *victim = (ShipEntity*)[UNIVERSE entityForUniversalID:target_laser_hit]; ShipEntity *victim = [UNIVERSE entityForUniversalID:target_laser_hit];
if ((victim)&&(victim->isShip)) if ((victim)&&(victim->isShip))
{ {
ShipEntity* subent = victim->subentity_taking_damage; ShipEntity* subent = victim->subentity_taking_damage;
@ -5222,7 +5213,7 @@ BOOL class_masslocks(int some_class)
[shot setColor:laser_color]; [shot setColor:laser_color];
[shot setScanClass: CLASS_NO_DRAW]; [shot setScanClass: CLASS_NO_DRAW];
[shot setVelocity: vel]; [shot setVelocity: vel];
ShipEntity *victim = (ShipEntity*)[UNIVERSE entityForUniversalID:target_laser_hit]; ShipEntity *victim = [UNIVERSE entityForUniversalID:target_laser_hit];
if ((victim)&&(victim->isShip)) if ((victim)&&(victim->isShip))
{ {
/* FIXME CRASH in [victim->sub_entities containsObject:subent] here (1.69, OS X/x86). /* FIXME CRASH in [victim->sub_entities containsObject:subent] here (1.69, OS X/x86).
@ -5393,10 +5384,13 @@ BOOL class_masslocks(int some_class)
- (BOOL) fireMissile - (BOOL) fireMissile
{ {
ShipEntity *missile = nil; NSString *missileRole = nil;
Vector vel; ShipEntity *missile = nil;
Vector origin = position; Vector vel;
Vector start, v_eject; Vector origin = position;
Vector start, v_eject;
Entity *target = nil;
ShipEntity *target_ship = nil;
// default launching position // default launching position
start.x = 0.0; // in the middle start.x = 0.0; // in the middle
@ -5407,40 +5401,43 @@ BOOL class_masslocks(int some_class)
double throw_speed = 250.0; double throw_speed = 250.0;
Quaternion q1 = orientation; Quaternion q1 = orientation;
Entity *target = [self primaryTarget]; target = [self primaryTarget];
if ((missiles <= 0)||(target == nil)||(target->scanClass == CLASS_NO_DRAW)) // no missile lock! if ((missiles <= 0)||(target == nil)||(target->scanClass == CLASS_NO_DRAW)) // no missile lock!
return NO; return NO;
if (target->isShip) if (target->isShip)
{ {
ShipEntity* target_ship = (ShipEntity*)target; target_ship = (ShipEntity*)target;
if ([target_ship isCloaked]) return NO; if ([target_ship isCloaked]) return NO;
if ((!has_military_scanner_filter)&&[target_ship isJammingScanning]) return NO; if ((!has_military_scanner_filter)&&[target_ship isJammingScanning]) return NO;
} }
// custom missiles // custom missiles
if ([shipinfoDictionary objectForKey:@"missile_role"]) missileRole = [shipinfoDictionary stringForKey:@"missile_role"];
missile = [UNIVERSE newShipWithRole:(NSString*)[shipinfoDictionary objectForKey:@"missile_role"]]; if (missileRole != nil) missile = [UNIVERSE newShipWithRole:missileRole];
if (!missile) // no custom role if (missile == nil) // no custom role
{ {
if (randf() < 0.90) // choose a standard missile 90% of the time if (randf() < 0.90) // choose a standard missile 90% of the time
missile = [UNIVERSE newShipWithRole:@"EQ_MISSILE"]; // retained {
missile = [UNIVERSE newShipWithRole:@"EQ_MISSILE"]; // retained
}
else // otherwise choose any with the role 'missile' - which may include alternative weapons else // otherwise choose any with the role 'missile' - which may include alternative weapons
missile = [UNIVERSE newShipWithRole:@"missile"]; // retained {
missile = [UNIVERSE newShipWithRole:@"missile"]; // retained
}
} }
if (!missile) if (missile == nil) return NO;
return NO;
missiles--; missiles--;
double mcr = missile->collision_radius; double mcr = missile->collision_radius;
v_eject = unit_vector(&start); v_eject = unit_vector(&start);
vel = kZeroVector; // starting velocity vel = kZeroVector; // starting velocity
// check if start is within bounding box... // check if start is within bounding box...
while ( (start.x > boundingBox.min.x - mcr)&&(start.x < boundingBox.max.x + mcr)&& while ( (start.x > boundingBox.min.x - mcr)&&(start.x < boundingBox.max.x + mcr)&&
(start.y > boundingBox.min.y - mcr)&&(start.y < boundingBox.max.y + mcr)&& (start.y > boundingBox.min.y - mcr)&&(start.y < boundingBox.max.y + mcr)&&
@ -5452,7 +5449,7 @@ BOOL class_masslocks(int some_class)
if (isPlayer) if (isPlayer)
q1.w = -q1.w; // player view is reversed remember! q1.w = -q1.w; // player view is reversed remember!
vel.x += (flightSpeed + throw_speed) * v_forward.x; vel.x += (flightSpeed + throw_speed) * v_forward.x;
vel.y += (flightSpeed + throw_speed) * v_forward.y; vel.y += (flightSpeed + throw_speed) * v_forward.y;
vel.z += (flightSpeed + throw_speed) * v_forward.z; vel.z += (flightSpeed + throw_speed) * v_forward.z;
@ -5461,24 +5458,24 @@ BOOL class_masslocks(int some_class)
origin.y = position.y + v_right.y * start.x + v_up.y * start.y + v_forward.y * start.z; origin.y = position.y + v_right.y * start.x + v_up.y * start.y + v_forward.y * start.z;
origin.z = position.z + v_right.z * start.x + v_up.z * start.y + v_forward.z * start.z; origin.z = position.z + v_right.z * start.x + v_up.z * start.y + v_forward.z * start.z;
[missile addTarget: target]; [missile addTarget:target];
[missile setOwner: self]; [missile setOwner:self];
[missile setGroupID: groupID]; [missile setGroupID:groupID];
[missile setPosition: origin]; [missile setPosition:origin];
[missile setOrientation: q1]; [missile setOrientation:q1];
[missile setVelocity: vel]; [missile setVelocity:vel];
[missile setSpeed: 150.0]; [missile setSpeed:150.0];
[missile setDistanceTravelled: 0.0]; [missile setDistanceTravelled:0.0];
[missile setStatus: STATUS_IN_FLIGHT]; // necessary to get it going! [missile setStatus:STATUS_IN_FLIGHT]; // necessary to get it going!
//
[UNIVERSE addEntity: missile]; [UNIVERSE addEntity: missile];
//
[missile release]; //release [missile release]; //release
if ([missile scanClass] == CLASS_MISSILE) if ([missile scanClass] == CLASS_MISSILE)
{ {
[(ShipEntity *)target setPrimaryAggressor:self]; [target_ship setPrimaryAggressor:self];
[[(ShipEntity *)target getAI] reactToMessage:@"INCOMING_MISSILE"]; [[target_ship getAI] reactToMessage:@"INCOMING_MISSILE"];
} }
return YES; return YES;
@ -5571,13 +5568,12 @@ BOOL class_masslocks(int some_class)
- (int)launchEscapeCapsule - (int)launchEscapeCapsule
{ {
OOUniversalID result = NO_TARGET; OOUniversalID result = NO_TARGET;
ShipEntity *pod = nil; ShipEntity *pod = nil;
int n_pods; unsigned n_pods;
// check number of pods aboard // check number of pods aboard -- require at least one.
// n_pods = [shipinfoDictionary unsignedIntForKey:@"has_escape_pod"];
n_pods = MIN([shipinfoDictionary intForKey:@"has_escape_pod"], 1);
pod = [UNIVERSE newShipWithRole:[shipinfoDictionary stringForKey:@"escape_pod_model" defaultValue:@"escape-capsule"]]; pod = [UNIVERSE newShipWithRole:[shipinfoDictionary stringForKey:@"escape_pod_model" defaultValue:@"escape-capsule"]];
@ -5605,7 +5601,7 @@ BOOL class_masslocks(int some_class)
result = [pod universalID]; result = [pod universalID];
} }
// launch other pods (passengers) // launch other pods (passengers)
int i; unsigned i;
for (i = 1; i < n_pods; i++) for (i = 1; i < n_pods; i++)
{ {
pod = [UNIVERSE newShipWithRole:@"escape-capsule"]; pod = [UNIVERSE newShipWithRole:@"escape-capsule"];
@ -6165,7 +6161,7 @@ BOOL class_masslocks(int some_class)
{ {
if ([roles isEqual:@"escort"]||[roles isEqual:@"trader"]) if ([roles isEqual:@"escort"]||[roles isEqual:@"trader"])
{ {
ShipEntity *group_leader = (ShipEntity *)[UNIVERSE entityForUniversalID:groupID]; ShipEntity *group_leader = [UNIVERSE entityForUniversalID:groupID];
if ((group_leader)&&(group_leader->isShip)) if ((group_leader)&&(group_leader->isShip))
{ {
[group_leader setFound_target:hunter]; [group_leader setFound_target:hunter];
@ -6486,11 +6482,8 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
if (pairOK(roles, [other_ship roles])) if (pairOK(roles, [other_ship roles]))
{ {
// check total number acceptable unsigned i;
int max_escorts = [(NSNumber *)[shipinfoDictionary objectForKey:@"escorts"] intValue];
// check it's not already been accepted // check it's not already been accepted
int i;
for (i = 0; i < escortCount; i++) for (i = 0; i < escortCount; i++)
{ {
if (escort_ids[i] == [other_ship universalID]) if (escort_ids[i] == [other_ship universalID])
@ -6500,7 +6493,9 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
return YES; return YES;
} }
} }
// check total number acceptable
unsigned max_escorts = [shipinfoDictionary unsignedIntForKey:@"escorts"];
if ((escortCount < MAX_ESCORTS)&&(escortCount < max_escorts)) if ((escortCount < MAX_ESCORTS)&&(escortCount < max_escorts))
{ {
escort_ids[escortCount] = [other_ship universalID]; escort_ids[escortCount] = [other_ship universalID];
@ -6559,7 +6554,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
while ((n_deploy > 0)&&(escortCount > 0)) while ((n_deploy > 0)&&(escortCount > 0))
{ {
int escort_id = escort_ids[i_deploy]; int escort_id = escort_ids[i_deploy];
ShipEntity *escorter = (ShipEntity *)[UNIVERSE entityForUniversalID:escort_id]; ShipEntity *escorter = [UNIVERSE entityForUniversalID:escort_id];
// check it's still an escort ship // check it's still an escort ship
BOOL escorter_okay = YES; BOOL escorter_okay = YES;
if (!escorter) if (!escorter)
@ -6591,11 +6586,11 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
if (escortCount < 1) if (escortCount < 1)
return; return;
int i; unsigned i;
for (i = 0; i < escortCount; i++) for (i = 0; i < escortCount; i++)
{ {
int escort_id = escort_ids[i]; int escort_id = escort_ids[i];
ShipEntity *escorter = (ShipEntity *)[UNIVERSE entityForUniversalID:escort_id]; ShipEntity *escorter = [UNIVERSE entityForUniversalID:escort_id];
// check it's still an escort ship // check it's still an escort ship
BOOL escorter_okay = YES; BOOL escorter_okay = YES;
if (!escorter) if (!escorter)
@ -6874,7 +6869,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
NSString* expandedMessage = ExpandDescriptionForCurrentSystem(ai_message); NSString* expandedMessage = ExpandDescriptionForCurrentSystem(ai_message);
[self checkScanner]; [self checkScanner];
int i; unsigned i;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
{ {
ShipEntity* ship = scanned_ships[i]; ShipEntity* ship = scanned_ships[i];
@ -6892,7 +6887,7 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
[self setCommsMessageColor]; [self setCommsMessageColor];
[self checkScanner]; [self checkScanner];
int i; unsigned i;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
{ {
ShipEntity* ship = scanned_ships[i]; ShipEntity* ship = scanned_ships[i];
@ -7239,21 +7234,6 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
@end @end
NSDictionary *DefaultShipShaderBindings(void)
{
static NSDictionary *bindings = nil;
NSDictionary *materialDefaults = nil;
if (bindings == nil)
{
materialDefaults = [ResourceManager dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
bindings = [[materialDefaults dictionaryForKey:@"ship-default-bindings" defaultValue:[NSDictionary dictionary]] retain];
}
return bindings;
}
NSDictionary *DefaultShipShaderMacros(void) NSDictionary *DefaultShipShaderMacros(void)
{ {
static NSDictionary *macros = nil; static NSDictionary *macros = nil;

View File

@ -127,7 +127,7 @@ MA 02110-1301, USA.
Entity* primeTarget = [UNIVERSE entityForUniversalID:primaryTarget]; Entity* primeTarget = [UNIVERSE entityForUniversalID:primaryTarget];
if ((primeTarget)&&(primeTarget->isShip)) if ((primeTarget)&&(primeTarget->isShip))
{ {
ShipEntity* currentShip = (ShipEntity*)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity* currentShip = [UNIVERSE entityForUniversalID:primaryTarget];
[[currentShip getAI] message:[NSString stringWithFormat:@"%@ %d %d", AIMS_AGGRESSOR_SWITCHED_TARGET, universalID, primaryAggressor]]; [[currentShip getAI] message:[NSString stringWithFormat:@"%@ %d %d", AIMS_AGGRESSOR_SWITCHED_TARGET, universalID, primaryAggressor]];
} }
@ -149,7 +149,7 @@ MA 02110-1301, USA.
// //
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
found_target = NO_TARGET; found_target = NO_TARGET;
int i; unsigned i;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
{ {
ShipEntity* ship = scanned_ships[i]; ShipEntity* ship = scanned_ships[i];
@ -176,10 +176,10 @@ MA 02110-1301, USA.
//-- Locates one of the merchantman in range --// //-- Locates one of the merchantman in range --//
[self checkScanner]; [self checkScanner];
// //
int ids_found[n_scanned_ships]; OOUniversalID ids_found[n_scanned_ships];
int n_found = 0; unsigned n_found = 0;
found_target = NO_TARGET; found_target = NO_TARGET;
int i; unsigned i;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
{ {
ShipEntity* ship = scanned_ships[i]; ShipEntity* ship = scanned_ships[i];
@ -229,7 +229,7 @@ MA 02110-1301, USA.
// //
double found_d2 = scannerRange * scannerRange; double found_d2 = scannerRange * scannerRange;
found_target = NO_TARGET; found_target = NO_TARGET;
int i; unsigned i;
for (i = 0; i < n_scanned_ships; i++) for (i = 0; i < n_scanned_ships; i++)
{ {
ShipEntity* other = (ShipEntity *)scanned_ships[i]; ShipEntity* other = (ShipEntity *)scanned_ships[i];
@ -263,10 +263,10 @@ MA 02110-1301, USA.
// //
[self checkScanner]; [self checkScanner];
// //
int thing_uids_found[16]; OOUniversalID thing_uids_found[16];
int things_found = 0; unsigned things_found = 0;
found_target = NO_TARGET; found_target = NO_TARGET;
int i; unsigned i;
for (i = 0; (i < n_scanned_ships)&&(things_found < 16) ; i++) for (i = 0; (i < n_scanned_ships)&&(things_found < 16) ; i++)
{ {
ShipEntity* other = scanned_ships[i]; ShipEntity* other = scanned_ships[i];
@ -334,7 +334,7 @@ MA 02110-1301, USA.
// //
StationEntity* station = nil; StationEntity* station = nil;
double nearest2 = SCANNER_MAX_RANGE2 * 1000000.0; // 1000x scanner range (25600 km), squared. double nearest2 = SCANNER_MAX_RANGE2 * 1000000.0; // 1000x scanner range (25600 km), squared.
int i; unsigned i;
for (i = 0; i < n_scanned_ships; i++) for (i = 0; i < n_scanned_ships; i++)
{ {
if (scanned_ships[i]->isStation) if (scanned_ships[i]->isStation)
@ -394,9 +394,9 @@ MA 02110-1301, USA.
{ {
// find an incoming missile... // find an incoming missile...
// //
ShipEntity* missile = nil; ShipEntity *missile = nil;
[self checkScanner]; [self checkScanner];
int i; unsigned i;
for (i = 0; (i < n_scanned_ships)&&(missile == nil); i++) for (i = 0; (i < n_scanned_ships)&&(missile == nil); i++)
{ {
ShipEntity* thing = scanned_ships[i]; ShipEntity* thing = scanned_ships[i];
@ -406,7 +406,7 @@ MA 02110-1301, USA.
missile = thing; missile = thing;
if ((escortCount > 0)&&(missile == nil)) if ((escortCount > 0)&&(missile == nil))
{ {
int j; unsigned j;
for (j = 0; j < escortCount; j++) for (j = 0; j < escortCount; j++)
{ {
if ([thing primaryTargetID] == escort_ids[j]) if ([thing primaryTargetID] == escort_ids[j])
@ -554,7 +554,7 @@ MA 02110-1301, USA.
- (void) checkTargetLegalStatus - (void) checkTargetLegalStatus
{ {
ShipEntity *other_ship = (ShipEntity *)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity *other_ship = [UNIVERSE entityForUniversalID:primaryTarget];
if (!other_ship) if (!other_ship)
{ {
[shipAI message:@"NO_TARGET"]; [shipAI message:@"NO_TARGET"];
@ -637,7 +637,7 @@ MA 02110-1301, USA.
// find the worst offender on the scanner // find the worst offender on the scanner
// //
[self checkScanner]; [self checkScanner];
int i; unsigned i;
float worst_legal_factor = 0; float worst_legal_factor = 0;
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
@ -700,7 +700,7 @@ WormholeEntity* whole;
} }
// check if we're clear of nearby masses // check if we're clear of nearby masses
ShipEntity* blocker = (ShipEntity*)[UNIVERSE entityForUniversalID:[self checkShipsInVicinityForWitchJumpExit]]; ShipEntity* blocker = [UNIVERSE entityForUniversalID:[self checkShipsInVicinityForWitchJumpExit]];
if (blocker) if (blocker)
{ {
found_target = [blocker universalID]; found_target = [blocker universalID];
@ -737,11 +737,11 @@ WormholeEntity* whole;
if (!whole) if (!whole)
return; return;
int i; unsigned i;
for (i = 0; i < escortCount; i++) for (i = 0; i < escortCount; i++)
{ {
int escort_id = escort_ids[i]; int escort_id = escort_ids[i];
ShipEntity *escorter = (ShipEntity *)[UNIVERSE entityForUniversalID:escort_id]; ShipEntity *escorter = [UNIVERSE entityForUniversalID:escort_id];
// check it's still an escort ship // check it's still an escort ship
BOOL escorter_okay = YES; BOOL escorter_okay = YES;
if (!escorter) if (!escorter)
@ -834,7 +834,7 @@ WormholeEntity* whole;
else else
distress_message = @"[distress-call]"; distress_message = @"[distress-call]";
int i; unsigned i;
for (i = 0; i < n_scanned_ships; i++) for (i = 0; i < n_scanned_ships; i++)
{ {
ShipEntity* ship = scanned_ships[i]; ShipEntity* ship = scanned_ships[i];
@ -883,7 +883,7 @@ WormholeEntity* whole;
default: default:
if ((scanClass == CLASS_POLICE)||[roles isEqual:@"police"]||[roles isEqual:@"interceptor"]||[roles isEqual:@"wingman"]) if ((scanClass == CLASS_POLICE)||[roles isEqual:@"police"]||[roles isEqual:@"interceptor"]||[roles isEqual:@"wingman"])
[(ShipEntity *)[UNIVERSE entityForUniversalID:found_target] markAsOffender:8]; // you have been warned!! [[UNIVERSE entityForUniversalID:found_target] markAsOffender:8]; // you have been warned!!
[shipAI reactToMessage:@"ACCEPT_DISTRESS_CALL"]; [shipAI reactToMessage:@"ACCEPT_DISTRESS_CALL"];
break; break;
} }
@ -919,7 +919,7 @@ WormholeEntity* whole;
{ {
/*-- Locates all the thargoid warships in range and chooses the nearest --*/ /*-- Locates all the thargoid warships in range and chooses the nearest --*/
[self checkScanner]; [self checkScanner];
int i; unsigned i;
// //
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
found_target = NO_TARGET; found_target = NO_TARGET;
@ -948,7 +948,7 @@ WormholeEntity* whole;
found_target = NO_TARGET; found_target = NO_TARGET;
[self checkScanner]; [self checkScanner];
int i; unsigned i;
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
{ {
@ -1009,7 +1009,7 @@ WormholeEntity* whole;
found_hostiles = 0; found_hostiles = 0;
[self checkScanner]; [self checkScanner];
int i; unsigned i;
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
{ {
@ -1068,7 +1068,7 @@ WormholeEntity* whole;
- (void) suggestEscort - (void) suggestEscort
{ {
ShipEntity *mother = (ShipEntity *)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity *mother = [UNIVERSE entityForUniversalID:primaryTarget];
if (mother) if (mother)
{ {
if (reportAImessages) if (reportAImessages)
@ -1099,7 +1099,7 @@ WormholeEntity* whole;
- (void) escortCheckMother - (void) escortCheckMother
{ {
ShipEntity *mother = (ShipEntity *)[UNIVERSE entityForUniversalID:owner]; ShipEntity *mother = [UNIVERSE entityForUniversalID:owner];
if (mother) if (mother)
{ {
if ([mother acceptAsEscort:self]) if ([mother acceptAsEscort:self])
@ -1129,7 +1129,7 @@ WormholeEntity* whole;
- (void) checkGroupOddsVersusTarget - (void) checkGroupOddsVersusTarget
{ {
int own_group_id = groupID; int own_group_id = groupID;
int target_group_id = [(ShipEntity *)[UNIVERSE entityForUniversalID:primaryTarget] groupID]; int target_group_id = [[UNIVERSE entityForUniversalID:primaryTarget] groupID];
int own_group_numbers = [self numberOfShipsInGroup:own_group_id] + (ranrot_rand() & 3); // add a random fudge factor int own_group_numbers = [self numberOfShipsInGroup:own_group_id] + (ranrot_rand() & 3); // add a random fudge factor
int target_group_numbers = [self numberOfShipsInGroup:target_group_id] + (ranrot_rand() & 3); // add a random fudge factor int target_group_numbers = [self numberOfShipsInGroup:target_group_id] + (ranrot_rand() & 3); // add a random fudge factor
@ -1176,7 +1176,7 @@ WormholeEntity* whole;
//-- Locates the nearest suitable formation leader in range --// //-- Locates the nearest suitable formation leader in range --//
found_target = NO_TARGET; found_target = NO_TARGET;
[self checkScanner]; [self checkScanner];
int i; unsigned i;
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
for (i = 0; i < n_scanned_ships; i++) for (i = 0; i < n_scanned_ships; i++)
{ {
@ -1207,7 +1207,7 @@ WormholeEntity* whole;
- (void) messageMother:(NSString *)msgString - (void) messageMother:(NSString *)msgString
{ {
ShipEntity *mother = (ShipEntity *)[UNIVERSE entityForUniversalID:owner]; ShipEntity *mother = [UNIVERSE entityForUniversalID:owner];
if (mother) if (mother)
{ {
[[mother getAI] reactToMessage:msgString]; [[mother getAI] reactToMessage:msgString];
@ -1386,7 +1386,7 @@ WormholeEntity* whole;
// //
found_target = NO_TARGET; found_target = NO_TARGET;
[self checkScanner]; [self checkScanner];
int i; unsigned i;
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
for (i = 0; i < n_scanned_ships; i++) for (i = 0; i < n_scanned_ships; i++)
{ {
@ -1454,7 +1454,7 @@ WormholeEntity* whole;
if ([self owner]) if ([self owner])
mother = (ShipEntity*)[self owner]; mother = (ShipEntity*)[self owner];
if ((mother == nil)&&([UNIVERSE entityForUniversalID:groupID])) if ((mother == nil)&&([UNIVERSE entityForUniversalID:groupID]))
mother = (ShipEntity*)[UNIVERSE entityForUniversalID:groupID]; mother = [UNIVERSE entityForUniversalID:groupID];
if (!mother) if (!mother)
{ {
[shipAI message:@"MOTHER_LOST"]; [shipAI message:@"MOTHER_LOST"];
@ -1465,7 +1465,7 @@ WormholeEntity* whole;
found_target = NO_TARGET; found_target = NO_TARGET;
found_hostiles = 0; found_hostiles = 0;
[self checkScanner]; [self checkScanner];
int i; unsigned i;
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
GLfloat max_e = 0; GLfloat max_e = 0;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
@ -1510,7 +1510,7 @@ WormholeEntity* whole;
/*-- Locates all the ships in range and chooses the nearest --*/ /*-- Locates all the ships in range and chooses the nearest --*/
found_target = NO_TARGET; found_target = NO_TARGET;
[self checkScanner]; [self checkScanner];
int i; unsigned i;
GLfloat found_d2 = scannerRange * scannerRange; GLfloat found_d2 = scannerRange * scannerRange;
for (i = 0; i < n_scanned_ships ; i++) for (i = 0; i < n_scanned_ships ; i++)
{ {
@ -1734,7 +1734,7 @@ WormholeEntity* whole;
- (void) targetNextBeaconWithCode:(NSString*) code - (void) targetNextBeaconWithCode:(NSString*) code
{ {
NSArray* all_beacons = [UNIVERSE listBeaconsWithCode: code]; NSArray* all_beacons = [UNIVERSE listBeaconsWithCode: code];
ShipEntity* current_beacon = (ShipEntity*)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity* current_beacon = [UNIVERSE entityForUniversalID:primaryTarget];
if ((!current_beacon)||(![current_beacon isBeacon])) if ((!current_beacon)||(![current_beacon isBeacon]))
{ {
@ -1770,7 +1770,7 @@ WormholeEntity* whole;
- (void) setRacepointsFromTarget - (void) setRacepointsFromTarget
{ {
// two point - one at z - cr one at z + cr // two point - one at z - cr one at z + cr
ShipEntity* ship = (ShipEntity*)[UNIVERSE entityForUniversalID:primaryTarget]; ShipEntity* ship = [UNIVERSE entityForUniversalID:primaryTarget];
if (!ship) if (!ship)
{ {
[shipAI message:@"NOTHING_FOUND"]; [shipAI message:@"NOTHING_FOUND"];

View File

@ -250,7 +250,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
{ {
int sid = [[ships objectAtIndex:i] intValue]; int sid = [[ships objectAtIndex:i] intValue];
if ([UNIVERSE entityForUniversalID:sid]) if ([UNIVERSE entityForUniversalID:sid])
[[(ShipEntity *)[UNIVERSE entityForUniversalID:sid] getAI] message:@"DOCKING_ABORTED"]; [[[UNIVERSE entityForUniversalID:sid] getAI] message:@"DOCKING_ABORTED"];
} }
[shipsOnApproach removeAllObjects]; [shipsOnApproach removeAllObjects];
@ -259,7 +259,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
{ {
int sid = [[ships objectAtIndex:i] intValue]; int sid = [[ships objectAtIndex:i] intValue];
if ([UNIVERSE entityForUniversalID:sid]) if ([UNIVERSE entityForUniversalID:sid])
[[(ShipEntity *)[UNIVERSE entityForUniversalID:sid] getAI] message:@"DOCKING_ABORTED"]; [[[UNIVERSE entityForUniversalID:sid] getAI] message:@"DOCKING_ABORTED"];
} }
[shipsOnHold removeAllObjects]; [shipsOnHold removeAllObjects];
@ -277,7 +277,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
{ {
int sid = [(NSString *)[ships objectAtIndex:i] intValue]; int sid = [(NSString *)[ships objectAtIndex:i] intValue];
if ([UNIVERSE entityForUniversalID:sid]) if ([UNIVERSE entityForUniversalID:sid])
[(ShipEntity *)[UNIVERSE entityForUniversalID:sid] enterDock:self]; [[UNIVERSE entityForUniversalID:sid] enterDock:self];
} }
[shipsOnApproach removeAllObjects]; [shipsOnApproach removeAllObjects];
@ -286,7 +286,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
{ {
int sid = [(NSString *)[ships objectAtIndex:i] intValue]; int sid = [(NSString *)[ships objectAtIndex:i] intValue];
if ([UNIVERSE entityForUniversalID:sid]) if ([UNIVERSE entityForUniversalID:sid])
[(ShipEntity *)[UNIVERSE entityForUniversalID:sid] enterDock:self]; [[UNIVERSE entityForUniversalID:sid] enterDock:self];
} }
[shipsOnHold removeAllObjects]; [shipsOnHold removeAllObjects];
@ -365,9 +365,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
Vector portPos = [self getPortPosition]; Vector portPos = [self getPortPosition];
Vector portDir = vector_forward_from_quaternion(port_orientation); Vector portDir = vector_forward_from_quaternion(port_orientation);
BOOL isOffCentre = (fabs(portPos.x) + fabs(portPos.y) > 0.0f)|(fabs(portDir.x) + fabs(portDir.y) > 0.0f); BOOL isOffCentre = (fabs(portPos.x) + fabs(portPos.y) > 0.0f)|(fabs(portDir.x) + fabs(portDir.y) > 0.0f);
BOOL isRotatingStation = NO; BOOL isRotatingStation = [shipinfoDictionary boolForKey:@"rotating" defaultValue:NO];
if ([shipinfoDictionary objectForKey:@"rotating"])
isRotatingStation = [[shipinfoDictionary objectForKey:@"rotating"] boolValue];
if ((!isRotatingStation)&&(isOffCentre)) if ((!isRotatingStation)&&(isOffCentre))
{ {
if (![shipsOnHold objectForKey:shipID]) if (![shipsOnHold objectForKey:shipID])
@ -616,7 +614,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
int ship_id = [ship universalID]; int ship_id = [ship universalID];
NSString* shipID = [NSString stringWithFormat:@"%d",ship_id]; NSString* shipID = [NSString stringWithFormat:@"%d",ship_id];
if ([UNIVERSE entityForUniversalID:[ship universalID]]) if ([UNIVERSE entityForUniversalID:[ship universalID]])
[[(ShipEntity *)[UNIVERSE entityForUniversalID:[ship universalID]] getAI] message:@"DOCKING_ABORTED"]; [[[UNIVERSE entityForUniversalID:[ship universalID]] getAI] message:@"DOCKING_ABORTED"];
if ([shipsOnHold objectForKey:shipID]) if ([shipsOnHold objectForKey:shipID])
[shipsOnHold removeObjectForKey:shipID]; [shipsOnHold removeObjectForKey:shipID];
@ -1361,15 +1359,13 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
- (void) launchDefenseShip - (void) launchDefenseShip
{ {
int defense_target = primaryTarget; OOUniversalID defense_target = primaryTarget;
ShipEntity *defense_ship; ShipEntity *defense_ship = nil;
NSString* defense_ship_key = nil; NSString *defense_ship_key = nil;
NSString* defense_ship_role_key = nil; NSString *defense_ship_role_key = nil;
NSString* defense_ship_ai = @"policeInterceptAI.plist";
int techlevel = [self equivalent_tech_level]; int techlevel = [self equivalent_tech_level];
if (techlevel == NSNotFound) if (techlevel == NSNotFound) techlevel = 6;
techlevel = 6;
if ((ranrot_rand() & 7) + 6 <= techlevel) if ((ranrot_rand() & 7) + 6 <= techlevel)
defense_ship_role_key = @"interceptor"; defense_ship_role_key = @"interceptor";
else else
@ -1383,54 +1379,44 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
[shipAI reactToMessage:@"TARGET_LOST"]; [shipAI reactToMessage:@"TARGET_LOST"];
return; return;
} }
if ([shipinfoDictionary objectForKey:@"defense_ship"]) defense_ship_key = [shipinfoDictionary stringForKey:@"defense_ship"];
{ if (defense_ship_key != nil)
defense_ship_key = (NSString*)[shipinfoDictionary objectForKey:@"defense_ship"];
defense_ship_ai = nil;
}
if ([shipinfoDictionary objectForKey:@"defense_ship_role"])
{
defense_ship_role_key = (NSString*)[shipinfoDictionary objectForKey:@"defense_ship_role"];
defense_ship_ai = nil;
}
if (defense_ship_key)
{ {
defense_ship = [UNIVERSE newShipWithName:defense_ship_key]; defense_ship = [UNIVERSE newShipWithName:defense_ship_key];
[defense_ship setRoles:@"defense_ship"];
} }
else else
{ {
defense_ship_role_key = [shipinfoDictionary stringForKey:@"defense_ship_role"];
defense_ship = [UNIVERSE newShipWithRole:defense_ship_role_key]; defense_ship = [UNIVERSE newShipWithRole:defense_ship_role_key];
[defense_ship setRoles:@"defense_ship"];
} }
if (!defense_ship) if (!defense_ship)
return; return;
[defense_ship setRoles:@"defense_ship"];
police_launched++; police_launched++;
if (![defense_ship crew]) if (![defense_ship crew])
{
[defense_ship setCrew:[NSArray arrayWithObject: [defense_ship setCrew:[NSArray arrayWithObject:
[OOCharacter randomCharacterWithRole: @"hunter" [OOCharacter randomCharacterWithRole: @"hunter"
andOriginalSystem: [UNIVERSE systemSeed]]]]; andOriginalSystem: [UNIVERSE systemSeed]]]];
}
[defense_ship setOwner: self]; [defense_ship setOwner: self];
[defense_ship setGroupID:universalID]; // who's your Daddy [defense_ship setGroupID:universalID]; // who's your Daddy
if (defense_ship_ai)
[[defense_ship getAI] setStateMachine:defense_ship_ai];
[defense_ship addTarget:[UNIVERSE entityForUniversalID:defense_target]]; [defense_ship addTarget:[UNIVERSE entityForUniversalID:defense_target]];
if ((scanClass != CLASS_ROCK)&&(scanClass != CLASS_STATION)) if ((scanClass != CLASS_ROCK)&&(scanClass != CLASS_STATION))
[defense_ship setScanClass: scanClass]; // same as self [defense_ship setScanClass: scanClass]; // same as self
[self addShipToLaunchQueue:defense_ship]; [self addShipToLaunchQueue:defense_ship];
[defense_ship release]; [defense_ship release];
no_docking_while_launching = YES; no_docking_while_launching = YES;
[self abortAllDockings]; [self abortAllDockings];
} }
@ -1756,10 +1742,12 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
return NO; return NO;
if ([UNIVERSE station] == self) if ([UNIVERSE station] == self)
return YES; return YES;
// NOTE: non-standard capitalization is documented and entrenched.
if ([shipinfoDictionary objectForKey:@"hasShipyard"]) if ([shipinfoDictionary objectForKey:@"hasShipyard"])
{ {
PlayerEntity *player = [PlayerEntity sharedPlayer]; PlayerEntity *player = [PlayerEntity sharedPlayer];
NSObject *determinant = [shipinfoDictionary objectForKey:@"hasShipyard"]; id determinant = [shipinfoDictionary objectForKey:@"hasShipyard"];
if ([determinant isKindOfClass:[NSArray class]]) if ([determinant isKindOfClass:[NSArray class]])
{ {
NSArray *conditions = (NSArray *)determinant; NSArray *conditions = (NSArray *)determinant;
@ -1771,7 +1759,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
} }
if ([determinant isKindOfClass:[NSNumber class]]) if ([determinant isKindOfClass:[NSNumber class]])
{ {
float chance = [(NSNumber*)determinant floatValue];; float chance = [(NSNumber*)determinant floatValue];
return (randf() < chance); return (randf() < chance);
} }
} }

View File

@ -94,7 +94,6 @@ SOFTWARE.
+ (id)materialWithName:(NSString *)name + (id)materialWithName:(NSString *)name
configuration:(NSDictionary *)configuration configuration:(NSDictionary *)configuration
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)object; bindingTarget:(id<OOWeakReferenceSupport>)object;
/* Select an appropriate material description (based on availability of /* Select an appropriate material description (based on availability of
@ -105,7 +104,6 @@ SOFTWARE.
materialDictionary:(NSDictionary *)materialDict materialDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)object; bindingTarget:(id<OOWeakReferenceSupport>)object;
@end @end

View File

@ -134,7 +134,6 @@ static OOMaterial *sActiveMaterial = nil;
+ (id)materialWithName:(NSString *)name + (id)materialWithName:(NSString *)name
configuration:(NSDictionary *)configuration configuration:(NSDictionary *)configuration
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)object bindingTarget:(id<OOWeakReferenceSupport>)object
{ {
id result = nil; id result = nil;
@ -144,7 +143,7 @@ static OOMaterial *sActiveMaterial = nil;
{ {
if ([OOShaderMaterial configurationDictionarySpecifiesShaderMaterial:configuration]) if ([OOShaderMaterial configurationDictionarySpecifiesShaderMaterial:configuration])
{ {
result = [OOShaderMaterial shaderMaterialWithName:name configuration:configuration macros:macros defaultBindings:defaults bindingTarget:object]; result = [OOShaderMaterial shaderMaterialWithName:name configuration:configuration macros:macros bindingTarget:object];
} }
} }
#endif #endif
@ -174,7 +173,6 @@ static OOMaterial *sActiveMaterial = nil;
materialDictionary:(NSDictionary *)materialDict materialDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)object bindingTarget:(id<OOWeakReferenceSupport>)object
{ {
NSDictionary *configuration = nil; NSDictionary *configuration = nil;
@ -191,7 +189,7 @@ static OOMaterial *sActiveMaterial = nil;
configuration = [materialDict dictionaryForKey:name]; configuration = [materialDict dictionaryForKey:name];
} }
return [self materialWithName:name configuration:configuration macros:macros defaultBindings:defaults bindingTarget:object]; return [self materialWithName:name configuration:configuration macros:macros bindingTarget:object];
} }
@end @end

View File

@ -111,7 +111,7 @@ static void PNGRead(png_structp png, png_bytep bytes, png_size_t size);
uint8_t planes; uint8_t planes;
// Set up PNG decoding // Set up PNG decoding
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, PNGError, PNGWarning); png = png_create_read_struct(PNG_LIBPNG_VER_STRING, self, PNGError, PNGWarning);
if (png == NULL) if (png == NULL)
{ {
OOLog(@"texture.load.png.setup.failed", @"***** Error preparing to read %@.", path); OOLog(@"texture.load.png.setup.failed", @"***** Error preparing to read %@.", path);
@ -236,13 +236,19 @@ static void PNGRead(png_structp png, png_bytep bytes, png_size_t size);
static void PNGError(png_structp png, png_const_charp message) static void PNGError(png_structp png, png_const_charp message)
{ {
OOLog(@"texture.load.png.error", @"***** A PNG loading error occurred: %s", message); OOPNGTextureLoader *loader = nil;
loader = png->error_ptr;
OOLog(@"texture.load.png.error", @"***** A PNG loading error occurred for %@: %s", [loader path], message);
} }
static void PNGWarning(png_structp png, png_const_charp message) static void PNGWarning(png_structp png, png_const_charp message)
{ {
OOLog(@"texture.load.png.warning", @"***** A PNG loading warning occurred: %s", message); OOPNGTextureLoader *loader = nil;
loader = png->error_ptr;
OOLog(@"texture.load.png.warning", @"***** A PNG loading warning occurred for %@: %s", [loader path], message);
} }

View File

@ -88,10 +88,7 @@ typedef uint16_t OOUniformConvertOptions;
will look for are currently: will look for are currently:
textures array of texture file names. textures array of texture file names.
vertex_shader name of vertex shader file. vertex_shader name of vertex shader file.
glsl-vertex vertex shader source (if no vertex_shader).
fragment_shader name of fragment shader file. fragment_shader name of fragment shader file.
glsl-fragment fragment shader source (if no fragment_shader).
glsl fragment shader source (if no glsl-fragment).
uniforms dictionary of uniforms. Values are either reals or uniforms dictionary of uniforms. Values are either reals or
dictionaries containing: dictionaries containing:
type "int", "texture" or "float" type "int", "texture" or "float"
@ -110,13 +107,11 @@ typedef uint16_t OOUniformConvertOptions;
+ (id)shaderMaterialWithName:(NSString *)name + (id)shaderMaterialWithName:(NSString *)name
configuration:(NSDictionary *)configuration configuration:(NSDictionary *)configuration
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)target; bindingTarget:(id<OOWeakReferenceSupport>)target;
- (id)initWithName:(NSString *)name - (id)initWithName:(NSString *)name
configuration:(NSDictionary *)configuration configuration:(NSDictionary *)configuration
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)target; bindingTarget:(id<OOWeakReferenceSupport>)target;
/* Bind a uniform to a property of an object. /* Bind a uniform to a property of an object.

View File

@ -76,9 +76,6 @@ static NSString *MacrosToString(NSDictionary *macros);
if ([configuration stringForKey:@"vertex_shader"] != nil) return YES; if ([configuration stringForKey:@"vertex_shader"] != nil) return YES;
if ([configuration stringForKey:@"fragment_shader"] != nil) return YES; if ([configuration stringForKey:@"fragment_shader"] != nil) return YES;
if ([configuration stringForKey:@"glsl-vertex"] != nil) return YES;
if ([configuration stringForKey:@"glsl-fragment"] != nil) return YES;
if ([configuration stringForKey:@"glsl"] != nil) return YES;
return NO; return NO;
} }
@ -87,17 +84,15 @@ static NSString *MacrosToString(NSDictionary *macros);
+ (id)shaderMaterialWithName:(NSString *)name + (id)shaderMaterialWithName:(NSString *)name
configuration:(NSDictionary *)configuration configuration:(NSDictionary *)configuration
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)target bindingTarget:(id<OOWeakReferenceSupport>)target
{ {
return [[[self alloc] initWithName:name configuration:configuration macros:macros defaultBindings:defaults bindingTarget:target] autorelease]; return [[[self alloc] initWithName:name configuration:configuration macros:macros bindingTarget:target] autorelease];
} }
- (id)initWithName:(NSString *)name - (id)initWithName:(NSString *)name
configuration:(NSDictionary *)configuration configuration:(NSDictionary *)configuration
macros:(NSDictionary *)macros macros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:(id<OOWeakReferenceSupport>)target bindingTarget:(id<OOWeakReferenceSupport>)target
{ {
BOOL OK = YES; BOOL OK = YES;
@ -138,19 +133,7 @@ static NSString *MacrosToString(NSDictionary *macros);
} }
else else
{ {
// Otherwise, look for inline source OOLog(@"shader.load.noShader", @"***** Error: no vertex or fragment shader specified specified in shader dictionary:\n%@", configuration);
vertexShader = [configuration stringForKey:@"glsl-vertex"];
fragmentShader = [configuration stringForKey:@"glsl-fragment"];
if (fragmentShader == nil) fragmentShader = [configuration stringForKey:@"glsl"];
if (vertexShader != nil || fragmentShader != nil)
{
shaderProgram = [OOShaderProgram shaderProgramWithVertexShaderSource:vertexShader fragmentShaderSource:fragmentShader prefix:macroString];
}
else
{
OOLog(@"shader.load.noShader", @"***** Error: no vertex or fragment shader specified specified in shader dictionary:\n%@", configuration);
}
} }
OK = (shaderProgram != nil); OK = (shaderProgram != nil);
@ -163,11 +146,9 @@ static NSString *MacrosToString(NSDictionary *macros);
uniformDefs = [configuration dictionaryForKey:@"uniforms"]; uniformDefs = [configuration dictionaryForKey:@"uniforms"];
textureDefs = [configuration arrayForKey:@"textures"]; textureDefs = [configuration arrayForKey:@"textures"];
uniforms = [[NSMutableDictionary alloc] initWithCapacity:[uniformDefs count] + [textureDefs count] + [defaults count]]; uniforms = [[NSMutableDictionary alloc] initWithCapacity:[uniformDefs count] + [textureDefs count]];
[self addUniformsFromDictionary:defaults withBindingTarget:target];
[self addUniformsFromDictionary:uniformDefs withBindingTarget:target]; [self addUniformsFromDictionary:uniformDefs withBindingTarget:target];
// ...and textures, which are a flavour of uniform for our purpose.
// ...and textures, which are a flavour of uniform four our purpose.
[self addTexturesFromArray:textureDefs unitCount:textureUnits]; [self addTexturesFromArray:textureDefs unitCount:textureUnits];
} }

View File

@ -69,11 +69,6 @@ SOFTWARE.
fragmentShaderName:(NSString *)fragmentShaderName fragmentShaderName:(NSString *)fragmentShaderName
prefix:(NSString *)prefixString; prefix:(NSString *)prefixString;
// Loads a shader from memory, always generating a new instance.
+ (id)shaderProgramWithVertexShaderSource:(NSString *)vertexShaderSource
fragmentShaderSource:(NSString *)fragmentShaderSource
prefix:(NSString *)prefixString;
- (void)apply; - (void)apply;
+ (void)applyNone; + (void)applyNone;

View File

@ -84,6 +84,7 @@ static NSString *GetGLSLInfoLog(GLhandleARB shaderObject);
if ([prefixString length] == 0) prefixString = nil; if ([prefixString length] == 0) prefixString = nil;
// Use cache to avoid creating duplicate shader programs -- saves on GPU resources and potentially state changes. // Use cache to avoid creating duplicate shader programs -- saves on GPU resources and potentially state changes.
// FIXME: probably needs to respond to graphics resets.
key = [NSString stringWithFormat:@"vertex:%@\nfragment:%@\n----\n%@", vertexShaderName, fragmentShaderName, prefixString ?: @""]; key = [NSString stringWithFormat:@"vertex:%@\nfragment:%@\n----\n%@", vertexShaderName, fragmentShaderName, prefixString ?: @""];
program = [[sShaderCache objectForKey:key] pointerValue]; program = [[sShaderCache objectForKey:key] pointerValue];
@ -107,20 +108,6 @@ static NSString *GetGLSLInfoLog(GLhandleARB shaderObject);
} }
+ (id)shaderProgramWithVertexShaderSource:(NSString *)vertexShaderSource
fragmentShaderSource:(NSString *)fragmentShaderSource
prefix:(NSString *)prefixString
{
if (prefixString != nil)
{
if (vertexShaderSource != nil) vertexShaderSource = [prefixString stringByAppendingString:vertexShaderSource];
if (fragmentShaderSource != nil) fragmentShaderSource = [prefixString stringByAppendingString:fragmentShaderSource];
}
return [[[self alloc] initWithVertexShaderSource:vertexShaderSource fragmentShaderSource:fragmentShaderSource key:nil] autorelease];
}
- (void)dealloc - (void)dealloc
{ {
OO_ENTER_OPENGL(); OO_ENTER_OPENGL();

View File

@ -49,7 +49,9 @@ SOFTWARE.
*/ */
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import "OOOpenGL.h" #import "OOOpenGL.h"
#import "OOWeakReference.h"
@class OOTextureLoader; @class OOTextureLoader;
@ -103,7 +105,7 @@ typedef enum
} OOTextureDataFormat; } OOTextureDataFormat;
@interface OOTexture: NSObject @interface OOTexture: OOWeakRefObject
{ {
NSString *_key; NSString *_key;
uint8_t _loaded: 1, uint8_t _loaded: 1,
@ -112,6 +114,7 @@ typedef enum
_isRectTexture: 1, _isRectTexture: 1,
#endif #endif
_valid: 1; _valid: 1;
uint8_t _mipLevels;
OOTextureLoader *_loader; OOTextureLoader *_loader;

View File

@ -74,7 +74,7 @@ SOFTWARE.
*/ */
enum enum
{ {
kRecentTexturesCount = 1002 kRecentTexturesCount = 50
}; };
static NSMutableDictionary *sInUseTextures = nil; static NSMutableDictionary *sInUseTextures = nil;
@ -320,8 +320,6 @@ static BOOL sRectangleTextureAvailable;
- (void)dealloc - (void)dealloc
{ {
OO_ENTER_OPENGL();
OOLog(@"texture.dealloc", @"Deallocating and uncaching texture %@", self); OOLog(@"texture.dealloc", @"Deallocating and uncaching texture %@", self);
if (_key != nil) if (_key != nil)
@ -333,7 +331,7 @@ static BOOL sRectangleTextureAvailable;
if (_loaded) if (_loaded)
{ {
if (_textureName != 0) glDeleteTextures(1, &_textureName); if (_textureName != 0) GLRecycleTextureName(_textureName, _mipLevels);
if (_bytes != NULL) free(_bytes); if (_bytes != NULL) free(_bytes);
} }
@ -538,7 +536,7 @@ static BOOL sRectangleTextureAvailable;
if (!_uploaded) if (!_uploaded)
{ {
glGenTextures(1, &_textureName); _textureName = GLAllocateTextureName();
glBindTexture(GL_TEXTURE_2D, _textureName); glBindTexture(GL_TEXTURE_2D, _textureName);
// Select wrap mode // Select wrap mode
@ -621,18 +619,17 @@ static BOOL sRectangleTextureAvailable;
h >>= 1; h >>= 1;
} }
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level - 1); _mipLevels = level - 1;
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, _mipLevels);
} }
- (void)forceRebind - (void)forceRebind
{ {
OO_ENTER_OPENGL();
if (_loaded && _uploaded && _valid) if (_loaded && _uploaded && _valid)
{ {
_uploaded = NO; _uploaded = NO;
glDeleteTextures(1, &_textureName); GLRecycleTextureName(_textureName, _mipLevels);
_textureName = 0; _textureName = 0;
} }
} }

View File

@ -88,6 +88,8 @@ SOFTWARE.
// Subclasses shouldn't do much on init, because of the whole asynchronous thing. // Subclasses shouldn't do much on init, because of the whole asynchronous thing.
- (id)initWithPath:(NSString *)path options:(uint32_t)options; - (id)initWithPath:(NSString *)path options:(uint32_t)options;
- (NSString *)path;
/* Load data, setting up data, width, and height, and rowBytes if it's not /* Load data, setting up data, width, and height, and rowBytes if it's not
width * 4. width * 4.

View File

@ -150,7 +150,7 @@ enum
- (void)dealloc - (void)dealloc
{ {
[path release]; [path autorelease];
if (data != NULL) free(data); if (data != NULL) free(data);
[super dealloc]; [super dealloc];
@ -172,6 +172,12 @@ enum
} }
- (NSString *)path
{
return path;
}
- (BOOL)isReady - (BOOL)isReady
{ {
return ready; return ready;

View File

@ -13,6 +13,9 @@ Starting with Oolite 1.69.1, the various integer methods will always clamp
values to the range of the return type, rather than truncating like NSNumber. values to the range of the return type, rather than truncating like NSNumber.
Before that, they weren't entirely inconsistent. Before that, they weren't entirely inconsistent.
The "non-negative float"/"non-negative double" will clamp read values to zero
if negative, but will return a negative defaultValue unchanged.
Oolite Oolite
Copyright (C) 2004-2007 Giles C Williams and contributors Copyright (C) 2004-2007 Giles C Williams and contributors
@ -82,6 +85,8 @@ SOFTWARE.
- (float)floatAtIndex:(unsigned)index defaultValue:(float)value; - (float)floatAtIndex:(unsigned)index defaultValue:(float)value;
- (double)doubleAtIndex:(unsigned)index defaultValue:(double)value; - (double)doubleAtIndex:(unsigned)index defaultValue:(double)value;
- (float)nonNegativeFloatAtIndex:(unsigned)index defaultValue:(float)value;
- (double)nonNegativeDoubleAtIndex:(unsigned)index defaultValue:(double)value;
- (id)objectAtIndex:(unsigned)index defaultValue:(id)value; - (id)objectAtIndex:(unsigned)index defaultValue:(id)value;
- (id)objectOfClass:(Class)class atIndex:(unsigned)index defaultValue:(id)value; - (id)objectOfClass:(Class)class atIndex:(unsigned)index defaultValue:(id)value;
@ -90,6 +95,9 @@ SOFTWARE.
- (NSDictionary *)dictionaryAtIndex:(unsigned)index defaultValue:(NSDictionary *)value; - (NSDictionary *)dictionaryAtIndex:(unsigned)index defaultValue:(NSDictionary *)value;
- (NSData *)dataAtIndex:(unsigned)index defaultValue:(NSData *)value; - (NSData *)dataAtIndex:(unsigned)index defaultValue:(NSData *)value;
- (struct Vector)vectorAtIndex:(unsigned)index defaultValue:(struct Vector)value;
- (struct Quaternion)quaternionAtIndex:(unsigned)index defaultValue:(struct Quaternion)value;
// Default: 0 // Default: 0
- (char)charAtIndex:(unsigned)index; - (char)charAtIndex:(unsigned)index;
@ -111,6 +119,8 @@ SOFTWARE.
// Default: 0.0 // Default: 0.0
- (float)floatAtIndex:(unsigned)index; - (float)floatAtIndex:(unsigned)index;
- (double)doubleAtIndex:(unsigned)index; - (double)doubleAtIndex:(unsigned)index;
- (float)nonNegativeFloatAtIndex:(unsigned)index;
- (double)nonNegativeDoubleAtIndex:(unsigned)index;
// Default: nil // Default: nil
// - (id)objectAtIndex:(unsigned)index; // Already defined // - (id)objectAtIndex:(unsigned)index; // Already defined
@ -120,6 +130,11 @@ SOFTWARE.
- (NSDictionary *)dictionaryAtIndex:(unsigned)index; - (NSDictionary *)dictionaryAtIndex:(unsigned)index;
- (NSData *)dataAtIndex:(unsigned)index; - (NSData *)dataAtIndex:(unsigned)index;
// Default: kZeroVector
- (struct Vector)vectorAtIndex:(unsigned)index;
// Default: kIdentityQuaternion
- (struct Quaternion)quaternionAtIndex:(unsigned)index;
@end @end
@ -142,6 +157,8 @@ SOFTWARE.
- (float)floatForKey:(id)key defaultValue:(float)value; - (float)floatForKey:(id)key defaultValue:(float)value;
- (double)doubleForKey:(id)key defaultValue:(double)value; - (double)doubleForKey:(id)key defaultValue:(double)value;
- (float)nonNegativeFloatForKey:(id)key defaultValue:(float)value;
- (double)nonNegativeDoubleForKey:(id)key defaultValue:(double)value;
- (id)objectForKey:(id)key defaultValue:(id)value; - (id)objectForKey:(id)key defaultValue:(id)value;
- (id)objectOfClass:(Class)class forKey:(id)key defaultValue:(id)value; - (id)objectOfClass:(Class)class forKey:(id)key defaultValue:(id)value;
@ -150,6 +167,9 @@ SOFTWARE.
- (NSDictionary *)dictionaryForKey:(id)key defaultValue:(NSDictionary *)value; - (NSDictionary *)dictionaryForKey:(id)key defaultValue:(NSDictionary *)value;
- (NSData *)dataForKey:(id)key defaultValue:(NSData *)value; - (NSData *)dataForKey:(id)key defaultValue:(NSData *)value;
- (struct Vector)vectorForKey:(id)key defaultValue:(struct Vector)value;
- (struct Quaternion)quaternionForKey:(id)key defaultValue:(struct Quaternion)value;
// Default: 0 // Default: 0
- (char)charForKey:(id)key; - (char)charForKey:(id)key;
@ -171,6 +191,8 @@ SOFTWARE.
// Default: 0.0 // Default: 0.0
- (float)floatForKey:(id)key; - (float)floatForKey:(id)key;
- (double)doubleForKey:(id)key; - (double)doubleForKey:(id)key;
- (float)nonNegativeFloatForKey:(id)key;
- (double)nonNegativeDoubleForKey:(id)key;
// Default: nil // Default: nil
// - (id)objectForKey:(id)key; // Already defined // - (id)objectForKey:(id)key; // Already defined
@ -180,6 +202,11 @@ SOFTWARE.
- (NSDictionary *)dictionaryForKey:(id)key; - (NSDictionary *)dictionaryForKey:(id)key;
- (NSData *)dataForKey:(id)key; - (NSData *)dataForKey:(id)key;
// Default: kZeroVector
- (struct Vector)vectorForKey:(id)key;
// Default: kIdentityQuaternion
- (struct Quaternion)quaternionForKey:(id)key;
@end @end
@ -202,6 +229,8 @@ SOFTWARE.
- (float)floatForKey:(id)key defaultValue:(float)value; - (float)floatForKey:(id)key defaultValue:(float)value;
- (double)doubleForKey:(id)key defaultValue:(double)value; - (double)doubleForKey:(id)key defaultValue:(double)value;
- (float)nonNegativeFloatForKey:(id)key defaultValue:(float)value;
- (double)nonNegativeDoubleForKey:(id)key defaultValue:(double)value;
- (id)objectForKey:(id)key defaultValue:(id)value; - (id)objectForKey:(id)key defaultValue:(id)value;
- (id)objectOfClass:(Class)class forKey:(id)key defaultValue:(id)value; - (id)objectOfClass:(Class)class forKey:(id)key defaultValue:(id)value;
@ -231,6 +260,8 @@ SOFTWARE.
// Default: 0.0 // Default: 0.0
// - (float)floatForKey:(id)key; // - (float)floatForKey:(id)key;
- (double)doubleForKey:(id)key; - (double)doubleForKey:(id)key;
- (float)nonNegativeFloatForKey:(id)key;
- (double)nonNegativeDoubleForKey:(id)key;
// Default: nil // Default: nil
// - (id)objectForKey:(id)key; // Already defined // - (id)objectForKey:(id)key; // Already defined
@ -302,6 +333,13 @@ BOOL OOFuzzyBooleanFromObject(id object, BOOL defaultValue);
float OOFloatFromObject(id object, float defaultValue); float OOFloatFromObject(id object, float defaultValue);
double OODoubleFromObject(id object, double defaultValue); double OODoubleFromObject(id object, double defaultValue);
float OONonNegativeFloatFromObject(id object, float defaultValue);
double OONonNegativeDoubleFromObject(id object, double defaultValue);
/* These take strings, dictionaries or arrays.
*/
struct Vector OOVectorFromObject(id object, struct Vector defaultValue);
struct Quaternion OOQuaternionFromObject(id object, struct Quaternion defaultValue);
OOINLINE long long OOClampInteger(long long value, long long minValue, long long maxValue) ALWAYS_INLINE_FUNC; OOINLINE long long OOClampInteger(long long value, long long minValue, long long maxValue) ALWAYS_INLINE_FUNC;

View File

@ -48,6 +48,7 @@ SOFTWARE.
#import "OOCollectionExtractors.h" #import "OOCollectionExtractors.h"
#import <limits.h> #import <limits.h>
#import "OOMaths.h" #import "OOMaths.h"
#import "OOStringParsing.h"
@implementation NSArray (OOExtractor) @implementation NSArray (OOExtractor)
@ -136,6 +137,18 @@ SOFTWARE.
} }
- (float)nonNegativeFloatAtIndex:(unsigned)index defaultValue:(float)value
{
return OONonNegativeFloatFromObject([self objectAtIndex:index], value);
}
- (double)nonNegativeDoubleAtIndex:(unsigned)index defaultValue:(double)value
{
return OONonNegativeDoubleFromObject([self objectAtIndex:index], value);
}
- (id)objectAtIndex:(unsigned)index defaultValue:(id)value - (id)objectAtIndex:(unsigned)index defaultValue:(id)value
{ {
id objVal = [self objectAtIndex:index]; id objVal = [self objectAtIndex:index];
@ -184,6 +197,18 @@ SOFTWARE.
} }
- (struct Vector)vectorAtIndex:(unsigned)index defaultValue:(struct Vector)value
{
return OOVectorFromObject([self objectAtIndex:index], value);
}
- (struct Quaternion)quaternionAtIndex:(unsigned)index defaultValue:(struct Quaternion)value;
{
return OOQuaternionFromObject([self objectAtIndex:index], value);
}
- (char)charAtIndex:(unsigned)index - (char)charAtIndex:(unsigned)index
{ {
return [self charAtIndex:index defaultValue:0]; return [self charAtIndex:index defaultValue:0];
@ -258,13 +283,25 @@ SOFTWARE.
- (float)floatAtIndex:(unsigned)index - (float)floatAtIndex:(unsigned)index
{ {
return [self floatAtIndex:index defaultValue:0.0f]; return OOFloatFromObject([self objectAtIndex:index], 0.0f);
} }
- (double)doubleAtIndex:(unsigned)index - (double)doubleAtIndex:(unsigned)index
{ {
return [self doubleAtIndex:index defaultValue:0.0]; return OODoubleFromObject([self objectAtIndex:index], 0.0);
}
- (float)nonNegativeFloatAtIndex:(unsigned)index
{
return OONonNegativeFloatFromObject([self objectAtIndex:index], 0.0f);
}
- (double)nonNegativeDoubleAtIndex:(unsigned)index
{
return OONonNegativeDoubleFromObject([self objectAtIndex:index], 0.0);
} }
@ -297,6 +334,18 @@ SOFTWARE.
return [self dataAtIndex:index defaultValue:nil]; return [self dataAtIndex:index defaultValue:nil];
} }
- (struct Vector)vectorAtIndex:(unsigned)index
{
return [self vectorAtIndex:index defaultValue:kZeroVector];
}
- (struct Quaternion)quaternionAtIndex:(unsigned)index
{
return [self quaternionAtIndex:index defaultValue:kIdentityQuaternion];
}
@end @end
@ -386,6 +435,18 @@ SOFTWARE.
} }
- (float)nonNegativeFloatForKey:(id)key defaultValue:(float)value
{
return OONonNegativeFloatFromObject([self objectForKey:key], value);
}
- (double)nonNegativeDoubleForKey:(id)key defaultValue:(double)value
{
return OONonNegativeDoubleFromObject([self objectForKey:key], value);
}
- (id)objectForKey:(id)key defaultValue:(id)value - (id)objectForKey:(id)key defaultValue:(id)value
{ {
id objVal = [self objectForKey:key]; id objVal = [self objectForKey:key];
@ -434,6 +495,18 @@ SOFTWARE.
} }
- (struct Vector)vectorForKey:(id)key defaultValue:(struct Vector)value
{
return OOVectorFromObject([self objectForKey:key], value);
}
- (struct Quaternion)quaternionForKey:(id)key defaultValue:(struct Quaternion)value
{
return OOQuaternionFromObject([self objectForKey:key], value);
}
- (char)charForKey:(id)key - (char)charForKey:(id)key
{ {
return [self charForKey:key defaultValue:0]; return [self charForKey:key defaultValue:0];
@ -508,13 +581,25 @@ SOFTWARE.
- (float)floatForKey:(id)key - (float)floatForKey:(id)key
{ {
return [self floatForKey:key defaultValue:0.0f]; return OOFloatFromObject([self objectForKey:key], 0.0f);
} }
- (double)doubleForKey:(id)key - (double)doubleForKey:(id)key
{ {
return [self doubleForKey:key defaultValue:0.0]; return OODoubleFromObject([self objectForKey:key], 0.0);
}
- (float)nonNegativeFloatForKey:(id)key
{
return OONonNegativeFloatFromObject([self objectForKey:key], 0.0f);
}
- (double)nonNegativeDoubleForKey:(id)key
{
return OONonNegativeDoubleFromObject([self objectForKey:key], 0.0);
} }
@ -547,6 +632,18 @@ SOFTWARE.
return [self dataForKey:key defaultValue:nil]; return [self dataForKey:key defaultValue:nil];
} }
- (struct Vector)vectorForKey:(id)key
{
return [self vectorForKey:key defaultValue:kZeroVector];
}
- (struct Quaternion)quaternionForKey:(id)key
{
return [self quaternionForKey:key defaultValue:kIdentityQuaternion];
}
@end @end
@ -636,6 +733,18 @@ SOFTWARE.
} }
- (float)nonNegativeFloatForKey:(id)key defaultValue:(float)value
{
return OONonNegativeFloatFromObject([self objectForKey:key], value);
}
- (double)nonNegativeDoubleForKey:(id)key defaultValue:(double)value
{
return OONonNegativeDoubleFromObject([self objectForKey:key], value);
}
- (id)objectForKey:(id)key defaultValue:(id)value - (id)objectForKey:(id)key defaultValue:(id)value
{ {
id objVal = [self objectForKey:key]; id objVal = [self objectForKey:key];
@ -752,7 +861,19 @@ SOFTWARE.
- (double)doubleForKey:(id)key - (double)doubleForKey:(id)key
{ {
return [self doubleForKey:key defaultValue:0.0]; return OODoubleFromObject([self objectForKey:key], 0.0);
}
- (float)nonNegativeFloatForKey:(id)key
{
return OONonNegativeFloatFromObject([self objectForKey:key], 0.0f);
}
- (double)nonNegativeDoubleForKey:(id)key
{
return OONonNegativeDoubleFromObject([self objectForKey:key], 0.0);
} }
@ -949,7 +1070,7 @@ float OOFloatFromObject(id object, float defaultValue)
double OODoubleFromObject(id object, double defaultValue) double OODoubleFromObject(id object, double defaultValue)
{ {
float result; double result;
if ([object respondsToSelector:@selector(doubleValue)]) result = [object doubleValue]; if ([object respondsToSelector:@selector(doubleValue)]) result = [object doubleValue];
else if ([object respondsToSelector:@selector(floatValue)]) result = [object floatValue]; else if ([object respondsToSelector:@selector(floatValue)]) result = [object floatValue];
@ -960,6 +1081,101 @@ double OODoubleFromObject(id object, double defaultValue)
} }
float OONonNegativeFloatFromObject(id object, float defaultValue)
{
float result;
if ([object respondsToSelector:@selector(floatValue)]) result = [object floatValue];
else if ([object respondsToSelector:@selector(doubleValue)]) result = [object doubleValue];
else if ([object respondsToSelector:@selector(intValue)]) result = [object intValue];
else return defaultValue; // Don't clamp default
return OOMax_f(result, 0.0f);
}
double OONonNegativeDoubleFromObject(id object, double defaultValue)
{
double result;
if ([object respondsToSelector:@selector(doubleValue)]) result = [object doubleValue];
else if ([object respondsToSelector:@selector(floatValue)]) result = [object floatValue];
else if ([object respondsToSelector:@selector(intValue)]) result = [object intValue];
else return defaultValue; // Don't clamp default
return OOMax_d(result, 0.0f);
}
struct Vector OOVectorFromObject(id object, struct Vector defaultValue)
{
Vector result = defaultValue;
if ([object isKindOfClass:[NSString class]])
{
// This will only write result if a valid vector is found, and will write an error message otherwise.
ScanVectorFromString(object, &result);
}
else if ([object isKindOfClass:[NSArray class]] && [object count] == 3)
{
result.x = [object floatAtIndex:0];
result.y = [object floatAtIndex:1];
result.z = [object floatAtIndex:2];
}
else if ([object isKindOfClass:[NSDictionary class]])
{
// Require at least one of the keys x, y, or z
if ([object objectForKey:@"x"] != nil ||
[object objectForKey:@"y"] != nil ||
[object objectForKey:@"z"] != nil)
{
// Note: uses 0 for unknown components rather than components of defaultValue.
result.x = [object floatForKey:@"x" defaultValue:0.0f];
result.y = [object floatForKey:@"y" defaultValue:0.0f];
result.z = [object floatForKey:@"z" defaultValue:0.0f];
}
}
return result;
}
struct Quaternion OOQuaternionFromObject(id object, struct Quaternion defaultValue)
{
Quaternion result = defaultValue;
if ([object isKindOfClass:[NSString class]])
{
// This will only write result if a valid quaternion is found, and will write an error message otherwise.
ScanQuaternionFromString(object, &result);
}
else if ([object isKindOfClass:[NSArray class]] && [object count] == 4)
{
result.w = [object floatAtIndex:0];
result.x = [object floatAtIndex:1];
result.y = [object floatAtIndex:2];
result.z = [object floatAtIndex:3];
}
else if ([object isKindOfClass:[NSDictionary class]])
{
// Require at least one of the keys w, x, y, or z
if ([object objectForKey:@"w"] != nil ||
[object objectForKey:@"x"] != nil ||
[object objectForKey:@"y"] != nil ||
[object objectForKey:@"z"] != nil)
{
// Note: uses 0 for unknown components rather than components of defaultValue.
result.w = [object floatForKey:@"w" defaultValue:0.0f];
result.x = [object floatForKey:@"x" defaultValue:0.0f];
result.y = [object floatForKey:@"y" defaultValue:0.0f];
result.z = [object floatForKey:@"z" defaultValue:0.0f];
}
}
return result;
}
static BOOL IsBooleanString(id object, BOOL *outValue) static BOOL IsBooleanString(id object, BOOL *outValue)
{ {
if ([object isKindOfClass:[NSString class]]) if ([object isKindOfClass:[NSString class]])

View File

@ -117,7 +117,6 @@ materialDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
smooth:(BOOL)smooth smooth:(BOOL)smooth
shaderMacros:(NSDictionary *)macros shaderMacros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
shaderBindingTarget:(id<OOWeakReferenceSupport>)object; shaderBindingTarget:(id<OOWeakReferenceSupport>)object;
- (NSString *) modelName; - (NSString *) modelName;

View File

@ -51,13 +51,11 @@ materialDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
smooth:(BOOL)smooth smooth:(BOOL)smooth
shaderMacros:(NSDictionary *)macros shaderMacros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
shaderBindingTarget:(id<OOWeakReferenceSupport>)object; shaderBindingTarget:(id<OOWeakReferenceSupport>)object;
- (void)setUpMaterialsWithMaterialsDictionary:(NSDictionary *)materialDict - (void)setUpMaterialsWithMaterialsDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
shaderMacros:(NSDictionary *)macros shaderMacros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
shaderBindingTarget:(id<OOWeakReferenceSupport>)target; shaderBindingTarget:(id<OOWeakReferenceSupport>)target;
- (BOOL) loadData:(NSString *)filename; - (BOOL) loadData:(NSString *)filename;
@ -97,7 +95,6 @@ materialDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
smooth:(BOOL)smooth smooth:(BOOL)smooth
shaderMacros:(NSDictionary *)macros shaderMacros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
shaderBindingTarget:(id<OOWeakReferenceSupport>)object shaderBindingTarget:(id<OOWeakReferenceSupport>)object
{ {
return [[[self alloc] initWithName:name return [[[self alloc] initWithName:name
@ -105,7 +102,6 @@ shaderBindingTarget:(id<OOWeakReferenceSupport>)object
shadersDictionary:shadersDict shadersDictionary:shadersDict
smooth:smooth smooth:smooth
shaderMacros:macros shaderMacros:macros
defaultBindings:defaults
shaderBindingTarget:object] autorelease]; shaderBindingTarget:object] autorelease];
} }
@ -423,7 +419,6 @@ materialDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
smooth:(BOOL)smooth smooth:(BOOL)smooth
shaderMacros:(NSDictionary *)macros shaderMacros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
shaderBindingTarget:(id<OOWeakReferenceSupport>)target shaderBindingTarget:(id<OOWeakReferenceSupport>)target
{ {
self = [super init]; self = [super init];
@ -437,7 +432,7 @@ shaderBindingTarget:(id<OOWeakReferenceSupport>)target
[self checkNormalsAndAdjustWinding]; [self checkNormalsAndAdjustWinding];
[self calculateBoundingVolumes]; [self calculateBoundingVolumes];
baseFile = [name copy]; baseFile = [name copy];
[self setUpMaterialsWithMaterialsDictionary:materialDict shadersDictionary:shadersDict shaderMacros:macros defaultBindings:defaults shaderBindingTarget:target]; [self setUpMaterialsWithMaterialsDictionary:materialDict shadersDictionary:shadersDict shaderMacros:macros shaderBindingTarget:target];
[[OOGraphicsResetManager sharedManager] registerClient:self]; [[OOGraphicsResetManager sharedManager] registerClient:self];
} }
else else
@ -454,7 +449,6 @@ shaderBindingTarget:(id<OOWeakReferenceSupport>)target
- (void)setUpMaterialsWithMaterialsDictionary:(NSDictionary *)materialDict - (void)setUpMaterialsWithMaterialsDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict shadersDictionary:(NSDictionary *)shadersDict
shaderMacros:(NSDictionary *)macros shaderMacros:(NSDictionary *)macros
defaultBindings:(NSDictionary *)defaults
shaderBindingTarget:(id<OOWeakReferenceSupport>)target shaderBindingTarget:(id<OOWeakReferenceSupport>)target
{ {
OOMeshMaterialCount i; OOMeshMaterialCount i;
@ -470,7 +464,6 @@ shaderBindingTarget:(id<OOWeakReferenceSupport>)target
materialDictionary:materialDict materialDictionary:materialDict
shadersDictionary:shadersDict shadersDictionary:shadersDict
macros:macros macros:macros
defaultBindings:(NSDictionary *)defaults
bindingTarget:target]; bindingTarget:target];
materials[i] = [material retain]; materials[i] = [material retain];
} }

View File

@ -114,3 +114,13 @@ void GLDrawBallBillboard(GLfloat radius, GLfloat step, GLfloat z_distance);
*/ */
void GLDrawOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step); void GLDrawOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step);
void GLDrawFilledOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step); void GLDrawFilledOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step);
/* Texture name cache.
glGenTextures() and glDeleteTextures() are expensive operations -- each
requres a complete flush of the rendering pipeline. We work around this by
caching texture objects.
*/
GLuint GLAllocateTextureName(void);
void GLRecycleTextureName(GLuint name, GLuint mipLevels);

View File

@ -146,6 +146,69 @@ void GLDrawFilledOval(GLfloat x, GLfloat y, GLfloat z, NSSize siz, GLfloat step)
} }
enum
{
// Number of cached texture names. Unused texture names are cheap, so we use lots.
kTextureNameCacheMaxSize = 128,
// Number of texture names to discard at a time when cache overflows.
kTextureNameCacheFlushCount = kTextureNameCacheMaxSize / 4
};
static GLuint sTextureNameCache[kTextureNameCacheMaxSize];
static unsigned sTextureNameCacheSize = 0;
GLuint GLAllocateTextureName(void)
{
OOLog(@"textureCache.allocate", @"Request for texture name while cache size is %u.", sTextureNameCacheSize);
if (sTextureNameCacheSize == 0)
{
OO_ENTER_OPENGL();
OOLog(@"textureCache.fill", @"Adding %u elements to texture names cache.", kTextureNameCacheMaxSize);
// Allocate a block of names.
glGenTextures(kTextureNameCacheMaxSize, sTextureNameCache);
sTextureNameCacheSize = kTextureNameCacheMaxSize;
}
assert(sTextureNameCacheSize != 0);
return sTextureNameCache[--sTextureNameCacheSize];
}
void GLRecycleTextureName(GLuint name, GLuint mipLevels)
{
if (name == 0) return;
OOLog(@"textureCache.recycle", @"Recycling texture name while cache size is %u.", sTextureNameCacheSize);
OO_ENTER_OPENGL();
if (sTextureNameCacheSize == kTextureNameCacheMaxSize)
{
OOLog(@"textureCache.flush", @"Deleting %u elements from texture names cache.", kTextureNameCacheFlushCount);
// No more space; delete several elements (to avoid a series of individual deletes)
sTextureNameCacheSize -= kTextureNameCacheFlushCount;
glDeleteTextures(kTextureNameCacheFlushCount, &sTextureNameCache[sTextureNameCacheSize]);
}
assert(sTextureNameCacheSize < kTextureNameCacheMaxSize);
GLuint i;
uint8_t junk[4];
for (i = 0; i != mipLevels; ++i)
{
glBindTexture(GL_TEXTURE_2D, name);
glTexImage2D(GL_TEXTURE_2D, i, GL_RGBA, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, junk);
}
sTextureNameCache[sTextureNameCacheSize++] = name;
}
// ======== LogOpenGLState() and helpers ======== // ======== LogOpenGLState() and helpers ========
#if 0 #if 0

View File

@ -126,3 +126,15 @@ This code is hereby placed in the public domain.
- (id)weakRefUnderlyingObject; // Always self for non-weakrefs (and of course nil for nil). - (id)weakRefUnderlyingObject; // Always self for non-weakrefs (and of course nil for nil).
@end @end
/* OOWeakRefObject
Simple object implementing OOWeakReferenceSupport, to subclass. This
provides a full implementation for simplicity, but keep in mind that the
protocol can be implemented by any class.
*/
@interface OOWeakRefObject: NSObject <OOWeakReferenceSupport>
{
OOWeakReference *weakSelf;
}
@end

View File

@ -142,6 +142,30 @@ This code is hereby placed in the public domain.
@end @end
@implementation OOWeakRefObject
- (id)weakRetain
{
if (weakSelf == nil) weakSelf = [OOWeakReference weakRefWithObject:self];
return [weakSelf retain];
}
- (void)weakRefDied:(OOWeakReference *)weakRef
{
if (weakRef == weakSelf) weakSelf = nil;
}
- (void)dealloc
{
[weakSelf weakRefDrop]; // Very important!
[super dealloc];
}
@end
@implementation OOWeakReferenceTemplates @implementation OOWeakReferenceTemplates
// These are never called, but an implementation must exist so that -methodSignatureForSelector: works. // These are never called, but an implementation must exist so that -methodSignatureForSelector: works.

View File

@ -159,7 +159,7 @@ GLuint max_texture_dimension = 512; // conservative start
texBytes = imageBuffer; texBytes = imageBuffer;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName); // get a new unique texture name texName = GLAllocateTextureName();
glBindTexture(GL_TEXTURE_2D, texName); glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -200,7 +200,7 @@ GLuint max_texture_dimension = 512; // conservative start
texBytes = imageBuffer; texBytes = imageBuffer;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName); // get a new unique texture name texName = GLAllocateTextureName();
glBindTexture(GL_TEXTURE_2D, texName); glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
@ -235,7 +235,7 @@ GLuint max_texture_dimension = 512; // conservative start
texBytes = imageBuffer; texBytes = imageBuffer;
glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures(1, &texName); // get a new unique texture name texName = GLAllocateTextureName();
glBindTexture(GL_TEXTURE_2D, texName); glBindTexture(GL_TEXTURE_2D, texName);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);

View File

@ -88,12 +88,6 @@ enum
#define KEY_EQUIPMENT_EXTRAS @"extras" #define KEY_EQUIPMENT_EXTRAS @"extras"
#define KEY_WEAPON_FACINGS @"weapon_facings" #define KEY_WEAPON_FACINGS @"weapon_facings"
#define KEY_SCRIPT_ACTIONS @"script_actions"
// used by cargo-containers with CARGO_SCRIPT_ACTION when you scoop them, used by Stations when you dock with them, used during custom system set up too
#define KEY_LAUNCH_ACTIONS @"launch_actions"
#define KEY_DEATH_ACTIONS @"death_actions"
#define KEY_SETUP_ACTIONS @"setup_actions"
#define SHIPYARD_KEY_ID @"id" #define SHIPYARD_KEY_ID @"id"
#define SHIPYARD_KEY_SHIPDATA_KEY @"shipdata_key" #define SHIPYARD_KEY_SHIPDATA_KEY @"shipdata_key"
#define SHIPYARD_KEY_SHIP @"ship" #define SHIPYARD_KEY_SHIP @"ship"

View File

@ -793,11 +793,9 @@ static NSComparisonResult comparePrice(NSDictionary *dict1, NSDictionary *dict2,
} }
// systeminfo might have a 'script_actions' resource we want to activate now... // systeminfo might have a 'script_actions' resource we want to activate now...
if ([systeminfo objectForKey:@"script_actions"])
if ([systeminfo objectForKey:KEY_SCRIPT_ACTIONS])
{ {
NSArray* script_actions = (NSArray *)[systeminfo objectForKey:KEY_SCRIPT_ACTIONS]; NSArray *script_actions = [systeminfo arrayForKey:@"script_actions"];
[player scriptActions:script_actions forTarget: nil]; [player scriptActions:script_actions forTarget: nil];
} }
@ -1050,16 +1048,11 @@ static NSComparisonResult comparePrice(NSDictionary *dict1, NSDictionary *dict2,
[a_station release]; [a_station release];
[a_planet release]; [a_planet release];
// NEW
// systeminfo might have a 'script_actions' resource we want to activate now... // systeminfo might have a 'script_actions' resource we want to activate now...
if ([systeminfo objectForKey:@"script_actions"])
if ([systeminfo objectForKey:KEY_SCRIPT_ACTIONS])
{ {
PlayerEntity* player = [PlayerEntity sharedPlayer]; NSArray *script_actions = [systeminfo arrayForKey:@"script_actions"];
NSArray* script_actions = [systeminfo objectForKey:KEY_SCRIPT_ACTIONS]; [[PlayerEntity sharedPlayer] scriptActions:script_actions forTarget: nil];
[player scriptActions: script_actions forTarget: nil];
} }
} }
@ -3259,7 +3252,7 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
if (commodity == nil) return @""; if (commodity == nil) return @"";
return [NSString stringWithFormat:@"%@",[commoditydata objectAtIndex:MARKET_NAME]]; return [commodity stringAtIndex:MARKET_NAME];
} }
@ -3269,7 +3262,7 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
if (commodity == nil) return NSNotFound; if (commodity == nil) return NSNotFound;
return [[commodity objectAtIndex:MARKET_UNITS] intValue]; return [commodity intAtIndex:MARKET_UNITS];
} }