summary refs log tree commit diff stats
path: root/libs/cocos2d/CCTileMapAtlas.m
diff options
context:
space:
mode:
Diffstat (limited to 'libs/cocos2d/CCTileMapAtlas.m')
-rwxr-xr-xlibs/cocos2d/CCTileMapAtlas.m234
1 files changed, 234 insertions, 0 deletions
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 @@
1/*
2 * cocos2d for iPhone: http://www.cocos2d-iphone.org
3 *
4 * Copyright (c) 2008-2010 Ricardo Quesada
5 * Copyright (c) 2011 Zynga Inc.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE.
24 *
25 */
26
27#import "ccConfig.h"
28#import "CCTileMapAtlas.h"
29#import "ccMacros.h"
30#import "Support/CCFileUtils.h"
31
32@interface CCTileMapAtlas (Private)
33-(void) loadTGAfile:(NSString*)file;
34-(void) calculateItemsToRender;
35-(void) updateAtlasValueAt:(ccGridSize)pos withValue:(ccColor3B)value withIndex:(NSUInteger)idx;
36@end
37
38
39@implementation CCTileMapAtlas
40
41@synthesize tgaInfo;
42
43#pragma mark CCTileMapAtlas - Creation & Init
44+(id) tileMapAtlasWithTileFile:(NSString*)tile mapFile:(NSString*)map tileWidth:(int)w tileHeight:(int)h
45{
46 return [[[self alloc] initWithTileFile:tile mapFile:map tileWidth:w tileHeight:h] autorelease];
47}
48
49
50-(id) initWithTileFile:(NSString*)tile mapFile:(NSString*)map tileWidth:(int)w tileHeight:(int)h
51{
52 [self loadTGAfile: map];
53 [self calculateItemsToRender];
54
55 if( (self=[super initWithTileFile:tile tileWidth:w tileHeight:h itemsToRender: itemsToRender]) ) {
56
57 posToAtlasIndex = [[NSMutableDictionary dictionaryWithCapacity:itemsToRender] retain];
58
59 [self updateAtlasValues];
60
61 [self setContentSize: CGSizeMake(tgaInfo->width*itemWidth_, tgaInfo->height*itemHeight_)];
62 }
63
64 return self;
65}
66
67-(void) dealloc
68{
69 if( tgaInfo )
70 tgaDestroy(tgaInfo);
71
72 [posToAtlasIndex release];
73
74 [super dealloc];
75}
76
77-(void) releaseMap
78{
79 if( tgaInfo )
80 tgaDestroy(tgaInfo);
81
82 tgaInfo = nil;
83
84 [posToAtlasIndex release];
85 posToAtlasIndex = nil;
86}
87
88-(void) calculateItemsToRender
89{
90 NSAssert( tgaInfo != nil, @"tgaInfo must be non-nil");
91
92 itemsToRender = 0;
93 for(int x = 0;x < tgaInfo->width; x++ ) {
94 for(int y = 0; y < tgaInfo->height; y++ ) {
95 ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData;
96 ccColor3B value = ptr[x + y * tgaInfo->width];
97 if( value.r )
98 itemsToRender++;
99 }
100 }
101}
102
103-(void) loadTGAfile:(NSString*)file
104{
105 NSAssert( file != nil, @"file must be non-nil");
106
107 NSString *path = [CCFileUtils fullPathFromRelativePath:file ];
108
109// //Find the path of the file
110// NSBundle *mainBndl = [CCDirector sharedDirector].loadingBundle;
111// NSString *resourcePath = [mainBndl resourcePath];
112// NSString * path = [resourcePath stringByAppendingPathComponent:file];
113
114 tgaInfo = tgaLoad( [path UTF8String] );
115#if 1
116 if( tgaInfo->status != TGA_OK )
117 [NSException raise:@"TileMapAtlasLoadTGA" format:@"TileMapAtas cannot load TGA file"];
118
119#endif
120}
121
122#pragma mark CCTileMapAtlas - Atlas generation / updates
123
124-(void) setTile:(ccColor3B) tile at:(ccGridSize) pos
125{
126 NSAssert( tgaInfo != nil, @"tgaInfo must not be nil");
127 NSAssert( posToAtlasIndex != nil, @"posToAtlasIndex must not be nil");
128 NSAssert( pos.x < tgaInfo->width, @"Invalid position.x");
129 NSAssert( pos.y < tgaInfo->height, @"Invalid position.x");
130 NSAssert( tile.r != 0, @"R component must be non 0");
131
132 ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData;
133 ccColor3B value = ptr[pos.x + pos.y * tgaInfo->width];
134 if( value.r == 0 )
135 CCLOG(@"cocos2d: Value.r must be non 0.");
136 else {
137 ptr[pos.x + pos.y * tgaInfo->width] = tile;
138
139 // XXX: this method consumes a lot of memory
140 // XXX: a tree of something like that shall be impolemented
141 NSNumber *num = [posToAtlasIndex objectForKey: [NSString stringWithFormat:@"%d,%d", pos.x, pos.y]];
142 [self updateAtlasValueAt:pos withValue:tile withIndex: [num integerValue]];
143 }
144}
145
146-(ccColor3B) tileAt:(ccGridSize) pos
147{
148 NSAssert( tgaInfo != nil, @"tgaInfo must not be nil");
149 NSAssert( pos.x < tgaInfo->width, @"Invalid position.x");
150 NSAssert( pos.y < tgaInfo->height, @"Invalid position.y");
151
152 ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData;
153 ccColor3B value = ptr[pos.x + pos.y * tgaInfo->width];
154
155 return value;
156}
157
158-(void) updateAtlasValueAt:(ccGridSize)pos withValue:(ccColor3B)value withIndex:(NSUInteger)idx
159{
160 ccV3F_C4B_T2F_Quad quad;
161
162 NSInteger x = pos.x;
163 NSInteger y = pos.y;
164 float row = (value.r % itemsPerRow_);
165 float col = (value.r / itemsPerRow_);
166
167 float textureWide = [[textureAtlas_ texture] pixelsWide];
168 float textureHigh = [[textureAtlas_ texture] pixelsHigh];
169
170#if CC_FIX_ARTIFACTS_BY_STRECHING_TEXEL
171 float left = (2*row*itemWidth_+1)/(2*textureWide);
172 float right = left+(itemWidth_*2-2)/(2*textureWide);
173 float top = (2*col*itemHeight_+1)/(2*textureHigh);
174 float bottom = top+(itemHeight_*2-2)/(2*textureHigh);
175#else
176 float left = (row*itemWidth_)/textureWide;
177 float right = left+itemWidth_/textureWide;
178 float top = (col*itemHeight_)/textureHigh;
179 float bottom = top+itemHeight_/textureHigh;
180#endif
181
182
183 quad.tl.texCoords.u = left;
184 quad.tl.texCoords.v = top;
185 quad.tr.texCoords.u = right;
186 quad.tr.texCoords.v = top;
187 quad.bl.texCoords.u = left;
188 quad.bl.texCoords.v = bottom;
189 quad.br.texCoords.u = right;
190 quad.br.texCoords.v = bottom;
191
192 quad.bl.vertices.x = (int) (x * itemWidth_);
193 quad.bl.vertices.y = (int) (y * itemHeight_);
194 quad.bl.vertices.z = 0.0f;
195 quad.br.vertices.x = (int)(x * itemWidth_ + itemWidth_);
196 quad.br.vertices.y = (int)(y * itemHeight_);
197 quad.br.vertices.z = 0.0f;
198 quad.tl.vertices.x = (int)(x * itemWidth_);
199 quad.tl.vertices.y = (int)(y * itemHeight_ + itemHeight_);
200 quad.tl.vertices.z = 0.0f;
201 quad.tr.vertices.x = (int)(x * itemWidth_ + itemWidth_);
202 quad.tr.vertices.y = (int)(y * itemHeight_ + itemHeight_);
203 quad.tr.vertices.z = 0.0f;
204
205 [textureAtlas_ updateQuad:&quad atIndex:idx];
206}
207
208-(void) updateAtlasValues
209{
210 NSAssert( tgaInfo != nil, @"tgaInfo must be non-nil");
211
212
213 int total = 0;
214
215 for(int x = 0;x < tgaInfo->width; x++ ) {
216 for(int y = 0; y < tgaInfo->height; y++ ) {
217 if( total < itemsToRender ) {
218 ccColor3B *ptr = (ccColor3B*) tgaInfo->imageData;
219 ccColor3B value = ptr[x + y * tgaInfo->width];
220
221 if( value.r != 0 ) {
222 [self updateAtlasValueAt:ccg(x,y) withValue:value withIndex:total];
223
224 NSString *key = [NSString stringWithFormat:@"%d,%d", x,y];
225 NSNumber *num = [NSNumber numberWithInt:total];
226 [posToAtlasIndex setObject:num forKey:key];
227
228 total++;
229 }
230 }
231 }
232 }
233}
234@end