Browse Source

Much better resource allocation and release. Scene manager stub.

legacy
Sam Hocevar sam 14 years ago
parent
commit
af3be15a7d
12 changed files with 299 additions and 60 deletions
  1. +1
    -1
      src/Makefile
  2. +10
    -1
      src/layer.cpp
  3. +2
    -0
      src/layer.h
  4. +70
    -28
      src/map.cpp
  5. +4
    -4
      src/map.h
  6. +29
    -0
      src/scene.cpp
  7. +25
    -0
      src/scene.h
  8. +4
    -6
      src/test-map.cpp
  9. +85
    -0
      src/tiler.cpp
  10. +17
    -0
      src/tiler.h
  11. +39
    -12
      src/tileset.cpp
  12. +13
    -8
      src/tileset.h

+ 1
- 1
src/Makefile View File

@@ -1,5 +1,5 @@

SRC = test-map.cpp video.cpp tileset.cpp layer.cpp map.cpp
SRC = test-map.cpp video.cpp tiler.cpp tileset.cpp scene.cpp layer.cpp map.cpp

all: test-map



+ 10
- 1
src/layer.cpp View File

@@ -1,4 +1,6 @@

#include <stdlib.h>

#include "layer.h"

Layer::Layer(int w, int h, int in_z, uint32_t *in_data)
@@ -21,7 +23,14 @@ Layer::Layer(int w, int h, int in_z, uint32_t *in_data)

Layer::~Layer()
{
delete data;
free(data);
}

void Layer::Draw()
{
for (int y = 0; y < 32; y++)
for (int x = 0; x < 32; x++)
;//tileset->AddTile(GetTile(x, y), x * 32, y * 32, z);
}

int Layer::GetZ()


+ 2
- 0
src/layer.h View File

@@ -18,6 +18,8 @@ public:
int GetZ();
unsigned int GetTile(int x, int y);

void Draw();

private:
int width, height, z;
uint32_t *data;


+ 70
- 28
src/map.cpp View File

@@ -7,15 +7,40 @@

#include "map.h"
#include "layer.h"
#include "tiler.h"

Map::Map(char const *path) :
layers(0),
nlayers(0)
#define MAX_TILERS 128

/*
* Map implementation class
*/

class MapData
{
friend class Map;

private:
int tilers[MAX_TILERS];
int ntilers;
Layer **layers;
int nlayers;
};

/*
* Public Map class
*/

Map::Map(char const *path)
{
data = new MapData();
data->ntilers = 0;
data->layers = NULL;
data->nlayers = 0;

char tmp[BUFSIZ];
uint32_t *data = NULL;
int width = 0, height = 0, level = 0, orientation = 0;
int firstgid = 0, ntiles = 0;
int gids[MAX_TILERS];
uint32_t *tiles = NULL;
int width = 0, height = 0, level = 0, orientation = 0, ntiles = 0;

FILE *fp = fopen(path, "r");

@@ -28,16 +53,34 @@ Map::Map(char const *path) :
int i, j, k;
char a, b;

/* Read a line, then decide what to do with it. */
fgets(tmp, BUFSIZ, fp);

if (data)
if (tiles)
{
/* We are in the process of reading layer data. Only stop
* when we have read the expected number of tiles. */
char const *parser = tmp;
while (ntiles < width * height)
{
data[ntiles++] = atoi(parser);
uint32_t code = 0;
int id = atoi(parser);
if (id)
{
for (int n = 0; n < data->ntilers; n++)
{
if (id < gids[n])
continue;
if (n == data->ntilers - 1
|| id < gids[n + 1])
{
code = (data->tilers[n] << 16) | (id - 1);
break;
}
}
}

tiles[ntiles++] = code;
while (isdigit(*parser))
parser++;
if (*parser == ',')
@@ -48,31 +91,33 @@ Map::Map(char const *path) :

if (ntiles == width * height)
{
layers[nlayers] = new Layer(width, height, level, data);
nlayers++;
data = NULL;
data->layers[data->nlayers] = new Layer(width, height, level, tiles);
data->nlayers++;
tiles = NULL;
}
}
else if (sscanf(tmp, " <tileset firstgid=\"%i\"", &i) == 1)
{
/* This is a tileset description. Remember its firstgid value. */
firstgid = i;
/* This is a tileset description. Remember its first gid value. */
gids[data->ntilers] = i;
}
else if (sscanf(tmp, " <image source=\"%[^\"]\"", str) == 1)
{
/* This is a tileset image file. Associate it with firstgid. */
data->tilers[data->ntilers] = Tiler::Register(str);
data->ntilers++;
}
else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" "
"width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5)
{
/* This is a layer description. Prepare to read the data. */
layers = (Layer **)realloc(layers,
sizeof(Layer **) * (nlayers + 1));
data->layers = (Layer **)realloc(data->layers,
sizeof(Layer **) * (data->nlayers + 1));
orientation = toupper(a) == 'V' ? 1 : 0;
width = j;
height = k;
tiles = (uint32_t *)malloc(width * height * sizeof(uint32_t));
ntiles = 0;
data = (uint32_t *)malloc(width * height * sizeof(uint32_t));
}
}

@@ -81,20 +126,17 @@ Map::Map(char const *path) :

Map::~Map()
{
for (int i = 0; i < nlayers; i++)
delete layers[i];
free(layers);
for (int i = 0; i < data->ntilers; i++)
Tiler::Deregister(data->tilers[i]);
for (int i = 0; i < data->nlayers; i++)
delete data->layers[i];
free(data->layers);
delete data;
}

void Map::Draw(Tileset *tileset)
void Map::Draw()
{
for (int i = 0; i < nlayers; i++)
{
int z = layers[i]->GetZ();

for (int y = 0; y < 32; y++)
for (int x = 0; x < 32; x++)
tileset->AddTile(layers[i]->GetTile(x, y), x * 32, y * 32, z);
}
for (int i = 0; i < data->nlayers; i++)
data->layers[i]->Draw();
}


+ 4
- 4
src/map.h View File

@@ -9,7 +9,8 @@
#include <cstdio>

#include "layer.h"
#include "tileset.h"

class MapData;

class Map
{
@@ -17,11 +18,10 @@ public:
Map(char const *path);
~Map();

void Draw(Tileset *tileset);
void Draw();

private:
Layer **layers;
int nlayers;
MapData *data;
};

#endif // __DH_MAP_H__


+ 29
- 0
src/scene.cpp View File

@@ -0,0 +1,29 @@

#include "scene.h"

/*
* Scene implementation class
*/

class SceneData
{
friend class Scene;

private:
int dummy;
};

/*
* Public Scene class
*/

Scene::Scene()
{
data = new SceneData();
}

Scene::~Scene()
{
delete data;
}


+ 25
- 0
src/scene.h View File

@@ -0,0 +1,25 @@

/*
* The scene object
*/

#if !defined __DH_SCENE_H__
#define __DH_SCENE_H__

#include <cstdio>
#include <stdint.h>

class SceneData;

class Scene
{
public:
Scene();
~Scene();

private:
SceneData *data;
};

#endif // __DH_SCENE_H__


+ 4
- 6
src/test-map.cpp View File

@@ -6,20 +6,19 @@
#include <math.h>

#include "video.h"
#include "tileset.h"
#include "tiler.h"
#include "map.h"

int main(int argc, char **argv)
{
Video *video = new Video("Deus Hax", 640, 480);
Tileset *tileset = new Tileset();
Map *map = new Map("maps/testmap-grass.tmx");

for (int done = 0; !done; )
{
video->Clear();

map->Draw(tileset);
//map->Draw(tiler);

/* Test stuff */
int playerx, playery;
@@ -27,9 +26,9 @@ int main(int argc, char **argv)
playerx = playerx * (640 - 32) / 640;
playery = playery * (480 - 32) / 480;

tileset->AddTile(50, playerx, playery, 1);
//tiler->AddTile(50, playerx, playery, 1);

tileset->Render();
//tiler->Render();
video->Refresh(33.33333f);

/* This could go in a separate function */
@@ -49,7 +48,6 @@ int main(int argc, char **argv)
}

delete map;
delete tileset;
delete video;

return EXIT_SUCCESS;


+ 85
- 0
src/tiler.cpp View File

@@ -0,0 +1,85 @@

#include <cstring>
#include <cstdio>
#include <stdlib.h>

#include "tiler.h"
#include "tileset.h"

/*
* Tiler implementation class
*/

static class TilerData
{
friend class Tiler;

public:
TilerData() :
tilesets(0),
ntilesets(0)
{
/* Nothing to do */
}

~TilerData()
{
free(tilesets);
}

private:
TileSet **tilesets;
int ntilesets;
}
tilerdata;

static TilerData * const data = &tilerdata;

/*
* Public Tiler class
*/

int Tiler::Register(char const *path)
{
int id, empty = -1;

/* If the tileset is already registered, remember its ID. Look for an
* empty slot at the same time. */
for (id = 0; id < data->ntilesets; id++)
{
TileSet *t = data->tilesets[id];
if (!t)
empty = id;
else if (!strcasecmp(path, t->GetName()))
break;
}

/* If this is a new tileset, create a new one. */
if (id == data->ntilesets)
{
if (empty == -1)
{
empty = data->ntilesets++;
data->tilesets = (TileSet **)realloc(data->tilesets,
data->ntilesets * sizeof(TileSet *));
}

data->tilesets[empty] = new TileSet(path);
id = empty;
}

data->tilesets[id]->Ref();
return id + 1; /* ID 0 is for the empty tileset */
}

void Tiler::Deregister(int id)
{
--id; /* ID 0 is for the empty tileset */

if (data->tilesets[id]->Unref() == 0)
{
delete data->tilesets[id];
data->tilesets[id] = NULL;
}
}


+ 17
- 0
src/tiler.h View File

@@ -0,0 +1,17 @@

/*
* The tile manager
*/

#if !defined __DH_TILER_H__
#define __DH_TILER_H__

class Tiler
{
public:
static int Register(char const *path);
static void Deregister(int id);
};

#endif // __DH_TILER_H__


+ 39
- 12
src/tileset.cpp View File

@@ -19,12 +19,12 @@
#include "tileset.h"

/*
* Tileset implementation class
* TileSet implementation class
*/

class TilesetData
class TileSetData
{
friend class Tileset;
friend class TileSet;

private:
static int Compare(void const *p1, void const *p2)
@@ -35,6 +35,8 @@ private:
return n1[2] + 32 * n1[3] - (n2[2] + 32 * n2[3]);
}

char *name;
int ref;
int *tiles;
int ntiles;

@@ -43,17 +45,23 @@ private:
};

/*
* Public Tileset class
* Public TileSet class
*/

Tileset::Tileset()
TileSet::TileSet(char const *path)
{
data = new TilesetData();
SDL_Surface *img = NULL;

data = new TileSetData();
data->name = strdup(path);
data->ref = 0;
data->tiles = NULL;
data->ntiles = 0;

/* One tile texture */
SDL_Surface *img = IMG_Load("art/test/grasstest.png");
for (char const *name = path; *name; name++)
if ((img = IMG_Load(name)))
break;

if (!img)
{
@@ -61,7 +69,7 @@ Tileset::Tileset()
exit(1);
}

glGenTextures(1, &data->texture[0]);
glGenTextures(1, data->texture);
glBindTexture(GL_TEXTURE_2D, data->texture[0]);

glTexImage2D(GL_TEXTURE_2D, 0, 4, img->w, img->h, 0,
@@ -74,13 +82,32 @@ Tileset::Tileset()
glGenBuffers(3, data->buflist);
}

Tileset::~Tileset()
TileSet::~TileSet()
{
glDeleteTextures(1, data->texture);
glDeleteBuffers(3, data->buflist);

free(data->tiles);
free(data->name);
delete data;
}

void Tileset::AddTile(int n, int x, int y, int z)
void TileSet::Ref()
{
data->ref++;
}

int TileSet::Unref()
{
return --data->ref;
}

char const *TileSet::GetName()
{
return data->name;
}

void TileSet::AddTile(int n, int x, int y, int z)
{
if ((data->ntiles % 1024) == 0)
{
@@ -96,10 +123,10 @@ void Tileset::AddTile(int n, int x, int y, int z)
data->ntiles++;
}

void Tileset::Render()
void TileSet::Render()
{
/* Sort tiles */
qsort(data->tiles, data->ntiles, 4 * sizeof(int), TilesetData::Compare);
qsort(data->tiles, data->ntiles, 4 * sizeof(int), TileSetData::Compare);

/* Texture coord buffer */
float uvs[8 * data->ntiles];


+ 13
- 8
src/tileset.h View File

@@ -3,24 +3,29 @@
* The tile manager
*/

#if !defined __DH_TILER_H__
#define __DH_TILER_H__
#if !defined __DH_TILESET_H__
#define __DH_TILESET_H__

class TilesetData;
class TileSetData;

class Tileset
class TileSet
{
public:
Tileset();
~Tileset();
TileSet(char const *path);
~TileSet();

void Ref();
int Unref();

char const *GetName();

void AddTile(int n, int x, int y, int z);

void Render();

private:
TilesetData *data;
TileSetData *data;
};

#endif // __DH_TILER_H__
#endif // __DH_TILESET_H__


Loading…
Cancel
Save