From 9cd57b731ab1c666d4a1cb725538fdc137763d12 Mon Sep 17 00:00:00 2001 From: Starla Insigna Date: Sat, 30 Jul 2011 11:19:14 -0400 Subject: Initial commit (version 0.2.1) --- libs/cocos2d/CCTileMapAtlas.m | 234 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100755 libs/cocos2d/CCTileMapAtlas.m (limited to 'libs/cocos2d/CCTileMapAtlas.m') diff --git a/libs/cocos2d/CCTileMapAtlas.m b/libs/cocos2d/CCTileMapAtlas.m new file mode 100755 index 0000000..aef6fe0 --- /dev/null +++ b/libs/cocos2d/CCTileMapAtlas.m @@ -0,0 +1,234 @@ +/* + * cocos2d for iPhone: http://www.cocos2d-iphone.org + * + * Copyright (c) 2008-2010 Ricardo Quesada + * Copyright (c) 2011 Zynga Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + */ + +#import "ccConfig.h" +#import "CCTileMapAtlas.h" +#import "ccMacros.h" +#import "Support/CCFileUtils.h" + +@interface CCTileMapAtlas (Private) +-(void) loadTGAfile:(NSString*)file; +-(void) calculateItemsToRender; +-(void) updateAtlasValueAt:(ccGridSize)pos withValue:(ccColor3B)value withIndex:(NSUInteger)idx; +@end + + +@implementation CCTileMapAtlas + +@synthesize tgaInfo; + +#pragma mark CCTileMapAtlas - Creation & Init ++(id) tileMapAtlasWithTileFile:(NSString*)tile mapFile:(NSString*)map tileWidth:(int)w tileHeight:(int)h +{ + return [[[self alloc] initWithTileFile:tile mapFile:map tileWidth:w tileHeight:h] autorelease]; +} + + +-(id) initWithTileFile:(NSString*)tile mapFile:(NSString*)map tileWidth:(int)w tileHeight:(int)h +{ + [self loadTGAfile: map]; + [self calculateItemsToRender]; + + if( (self=[super initWithTileFile:tile tileWidth:w tileHeight:h itemsToRender: itemsToRender]) ) { + + posToAtlasIndex = [[NSMutableDictionary dictionaryWithCapacity:itemsToRender] retain]; + + [self updateAtlasValues]; + + [self setContentSize: CGSizeMake(tgaInfo->width*itemWidth_, tgaInfo->height*itemHeight_)]; + } + + return self; +} + +-(void) dealloc +{ + if( tgaInfo ) + tgaDestroy(tgaInfo); + + [posToAtlasIndex release]; + + [super dealloc]; +} + +-(void) releaseMap +{ + if( tgaInfo ) + tgaDestroy(tgaInfo); + + tgaInfo = nil; + + [posToAtlasIndex release]; + posToAtlasIndex = nil; +} + +-(void) calculateItemsToRender +{ + NSAssert( tgaInfo != nil, @"tgaInfo must be non-nil"); + + itemsToRender = 0; + for(int x = 0;x < tgaInfo->width; x++ ) { + for(int y = 0; y < tgaInfo->height; y++ ) { + ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData; + ccColor3B value = ptr[x + y * tgaInfo->width]; + if( value.r ) + itemsToRender++; + } + } +} + +-(void) loadTGAfile:(NSString*)file +{ + NSAssert( file != nil, @"file must be non-nil"); + + NSString *path = [CCFileUtils fullPathFromRelativePath:file ]; + +// //Find the path of the file +// NSBundle *mainBndl = [CCDirector sharedDirector].loadingBundle; +// NSString *resourcePath = [mainBndl resourcePath]; +// NSString * path = [resourcePath stringByAppendingPathComponent:file]; + + tgaInfo = tgaLoad( [path UTF8String] ); +#if 1 + if( tgaInfo->status != TGA_OK ) + [NSException raise:@"TileMapAtlasLoadTGA" format:@"TileMapAtas cannot load TGA file"]; + +#endif +} + +#pragma mark CCTileMapAtlas - Atlas generation / updates + +-(void) setTile:(ccColor3B) tile at:(ccGridSize) pos +{ + NSAssert( tgaInfo != nil, @"tgaInfo must not be nil"); + NSAssert( posToAtlasIndex != nil, @"posToAtlasIndex must not be nil"); + NSAssert( pos.x < tgaInfo->width, @"Invalid position.x"); + NSAssert( pos.y < tgaInfo->height, @"Invalid position.x"); + NSAssert( tile.r != 0, @"R component must be non 0"); + + ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData; + ccColor3B value = ptr[pos.x + pos.y * tgaInfo->width]; + if( value.r == 0 ) + CCLOG(@"cocos2d: Value.r must be non 0."); + else { + ptr[pos.x + pos.y * tgaInfo->width] = tile; + + // XXX: this method consumes a lot of memory + // XXX: a tree of something like that shall be impolemented + NSNumber *num = [posToAtlasIndex objectForKey: [NSString stringWithFormat:@"%d,%d", pos.x, pos.y]]; + [self updateAtlasValueAt:pos withValue:tile withIndex: [num integerValue]]; + } +} + +-(ccColor3B) tileAt:(ccGridSize) pos +{ + NSAssert( tgaInfo != nil, @"tgaInfo must not be nil"); + NSAssert( pos.x < tgaInfo->width, @"Invalid position.x"); + NSAssert( pos.y < tgaInfo->height, @"Invalid position.y"); + + ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData; + ccColor3B value = ptr[pos.x + pos.y * tgaInfo->width]; + + return value; +} + +-(void) updateAtlasValueAt:(ccGridSize)pos withValue:(ccColor3B)value withIndex:(NSUInteger)idx +{ + ccV3F_C4B_T2F_Quad quad; + + NSInteger x = pos.x; + NSInteger y = pos.y; + float row = (value.r % itemsPerRow_); + float col = (value.r / itemsPerRow_); + + float textureWide = [[textureAtlas_ texture] pixelsWide]; + float textureHigh = [[textureAtlas_ texture] pixelsHigh]; + +#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL + float left = (2*row*itemWidth_+1)/(2*textureWide); + float right = left+(itemWidth_*2-2)/(2*textureWide); + float top = (2*col*itemHeight_+1)/(2*textureHigh); + float bottom = top+(itemHeight_*2-2)/(2*textureHigh); +#else + float left = (row*itemWidth_)/textureWide; + float right = left+itemWidth_/textureWide; + float top = (col*itemHeight_)/textureHigh; + float bottom = top+itemHeight_/textureHigh; +#endif + + + quad.tl.texCoords.u = left; + quad.tl.texCoords.v = top; + quad.tr.texCoords.u = right; + quad.tr.texCoords.v = top; + quad.bl.texCoords.u = left; + quad.bl.texCoords.v = bottom; + quad.br.texCoords.u = right; + quad.br.texCoords.v = bottom; + + quad.bl.vertices.x = (int) (x * itemWidth_); + quad.bl.vertices.y = (int) (y * itemHeight_); + quad.bl.vertices.z = 0.0f; + quad.br.vertices.x = (int)(x * itemWidth_ + itemWidth_); + quad.br.vertices.y = (int)(y * itemHeight_); + quad.br.vertices.z = 0.0f; + quad.tl.vertices.x = (int)(x * itemWidth_); + quad.tl.vertices.y = (int)(y * itemHeight_ + itemHeight_); + quad.tl.vertices.z = 0.0f; + quad.tr.vertices.x = (int)(x * itemWidth_ + itemWidth_); + quad.tr.vertices.y = (int)(y * itemHeight_ + itemHeight_); + quad.tr.vertices.z = 0.0f; + + [textureAtlas_ updateQuad:&quad atIndex:idx]; +} + +-(void) updateAtlasValues +{ + NSAssert( tgaInfo != nil, @"tgaInfo must be non-nil"); + + + int total = 0; + + for(int x = 0;x < tgaInfo->width; x++ ) { + for(int y = 0; y < tgaInfo->height; y++ ) { + if( total < itemsToRender ) { + ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData; + ccColor3B value = ptr[x + y * tgaInfo->width]; + + if( value.r != 0 ) { + [self updateAtlasValueAt:ccg(x,y) withValue:value withIndex:total]; + + NSString *key = [NSString stringWithFormat:@"%d,%d", x,y]; + NSNumber *num = [NSNumber numberWithInt:total]; + [posToAtlasIndex setObject:num forKey:key]; + + total++; + } + } + } + } +} +@end -- cgit 1.4.1