Selaa lähdekoodia

Much better resource allocation and release. Scene manager stub.

legacy
Sam Hocevar sam 14 vuotta sitten
vanhempi
commit
af3be15a7d
12 muutettua tiedostoa jossa 299 lisäystä ja 60 poistoa
  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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

@@ -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 Näytä tiedosto

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


Ladataan…
Peruuta
Tallenna