1 /* SCCS Id: @(#)gnglyph.c 3.4 2000/07/16 */
2 /* Copyright (C) 1998 by Erik Andersen <andersee@debian.org> */
3 /* NetHack may be freely redistributed. See license for details. */
9 extern int total_tiles_used;
11 static GHackGlyphs ghack_glyphs;
12 static GdkImlibImage** ghack_tiles = NULL;
15 * ghack_init_glyphs(char* xpm_file)
18 * char *xpm_file -- The name of the image file.
19 * May be any image format imlib recognizes.
20 * Does not have to be XPM.
23 * TRUE upon successful loading of the glyphs.
27 * Constructor for the Glyph object. Well, really each glyph
28 * object is a collection of glyphs, or tiles. This constructor
29 * takes a single argument: the name of the image file that contains
33 * The glyphs (tiles) must be in the image in a certain way: the
34 * glyphs must be stacked such that the resultant image is
35 * TILE_X * TILES_PER_ROW wide, and
36 * TILE_Y * (number of glyphs) / TILES_PER_ROW high (rounded up).
37 * In this sense, TILE_X == TILE_Y, and can be any reasonable integer
38 * say, 16 <= TILE_X <= 64. Because the glyph number is tightly
39 * coupled to the Nethack object it represents, the order of the
40 * glyphs in the image is imporant: Glyph 1 is at the top of the
41 * image, while Glyph N (the last glyph) is at the bottom.
43 * What's the difference between a glyph and a tile? Well, a
44 * tile is just an image. A glyph is a tile that knows its
47 * This initializer relies heavily on gdk_imlib. Thanks, Rasterman.
51 ghack_init_glyphs(const char *xpmFile)
53 ghack_glyphs.im = gdk_imlib_load_image((char *) xpmFile);
54 if ( ! ghack_glyphs.im ) {
55 g_error("Couldn't load required xpmFile!");
59 gdk_imlib_render(ghack_glyphs.im, ghack_glyphs.im->rgb_width,
60 ghack_glyphs.im->rgb_height);
62 if ((ghack_glyphs.im->rgb_width % TILES_PER_ROW) != 0 ||
63 ghack_glyphs.im->rgb_width <= TILES_PER_ROW) {
64 g_error("%s is not a multiple of %d (number of tiles/row) pixels wide",
65 xpmFile, TILES_PER_ROW);
68 ghack_glyphs.count = total_tiles_used;
69 if ((ghack_glyphs.count % TILES_PER_ROW) != 0) {
71 TILES_PER_ROW - (ghack_glyphs.count % TILES_PER_ROW);
73 ghack_glyphs.width = ghack_glyphs.im->rgb_width / TILES_PER_ROW;
75 ghack_glyphs.im->rgb_height / (ghack_glyphs.count / TILES_PER_ROW);
78 /* Assume the tiles are organized in rows of TILES_PER_ROW */
79 ghack_tiles = g_new0( GdkImlibImage*, ghack_glyphs.count );
80 return (ghack_tiles == NULL) ? -1 : 0;
87 for ( i=0 ; i<ghack_glyphs.count ; i++)
88 gdk_imlib_destroy_image(ghack_tiles[i]);
90 gdk_imlib_destroy_image(ghack_glyphs.im);
96 * ghack_glyph_count( )
102 * int -- The number of glyphs in this object.
105 * Simply reports the number of glyphs in this object.
111 return ghack_glyphs.count;
116 * ghack_glyph_height()
122 * int -- The glyph height.
125 * Returns the standard glyph height.
131 return ghack_glyphs.height;
136 * ghack_glyph_width()
142 * int -- The glyph width.
145 * Returns the standard glyph width.
151 return ghack_glyphs.width;
156 * ghack_image_from_glyph( int glyph, gboolean force)
159 * int glyph -- The glyph number.
160 * gboolean force -- force it to re-render.
163 * GdkImlibImage* -- The glyph image, as a GdkImlibImage.
166 * Decodes the glyph into an image suitable for manipulation
170 ghack_image_from_glyph( int glyph, gboolean force )
172 int tile = glyph2tile[glyph];
174 if ( tile >= ghack_glyphs.count || tile < 0 )
176 g_warning("Aiiee! I've was asked for a tile outside the allowed range!\n"
177 "Email this to other-gnomehack@lists.debian.org");
178 g_warning("Max tile: %d Tile asked for: %d",
179 ghack_glyphs.count, tile);
183 if (ghack_glyphs.im == NULL)
185 g_warning("Aiiee! I've been asked to clone from a null image.\n"
186 "Email this to other-gnomehack@lists.debian.org");
187 g_warning( "making image from tile %d, force=%s\n", tile,
188 (force==TRUE)? "TRUE": "FALSE");
193 g_warning("Aiiee! I've been asked to force rendering.\n"
194 "Email this to other-gnomehack@lists.debian.org");
195 g_warning( "making image from tile %d, force=%s\n", tile,
196 (force==TRUE)? "TRUE" : "FALSE");
199 if (!ghack_tiles[tile] || force) {
202 fprintf( stderr, "crop_and_clone: glyph=%d, tile=%d, ptr=%p, x=%d, y=%d, w=%d, h=%d\n", glyph, tile,
203 (void*)&(ghack_tiles[tile]), 0,
204 tile * ghack_glyphs.width,
208 if (ghack_glyphs.im->pixmap == NULL)
209 g_warning( "Aiiee! ghack_glyphs.im->pixmap==NULL!!!!\n");
210 src_x = (tile % TILES_PER_ROW) * ghack_glyphs.width;
211 src_y = (tile / TILES_PER_ROW) * ghack_glyphs.height;
212 ghack_tiles[tile] = gdk_imlib_crop_and_clone_image(ghack_glyphs.im,
215 ghack_glyphs.height);
218 if (ghack_tiles[tile] && (!ghack_tiles[tile]->pixmap || force))
220 if ( gdk_imlib_render(ghack_tiles[tile],
221 ghack_tiles[tile]->rgb_width,
222 ghack_tiles[tile]->rgb_height) == 0) {
223 g_error("GLYPH: couldn't create tile # %d", tile);
225 if ( !ghack_tiles[tile]->pixmap )
226 g_error("Strange, tile # %d didn't get rendered???", tile);
229 return ghack_tiles[tile];