diff --git a/src/Makefile b/src/Makefile index 192d7c93..a31409b7 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,5 +1,6 @@ -SRC = test-map.cpp video.cpp tiler.cpp tileset.cpp scene.cpp layer.cpp map.cpp +SRC = test-map.cpp \ + game.cpp video.cpp tiler.cpp tileset.cpp scene.cpp layer.cpp map.cpp all: test-map diff --git a/src/game.cpp b/src/game.cpp new file mode 100644 index 00000000..85366c23 --- /dev/null +++ b/src/game.cpp @@ -0,0 +1,51 @@ + +#include "game.h" +#include "map.h" + +/* + * Game implementation class + */ + +class GameData +{ + friend class Game; + +private: + Map *map; + int x, y; + int mousex, mousey; +}; + +/* + * Public Game class + */ + +Game::Game(char const *mapname) +{ + data = new GameData(); + data->map = new Map(mapname); + data->x = data->y = 0; +} + +Game::~Game() +{ + delete data->map; + delete data; +} + +void Game::SetMouse(int x, int y) +{ + data->mousex = x; + data->mousey = y; +} + +void Game::Render() +{ + Scene *scene = new Scene(); + + data->map->Render(scene, data->mousex, data->mousey, 0); + + scene->Render(); + delete scene; +} + diff --git a/src/game.h b/src/game.h new file mode 100644 index 00000000..820b4ba0 --- /dev/null +++ b/src/game.h @@ -0,0 +1,25 @@ + +/* + * The game object + */ + +#if !defined __DH_GAME_H__ +#define __DH_GAME_H__ + +class GameData; + +class Game +{ +public: + Game(char const *mapname); + ~Game(); + + void SetMouse(int x, int y); + void Render(); + +private: + GameData *data; +}; + +#endif // __DH_GAME_H__ + diff --git a/src/layer.cpp b/src/layer.cpp index c7e8b4c6..6656f364 100644 --- a/src/layer.cpp +++ b/src/layer.cpp @@ -3,11 +3,11 @@ #include "layer.h" -Layer::Layer(int w, int h, int in_z, uint32_t *in_data) +Layer::Layer(int w, int h, int z, uint32_t *in_data) { width = w; height = h; - z = in_z; + altitude = z; data = in_data; #if 0 @@ -26,20 +26,17 @@ Layer::~Layer() free(data); } -void Layer::Draw() +void Layer::Render(Scene *scene, int x, int y, int z) { - for (int y = 0; y < 32; y++) - for (int x = 0; x < 32; x++) - ;//tileset->AddTile(GetTile(x, y), x * 32, y * 32, z); + for (int j = 0; j < height; j++) + for (int i = 0; i < width; i++) + if (data[j * width + i]) + scene->AddTile(data[j * width + i], + i * 32 - x, j * 32 - y, altitude + z); } int Layer::GetZ() { - return z; -} - -unsigned int Layer::GetTile(int x, int y) -{ - return data[y * width + x]; + return altitude; } diff --git a/src/layer.h b/src/layer.h index 62548f57..f4943ffd 100644 --- a/src/layer.h +++ b/src/layer.h @@ -6,9 +6,10 @@ #if !defined __DH_LAYER_H__ #define __DH_LAYER_H__ -#include #include +#include "scene.h" + class Layer { public: @@ -16,12 +17,11 @@ public: ~Layer(); int GetZ(); - unsigned int GetTile(int x, int y); - void Draw(); + void Render(Scene *scene, int x, int y, int z); private: - int width, height, z; + int width, height, altitude; uint32_t *data; }; diff --git a/src/map.cpp b/src/map.cpp index 5f1af52a..31c5c871 100644 --- a/src/map.cpp +++ b/src/map.cpp @@ -56,7 +56,7 @@ Map::Map(char const *path) /* Read a line, then decide what to do with it. */ fgets(tmp, BUFSIZ, fp); - if (tiles) + if (tiles && !strchr(tmp, '<')) { /* We are in the process of reading layer data. Only stop * when we have read the expected number of tiles. */ @@ -94,6 +94,7 @@ Map::Map(char const *path) data->layers[data->nlayers] = new Layer(width, height, level, tiles); data->nlayers++; tiles = NULL; + //fprintf(stderr, "new layer %ix%i\n", width, height); } } else if (sscanf(tmp, " tilers[data->ntilers] = Tiler::Register(str); data->ntilers++; + //fprintf(stderr, "new tiler %s\n", str); } else if (sscanf(tmp, " nlayers; i++) - data->layers[i]->Draw(); + data->layers[i]->Render(scene, x, y, z); } diff --git a/src/map.h b/src/map.h index c4e69687..2a1d7a7f 100644 --- a/src/map.h +++ b/src/map.h @@ -6,9 +6,7 @@ #if !defined __DH_MAP_H__ #define __DH_MAP_H__ -#include - -#include "layer.h" +#include "scene.h" class MapData; @@ -18,7 +16,7 @@ public: Map(char const *path); ~Map(); - void Draw(); + void Render(Scene *scene, int x, int y, int z); private: MapData *data; diff --git a/src/scene.cpp b/src/scene.cpp index ac622f19..9bcbe18c 100644 --- a/src/scene.cpp +++ b/src/scene.cpp @@ -1,5 +1,14 @@ +#include + #include "scene.h" +#include "tiler.h" + +struct Tile +{ + uint32_t prio, code; + int x, y; +}; /* * Scene implementation class @@ -10,7 +19,16 @@ class SceneData friend class Scene; private: - int dummy; + static int Compare(void const *p1, void const *p2) + { + Tile const *t1 = (Tile const *)p1; + Tile const *t2 = (Tile const *)p2; + + return t1->prio - t2->prio; + } + + Tile *tiles; + int ntiles; }; /* @@ -20,6 +38,8 @@ private: Scene::Scene() { data = new SceneData(); + data->tiles = 0; + data->ntiles = 0; } Scene::~Scene() @@ -27,3 +47,27 @@ Scene::~Scene() delete data; } +void Scene::AddTile(uint32_t code, int x, int y, int z) +{ + if ((data->ntiles % 1024) == 0) + data->tiles = (Tile *)realloc(data->tiles, + (data->ntiles + 1024) * sizeof(Tile)); + data->tiles[data->ntiles].prio = 0; + data->tiles[data->ntiles].code = code; + data->tiles[data->ntiles].x = x; + data->tiles[data->ntiles].y = y; + data->ntiles++; +} + +void Scene::Render() // XXX: rename to Blit() +{ + qsort(data->tiles, data->ntiles, sizeof(Tile), SceneData::Compare); + + for (int i = 0; i < data->ntiles; i++) + Tiler::Render(data->tiles[i].code, data->tiles[i].x, data->tiles[i].y); + + free(data->tiles); + data->tiles = 0; + data->ntiles = 0; +} + diff --git a/src/scene.h b/src/scene.h index ce04675d..092eb83a 100644 --- a/src/scene.h +++ b/src/scene.h @@ -6,7 +6,6 @@ #if !defined __DH_SCENE_H__ #define __DH_SCENE_H__ -#include #include class SceneData; @@ -17,6 +16,9 @@ public: Scene(); ~Scene(); + void AddTile(uint32_t code, int x, int y, int z); + void Render(); + private: SceneData *data; }; diff --git a/src/test-map.cpp b/src/test-map.cpp index 5287bdcf..dd1f5828 100644 --- a/src/test-map.cpp +++ b/src/test-map.cpp @@ -6,29 +6,23 @@ #include #include "video.h" -#include "tiler.h" -#include "map.h" +#include "game.h" int main(int argc, char **argv) { Video *video = new Video("Deus Hax", 640, 480); - Map *map = new Map("maps/testmap-grass.tmx"); + Game *game = new Game("maps/testmap-library.tmx"); for (int done = 0; !done; ) { video->Clear(); - //map->Draw(tiler); - /* Test stuff */ - int playerx, playery; - SDL_GetMouseState(&playerx, &playery); - playerx = playerx * (640 - 32) / 640; - playery = playery * (480 - 32) / 480; - - //tiler->AddTile(50, playerx, playery, 1); + int mx, my; + SDL_GetMouseState(&mx, &my); + game->SetMouse(mx * (640 - 32) / 640, my * (480 - 32) / 480); - //tiler->Render(); + game->Render(); video->Refresh(33.33333f); /* This could go in a separate function */ @@ -47,7 +41,7 @@ int main(int argc, char **argv) } } - delete map; + delete game; delete video; return EXIT_SUCCESS; diff --git a/src/tiler.cpp b/src/tiler.cpp index 4dd36d41..f551f6b2 100644 --- a/src/tiler.cpp +++ b/src/tiler.cpp @@ -83,3 +83,10 @@ void Tiler::Deregister(int id) } } +void Tiler::Render(uint32_t code, int x, int y) +{ + int id = (code >> 16) - 1; /* ID 0 is for the empty tileset */ + + data->tilesets[id]->BlitTile(code & 0xffff, x, y); +} + diff --git a/src/tiler.h b/src/tiler.h index 64e6a56e..6e232777 100644 --- a/src/tiler.h +++ b/src/tiler.h @@ -6,11 +6,15 @@ #if !defined __DH_TILER_H__ #define __DH_TILER_H__ +#include + class Tiler { public: static int Register(char const *path); static void Deregister(int id); + + static void Render(uint32_t code, int x, int y); }; #endif // __DH_TILER_H__ diff --git a/src/tileset.cpp b/src/tileset.cpp index 0c1c0aa0..e8a4eef1 100644 --- a/src/tileset.cpp +++ b/src/tileset.cpp @@ -41,7 +41,6 @@ private: int ntiles; GLuint texture[1]; - GLuint buflist[3]; }; /* @@ -77,15 +76,11 @@ TileSet::TileSet(char const *path) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - - /* Three GPU buffers */ - glGenBuffers(3, data->buflist); } TileSet::~TileSet() { glDeleteTextures(1, data->texture); - glDeleteBuffers(3, data->buflist); free(data->tiles); free(data->name); @@ -107,97 +102,21 @@ char const *TileSet::GetName() return data->name; } -void TileSet::AddTile(int n, int x, int y, int z) +void TileSet::BlitTile(uint32_t id, int x, int y) { - if ((data->ntiles % 1024) == 0) - { - data->tiles = (int *)realloc(data->tiles, - (data->ntiles + 1024) * 4 * sizeof(int)); - } - - data->tiles[4 * data->ntiles] = n; - data->tiles[4 * data->ntiles + 1] = x; - data->tiles[4 * data->ntiles + 2] = y; - data->tiles[4 * data->ntiles + 3] = z; - - data->ntiles++; -} - -void TileSet::Render() -{ - /* Sort tiles */ - qsort(data->tiles, data->ntiles, 4 * sizeof(int), TileSetData::Compare); - - /* Texture coord buffer */ - float uvs[8 * data->ntiles]; - for (int n = 0; n < data->ntiles; n++) - { - int tile = data->tiles[4 * n]; - float ty = .0625f * (tile / 16); - float tx = .0625f * (tile % 16); - uvs[8 * n + 0] = tx; - uvs[8 * n + 1] = ty; - uvs[8 * n + 2] = tx + .0625f; - uvs[8 * n + 3] = ty; - uvs[8 * n + 4] = tx + .0625f; - uvs[8 * n + 5] = ty + .0625f; - uvs[8 * n + 6] = tx; - uvs[8 * n + 7] = ty + .0625f; - } - glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]); - glBufferData(GL_ARRAY_BUFFER, - 8 * data->ntiles * sizeof(float), uvs, GL_STATIC_DRAW); - - /* Vertex buffer */ - float vertices[8 * data->ntiles]; - for (int n = 0; n < data->ntiles; n++) - { - int x = data->tiles[4 * n + 1]; - int y = data->tiles[4 * n + 2]; - vertices[8 * n + 0] = x; - vertices[8 * n + 1] = y; - vertices[8 * n + 2] = x + 32; - vertices[8 * n + 3] = y; - vertices[8 * n + 4] = x + 32; - vertices[8 * n + 5] = y + 32; - vertices[8 * n + 6] = x; - vertices[8 * n + 7] = y + 32; - } - glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]); - glBufferData(GL_ARRAY_BUFFER, 8 * data->ntiles * sizeof(float), - vertices, GL_STATIC_DRAW); - - /* Index buffer */ - int indices[4 * data->ntiles]; - for (int n = 0; n < 4 * data->ntiles; n++) - indices[n] = n; - glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]); - glBufferData(GL_ARRAY_BUFFER, 4 * data->ntiles * sizeof(int), - indices, GL_STATIC_DRAW); - - /* Draw everything */ - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_TEXTURE_COORD_ARRAY); - glEnableClientState(GL_INDEX_ARRAY); + float tx = .0625f * (id & 0xf); + float ty = .0625f * ((id >> 4) & 0xf); glBindTexture(GL_TEXTURE_2D, data->texture[0]); - - glBindBuffer(GL_ARRAY_BUFFER, data->buflist[0]); - glVertexPointer(2, GL_FLOAT, 0, NULL); - glBindBuffer(GL_ARRAY_BUFFER, data->buflist[1]); - glTexCoordPointer(2, GL_FLOAT, 0, NULL); - glBindBuffer(GL_ARRAY_BUFFER, data->buflist[2]); - glIndexPointer(GL_INT, 0, NULL); - - glDrawArrays(GL_QUADS, 0, 4 * data->ntiles); - - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_TEXTURE_COORD_ARRAY); - glDisableClientState(GL_INDEX_ARRAY); - - /* Empty our shit */ - free(data->tiles); - data->tiles = NULL; - data->ntiles = 0; + glBegin(GL_QUADS); + glTexCoord2f(tx, ty); + glVertex2f(x, y); + glTexCoord2f(tx + .0625f, ty); + glVertex2f(x + 32, y); + glTexCoord2f(tx + .0625f, ty + .0625f); + glVertex2f(x + 32, y + 32); + glTexCoord2f(tx, ty + .0625f); + glVertex2f(x, y + 32); + glEnd(); } diff --git a/src/tileset.h b/src/tileset.h index 24f0c26a..9adadc8a 100644 --- a/src/tileset.h +++ b/src/tileset.h @@ -6,6 +6,8 @@ #if !defined __DH_TILESET_H__ #define __DH_TILESET_H__ +#include + class TileSetData; class TileSet @@ -19,9 +21,7 @@ public: char const *GetName(); - void AddTile(int n, int x, int y, int z); - - void Render(); + void BlitTile(uint32_t id, int x, int y); private: TileSetData *data; diff --git a/src/video.cpp b/src/video.cpp index 40b68cf6..f248d12a 100644 --- a/src/video.cpp +++ b/src/video.cpp @@ -54,7 +54,7 @@ Video::Video(char const *title, int width, int height) SDL_WM_SetCaption(title, NULL); SDL_ShowCursor(0); - //SDL_WM_GrabInput(SDL_GRAB_ON); + SDL_WM_GrabInput(SDL_GRAB_ON); /* Initialise OpenGL */ glViewport(0, 0, data->video->w, data->video->h);