| @@ -1,6 +1,7 @@ | |||||
| SRC = test-map.cpp \ | SRC = test-map.cpp \ | ||||
| game.cpp video.cpp tiler.cpp tileset.cpp scene.cpp layer.cpp map.cpp | |||||
| game.cpp video.cpp tiler.cpp tileset.cpp scene.cpp \ | |||||
| font.cpp layer.cpp map.cpp | |||||
| all: test-map | all: test-map | ||||
| @@ -0,0 +1,94 @@ | |||||
| #ifdef WIN32 | |||||
| # define WIN32_LEAN_AND_MEAN | |||||
| # include <windows.h> | |||||
| #endif | |||||
| #if defined __APPLE__ && defined __MACH__ | |||||
| # include <OpenGL/gl.h> | |||||
| #else | |||||
| # define GL_GLEXT_PROTOTYPES | |||||
| # include <GL/gl.h> | |||||
| #endif | |||||
| #include <SDL.h> | |||||
| #include <SDL_image.h> | |||||
| #include "font.h" | |||||
| /* | |||||
| * Font implementation class | |||||
| */ | |||||
| class FontData | |||||
| { | |||||
| friend class Font; | |||||
| private: | |||||
| SDL_Surface *img; | |||||
| GLuint texture[1]; | |||||
| }; | |||||
| /* | |||||
| * Public Font class | |||||
| */ | |||||
| Font::Font(char const *path) | |||||
| { | |||||
| data = new FontData(); | |||||
| data->img = NULL; | |||||
| for (char const *name = path; *name; name++) | |||||
| if ((data->img = IMG_Load(name))) | |||||
| break; | |||||
| if (!data->img) | |||||
| { | |||||
| SDL_Quit(); | |||||
| exit(1); | |||||
| } | |||||
| glGenTextures(1, data->texture); | |||||
| glBindTexture(GL_TEXTURE_2D, data->texture[0]); | |||||
| glTexImage2D(GL_TEXTURE_2D, 0, 4, data->img->w, data->img->h, 0, | |||||
| GL_RGBA, GL_UNSIGNED_BYTE, data->img->pixels); | |||||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | |||||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | |||||
| } | |||||
| Font::~Font() | |||||
| { | |||||
| glDeleteTextures(1, data->texture); | |||||
| SDL_FreeSurface(data->img); | |||||
| delete data; | |||||
| } | |||||
| void Font::Print(int x, int y, char const *str) | |||||
| { | |||||
| int w = data->img->w / 16; | |||||
| int h = data->img->h / 16; | |||||
| glBindTexture(GL_TEXTURE_2D, data->texture[0]); | |||||
| glBegin(GL_QUADS); | |||||
| while (*str) | |||||
| { | |||||
| uint32_t ch = (uint8_t)*str++; | |||||
| float tx = .0625f * (ch & 0xf); | |||||
| float ty = .0625f * ((ch >> 4) & 0xf); | |||||
| glTexCoord2f(tx, ty); | |||||
| glVertex2f(x, y); | |||||
| glTexCoord2f(tx + .0625f, ty); | |||||
| glVertex2f(x + w, y); | |||||
| glTexCoord2f(tx + .0625f, ty + .0625f); | |||||
| glVertex2f(x + w, y + h); | |||||
| glTexCoord2f(tx, ty + .0625f); | |||||
| glVertex2f(x, y + h); | |||||
| x += w; | |||||
| } | |||||
| glEnd(); | |||||
| } | |||||
| @@ -0,0 +1,24 @@ | |||||
| /* | |||||
| * The font object | |||||
| */ | |||||
| #if !defined __DH_FONT_H__ | |||||
| #define __DH_FONT_H__ | |||||
| class FontData; | |||||
| class Font | |||||
| { | |||||
| public: | |||||
| Font(char const *path); | |||||
| ~Font(); | |||||
| void Print(int x, int y, char const *str); | |||||
| private: | |||||
| FontData *data; | |||||
| }; | |||||
| #endif // __DH_FONT_H__ | |||||
| @@ -1,6 +1,9 @@ | |||||
| #include <cstdio> | |||||
| #include "game.h" | #include "game.h" | ||||
| #include "map.h" | #include "map.h" | ||||
| #include "font.h" | |||||
| /* | /* | ||||
| * Game implementation class | * Game implementation class | ||||
| @@ -12,8 +15,11 @@ class GameData | |||||
| private: | private: | ||||
| Map *map; | Map *map; | ||||
| Font *font; | |||||
| int x, y; | int x, y; | ||||
| int mousex, mousey; | int mousex, mousey; | ||||
| int frame; | |||||
| }; | }; | ||||
| /* | /* | ||||
| @@ -24,11 +30,14 @@ Game::Game(char const *mapname) | |||||
| { | { | ||||
| data = new GameData(); | data = new GameData(); | ||||
| data->map = new Map(mapname); | data->map = new Map(mapname); | ||||
| data->font = new Font("gfx/font/ascii.png"); | |||||
| data->x = data->y = 0; | data->x = data->y = 0; | ||||
| data->frame = 0; | |||||
| } | } | ||||
| Game::~Game() | Game::~Game() | ||||
| { | { | ||||
| delete data->font; | |||||
| delete data->map; | delete data->map; | ||||
| delete data; | delete data; | ||||
| } | } | ||||
| @@ -47,5 +56,9 @@ void Game::Render() | |||||
| scene->Render(); | scene->Render(); | ||||
| delete scene; | delete scene; | ||||
| char buf[1024]; | |||||
| sprintf(buf, "Frame %i", data->frame++); | |||||
| data->font->Print(10, 10, buf); | |||||
| } | } | ||||
| @@ -39,6 +39,7 @@ private: | |||||
| int *tiles; | int *tiles; | ||||
| int ntiles; | int ntiles; | ||||
| SDL_Surface *img; | |||||
| GLuint texture[1]; | GLuint texture[1]; | ||||
| }; | }; | ||||
| @@ -48,20 +49,18 @@ private: | |||||
| TileSet::TileSet(char const *path) | TileSet::TileSet(char const *path) | ||||
| { | { | ||||
| SDL_Surface *img = NULL; | |||||
| data = new TileSetData(); | data = new TileSetData(); | ||||
| data->name = strdup(path); | data->name = strdup(path); | ||||
| data->ref = 0; | data->ref = 0; | ||||
| data->tiles = NULL; | data->tiles = NULL; | ||||
| data->ntiles = 0; | data->ntiles = 0; | ||||
| data->img = NULL; | |||||
| /* One tile texture */ | |||||
| for (char const *name = path; *name; name++) | for (char const *name = path; *name; name++) | ||||
| if ((img = IMG_Load(name))) | |||||
| if ((data->img = IMG_Load(name))) | |||||
| break; | break; | ||||
| if (!img) | |||||
| if (!data->img) | |||||
| { | { | ||||
| SDL_Quit(); | SDL_Quit(); | ||||
| exit(1); | exit(1); | ||||
| @@ -70,8 +69,8 @@ TileSet::TileSet(char const *path) | |||||
| glGenTextures(1, data->texture); | glGenTextures(1, data->texture); | ||||
| glBindTexture(GL_TEXTURE_2D, data->texture[0]); | glBindTexture(GL_TEXTURE_2D, data->texture[0]); | ||||
| glTexImage2D(GL_TEXTURE_2D, 0, 4, img->w, img->h, 0, | |||||
| GL_RGBA, GL_UNSIGNED_BYTE, img->pixels); | |||||
| glTexImage2D(GL_TEXTURE_2D, 0, 4, data->img->w, data->img->h, 0, | |||||
| GL_RGBA, GL_UNSIGNED_BYTE, data->img->pixels); | |||||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | ||||
| glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | ||||