Skip to content

Commit

Permalink
Tileset: convert arrays to vectors.
Browse files Browse the repository at this point in the history
This decreases memory consumption as not so many
structs are created, but only the needed amount.

The implementation is based on std::vector, so random
access is fast, but if there are gaps in the tile ids,
still memory is wasted as the vector allocates
memory for tilee ids from 0 to max tile id.
  • Loading branch information
stefanbeller committed Jul 15, 2012
1 parent 3b77ce0 commit ac02481
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 49 deletions.
85 changes: 43 additions & 42 deletions src/TileSet.cpp
Expand Up @@ -28,6 +28,7 @@ FLARE. If not, see http://www.gnu.org/licenses/
#include "Settings.h"

#include <cstdio>
#include <iostream>

using namespace std;

Expand All @@ -46,25 +47,13 @@ void TileSet::reset() {
trans_b = 255;

sprites = NULL;
for (int i=0; i<TILE_SET_MAX_TILES; i++) {
tiles[i].src.x = 0;
tiles[i].src.y = 0;
tiles[i].src.w = 0;
tiles[i].src.h = 0;
tiles[i].offset.x = 0;
tiles[i].offset.y = 0;
}

for (int i = 0; i < TILE_SET_MAX_TILES; i++) {
anim[i].current_frame = 1;
anim[i].duration = 0;
anim[i].frames = 1;
}
tiles.clear();
anim.clear();
}

void TileSet::loadGraphics(const std::string& filename) {
if (sprites) SDL_FreeSurface(sprites);

if (TEXTURE_QUALITY == false)
sprites = IMG_Load((mods->locate("images/tilesets/noalpha/" + filename)).c_str());

Expand All @@ -77,14 +66,14 @@ void TileSet::loadGraphics(const std::string& filename) {
} else {
alpha_background = false;
}

// only set a color key if the tile set doesn't have an alpha channel
// the color ke is specified in the tilesetdef file like this:
// transparency=r,g,b
if (!alpha_background) {
SDL_SetColorKey( sprites, SDL_SRCCOLORKEY, SDL_MapRGB(sprites->format, trans_r, trans_g, trans_b) );
}

// optimize
SDL_Surface *cleanup = sprites;
sprites = SDL_DisplayFormatAlpha(sprites);
Expand All @@ -93,49 +82,60 @@ void TileSet::loadGraphics(const std::string& filename) {

void TileSet::load(const std::string& filename) {
if (current_map == filename) return;

reset();

FileParser infile;
unsigned short index;
string img;

if (infile.open(mods->locate("tilesetdefs/" + filename))) {
bool first_tile_passed = false;
while (infile.next()) {
if (infile.key == "tile") {

infile.val = infile.val + ',';
index = eatFirstInt(infile.val, ',');

if (index > 0 && index < TILE_SET_MAX_TILES) {

tiles[index].src.x = eatFirstInt(infile.val, ',');
tiles[index].src.y = eatFirstInt(infile.val, ',');
tiles[index].src.w = eatFirstInt(infile.val, ',');
tiles[index].src.h = eatFirstInt(infile.val, ',');
tiles[index].offset.x = eatFirstInt(infile.val, ',');
tiles[index].offset.y = eatFirstInt(infile.val, ',');
}
else {
fprintf(stderr, "Warning: invalid tileset index in %s. Expected a value from 1 to %d\n", filename.c_str(), TILE_SET_MAX_TILES);
}

unsigned index = eatFirstInt(infile.val, ',');

if (first_tile_passed && index > tiles.size())
cerr << "Warning: non-continous tileset indexes in " << filename << ". This may blow up memory usage." << endl;

first_tile_passed = true;

if (index >= tiles.size())
tiles.resize(index + 1);

tiles[index].src.x = eatFirstInt(infile.val, ',');
tiles[index].src.y = eatFirstInt(infile.val, ',');
tiles[index].src.w = eatFirstInt(infile.val, ',');
tiles[index].src.h = eatFirstInt(infile.val, ',');
tiles[index].offset.x = eatFirstInt(infile.val, ',');
tiles[index].offset.y = eatFirstInt(infile.val, ',');
}
else if (infile.key == "img") {
img = infile.val;
}
else if (infile.key == "transparency") {
alpha_background = false;

infile.val = infile.val + ',';
trans_r = (Uint8)eatFirstInt(infile.val, ',');
trans_g = (Uint8)eatFirstInt(infile.val, ',');
trans_b = (Uint8)eatFirstInt(infile.val, ',');

}
else if (infile.key == "animation") {
int frame = 0;
int TILE_ID = atoi(infile.nextValue().c_str());
unsigned TILE_ID = atoi(infile.nextValue().c_str());

if (TILE_ID >= anim.size())
anim.resize(TILE_ID + 1);

anim[TILE_ID].current_frame = 0;
anim[TILE_ID].duration = 0;

anim[TILE_ID].pos.resize(1);
anim[TILE_ID].frame_duration.resize(1);

anim[TILE_ID].pos[frame].x = atoi(infile.nextValue().c_str());
anim[TILE_ID].pos[frame].y = atoi(infile.nextValue().c_str());
anim[TILE_ID].frame_duration[frame] = atoi(infile.nextValue().c_str());
Expand All @@ -144,15 +144,16 @@ void TileSet::load(const std::string& filename) {
while (repeat_val != "") {
frame++;
anim[TILE_ID].frames++;
if (anim[TILE_ID].frames > MAX_TILE_FRAMES) break;
anim[TILE_ID].pos.resize(frame + 1);
anim[TILE_ID].frame_duration.resize(frame + 1);
anim[TILE_ID].pos[frame].x = atoi(repeat_val.c_str());
anim[TILE_ID].pos[frame].y = atoi(infile.nextValue().c_str());
anim[TILE_ID].frame_duration[frame] = atoi(infile.nextValue().c_str());

repeat_val = infile.nextValue();
}
}

}
infile.close();
loadGraphics(img);
Expand All @@ -162,8 +163,8 @@ void TileSet::load(const std::string& filename) {
}

void TileSet::logic() {
for (int i = 0; i < TILE_SET_MAX_TILES; i++) {
if (anim[i].duration == anim[i].frame_duration[anim[i].current_frame-1] && (anim[i].frames > 1)) {
for (unsigned i = 0; i < anim.size() ; i++) {
if ((anim[i].frames > 1) && anim[i].duration == anim[i].frame_duration[anim[i].current_frame-1]) {
tiles[i].src.x = anim[i].pos[anim[i].current_frame-1].x;
tiles[i].src.y = anim[i].pos[anim[i].current_frame-1].y;
anim[i].duration = 0;
Expand Down
12 changes: 5 additions & 7 deletions src/TileSet.h
Expand Up @@ -30,9 +30,7 @@ FLARE. If not, see http://www.gnu.org/licenses/
#include <SDL_image.h>

#include <string>

const int TILE_SET_MAX_TILES = 1024;
const int MAX_TILE_FRAMES = 64;
#include <vector>

/**
* Describes a tile by its location \a src in the tileset sprite and
Expand All @@ -46,11 +44,11 @@ struct Tile_Def {
};

struct Tile_Anim {
Point pos[MAX_TILE_FRAMES];
std::vector<Point> pos;
int frames;
int current_frame;
int duration;
int frame_duration[MAX_TILE_FRAMES];
std::vector<int> frame_duration;
};

class TileSet {
Expand All @@ -71,8 +69,8 @@ class TileSet {
void load(const std::string& filename);
void logic();

Tile_Def tiles[TILE_SET_MAX_TILES];
Tile_Anim anim[TILE_SET_MAX_TILES];
std::vector<Tile_Def> tiles;
std::vector<Tile_Anim> anim;
SDL_Surface *sprites;
};

Expand Down

0 comments on commit ac02481

Please sign in to comment.