OSDN Git Service

日本語版
[nazghul-jp/nazghul-jp.git] / src / foogod.c
1 //
2 // nazghul - an old-school RPG engine
3 // Copyright (C) 2002, 2003 Gordon McNutt
4 //
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)
8 // any later version.
9 //
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
13 // more details.
14 //
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
18 //
19 // Gordon McNutt
20 // gmcnutt@users.sourceforge.net
21 //
22 #include "foogod.h"
23 #include "status.h"  // for status_get_h()
24 #include "stdarg.h"
25 #include "screen.h"
26 #include "common.h"
27 #include "player.h"
28 #include "wq.h"
29 #include "combat.h"
30 #include "session.h"
31 #include "vehicle.h"
32 #include "sprite.h"
33 #include "images.h"
34 #include "effect.h"
35 #include "cfg.h"
36
37 #include <SDL_image.h>
38
39 #define FOOGOD_CHARS_PER_LINE STAT_CHARS_PER_LINE
40 #define FOOGOD_MAX_TITLE_LEN (FOOGOD_CHARS_PER_LINE-2)
41
42 struct foogod {
43         SDL_Rect screenRect;
44         SDL_Rect turnRect;
45         SDL_Rect foodRect;
46         SDL_Rect combatRect;
47         SDL_Rect goldRect;
48         SDL_Rect hullRect;
49         SDL_Rect effectsRect;
50         SDL_Rect titleRect;
51         foogod_mode_t mode;
52         int hintLen;
53         char *hintText;
54         unsigned int progress_bar_max_steps;
55         unsigned int progress_bar_steps;
56         char *progress_bar_title;
57         struct images *image;
58         struct sprite *progress_bar_sprites[3];
59         char title[FOOGOD_MAX_TITLE_LEN+1];
60 } Foogod;
61
62 static void foogod_repaint_title(void)
63 {
64     screenErase(&Foogod.titleRect);
65     screenPrint(&Foogod.titleRect, SP_CENTERED | SP_ONBORDER, "%s", Foogod.title);
66     screenUpdate(&Foogod.titleRect);
67 }
68
69 static int foogod_load_progress_bar_sprites(void)
70 {
71         int i;
72         char *fname = cfg_get("progress-bar-image-filename");
73
74         if (!fname) {
75                 return -1;
76         }
77
78         Foogod.image = (struct images *)calloc(1, sizeof(*Foogod.image));
79         assert(Foogod.image);
80
81         Foogod.image = images_new(0, 8, 16, 1, 3, 0, 0, fname);
82         if (!Foogod.image) {
83             err("images_new() failed for file '%s': '%s'\n", fname, SDL_GetError() );
84             goto fail;
85         }
86
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");
90                         goto fail;
91                 }
92         }
93
94         return 0;
95
96  fail:
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;
101                 }
102         }
103
104         if (Foogod.image) {
105                 free(Foogod.image);
106                 Foogod.image = 0;
107         }
108
109         return -1;
110 }
111
112 void foogodAdvanceTurns(void)
113 {
114         foogodRepaint();
115 }
116
117 int foogodInit(void)
118 {
119         memset(&Foogod, 0, sizeof(Foogod));
120
121         Foogod.mode = FOOGOD_DEFAULT;
122
123         // hint text buffer
124         Foogod.hintLen = FOOGOD_W / ASCII_W;
125         Foogod.hintText = (char*)malloc(Foogod.hintLen+1);
126         memset(Foogod.hintText, 0, Foogod.hintLen);
127
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;
132     
133         // turns
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;
138
139         // food
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;
144
145         // hull
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;
150
151         // effects
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;
156
157         // gold
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;
162
163         // mode
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;
168
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;
174
175         return foogod_load_progress_bar_sprites();
176 }
177
178 static void foogodPaintEffect(SDL_Rect *rect, struct sprite *sprite)
179 {
180         sprite_paint(sprite, 0, rect->x, rect->y);
181         rect->x += ASCII_W;
182 }
183
184 static int foogod_paint_effect_wrapper(struct hook_entry *entry, void *data)
185 {
186         SDL_Rect *rect = (SDL_Rect*)data;
187         struct effect *effect = entry->effect;
188         if (effect->sprite) {
189                 foogodPaintEffect(rect, effect->sprite);
190         }
191         return 0;
192 }
193
194 static void foogodPaintEffects()
195 {
196         SDL_Rect rect = Foogod.effectsRect;
197
198         /* Effects well-known to the engine */
199         if (TimeStop) {
200                 foogodPaintEffect(&rect, time_stop_effect_sprite());
201         }
202
203         if (Reveal) {
204                 foogodPaintEffect(&rect, reveal_effect_sprite());
205         }
206
207         if (Quicken) {
208                 foogodPaintEffect(&rect, quicken_effect_sprite());
209         }
210
211         if (MagicNegated) {
212                 foogodPaintEffect(&rect, magic_negated_effect_sprite());
213         }
214
215         if (XrayVision) {
216                 foogodPaintEffect(&rect, xray_vision_effect_sprite());
217         }
218
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);
222         }
223
224
225 }
226
227 static void foogodPaintSessionInfo()
228 {
229         screenPrint(&Foogod.turnRect, 0, "²ó¿ô: %d", session_get_turn_count());
230         foogodPaintEffects();
231
232         if (player_party) {
233                 screenPrint(&Foogod.foodRect, 0, "¿©ÎÁ: %d", 
234                             player_party->food);
235                 screenPrint(&Foogod.goldRect, SP_RIGHTJUSTIFIED, "¶â: %d",  
236                             player_party->gold);
237                 if (player_party->getVehicle()) {
238                         screenPrint(&Foogod.hullRect, 0, "Á¥ÂÎ: %d", 
239                                     player_party->getVehicle()->getHp());
240                 }
241         }
242 }
243
244 static void foogod_progress_bar_paint()
245 {
246         int i;
247         int ticks;
248         int max_ticks;
249         SDL_Rect rect = Foogod.screenRect;
250
251         /* title */
252         rect.h = ASCII_H;
253         screenPrint(&rect, SP_CENTERED, Foogod.progress_bar_title);
254         
255         /* bar */
256         rect.y += ASCII_H;
257         rect.w = ASCII_W;
258
259         /* (ticks : maxTicks) = (steps : totalSteps) */
260         max_ticks = (Foogod.screenRect.w / ASCII_W);
261
262         /* Subtract two for the edges pieces of the progress bar. */
263         max_ticks -= 2;
264
265         ticks = (Foogod.progress_bar_steps * max_ticks) 
266                 / Foogod.progress_bar_max_steps;
267
268         /* Paint the left edge. */
269         sprite_paint(Foogod.progress_bar_sprites[0], 0, rect.x, rect.y);
270         rect.x += ASCII_W;
271
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, ".");
276                 rect.x += ASCII_W;
277         }
278
279         /* Paint the right edge. */
280         sprite_paint(Foogod.progress_bar_sprites[2], 0, rect.x, rect.y);
281 }
282
283 void foogodRepaint(void)
284 {
285         screenErase(&Foogod.screenRect);
286
287         switch (Foogod.mode) {
288
289         default:
290         case FOOGOD_DEFAULT:
291                 if (Session) {
292                         foogodPaintSessionInfo();
293                 }
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 = "";
300                 }
301                 screenPrint(&Foogod.combatRect, SP_RIGHTJUSTIFIED, 
302                             "ÀïÆ®¾õÂÖ: %s", combat_state_jp);
303                 break;
304
305         case FOOGOD_HINT:
306                 screenPrint(&Foogod.screenRect, 0, Foogod.hintText);
307                 break;
308
309         case FOOGOD_PROGRESS_BAR:
310                 foogod_progress_bar_paint();
311                 break;
312         }
313
314         foogod_repaint_title();
315         screenUpdate(&Foogod.screenRect);
316 }
317
318 void foogod_set_y(int y)
319 {
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;
328 }
329
330 int foogod_get_y(void)
331 {
332         return Foogod.screenRect.y;
333 }
334
335 int foogod_get_h(void)
336 {
337         return (FOOGOD_H + BORDER_H);
338 }
339
340 void foogodSetMode(foogod_mode_t mode)
341 {
342         Foogod.mode = mode;
343         foogodRepaint();
344 }
345
346 void foogodSetHintText(const char *text)
347 {
348         strncpy(Foogod.hintText, text, Foogod.hintLen);
349 }
350
351 void foogod_progress_bar_set_title(const char *title)
352 {
353         if (Foogod.progress_bar_title) {
354                 free(Foogod.progress_bar_title);
355                 Foogod.progress_bar_title = 0;
356         }
357
358         if (title) {
359                 Foogod.progress_bar_title = strdup(title);
360         }
361 }
362
363 void foogod_progress_bar_set_max_steps(unsigned int val)
364 {
365         Foogod.progress_bar_max_steps = val;
366         Foogod.progress_bar_steps = 0;
367 }
368
369 void foogod_progress_bar_advance(unsigned int steps)
370 {
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;
374         }
375 }
376
377 void foogod_progress_bar_finish()
378 {
379         dbg("Foogod.progress_bar_steps=%d\n", Foogod.progress_bar_steps);
380         Foogod.progress_bar_steps = Foogod.progress_bar_max_steps;
381 }
382
383 void foogod_set_title(const char *fmt, ...)
384 {
385     va_list args;
386     va_start(args, fmt);
387     vsnprintf(Foogod.title, FOOGOD_MAX_TITLE_LEN, fmt, args);
388     va_end(args);
389 }
390