2 // nazghul - an old-school RPG engine
3 // Copyright (C) 2002, 2003 Gordon McNutt
5 // This program is free software; you can redistribute it and/or modify it
6 // under the terms of the GNU General Public License as published by the Free
7 // Software Foundation; either version 2 of the License, or (at your option)
10 // This program is distributed in the hope that it will be useful, but WITHOUT
11 // ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 // FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 // You should have received a copy of the GNU General Public License along with
16 // this program; if not, write to the Free Foundation, Inc., 59 Temple Place,
17 // Suite 330, Boston, MA 02111-1307 USA
20 // gmcnutt@users.sourceforge.net
33 //int TERRAIN_MAGIC = 0xc01dbee3;
35 extern struct terrain *terrain_new(const char *tag,
37 struct sprite *sprite,
42 struct terrain *terrain;
44 terrain = (struct terrain*)calloc(1, sizeof(*terrain));
47 terrain->magic = TERRAIN_MAGIC;
48 terrain->tag = strdup(tag);
49 terrain->name = strdup(name);
50 terrain->sprite = sprite;
51 terrain->pclass = pclass;
52 terrain->alpha = alpha;
53 terrain->light = light;
57 void terrain_del(struct terrain *terrain)
65 if (terrain->effect) {
66 closure_unref(terrain->effect);
71 #define BOGUS_MAX_SIZE 255 // Hack, should get a constant from somewhere
72 // LONGEST_TERRAIN_GLYPH would be appropriate for glyph_str...
74 void palette_entry_print(FILE * fp, int indent,
75 struct terrain_palette_entry *entry)
77 static char glyph_str[BOGUS_MAX_SIZE + 1];
78 static char tag_str[BOGUS_MAX_SIZE + 1];
82 snprintf(glyph_str, BOGUS_MAX_SIZE, "\"%s\"", entry->glyph);
83 snprintf(tag_str, BOGUS_MAX_SIZE, "%s)", entry->terrain->tag);
86 fprintf(fp, "(list %-6s %-20s ;; \"%s\"\n", glyph_str, tag_str, entry->terrain->name);
87 } // palette_entry_print()
89 struct terrain_palette *terrain_palette_new(const char *tag)
91 struct terrain_palette *palette = new struct terrain_palette;
93 memset(palette, 0, sizeof(struct terrain_palette));
95 list_init(&palette->lookup_head);
96 list_init(&palette->edit_head);
97 palette->tag = strdup(tag);
98 palette->widest_glyph = 0;
99 palette->num_entries = 0;
104 struct terrain_palette_entry *
105 terrain_palette_entry_new(char *glyph, struct terrain *terrain)
107 struct terrain_palette_entry *entry;
108 entry = (struct terrain_palette_entry *)malloc(sizeof(*entry));
109 list_init(&entry->lookup_list);
110 list_init(&entry->edit_list);
111 entry->glyph = strdup(glyph);
112 assert(entry->glyph);
113 entry->terrain = terrain;
117 void terrain_palette_entry_del(struct terrain_palette_entry *entry)
119 // For each entry free the glyph (because we strdup'd our own copy) but
120 // leave the terrain alone (it's a singleton and belongs to someone
126 void terrain_palette_del(struct terrain_palette *pal)
130 elem = pal->edit_head.next;
131 while (elem != &pal->edit_head) {
132 struct terrain_palette_entry *entry;
133 entry = outcast(elem, struct terrain_palette_entry, edit_list);
135 terrain_palette_entry_del(entry);
143 void terrain_palette_add(struct terrain_palette *pal, char *glyph,
146 struct terrain_palette_entry *entry;
147 int n = strlen(glyph);
149 entry = terrain_palette_entry_new(glyph, ter);
150 list_add_tail(&pal->lookup_head, &entry->lookup_list);
151 list_add_tail(&pal->edit_head, &entry->edit_list);
153 if (pal->widest_glyph < n)
154 pal->widest_glyph = n;
157 struct terrain_palette_entry *palette_entry(struct terrain_palette *palette, int n)
162 if (palette->num_entries < 1) {
163 dbg("palette_terrain_for_glyph() num_entries == 0\n");
166 if (n < 0 || n >= palette->num_entries) {
167 dbg("palette_terrain_for_glyph() called with out-of-bounds "\
172 elem = palette->edit_head.next;
178 return outcast(elem, struct terrain_palette_entry, edit_list);
181 char *palette_glyph(struct terrain_palette *palette, int n)
183 struct terrain_palette_entry *entry;
185 entry = palette_entry(palette, n);
191 struct terrain_palette_entry *
192 palette_entry_for_terrain(struct terrain_palette * pp, struct terrain * tt)
195 struct terrain_palette_entry *entry;
197 list_for_each(&pp->lookup_head, elem) {
198 entry = outcast(elem, struct terrain_palette_entry, lookup_list);
199 if (tt == entry->terrain)
203 return 0; // Did not find the terrain
206 char * palette_glyph_for_terrain (struct terrain_palette * pp, struct terrain * tt)
208 struct terrain_palette_entry *entry;
210 entry = palette_entry_for_terrain(pp, tt);
213 return 0; // Did not find the terrain
216 struct terrain *palette_terrain(struct terrain_palette *palette, int n)
218 struct terrain_palette_entry *entry;
220 entry = palette_entry(palette, n);
222 return entry->terrain;
226 struct terrain *palette_terrain_for_glyph(struct terrain_palette *palette,
230 struct terrain_palette_entry *entry;
232 list_for_each(&palette->lookup_head, elem) {
233 entry = outcast(elem, struct terrain_palette_entry, lookup_list);
234 if (! strcmp(glyph, entry->glyph)) {
235 /* Odds are good that we'll want this same terrain in
236 * the near future, so move it to the front of the list
237 * (if not already there) to improve performance during
239 if (elem != palette->lookup_head.next) {
241 list_add(&palette->lookup_head, elem);
243 return entry->terrain;
247 return 0; // Did not find the terrain
248 } // palette_terrain_for_glyph()
250 struct terrain_palette * palette_contains_terrain (struct terrain_palette *pp,
253 // The current user of this function is
254 // combat.c create_camping_map().
255 // It is used to find a palette (any palette)
256 // which contains a certain fill terrain.
258 // For other uses, I wonder if returning the index
259 // where it is found, or -1 for not found,
260 // would be more useful?
261 struct terrain_palette_entry *entry;
263 entry = palette_entry_for_terrain(pp, tt);
266 return 0; // Did not find the terrain
269 void palette_print(FILE * fp, int indent, struct terrain_palette *palette)
274 // (kern-mk-palette 'pal_expanded
276 // ;; There are 999 entries in this palette
277 // ;; The widest glyph is 4 characters
278 // (list "__" t_deep)
279 // (list ".." t_grass)
285 fprintf(fp, "(kern-mk-palette '%s\n", palette->tag);
286 indent += INDENTATION_FACTOR;
289 fprintf(fp, "(list\n");
290 indent += INDENTATION_FACTOR;
292 fprintf(fp, ";; There are %d entries in this palette\n", palette->num_entries);
294 fprintf(fp, ";; The widest glyph is %d characters\n", palette->widest_glyph);
296 list_for_each(&palette->edit_head, elem) {
297 struct terrain_palette_entry *entry;
298 entry = outcast(elem, struct terrain_palette_entry, edit_list);
299 palette_entry_print(fp, indent, entry);
304 indent -= INDENTATION_FACTOR;
308 indent -= INDENTATION_FACTOR;
310 fprintf(fp, ") ;; palette %s\n", palette->tag);