1 /* aNetHack 0.0.1 gnglyph.c $ANH-Date: 1432512806 2015/05/25 00:13:26 $ $ANH-Branch: master $:$ANH-Revision: 1.10 $ */
2 /* Copyright (C) 1998 by Erik Andersen <andersee@debian.org> */
3 /* aNetHack 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
) {
65 "%s is not a multiple of %d (number of tiles/row) pixels wide",
66 xpmFile
, TILES_PER_ROW
);
69 ghack_glyphs
.count
= total_tiles_used
;
70 if ((ghack_glyphs
.count
% TILES_PER_ROW
) != 0) {
72 TILES_PER_ROW
- (ghack_glyphs
.count
% TILES_PER_ROW
);
74 ghack_glyphs
.width
= ghack_glyphs
.im
->rgb_width
/ TILES_PER_ROW
;
76 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
);
91 ghack_glyphs
.im
= NULL
;
95 * ghack_glyph_count( )
101 * int -- The number of glyphs in this object.
104 * Simply reports the number of glyphs in this object.
110 return ghack_glyphs
.count
;
114 * ghack_glyph_height()
120 * int -- The glyph height.
123 * Returns the standard glyph height.
129 return ghack_glyphs
.height
;
133 * ghack_glyph_width()
139 * int -- The glyph width.
142 * Returns the standard glyph width.
148 return ghack_glyphs
.width
;
152 * ghack_image_from_glyph( int glyph, gboolean force)
155 * int glyph -- The glyph number.
156 * gboolean force -- force it to re-render.
159 * GdkImlibImage* -- The glyph image, as a GdkImlibImage.
162 * Decodes the glyph into an image suitable for manipulation
166 ghack_image_from_glyph(int glyph
, gboolean force
)
168 int tile
= glyph2tile
[glyph
];
170 if (tile
>= ghack_glyphs
.count
|| tile
< 0) {
172 "Aiiee! I've was asked for a tile outside the allowed range!\n"
173 "Email this to other-gnomehack@lists.debian.org");
174 g_warning("Max tile: %d Tile asked for: %d", ghack_glyphs
.count
,
179 if (ghack_glyphs
.im
== NULL
) {
180 g_warning("Aiiee! I've been asked to clone from a null image.\n"
181 "Email this to other-gnomehack@lists.debian.org");
182 g_warning("making image from tile %d, force=%s\n", tile
,
183 (force
== TRUE
) ? "TRUE" : "FALSE");
187 g_warning("Aiiee! I've been asked to force rendering.\n"
188 "Email this to other-gnomehack@lists.debian.org");
189 g_warning("making image from tile %d, force=%s\n", tile
,
190 (force
== TRUE
) ? "TRUE" : "FALSE");
193 if (!ghack_tiles
[tile
] || force
) {
196 fprintf( stderr
, "crop_and_clone: glyph=%d, tile=%d, ptr=%p, x=%d, y=%d, w=%d, h=%d\n", glyph
, tile
,
197 (void*)&(ghack_tiles
[tile
]), 0,
198 tile
* ghack_glyphs
.width
,
202 if (ghack_glyphs
.im
->pixmap
== NULL
)
203 g_warning("Aiiee! ghack_glyphs.im->pixmap==NULL!!!!\n");
204 src_x
= (tile
% TILES_PER_ROW
) * ghack_glyphs
.width
;
205 src_y
= (tile
/ TILES_PER_ROW
) * ghack_glyphs
.height
;
206 ghack_tiles
[tile
] = gdk_imlib_crop_and_clone_image(
207 ghack_glyphs
.im
, src_x
, src_y
, ghack_glyphs
.width
,
208 ghack_glyphs
.height
);
211 if (ghack_tiles
[tile
] && (!ghack_tiles
[tile
]->pixmap
|| force
)) {
212 if (gdk_imlib_render(ghack_tiles
[tile
], ghack_tiles
[tile
]->rgb_width
,
213 ghack_tiles
[tile
]->rgb_height
) == 0) {
214 g_error("GLYPH: couldn't create tile # %d", tile
);
216 if (!ghack_tiles
[tile
]->pixmap
)
217 g_error("Strange, tile # %d didn't get rendered???", tile
);
220 return ghack_tiles
[tile
];