Bladeren bron

Much better resource allocation and release. Scene manager stub.

legacy
Sam Hocevar sam 14 jaren geleden
bovenliggende
commit
af3be15a7d
12 gewijzigde bestanden met toevoegingen van 299 en 60 verwijderingen
  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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

@@ -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 Bestand weergeven

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


Laden…
Annuleren
Opslaan