@@ -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 | |||
@@ -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; | |||
} | |||
@@ -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__ | |||
@@ -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; | |||
} | |||
@@ -6,9 +6,10 @@ | |||
#if !defined __DH_LAYER_H__ | |||
#define __DH_LAYER_H__ | |||
#include <cstdio> | |||
#include <stdint.h> | |||
#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; | |||
}; | |||
@@ -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, " <tileset firstgid=\"%i\"", &i) == 1) | |||
@@ -106,6 +107,7 @@ Map::Map(char const *path) | |||
/* This is a tileset image file. Associate it with firstgid. */ | |||
data->tilers[data->ntilers] = Tiler::Register(str); | |||
data->ntilers++; | |||
//fprintf(stderr, "new tiler %s\n", str); | |||
} | |||
else if (sscanf(tmp, " <layer name=\"%c%i%c%*[^\"]\" " | |||
"width=\"%i\" height=\"%i\"", &a, &i, &b, &j, &k) == 5) | |||
@@ -134,9 +136,9 @@ Map::~Map() | |||
delete data; | |||
} | |||
void Map::Draw() | |||
void Map::Render(Scene *scene, int x, int y, int z) | |||
{ | |||
for (int i = 0; i < data->nlayers; i++) | |||
data->layers[i]->Draw(); | |||
data->layers[i]->Render(scene, x, y, z); | |||
} | |||
@@ -6,9 +6,7 @@ | |||
#if !defined __DH_MAP_H__ | |||
#define __DH_MAP_H__ | |||
#include <cstdio> | |||
#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; | |||
@@ -1,5 +1,14 @@ | |||
#include <stdlib.h> | |||
#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; | |||
} | |||
@@ -6,7 +6,6 @@ | |||
#if !defined __DH_SCENE_H__ | |||
#define __DH_SCENE_H__ | |||
#include <cstdio> | |||
#include <stdint.h> | |||
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; | |||
}; | |||
@@ -6,29 +6,23 @@ | |||
#include <math.h> | |||
#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; | |||
@@ -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); | |||
} | |||
@@ -6,11 +6,15 @@ | |||
#if !defined __DH_TILER_H__ | |||
#define __DH_TILER_H__ | |||
#include <stdint.h> | |||
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__ | |||
@@ -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(); | |||
} | |||
@@ -6,6 +6,8 @@ | |||
#if !defined __DH_TILESET_H__ | |||
#define __DH_TILESET_H__ | |||
#include <stdint.h> | |||
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; | |||
@@ -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); | |||