00001
00013 #include <string.h>
00015 #include <malloc.h>
00016
00017 #include "IsoTileSet.h"
00018
00020
00021 IsoTileSet::IsoTileSet() {
00022 tileCount = 0;
00023 tileList = NULL;
00024 tilesetSurface = NULL;
00025 filename = NULL;
00026 }
00027
00028 IsoTileSet::~IsoTileSet() {
00029 unloadTileset();
00030 }
00031
00033
00034
00035
00037
00039 bool IsoTileSet::loadTileset(char* name) {
00040
00041 if(!unloadTileset()) {
00042
00043 return false;
00044 }
00045
00046
00047 filename = strdup(name);
00048
00049
00050 ImageCanvas ts;
00051 if(!ts.loadImage(filename)) {
00052 return false;
00053 }
00054
00055
00056 tilesetSurface = SDL_CreateRGBSurface(((SDL_Surface*)ts)->flags,
00057 ((SDL_Surface*)ts)->w,
00058 ((SDL_Surface*)ts)->h,
00059 ((SDL_Surface*)ts)->format->BitsPerPixel,
00060 ((SDL_Surface*)ts)->format->Rmask,
00061 ((SDL_Surface*)ts)->format->Gmask,
00062 ((SDL_Surface*)ts)->format->Bmask,
00063 ((SDL_Surface*)ts)->format->Amask);
00064
00065 SDL_BlitSurface(ts, NULL, tilesetSurface, NULL);
00066
00067
00068 int width = tilesetSurface->w;
00069 int height = tilesetSurface->h;
00070
00071
00072 int* hTileBound = NULL;
00073 int hTileBoundCount = 0;
00074 int* vTileBound = NULL;
00075 int vTileBoundCount = 0;
00076 int xCount = 0;
00077 int yCount = 0;
00078
00079
00080 SDL_LockSurface(tilesetSurface);
00081
00082
00083 Uint32 transparentColor = getPixel(tilesetSurface, width - 1, 0);
00084
00085 Uint32 anchorColor = getPixel(tilesetSurface, width - 1, 2);
00086 Uint32 insideColor = getPixel(tilesetSurface, width - 1, 3);
00087 Uint32 insideAnchorColor = getPixel(tilesetSurface, width - 1, 4);
00088 Uint32 testColor = 0;
00089
00090
00091 vTileBoundCount = 0;
00092 for(xCount=0; xCount<width; xCount++) {
00093
00094 testColor = getPixel(tilesetSurface, xCount, 0);
00095
00096
00097 if(testColor == transparentColor) {
00098 vTileBoundCount ++;
00099 }
00100 }
00101
00102
00103 vTileBound = new int[vTileBoundCount];
00104
00105
00106 vTileBoundCount = 0;
00107 for(xCount=0; xCount<width; xCount++) {
00108
00109 testColor = getPixel(tilesetSurface, xCount, 0);
00110
00111
00112 if(testColor == transparentColor) {
00113
00114 vTileBound[vTileBoundCount] = xCount;
00115
00116
00117 vTileBoundCount ++;
00118 }
00119 }
00120
00121
00122 hTileBoundCount = 0;
00123 for(yCount=0; yCount<height; yCount++) {
00124
00125 testColor = getPixel(tilesetSurface, 0, yCount);
00126
00127
00128 if(testColor == transparentColor) {
00129 hTileBoundCount ++;
00130 }
00131 }
00132
00133
00134 hTileBound = new int[hTileBoundCount];
00135
00136
00137 hTileBoundCount = 0;
00138 for(yCount=0; yCount<height; yCount++) {
00139
00140 testColor = getPixel(tilesetSurface, 0, yCount);
00141
00142
00143 if(testColor == transparentColor) {
00144 hTileBound[hTileBoundCount] = yCount;
00145
00146 hTileBoundCount ++;
00147 }
00148 }
00149
00150
00151 int numrows = hTileBoundCount - 1;
00152 int numcols = vTileBoundCount - 1;
00153 tileCount = numrows * numcols;
00154
00155
00156 int currentTile = 0;
00157 bool found = false;
00158
00159
00160 tileList = new TILEINFO[tileCount];
00161
00162
00163 for(int rowcount=0; rowcount<numrows; rowcount++) {
00164 for(int colcount=0; colcount<numcols; colcount++) {
00165
00166 currentTile = colcount + rowcount * numcols;
00167
00168
00169 found = false;
00170
00171
00172 yCount = hTileBound[rowcount];
00173
00174
00175 for(xCount=vTileBound[colcount]+1; (!found)&&(xCount<vTileBound[colcount+1]-1); xCount++) {
00176
00177 testColor = getPixel(tilesetSurface, xCount, yCount);
00178
00179
00180 if((testColor == anchorColor) || (testColor == insideAnchorColor)) {
00181 found = true;
00182 tileList[currentTile].ptAnchor.x = xCount;
00183 }
00184 }
00185
00186
00187 found = false;
00188 for(xCount=vTileBound[colcount] + 1;
00189 (!found) && (xCount < vTileBound[colcount+1] - 1);
00190 xCount++) {
00191
00192 testColor = getPixel(tilesetSurface, xCount, yCount);
00193
00194 if((testColor == insideColor) || (testColor == insideAnchorColor)) {
00195 found = true;
00196 tileList[currentTile].rcSrc.left = xCount;
00197 }
00198 }
00199
00200
00201 if(!found) {
00202 tileList[currentTile].rcSrc.left = vTileBound[colcount] + 1;
00203 }
00204
00205
00206 found = false;
00207 for(xCount=vTileBound[colcount+1] - 1;
00208 (!found) && (xCount >= vTileBound[colcount] + 1);
00209 xCount--) {
00210
00211 testColor = getPixel(tilesetSurface, xCount, yCount);
00212
00213 if((testColor == insideColor) || (testColor == insideAnchorColor)) {
00214 found = true;
00215 tileList[currentTile].rcSrc.right = xCount + 1;
00216 }
00217 }
00218
00219
00220 if(!found) {
00221 tileList[currentTile].rcSrc.right = vTileBound[colcount + 1];
00222 }
00223
00224
00225 xCount = vTileBound[colcount];
00226
00227
00228 found = false;
00229 for(yCount=hTileBound[rowcount] + 1;
00230 (!found) && (yCount < hTileBound[rowcount+1] - 1);
00231 yCount++) {
00232
00233 testColor = getPixel(tilesetSurface, xCount, yCount);
00234
00235
00236 if((testColor == anchorColor) || (testColor == insideAnchorColor)) {
00237 found = true;
00238 tileList[currentTile].ptAnchor.y = yCount;
00239 }
00240 }
00241
00242
00243 found = false;
00244 for(yCount=hTileBound[rowcount] + 1;
00245 (!found) && (yCount < hTileBound[rowcount+1] - 1);
00246 yCount++) {
00247
00248 testColor = getPixel(tilesetSurface, xCount, yCount);
00249
00250
00251 if((testColor == insideColor) || (testColor == insideAnchorColor)) {
00252 found = true;
00253 tileList[currentTile].rcSrc.top = yCount;
00254 }
00255 }
00256
00257
00258 if(!found) {
00259 tileList[currentTile].rcSrc.top = hTileBound[rowcount] + 1;
00260 }
00261
00262
00263 found = false;
00264 for(yCount=hTileBound[rowcount+1] - 1;
00265 (!found) && (yCount >= hTileBound[rowcount] + 1);
00266 yCount--) {
00267
00268 testColor = getPixel(tilesetSurface, xCount, yCount);
00269
00270
00271 if((testColor == insideColor) || (testColor == insideAnchorColor)) {
00272 found = true;
00273 tileList[currentTile].rcSrc.bottom = yCount+1;
00274 }
00275 }
00276
00277
00278 if(!found) {
00279 tileList[currentTile].rcSrc.bottom = hTileBound[rowcount+1];
00280 }
00281
00282
00283 CopyRect(&tileList[currentTile].rcDstExtent, &tileList[currentTile].rcSrc);
00284 OffsetRect(&tileList[currentTile].rcDstExtent, -tileList[currentTile].ptAnchor.x, -tileList[currentTile].ptAnchor.y);
00285 }
00286 }
00287
00288
00289 SDL_UnlockSurface(tilesetSurface);
00290
00291
00292 SDL_SetColorKey(tilesetSurface, SDL_SRCCOLORKEY, transparentColor);
00293
00294 return true;
00295 }
00296
00298 bool IsoTileSet::reloadTileset() {
00299
00300 ImageCanvas ts;
00301 if(!ts.loadImage(filename)) {
00302 return false;
00303 }
00304
00305
00306 tilesetSurface = SDL_CreateRGBSurface(((SDL_Surface*)ts)->flags,
00307 ((SDL_Surface*)ts)->w,
00308 ((SDL_Surface*)ts)->h,
00309 ((SDL_Surface*)ts)->format->BitsPerPixel,
00310 ((SDL_Surface*)ts)->format->Rmask,
00311 ((SDL_Surface*)ts)->format->Gmask,
00312 ((SDL_Surface*)ts)->format->Bmask,
00313 ((SDL_Surface*)ts)->format->Amask);
00314
00315 SDL_BlitSurface(ts, NULL, tilesetSurface, NULL);
00316
00317 return true;
00318 }
00319
00321 bool IsoTileSet::unloadTileset() {
00322
00323
00324 if(tileList) {
00325 delete [] tileList;
00326 tileList = NULL;
00327 tileCount = 0;
00328 }
00329
00330
00331 SDL_FreeSurface(tilesetSurface);
00332
00333
00334 if(filename) {
00335 free(filename);
00336 filename = NULL;
00337 }
00338
00339 return true;
00340 }
00341
00343
00344
00345
00347
00349 Uint32 IsoTileSet::getTileCount() {
00350 return tileCount;
00351 }
00352
00354 TILEINFO* IsoTileSet::getTileList() {
00355 return tileList;
00356 }
00357
00359 SDL_Surface* IsoTileSet::getSurface() {
00360 return tilesetSurface;
00361 }
00362
00365 char* IsoTileSet::getFileName() {
00366 return filename;
00367 }
00368
00370
00372 void IsoTileSet::putTile(SDL_Surface* destinationSurface, int xCoord, int yCoord, int tileNumber) {
00373
00374 OffsetRect(&tileList[tileNumber].rcDstExtent, xCoord, yCoord);
00375
00376 SDL_BlitSurface(tilesetSurface, GetSDLRect(&tileList[tileNumber].rcSrc), destinationSurface, GetSDLRect(&tileList[tileNumber].rcDstExtent));
00377
00378 OffsetRect(&tileList[tileNumber].rcDstExtent, -xCoord, -yCoord);
00379 }