ソースを参照

Much better resource allocation and release. Scene manager stub.

legacy
Sam Hocevar sam 14年前
コミット
af3be15a7d
12個のファイルの変更299行の追加60行の削除
  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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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 ファイルの表示

@@ -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__


読み込み中…
キャンセル
保存