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
23 #include "status.h" // for status_get_h()
37 #include <SDL_image.h>
39 #define FOOGOD_CHARS_PER_LINE STAT_CHARS_PER_LINE
40 #define FOOGOD_MAX_TITLE_LEN (FOOGOD_CHARS_PER_LINE-2)
54 unsigned int progress_bar_max_steps;
55 unsigned int progress_bar_steps;
56 char *progress_bar_title;
58 struct sprite *progress_bar_sprites[3];
59 char title[FOOGOD_MAX_TITLE_LEN+1];
62 static void foogod_repaint_title(void)
64 screenErase(&Foogod.titleRect);
65 screenPrint(&Foogod.titleRect, SP_CENTERED | SP_ONBORDER, "%s", Foogod.title);
66 screenUpdate(&Foogod.titleRect);
69 static int foogod_load_progress_bar_sprites(void)
72 char *fname = cfg_get("progress-bar-image-filename");
78 Foogod.image = (struct images *)calloc(1, sizeof(*Foogod.image));
81 Foogod.image = images_new(0, 8, 16, 1, 3, 0, 0, fname);
83 err("images_new() failed for file '%s': '%s'\n", fname, SDL_GetError() );
87 for (i = 0; i < 3; i++) {
88 if (!(Foogod.progress_bar_sprites[i] = sprite_new(0, 1, i, 0, 0, Foogod.image))) {
89 err("sprite_new() failed\n");
97 for (i = 0; i < 3; i++) {
98 if ((Foogod.progress_bar_sprites[i])) {
99 sprite_del(Foogod.progress_bar_sprites[i]);
100 Foogod.progress_bar_sprites[i] = 0;
112 void foogodAdvanceTurns(void)
119 memset(&Foogod, 0, sizeof(Foogod));
121 Foogod.mode = FOOGOD_DEFAULT;
124 Foogod.hintLen = FOOGOD_W / ASCII_W;
125 Foogod.hintText = (char*)malloc(Foogod.hintLen+1);
126 memset(Foogod.hintText, 0, Foogod.hintLen);
128 Foogod.screenRect.x = FOOGOD_X;
129 Foogod.screenRect.w = FOOGOD_W;
130 foogod_set_y(STAT_Y + status_get_h() + BORDER_H);
131 Foogod.screenRect.h = FOOGOD_H;
134 Foogod.turnRect.x = FOOGOD_X;
135 Foogod.turnRect.y = foogod_get_y();
136 Foogod.turnRect.w = FOOGOD_W / 3;
137 Foogod.turnRect.h = ASCII_H;
140 Foogod.foodRect.x = FOOGOD_X;
141 Foogod.foodRect.y = foogod_get_y() + ASCII_H;
142 Foogod.foodRect.w = FOOGOD_W / 3;
143 Foogod.foodRect.h = ASCII_H;
146 Foogod.hullRect.x = FOOGOD_X + FOOGOD_W / 3;
147 Foogod.hullRect.y = foogod_get_y();
148 Foogod.hullRect.w = FOOGOD_W / 3;
149 Foogod.hullRect.h = ASCII_H;
152 Foogod.effectsRect.x = FOOGOD_X + FOOGOD_W / 3;
153 Foogod.effectsRect.y = foogod_get_y() + ASCII_H;
154 Foogod.effectsRect.w = FOOGOD_W / 3;
155 Foogod.effectsRect.h = ASCII_H;
158 Foogod.goldRect.w = FOOGOD_W / 3;
159 Foogod.goldRect.x = FOOGOD_X + FOOGOD_W - FOOGOD_W / 3;
160 Foogod.goldRect.y = foogod_get_y();
161 Foogod.goldRect.h = ASCII_H;
164 Foogod.combatRect.w = FOOGOD_W / 3;
165 Foogod.combatRect.x = FOOGOD_X + FOOGOD_W - FOOGOD_W / 3;
166 Foogod.combatRect.y = foogod_get_y() + ASCII_H;
167 Foogod.combatRect.h = ASCII_H;
169 // title (on the border)
170 Foogod.titleRect.x = FOOGOD_X;
171 Foogod.titleRect.y = foogod_get_y() - BORDER_H;
172 Foogod.titleRect.w = FOOGOD_W;
173 Foogod.titleRect.h = BORDER_H;
175 return foogod_load_progress_bar_sprites();
178 static void foogodPaintEffect(SDL_Rect *rect, struct sprite *sprite)
180 sprite_paint(sprite, 0, rect->x, rect->y);
184 static int foogod_paint_effect_wrapper(struct hook_entry *entry, void *data)
186 SDL_Rect *rect = (SDL_Rect*)data;
187 struct effect *effect = entry->effect;
188 if (effect->sprite) {
189 foogodPaintEffect(rect, effect->sprite);
194 static void foogodPaintEffects()
196 SDL_Rect rect = Foogod.effectsRect;
198 /* Effects well-known to the engine */
200 foogodPaintEffect(&rect, time_stop_effect_sprite());
204 foogodPaintEffect(&rect, reveal_effect_sprite());
208 foogodPaintEffect(&rect, quicken_effect_sprite());
212 foogodPaintEffect(&rect, magic_negated_effect_sprite());
216 foogodPaintEffect(&rect, xray_vision_effect_sprite());
219 /* Custom effects added by the game */
220 for (int i = 0; i < OBJ_NUM_HOOKS; i++) {
221 player_party->hookForEach(i, foogod_paint_effect_wrapper, 0);
227 static void foogodPaintSessionInfo()
229 screenPrint(&Foogod.turnRect, 0, "²ó¿ô: %d", session_get_turn_count());
230 foogodPaintEffects();
233 screenPrint(&Foogod.foodRect, 0, "¿©ÎÁ: %d",
235 screenPrint(&Foogod.goldRect, SP_RIGHTJUSTIFIED, "¶â: %d",
237 if (player_party->getVehicle()) {
238 screenPrint(&Foogod.hullRect, 0, "Á¥ÂÎ: %d",
239 player_party->getVehicle()->getHp());
244 static void foogod_progress_bar_paint()
249 SDL_Rect rect = Foogod.screenRect;
253 screenPrint(&rect, SP_CENTERED, Foogod.progress_bar_title);
259 /* (ticks : maxTicks) = (steps : totalSteps) */
260 max_ticks = (Foogod.screenRect.w / ASCII_W);
262 /* Subtract two for the edges pieces of the progress bar. */
265 ticks = (Foogod.progress_bar_steps * max_ticks)
266 / Foogod.progress_bar_max_steps;
268 /* Paint the left edge. */
269 sprite_paint(Foogod.progress_bar_sprites[0], 0, rect.x, rect.y);
272 /* Paint the center. */
273 for (i = 0; i < ticks; i++) {
274 sprite_paint(Foogod.progress_bar_sprites[1], 0, rect.x, rect.y);
275 //screenPrint(&rect, 0, ".");
279 /* Paint the right edge. */
280 sprite_paint(Foogod.progress_bar_sprites[2], 0, rect.x, rect.y);
283 void foogodRepaint(void)
285 screenErase(&Foogod.screenRect);
287 switch (Foogod.mode) {
292 foogodPaintSessionInfo();
294 const char *combat_state_jp;
295 switch (combatGetState()) {
296 case 'N': combat_state_jp = "̵"; break;
297 case 'Y': combat_state_jp = "Àï"; break;
298 case 'V': combat_state_jp = "¾¡"; break;
299 default: combat_state_jp = "";
301 screenPrint(&Foogod.combatRect, SP_RIGHTJUSTIFIED,
302 "ÀïÆ®¾õÂÖ: %s", combat_state_jp);
306 screenPrint(&Foogod.screenRect, 0, Foogod.hintText);
309 case FOOGOD_PROGRESS_BAR:
310 foogod_progress_bar_paint();
314 foogod_repaint_title();
315 screenUpdate(&Foogod.screenRect);
318 void foogod_set_y(int y)
320 Foogod.screenRect.y = y;
321 Foogod.turnRect.y = y;
322 Foogod.foodRect.y = y + ASCII_H;
323 Foogod.goldRect.y = y;
324 Foogod.combatRect.y = y + ASCII_H;
325 Foogod.hullRect.y = y;
326 Foogod.effectsRect.y = y + ASCII_H;
327 Foogod.titleRect.y = y - BORDER_H;
330 int foogod_get_y(void)
332 return Foogod.screenRect.y;
335 int foogod_get_h(void)
337 return (FOOGOD_H + BORDER_H);
340 void foogodSetMode(foogod_mode_t mode)
346 void foogodSetHintText(const char *text)
348 strncpy(Foogod.hintText, text, Foogod.hintLen);
351 void foogod_progress_bar_set_title(const char *title)
353 if (Foogod.progress_bar_title) {
354 free(Foogod.progress_bar_title);
355 Foogod.progress_bar_title = 0;
359 Foogod.progress_bar_title = strdup(title);
363 void foogod_progress_bar_set_max_steps(unsigned int val)
365 Foogod.progress_bar_max_steps = val;
366 Foogod.progress_bar_steps = 0;
369 void foogod_progress_bar_advance(unsigned int steps)
371 Foogod.progress_bar_steps += steps;
372 if (Foogod.progress_bar_steps > Foogod.progress_bar_max_steps) {
373 Foogod.progress_bar_steps = Foogod.progress_bar_max_steps;
377 void foogod_progress_bar_finish()
379 dbg("Foogod.progress_bar_steps=%d\n", Foogod.progress_bar_steps);
380 Foogod.progress_bar_steps = Foogod.progress_bar_max_steps;
383 void foogod_set_title(const char *fmt, ...)
387 vsnprintf(Foogod.title, FOOGOD_MAX_TITLE_LEN, fmt, args);