: : : : : : : : : :
--------: ---------: ---------: ---------: ---- :
..| |*..| |*..| |*..| |*..| |*....:.
| |* | |* | |* | |* | |* :
--- ---* | |-----* | |-----* | |-----* | |* :
....| |*.:..| |--****..| |-----*..| |--****..| |*....:.
| |* : | |* : | |-- |* | |* : | |* :
| |* : | |--* : | |*| |* | |--* : | |* :
....| |*.:..| |-----:..| --- |*..| |-----:..| -----.:.
| |* : | |* | |* | |* | |*:
| |* : | |* | |* | |* | |*:
....----*.:..---------*..---------*..---------*..--------*:.
:**** : ********* ********* ********* ********:
: : : : : : : : : :
Tegel Edit, a tilemap editor, v0.81
Copyright (c) 2002-2007
Martijn "Amarillion" van Iersel.
The latest version of tegel is available at http://tegel.sourceforge.net
I hope you like this program. Please send questions, comments, flames and feature requests to amarillion@yahoo.com.
Tegel is a package for writing games which use tilemaps. The package contains a C library and an advanced editor. Tegel supports various special tilemap tricks such as:
The latest version of tegel is available at http://tegel.sourceforge.net
I hope you like this program. Please send questions, comments, flames and feature requests to amarillion@yahoo.com.
Tegel depends on a couple of other libraries that need to be
installed before you can compile it. These are:
note: MASkinG and Alfont are only required for the editor. In
principle it is possible to compile the playback library and examples
without these.
Once you haveproperly set up these prerequisites the process of
compiling tegel should be simple enough
windows:
fix mingw32
make
make install
linux:
./fix.sh linux
make
sudo make install
If you can't or don't want to install MASkinG, you can still compile the library and the examples with
make examplesor
make lib
The first thing you need to do before you can start making maps is create a tilelist. A tilelist is a set of tiles that are loaded as a unit. They are separate from the maps using them. This allows you to save memory when you have many maps using the same tilelist.
A tilelist consists of a datafile containing all the tiles, and a text file which contains the properties of the tilelist. This textfile is grabbed as a binary object in the datafile.
There are four basic types of tilelist:
type 1. each tile is a separate bitmap object
type 2. each tile is a RLE sprite object
type 3. all the tiles are on a single large bitmap. The bitmap is
divided in tiles using a grid the tile in the upper left corner is tile
0, and right next to it is tile 1, etc.
type 4. same as 3, but rather than using left to right, up to down
ordering, the order of tiles can be specified using indices. This can be
useful for making animated tilesets.
note: below the new tilelist format version 2 is described. A description of older formats is archived at the end of this help file.
the textfile with the tile properties starts with a header like this:
TILELIST
version=2
tilew=32
tileh=32
bpp=8
flags=2
animsteps=1
the first line "TILELIST" is an identifier that confirms that this is a tilelist file. tilew and tileh are the width and height of the tiles. bpp is the color depth of the tiles. flags is the type of tilelist (1 for bitmap objects, 2 for rle sprites, etc.) animsteps is the number of frames in an animated tileset. If the tileset is not animated, set this to 1.
What follows then depends on the type of tileset. For types 3 & 4, first one object name is specified, this name refers to a bitmap object in the datafile with a width that is a multiple of the specified tile width and a height that is a multiple of the specified tile height.
For types 1 & 2, a list follows with on each line a number and then a list of 1 to animsteps object names. These values can be separated by spaces, tabs, dots, colons, semicolons or any combination thereof. The number may be in decimal, octal or hexadecimal format.
For example:
0xFF, TILE1FRAME1, TILE1FRAME2, TILE1FRAME3
As you can see this tile has a flag value of 255 (hexadecimal: 0xFF)
and consists of three frames. If there are more animsteps than the
number of objects specified, the specified frames are looped to fill the
specified number of animsteps. For example, if in this case the number
of animsteps is 6, the actual animation would be:
TILE1FRAME1, TILE1FRAME2, TILE1FRAME3, TILE1FRAME1, TILE1FRAME2, TILE1FRAME3
The specified objects have to be a bitmap (for type 1) or an RLE sprite (for type 2) with widths and heights equal to the specified widths and heights.
For type 3, a similar list follows, but instead of object names you
get a list of numbers. Each number is an index that specifies a certain
cell of the grid on the bitmap (e.g. 0 specifies upper left cell). Each
index should be on a separate line. First all the indices for frame 1,
then the indices for frame 2, etc.
The list of object name should end with an exclamation mark (!)
alone on a line. This marks the end of the list.
The tilelist file has to be loaded as a separate datafile object in the same datafile as the tiles, with a type value of "TEGT".
Once you've collected your tiles in a datafile and you've created a tilelist property file, you can start up the Tegel editor and start creating tile maps.
When you start the editor, you see 4 boxes on the screen and a menu and a toolbar at the top.
When you start the first time, the first step is to load tiles with file->load tiles, then you can create a new map with file->new.
The large box at the top left is the map box. It is used to display and edit maps. Click in the mapbox to make changes. You edit only one layer at the time. The layer that you are edittin is called the "active layer".
The bottom left box is the layer box. It shows which is the active layer, and which layers are currently visible. The active layer is marked with a "*". Click on the layer number with the left mouse button to toggle it on or off. Click with the right mouse button to make it the active layer.
The top right is the tiles box. It shows the currenty loaded tilelist, and you can use it to select a tile. The bottom right is the minimap box. It can be used to give you an overview of the map you are editting, and it can be used to quickly scroll around.
The menu gives you access to various tools.
File->New | Create a new map. Only available when you have loaded a tilelist. This opens up a dialog that allows you to specify the width, height and number of layers in the map. |
File->Load Map | Load a map. Only available when you have loaded a tilelist. A dialog pops up that allows you to select a map file. |
File->Save Map | Save the map that you created. |
File->Import | Currently not implemented |
File->Load Tiles | This allows you to load tiles. You have to specify the datafile containing the tile bitmaps and the textfile with the tilelist properties. |
File->Quit | end the program |
at the end of the file menu, the 4 most recently used map files are shown. You can select these to quickly load one of the maps that you have been working on recently. |
|
Edit->Copy |
Copy the current selection to the clipboard |
Edit->Paste | Paste the contents of the clipboard to the map |
Edit->Resize | Select this to change the dimensions of the map, or to add extra layers. Warning: parts of the map are deleted if you specify a size that is smaller than the original size of the map. |
Tools->Brush | A mark appears in front of this menu item if you select it. If this item is marked, a mouseclick in the mapbox changes a single tile to the current tile. |
Tools->Flood Fill | A mark appears in front of this menu item if you select it. If this item is marked, a mouseclick in the mapbox changes a region of the same tile to the current tile. |
Tools->Select rectangle | Let's you select a rectangular area of the map by dragging the mouse. The selection is only one layer high. |
Tools->Map Screenshot | Draw the entire map (not just the visible part) to a single bitmap. You are then asked for a location where to save this bitmap. |
Help->Contents | Show this text |
Help->About | Show copyright information |
Ctrl+N | New map |
Ctrl+L | Load map |
Ctrl+S | Save map |
Ctrl+T | Load tiles |
Ctrl+Q | quit |
Ctrl+Z | undo |
Ctrl+C | copy |
Ctrl+V | paste |
Arrow keys | move cursor |
Shift + arrow keys | move the cursor and start / extend a selection |
Ctrl + arrow keys | move the cursor to the edge of the map |
F1 | help |
If you have managed to properly install the tegel package, you are
probably eager to make a game with it. Here is what you have to do.
TILELISTuse flags=1 if you're using BITMAP objects, use flags=2 if you're using RLE_SPRITE objects. Assuming of course that TILE000 - TILE003 are the names of the grabbed tile objects. The ! in the end is important too - it denotes the end of the list of object names.
version=2
tilew=32
tileh=32
bpp=8
flags=2
animsteps=1
0, TILE000
0, TILE001
0, TILE002
0, TILE003
!
start the edit program (in tegel/edit/), and use File->Load
Tilelist to open the datafile containing the tilelist you just created.
Then select File->New Map and start editing. When you're done, use
File->Save Map to save.
#include <tegel.h>
allegro_init();
teg_install();
DATAFILE *data;We need to pass a pointer to TEG_TILELIST as the second parameter to teg_loadmap. This tilelist object is contained in the datafile loaded in the previous line. Here we use find_datafile_object to obtain a pointer to the tilelist object from the datafile, but we could also have used e.g. data[TILESET].dat if you prefer that construction.
TEG_TILEMAP *map;
data = teg_load_datafile ("tileset.dat");
map = teg_loadmap ("level1.map", (TEG_TILELIST*)(find_datafile_object (data, "TILESET")->dat));
teg_draw (screen, map, 0, 0, 0);
alternatively, if you want to make use of the multi-layer
functionality you can draw more than one layer like this:
for (i = 0; i < map->layernum; ++i)
{
teg_draw (screen, map, i, 0, 0);
}
Another common situation is that you want to draw objects between layers, in that case you may want to do it like this:
teg_draw (screen, map, 0, 0, 0); // draw background layer
draw_objects();
teg_draw (screen, map, 1, 0, 0); // draw foreground layer
teg_unload_datafile (data);As the bitmaps and tilelist information are not copied from the datafile object, you have to keep it around until you are completely done with that tileset. teg_uninstall has to be called before you exit allegro. You may destroy the map using a particular tileset before or after you destroy that tileset.
teg_destroymap (map);
teg_uninstall ();
allegro_exit ();
The TEG_TILEFLAG_* constants are used for the four different
tilelist types
#define TEG_TILEFLAG_BMP 1
#define TEG_TILEFLAG_RLE 2
#define TEG_TILEFLAG_LARGE 3
#define TEG_TILEFLAG_LARGEI 0
These DAT_ID's can be used to identify tegel tilelist or tilemap objects in a datafile.
#define DAT_TEG_TILELIST DAT_ID('T','E','G','T')
#define DAT_TEG_MAP DAT_ID('T','E','G','M')
teg_error contains a friendly description of the last error that
occurred.
extern char teg_error[256];
the TEG_TILE struct holds information about a single tile. flags can
hold user defined information. The actual bitmap information for this
tile is, depending of the tilelist type, held in either rle or bmp, or
in a separate bitmap altogether in which case index refers to that. You
should rarely need to access the bitmap data directly.
typedef struct TEG_TILE
{
RLE_SPRITE* rle;
BITMAP *bmp;
int index;
int flags;
} TEG_TILE;
TEG_TILELIST holds a set of tiles. If the tileset is animated, animsteps is determines the number of frames in a cycle (each tile in the set has to have the same number of frames). All tiles need to be the same size, tilew x tileh pixels. Also, they need to be the same number of bits per pixel, as in the bpp parameter. Tilenum holds the number of tiles in this set. pal may refer to palette information for this tilelist, although it may also be NULL. rawdata and rawsize are for internal use.
typedef struct TEG_TILELIST
{
int flags;
int tilew, tileh, tilenum;
int bpp;
int animsteps;
TEG_TILE* tiles;
BITMAP* largebmp;
RGB *pal;
char *rawdata;
int rawsize;
} TEG_TILELIST;
TEG_MAP holds the information about one, multi-layered map. dl, w, and h specify the dimensions of the map (dl stands for delta-layers, or the number of layers in this map). Tilelist is a pointer to the tilelist data for this map.
typedef struct TEG_MAP
{
int *data;
int dl, w, h;
TEG_TILELIST *tilelist;
} TEG_MAP;
teg_createmap and teg_destroymap are a constructor resp. destructor for the map struct. teg_createmap creates a map of the specified size and allocates memory to hold a map of that size. The tilelist parameter may be NULL, in which case it has to be set manually later.
TEG_MAP *teg_createmap (int dl, int w, int h, TEG_TILELIST *tilelist);
void teg_destroymap (TEG_MAP* map);
teg_loadmap loads a map from the specified file and links it with
the specified tilelist (which may be null, in which case it has to be
set manually later).
A map loaded with teg_loadmap should be cleaned up with teg_destroymap
to make sure all memory is reclaimed.
TEG_MAP *teg_loadmap (const char *filename, TEG_TILELIST *tilelist);
teg_mapget and teg_mapput can be used to set or get the index of a tile at the specified coordinate.
int teg_mapget (const TEG_MAP* map, int l, int x, int y);
void teg_mapput (TEG_MAP* map, int l, int x, int y, int val);
teg_loadtiles can be used to read tilelist information directly from
a text file. However, it is preferable to store tilelists as datafile
objects.
TEG_TILELIST *teg_loadtiles (const char *filename, const DATAFILE *data);
A tilelist loaded with teg_loadtiles can be destroyed again with teg_destroytiles. If you use datafiles to store tilelists you'll never need to call this function as the tilelist is cleaned up when you unload the datafile.
void teg_destroytiles (TEG_TILELIST* tiles);
the teg_draw.... functions are used to render a tilemap to the screen (in the normal, non-rotated way). Teg_draw is the simplest version, which fills the complete destination bitmap and can't be used for animated tilesets. xview and yview are offsets that can be used to scroll the map. Teg_draw_frame can be used to draw consecutive frames of an animation and when called with a different frame parameter at a steady pace, will result in the fluid animation of the tilemap. teg_draw_rle, teg_draw_bmp, teg_draw_largei and teg_draw_large needn't be called directly, they are tilelist format dependant versions of teg_draw_frame. teg_draw_frame does nothing more than select the proper function to call. If you're worried about the tiny overhead that this creates and you are positive that you'll always use the same tilelist format you may call these directly. The teg_partdraw.... functions only draw to a part of the destination bitmap and may be used to render only part of the tilemap, e.g. in a dirty-rectangle type system.
void teg_draw (BITMAP *bmp, const TEG_MAP* map, int layer, int xview, int yview);
void teg_draw_frame (BITMAP *bmp, const TEG_MAP* map, int layer, int xview, int yview, int frame);
void teg_draw_rle (BITMAP *bmp, const TEG_MAP* map, int layer, int xview, int yview, int frame);
void teg_draw_bmp (BITMAP *bmp, const TEG_MAP* map, int layer, int xview, int yview, int frame);
void teg_draw_large (BITMAP *bmp, const TEG_MAP* map, int layer, int xview, int yview, int frame);
void teg_draw_largei (BITMAP *bmp, const TEG_MAP* map, int layer, int xview, int yview, int frame);
void teg_partdraw (BITMAP *bmp, const TEG_MAP* map, int layer, int x, int y, int w, int h, int xview, int yview);
void teg_partdraw_rle (BITMAP *bmp, const TEG_MAP* map, int layer, int x, int y, int w, int h, int xview, int yview);
void teg_partdraw_bmp (BITMAP *bmp, const TEG_MAP* map, int layer, int x, int y, int w, int h, int xview, int yview);
void teg_partdraw_large (BITMAP *bmp, const TEG_MAP* map, int layer, int x, int y, int w, int h, int xview, int yview);
void teg_partdraw_largei (BITMAP *bmp, const TEG_MAP* map, int layer, int x, int y, int w, int h, int xview, int yview);
teg_pixelw and teg_pixelh give the dimensions of a particular map
not in number of tiles but in number of pixels.
int teg_pixelw(const TEG_MAP *map);
int teg_pixelh(const TEG_MAP *map);
Tegel records links that exist between various resources. For example, a tilelist links to a set of tiles that go with it, and a map links to the tilelist that is supposed to go with it. In the same way an animation may link to the frames that make up the animation, or a set of 8 bit graphics may link to the palette that has to be used to draw them, or a level data file may link to the proper background music for that level. To accomodate these links tegel comes with a specialized datafile loading system. teg_load_datafile and teg_unload_datafile are wrappers around the allegro datafile functions that handle and resolve links between objects. It never hurts to use teg_load_datafile instead of load_datafile, as the overhead is minimal. However, it does give you the additional advantage of storing the links between datafile objects.
DATAFILE *teg_load_datafile (const char *datafile);
void teg_unload_datafile (DATAFILE *data);
teg_install must be called before you use any other teg_ function,
but after allegro is installed. teg_uninstall must be called after any
other teg_ function call.
int teg_install();
void teg_uninstall();
save a map
void teg_savemap (TEG_MAP* map, char *filename);
copy a part of a map to an existing other map.
void teg_mapcopy (TEG_MAP *srcmap, TEG_MAP* destmap,
int srcl, int srcx, int srcy,
int destl, int destx, int desty,
int dl, int w, int h);
map copy constructor. New memory is allocated
TEG_MAP *teg_create_copy (TEG_MAP *src);
fill an area with the same tile index
void teg_maprect (TEG_MAP *destmap,
int destl, int destx, int desty,
int dl, int w, int h, int value);
resize a map. As much as possible is kept of the original.
void teg_resizemap (TEG_MAP **map, int newdl, int neww, int newh);
draw a tile, specified by its tile index
void teg_drawtile (BITMAP *dest, TEG_TILELIST *tiles, int index, int x, int y);
some usefull macros
#define RED makecol (255, 0, 0)
#define BLUE makecol (0, 0, 255)
#define GREEN makecol (0, 255, 0)
#define YELLOW makecol (255, 255, 0)
#define BLACK makecol (0, 0, 0)
#define WHITE makecol (255, 255, 255)
#define GREY makecol (128, 128, 128)
#define CYAN makecol (0, 255, 255)
#define MAGENTA makecol (255, 0, 255)
#define TEG_MIN(x,y) (((x) < (y)) ? (x) : (y))
#define TEG_MAX(x,y) (((x) < (y)) ? (y) : (x))
#define TEG_BOUND(x,y,z) (((y) < (x)) ? (((y) > (z)) ? (z) : (y)) : (x))
take a screenshot and save it as ssNNNNNN.pcx
void screenshot ();
void dat_rle2bmp (DATAFILE *data);
void dat_object_rle2bmp (DATAFILE *data);
typedef int ClipRect[4];
void tempClipRect (BITMAP *bmp, ClipRect *cr, int x, int y, int w, int h);
void restoreClipRect (BITMAP *bmp, ClipRect *cr);
typedef struct TEG_MODE_7_PARAMS
{
fixed space_z;
int horizon;
fixed scale_x, scale_y;
fixed obj_scale_x, obj_scale_y;
} TEG_MODE_7_PARAMS;
void teg_draw_object (BITMAP *bmp, BITMAP *obj,
fixed object_x, fixed object_y, fixed angle,
fixed cx, fixed cy, TEG_MODE_7_PARAMS params);
void teg_mode_7_sprite (BITMAP *bmp, BITMAP *tile, fixed angle, fixed cx, fixed cy, TEG_MODE_7_PARAMS params);
void teg_mode_7_map (BITMAP *bmp, TEG_MAP *map, fixed angle, fixed cx, fixed cy, TEG_MODE_7_PARAMS params);
The tegel package comes with a set of examples to help you get
started quickly.