Преглед на файлове

Much better resource allocation and release. Scene manager stub.

legacy
Sam Hocevar sam преди 16 години
родител
ревизия
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 all: test-map




+ 10
- 1
src/layer.cpp Целия файл

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


#include <stdlib.h>

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


Layer::Layer(int w, int h, int in_z, uint32_t *in_data) 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() 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() int Layer::GetZ()


+ 2
- 0
src/layer.h Целия файл

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


void Draw();

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


+ 70
- 28
src/map.cpp Целия файл

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


#include "map.h" #include "map.h"
#include "layer.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]; 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"); FILE *fp = fopen(path, "r");


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


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


if (data)
if (tiles)
{ {
/* We are in the process of reading layer data. Only stop /* We are in the process of reading layer data. Only stop
* when we have read the expected number of tiles. */ * when we have read the expected number of tiles. */
char const *parser = tmp; char const *parser = tmp;
while (ntiles < width * height) 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)) while (isdigit(*parser))
parser++; parser++;
if (*parser == ',') if (*parser == ',')
@@ -48,31 +91,33 @@ Map::Map(char const *path) :


if (ntiles == width * height) 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) 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) else if (sscanf(tmp, " <image source=\"%[^\"]\"", str) == 1)
{ {
/* This is a tileset image file. Associate it with firstgid. */ /* 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%*[^\"]\" " else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" "
"width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5) "width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5)
{ {
/* This is a layer description. Prepare to read the data. */ /* 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; orientation = toupper(a) == 'V' ? 1 : 0;
width = j; width = j;
height = k; height = k;
tiles = (uint32_t *)malloc(width * height * sizeof(uint32_t));
ntiles = 0; ntiles = 0;
data = (uint32_t *)malloc(width * height * sizeof(uint32_t));
} }
} }


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


Map::~Map() 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 <cstdio>


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

class MapData;


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


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


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


#endif // __DH_MAP_H__ #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 <math.h>


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


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


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


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


/* Test stuff */ /* Test stuff */
int playerx, playery; int playerx, playery;
@@ -27,9 +26,9 @@ int main(int argc, char **argv)
playerx = playerx * (640 - 32) / 640; playerx = playerx * (640 - 32) / 640;
playery = playery * (480 - 32) / 480; 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); video->Refresh(33.33333f);


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


delete map; delete map;
delete tileset;
delete video; delete video;


return EXIT_SUCCESS; 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" #include "tileset.h"


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


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


private: private:
static int Compare(void const *p1, void const *p2) 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]); return n1[2] + 32 * n1[3] - (n2[2] + 32 * n2[3]);
} }


char *name;
int ref;
int *tiles; int *tiles;
int ntiles; 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->tiles = NULL;
data->ntiles = 0; data->ntiles = 0;


/* One tile texture */ /* 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) if (!img)
{ {
@@ -61,7 +69,7 @@ Tileset::Tileset()
exit(1); exit(1);
} }


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


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


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

free(data->tiles); free(data->tiles);
free(data->name);
delete data; 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) if ((data->ntiles % 1024) == 0)
{ {
@@ -96,10 +123,10 @@ void Tileset::AddTile(int n, int x, int y, int z)
data->ntiles++; data->ntiles++;
} }


void Tileset::Render()
void TileSet::Render()
{ {
/* Sort tiles */ /* 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 */ /* Texture coord buffer */
float uvs[8 * data->ntiles]; float uvs[8 * data->ntiles];


+ 13
- 8
src/tileset.h Целия файл

@@ -3,24 +3,29 @@
* The tile manager * 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: 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 AddTile(int n, int x, int y, int z);


void Render(); void Render();


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


#endif // __DH_TILER_H__
#endif // __DH_TILESET_H__



Зареждане…
Отказ
Запис