Kaynağa Gözat

Much better resource allocation and release. Scene manager stub.

legacy
Sam Hocevar sam 14 yıl önce
ebeveyn
işleme
af3be15a7d
12 değiştirilmiş dosya ile 299 ekleme ve 60 silme
  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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

@@ -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 Dosyayı Görüntüle

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


Yükleniyor…
İptal
Kaydet