--- /dev/null
+//
+// AnimationContainer.h
+// tanks
+//
+// Created by Doris Chen on 5/12/11.
+// Copyright 2011 __MyCompanyName__. All rights reserved.
+//
+
+#import <Foundation/Foundation.h>
+#import "SPTextureAtlas.h"
+
+////////////////////////////////////////////////////////////////////////////////////
+@interface AnimationContainer : NSObject <NSXMLParserDelegate> {
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+@property(nonatomic,retain) NSMutableDictionary* mAnimationLookup;
+@property(nonatomic,retain) SPTextureAtlas* mAtlas;
+
+@property(nonatomic,retain) NSString* mAtlasPath;
+@property(nonatomic,retain) NSString* mAnimationName;
+
+////////////////////////////////////////////////////////////////////////////////////
+-(id)init;
+-(id)initWithContainer:(NSString*)containerPath;
+-(void)dealloc;
+
+-(void)releaseVRAM;
+
+@end
--- /dev/null
+//
+// AnimationContainer.m
+// tanks
+//
+// Created by Doris Chen on 5/12/11.
+// Copyright 2011 __MyCompanyName__. All rights reserved.
+//
+
+#import "AnimationContainer.h"
+
+#import "SPMovieClip.h"
+
+////////////////////////////////////////////////////////////////////////////////////
+// private method
+@interface AnimationContainer()
+
+-(void)parseContentXml:(NSString *)contentPath;
+
+@end
+
+
+////////////////////////////////////////////////////////////////////////////////////
+@implementation AnimationContainer
+
+////////////////////////////////////////////////////////////////////////////////////
+@synthesize mAnimationLookup;
+@synthesize mAtlas;
+@synthesize mAtlasPath;
+@synthesize mAnimationName;
+
+////////////////////////////////////////////////////////////////////////////////////
+-(id)init {
+ if ((self = [super init])) {
+ self.mAnimationLookup = [[NSMutableDictionary alloc] init];
+ }
+
+ return self;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+-(id)initWithContainer:(NSString *)containerPath {
+ if ((self = [super init])) {
+ [self parseContentXml:containerPath];
+ }
+
+ return self;
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+-(void)dealloc {
+ [mAnimationLookup removeAllObjects];
+ [mAnimationLookup release];
+ [mAtlas release];
+ [mAtlasPath release];
+ [mAnimationName release];
+ [super dealloc];
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// need a way to get the VRAM back
+-(void)releaseVRAM {
+ [mAnimationLookup removeAllObjects]; // remove all the movie clips, since they hold on to stuff in the atlas, but keep the dictionary
+ [mAtlas release]; // remove the atlas
+ mAtlas = nil; // is this extraneous?
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+-(void)parseContentXml:(NSString *)contentPath {
+ NSAutoreleasePool* autoreleasePool = [[NSAutoreleasePool alloc] init];
+
+ if (!contentPath) return;
+
+ NSString* fullPath = [[NSBundle mainBundle] pathForResource:contentPath ofType:nil];
+ NSURL* xmlUrl = [NSURL fileURLWithPath:fullPath];
+ NSXMLParser* xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlUrl];
+ xmlParser.delegate = self;
+ BOOL success = [xmlParser parse];
+
+ [autoreleasePool drain]; // is this wrong?
+
+ if (!success) {
+ NSLog(@"could not parse content XML %@. Error code: %d, domain: %@",
+ contentPath, xmlParser.parserError.code, xmlParser.parserError.domain);
+ }
+
+ [xmlParser release];
+}
+
+////////////////////////////////////////////////////////////////////////////////////
+// XML parser callback for the following format:
+//
+// <AnimationClips name='foo' xmlPath='dir/foo.xml'>
+// <Clip name='do_bar' frames='15' />
+// <Clip name='do_foo' frames='5' />
+// </AnimationClips>
+//
+- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
+ namespaceURI: (NSString *)namespaceURI
+ qualifiedName: (NSString *)qName
+ attributes: (NSDictionary *)attributeDict {
+ if ([elementName isEqualToString:@"AnimationClips"])
+ {
+ mAnimationLookup = [[NSMutableDictionary alloc] init];
+ self.mAnimationName = [attributeDict valueForKey:@"name"];
+ self.mAtlasPath = [attributeDict valueForKey:@"xmlPath"];
+ mAtlas = [[SPTextureAtlas alloc] initWithContentsOfFile:mAtlasPath];
+ }
+ else if ([elementName isEqualToString:@"Clip"])
+ {
+ NSString* name = [attributeDict valueForKey:@"name"];
+ int numFrames = [[attributeDict valueForKey:@"frames"] intValue];
+ SPMovieClip* movieClip = [[SPMovieClip alloc] initWithFrames:[mAtlas texturesStartingWith:name] fps:15];
+ [mAnimationLookup setValue:movieClip forKey:name]; // add our clip to the dictionary so we can reference it in the future
+
+ if (movieClip.numFrames != numFrames)
+ {
+ NSLog(@"Number of frames (%d) in XML does not match number of frames (%d) in atlas!", numFrames, movieClip.numFrames);
+ }
+ }
+}
+
+
+@end
4B8B2A4A1378E74700CA4076 /* iPhoneTestEntries.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B8B2A3E1378E74700CA4076 /* iPhoneTestEntries.mm */; };
4B8B2A4B1378E74700CA4076 /* TestEntriesViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8B2A3F1378E74700CA4076 /* TestEntriesViewController.h */; };
4B8B2A4C1378E74700CA4076 /* TestEntriesViewController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 4B8B2A401378E74700CA4076 /* TestEntriesViewController.mm */; };
+ 4B8B2A50137D098500CA4076 /* AnimationContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 4B8B2A4E137D098500CA4076 /* AnimationContainer.h */; };
+ 4B8B2A51137D098500CA4076 /* AnimationContainer.m in Sources */ = {isa = PBXBuildFile; fileRef = 4B8B2A4F137D098500CA4076 /* AnimationContainer.m */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
4B8B2A3E1378E74700CA4076 /* iPhoneTestEntries.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = iPhoneTestEntries.mm; path = references/iPhoneTestEntries.mm; sourceTree = "<group>"; };
4B8B2A3F1378E74700CA4076 /* TestEntriesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestEntriesViewController.h; path = references/TestEntriesViewController.h; sourceTree = "<group>"; };
4B8B2A401378E74700CA4076 /* TestEntriesViewController.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = TestEntriesViewController.mm; path = references/TestEntriesViewController.mm; sourceTree = "<group>"; };
+ 4B8B2A4E137D098500CA4076 /* AnimationContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AnimationContainer.h; path = animation/AnimationContainer.h; sourceTree = "<group>"; };
+ 4B8B2A4F137D098500CA4076 /* AnimationContainer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AnimationContainer.m; path = animation/AnimationContainer.m; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
49F2D9B313764666000B6B8C /* render */ = {
isa = PBXGroup;
children = (
+ 4B8B2A4D137D090D00CA4076 /* animation */,
);
path = render;
sourceTree = "<group>";
name = references;
sourceTree = "<group>";
};
+ 4B8B2A4D137D090D00CA4076 /* animation */ = {
+ isa = PBXGroup;
+ children = (
+ 4B8B2A4E137D098500CA4076 /* AnimationContainer.h */,
+ 4B8B2A4F137D098500CA4076 /* AnimationContainer.m */,
+ );
+ name = animation;
+ sourceTree = "<group>";
+ };
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
4B8B2A461378E74700CA4076 /* GLES-Render.h in Headers */,
4B8B2A481378E74700CA4076 /* iPhoneTest.h in Headers */,
4B8B2A4B1378E74700CA4076 /* TestEntriesViewController.h in Headers */,
+ 4B8B2A50137D098500CA4076 /* AnimationContainer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
4B8B2A491378E74700CA4076 /* iPhoneTest.mm in Sources */,
4B8B2A4A1378E74700CA4076 /* iPhoneTestEntries.mm in Sources */,
4B8B2A4C1378E74700CA4076 /* TestEntriesViewController.mm in Sources */,
+ 4B8B2A51137D098500CA4076 /* AnimationContainer.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};