OSDN Git Service

日本語版
[nazghul-jp/nazghul-jp.git] / src / cmdwin.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
23 #include "cmdwin.h"
24
25 #include "cfg.h"
26 #include "common.h"
27 #include "console.h"
28 #include "dimensions.h"
29 #include "images.h"
30 #include "log.h"
31 #include "screen.h"
32 #include "sprite.h"
33
34 #include <assert.h>
35 #include <errno.h>
36 #include <stdarg.h>
37
38 #define CMDWIN_FRAG_MAX_LEN 64
39 #define CMDWIN_BUF_SZ       256
40
41 /* Fragment flags */
42 #define CMDWIN_FRAG_SEP     (1<<0)
43 #define CMDWIN_FRAG_MARK    (1<<1)
44
45 struct cmdwin_frag {
46         struct list list;
47         int flags;
48         char buf[CMDWIN_FRAG_MAX_LEN];
49 };
50
51 static struct {
52         SDL_Rect srect; /* screen rectangle (pixels) */
53         char *buf;      /* string buffer */
54         char *ptr;      /* next empty spot in buffer */
55         int blen;       /* buffer length, this should be bigger than slen and
56                          * is the max expected total size of any prompt (the
57                          * longest prompts may be too big for the window) */
58         int room;       /* empty space in buffer */
59         int slen;       /* printable string length (blen >= slen), this is
60                          * limited by the cmdwin UI size */
61         struct sprite *cursor_sprite;
62         struct list frags;
63 } cmdwin;
64
65 #ifdef DEBUG
66 static FILE *log = NULL;
67 #endif
68
69 struct dictionary *dictionary = NULL;
70
71 static inline void cmdwin_clear_no_repaint()
72 {
73         memset(cmdwin.buf, 0, cmdwin.blen);
74         cmdwin.ptr = cmdwin.buf;
75         cmdwin.room = cmdwin.blen;
76 }
77
78 static void cmdwin_cursor_sprite_init()
79 {
80         char *fname = cfg_get("cursor-image-filename");
81         struct images *ss_cursor = 0;
82
83         assert(fname);
84         ss_cursor = images_new(0, 8, 16, 1, 4, 0, 0, fname);
85         assert(ss_cursor);
86         cmdwin.cursor_sprite = sprite_new(0, 4, 0, 0, 0, ss_cursor);
87         assert(cmdwin.cursor_sprite);
88 }
89
90 static void cmdwin_clear_frag_stack(void)
91 {
92         struct list *entry;
93         
94         entry = cmdwin.frags.next;
95         while (entry != &cmdwin.frags) {
96                 struct cmdwin_frag *frag = (struct cmdwin_frag*)entry;
97                 entry = entry->next;
98                 list_remove(&frag->list);
99                 free(frag);
100         }
101 }
102
103 static struct cmdwin_frag *cmdwin_top()
104 {
105         if (list_empty(&cmdwin.frags))
106                 return 0;
107         return (struct cmdwin_frag*)cmdwin.frags.prev;
108 }
109
110 static void cmdwin_reprint_buffer(void)
111 {
112         struct list *entry;
113
114         /* Erase the buffer */
115         cmdwin_clear_no_repaint();
116
117         /* Loop over the fragments until out of room or out of fragments */
118         list_for_each(&cmdwin.frags, entry) {
119                 struct cmdwin_frag *frag = (struct cmdwin_frag*)entry;
120                 int n = 0;
121
122                 /* Append the fragment to the buffer. */
123                 if ((frag->flags & CMDWIN_FRAG_SEP)
124                     && (entry->next != &cmdwin.frags)) {
125                         /* Print a '-' after this fragment. */
126                         n = snprintf(cmdwin.ptr, cmdwin.room, "%s-", frag->buf);
127                 } else {
128                         /* No '-' afterwards. */
129                         n = snprintf(cmdwin.ptr, cmdwin.room, "%s", frag->buf);
130                 }
131                 n = min(n, cmdwin.room);
132                 cmdwin.room -= n;
133                 cmdwin.ptr += n;
134
135                 /* If out of room then stop, and backup the ptr to the last
136                  * entry in the buffer */
137                 if (!cmdwin.room) {
138                         cmdwin.ptr--;
139                         break;
140                 }
141
142         }
143 }
144
145 int cmdwin_init(void)
146 {
147         cmdwin_cursor_sprite_init();
148
149         list_init(&cmdwin.frags);
150
151         cmdwin.srect.x = CMD_X;
152         cmdwin.srect.y = CMD_Y;
153         cmdwin.srect.w = CMD_W;
154         cmdwin.srect.h = CMD_H;
155         cmdwin.slen = (CMD_W / ASCII_W) - 1; /* leave one space for the
156                                               * cursor */
157         cmdwin.blen = CMDWIN_BUF_SZ;
158         assert(cmdwin.blen >= cmdwin.slen);
159
160         cmdwin.buf = (char *) malloc(cmdwin.blen);
161         if (!cmdwin.buf)
162                 return -1;
163
164 #ifdef DEBUG
165         log = fopen(".cmdwin", "w+");
166         if (!log) {
167                 err(strerror(errno));
168                 return -1;
169         }
170 #endif
171
172         cmdwin_clear_no_repaint();
173         return 0;
174 }
175
176 static void cmdwin_vpush(int flags, const char *fmt, va_list args)
177 {
178         /* Allocate a new fragment */
179         struct cmdwin_frag *frag = (struct cmdwin_frag*)malloc(sizeof(*frag));
180         if (!frag) {
181                 warn("allocation failed");
182                 return;
183         }
184
185         frag->flags = flags;
186
187         /* default to empty string */
188         frag->buf[0] = 0;
189
190         /* Store the string in the fragment */
191         if (fmt != NULL) {
192                 vsnprintf(frag->buf, sizeof(frag->buf), fmt, args);
193         }
194
195         /* Push the fragment onto the stack */
196         list_add_tail(&cmdwin.frags, &frag->list);
197
198         /* Reprint the buffer with the new fragment */
199         cmdwin_reprint_buffer();
200
201         /* Update the display */
202         cmdwin_repaint();        
203 }
204
205 void cmdwin_spush(const char *fmt, ...)
206 {
207         va_list args;
208
209         va_start(args, fmt);
210         cmdwin_vpush(CMDWIN_FRAG_SEP, fmt, args);
211         va_end(args);
212         
213 }
214
215 void cmdwin_push(const char *fmt, ...)
216 {
217         va_list args;
218
219         va_start(args, fmt);
220         cmdwin_vpush(0, fmt, args);
221         va_end(args);
222 }
223
224 void cmdwin_push_mark()
225 {
226         cmdwin_vpush(CMDWIN_FRAG_MARK, 0, 0);
227 }
228
229 void cmdwin_pop(void)
230 {
231         struct cmdwin_frag *frag;
232
233         /* Fragment stack should not be empty. */
234         assert(! list_empty(&cmdwin.frags));
235
236         /* Remove the last fragment and free it. */
237         frag = (struct cmdwin_frag*)cmdwin.frags.prev;
238         list_remove(&frag->list);
239         free(frag);
240
241         /* Reprint the buffer without the fragment */
242         cmdwin_reprint_buffer();
243
244         /* Update the display */
245         cmdwin_repaint();
246 }
247
248 void cmdwin_pop_to_mark()
249 {
250         struct cmdwin_frag *frag = cmdwin_top();
251         while (frag && frag->flags != CMDWIN_FRAG_MARK) {
252                 cmdwin_pop();
253                 frag = cmdwin_top();
254         }
255
256         /* DON'T pop the mark itself */
257 }
258
259 void cmdwin_clear(void)
260 {
261         cmdwin_clear_frag_stack();
262         cmdwin_clear_no_repaint();
263         cmdwin_repaint();
264 }
265
266 void cmdwin_repaint_cursor(void)
267 {
268         SDL_Rect rect;
269
270         rect.x = cmdwin.srect.x;
271         rect.y = cmdwin.srect.y;
272         rect.w = ASCII_W;
273         rect.h = ASCII_H;
274
275         /* If the string is too big, show the last part of it (in other words,
276          * right-justify it) */
277         char *start = max(cmdwin.buf, cmdwin.ptr - cmdwin.slen);
278         rect.x += (cmdwin.ptr - start) * ASCII_W;
279
280         sprite_paint(cmdwin.cursor_sprite, 0, rect.x, rect.y);
281         screenUpdate(&rect);
282 }
283
284 void cmdwin_repaint(void)
285 {
286         /* If the string is too big, show the last part of it (in other words,
287          * right-justify it) */
288         char *start = max(cmdwin.buf, cmdwin.ptr - cmdwin.slen);
289         screenErase(&cmdwin.srect);
290         screenPrint(&cmdwin.srect, 0, start);
291         screenUpdate(&cmdwin.srect);
292         cmdwin_repaint_cursor();
293 }
294
295 void cmdwin_flush(void)
296 {
297         if (!strlen(cmdwin.buf))
298                 return;
299
300         log_msg("%s\n", cmdwin.buf);
301         cmdwin_clear();
302 }
303
304 int kana_to_english(char *kana, char *english, char *kanji)
305 {
306         int i;
307         
308         for (i = 0; dictionary[i].kana != NULL; i++) {
309                 if (!strcmp(kana, dictionary[i].kana)) {
310                         if (english) {
311                                 strcpy(english, dictionary[i].english);
312                         }
313                         if (kanji) {
314                                 strcpy(kanji, dictionary[i].kanji);
315                         }
316                         return true;
317                 }
318         }
319
320         if (english) {
321                 strcpy(english, kana);
322         }
323         if (kanji) {
324                 strcpy(kanji, kana);
325         }
326         return false;
327 }
328
329 int alpha_to_kana(int key, char *buf)
330 {
331         const static struct {
332                 const char *alpha;
333                 const char *kana;
334         } kana[] = {
335                 { "ayb", "¥Ó¥ã" },
336                 { "iyb", "¥Ó¥£" },
337                 { "uyb", "¥Ó¥å" },
338                 { "eyb", "¥Ó¥§" },
339                 { "oyb", "¥Ó¥ç" },
340                 { "ayc", "¥Á¥ã" },
341                 { "iyc", "¥Á¥£" },
342                 { "uyc", "¥Á¥å" },
343                 { "eyc", "¥Á¥§" },
344                 { "oyc", "¥Á¥ç" },
345                 { "ayd", "¥Â¥ã" },
346                 { "iyd", "¥Â¥£" },
347                 { "uyd", "¥Â¥å" },
348                 { "eyd", "¥Â¥§" },
349                 { "oyd", "¥Â¥ç" },
350                 { "ayf", "¥Õ¥ã" },
351                 { "iyf", "¥Õ¥£" },
352                 { "uyf", "¥Õ¥å" },
353                 { "eyf", "¥Õ¥§" },
354                 { "oyf", "¥Õ¥ç" },
355                 { "ayg", "¥®¥ã" },
356                 { "iyg", "¥®¥£" },
357                 { "uyg", "¥®¥å" },
358                 { "eyg", "¥®¥§" },
359                 { "oyg", "¥®¥ç" },
360                 { "ayh", "¥Ò¥ã" },
361                 { "iyh", "¥Ò¥£" },
362                 { "uyh", "¥Ò¥å" },
363                 { "eyh", "¥Ò¥§" },
364                 { "oyh", "¥Ò¥ç" },
365                 { "ayj", "¥¸¥ã" },
366                 { "iyj", "¥¸¥£" },
367                 { "uyj", "¥¸¥å" },
368                 { "eyj", "¥¸¥§" },
369                 { "oyj", "¥¸¥ç" },
370                 { "ayk", "¥­¥ã" },
371                 { "iyk", "¥­¥£" },
372                 { "uyk", "¥­¥å" },
373                 { "eyk", "¥­¥§" },
374                 { "oyk", "¥­¥ç" },
375                 { "aym", "¥ß¥ã" },
376                 { "iym", "¥ß¥£" },
377                 { "uym", "¥ß¥å" },
378                 { "eym", "¥ß¥§" },
379                 { "oym", "¥ß¥ç" },
380                 { "ayn", "¥Ë¥ã" },
381                 { "iyn", "¥Ë¥£" },
382                 { "uyn", "¥Ë¥å" },
383                 { "eyn", "¥Ë¥§" },
384                 { "oyn", "¥Ë¥ç" },
385                 { "ayp", "¥Ô¥ã" },
386                 { "iyp", "¥Ô¥£" },
387                 { "uyp", "¥Ô¥å" },
388                 { "eyp", "¥Ô¥§" },
389                 { "oyp", "¥Ô¥ç" },
390                 { "ayq", "¥¯¥¡" },
391                 { "iyq", "¥¯¥£" },
392                 { "uyq", "¥¯¥¥" },
393                 { "eyq", "¥¯¥§" },
394                 { "oyq", "¥¯¥©" },
395                 { "ayr", "¥ê¥ã" },
396                 { "iyr", "¥ê¥£" },
397                 { "uyr", "¥ê¥å" },
398                 { "eyr", "¥ê¥§" },
399                 { "oyr", "¥ê¥ç" },
400                 { "ays", "¥·¥ã" },
401                 { "iys", "¥·¥£" },
402                 { "uys", "¥·¥å" },
403                 { "eys", "¥·¥§" },
404                 { "oys", "¥·¥ç" },
405                 { "ayt", "¥Á¥ã" },
406                 { "iyt", "¥Á¥£" },
407                 { "uyt", "¥Á¥å" },
408                 { "eyt", "¥Á¥§" },
409                 { "oyt", "¥Á¥ç" },
410                 { "ayv", "¥ô¥ã" },
411                 { "iyv", "¥ô¥£" },
412                 { "uyv", "¥ô¥å" },
413                 { "eyv", "¥ô¥§" },
414                 { "oyv", "¥ô¥ç" },
415                 { "ayx", "¥ã" },
416                 { "iyx", "¥£" },
417                 { "uyx", "¥å" },
418                 { "eyx", "¥§" },
419                 { "oyx", "¥ç" },
420                 { "ayz", "¥¸¥ã" },
421                 { "iyz", "¥¸¥£" },
422                 { "uyz", "¥¸¥å" },
423                 { "eyz", "¥¸¥§" },
424                 { "oyz", "¥¸¥ç" },
425                 { "ahc", "¥Á¥ã" },
426                 { "ihc", "¥Á" },
427                 { "uhc", "¥Á¥å" },
428                 { "ehc", "¥Á¥§" },
429                 { "ohc", "¥Á¥ç" },
430                 { "ahd", "¥Ç¥ã" },
431                 { "ihd", "¥Ç¥£" },
432                 { "uhd", "¥Ç¥å" },
433                 { "ehd", "¥Ç¥§" },
434                 { "ohd", "¥Ç¥ç" },
435                 { "ahp", "¥Õ¥¡" },
436                 { "ihp", "¥Õ¥£" },
437                 { "uhp", "¥Õ" },
438                 { "ehp", "¥Õ¥§" },
439                 { "ohp", "¥Õ¥©" },
440                 { "ahs", "¥·¥ã" },
441                 { "ihs", "¥·" },
442                 { "uhs", "¥·¥å" },
443                 { "ehs", "¥·¥§" },
444                 { "ohs", "¥·¥ç" },
445                 { "aht", "¥Æ¥ã" },
446                 { "iht", "¥Æ¥£" },
447                 { "uht", "¥Æ¥å" },
448                 { "eht", "¥Æ¥§" },
449                 { "oht", "¥Æ¥ç" },
450                 { "ahw", "¥¦¥¡" },
451                 { "ihw", "¥¦¥£" },
452                 { "uhw", "¥¦" },
453                 { "ehw", "¥¦¥§" },
454                 { "ohw", "¥¦¥©" },
455                 { "ast", "¥Ä¥¡" },
456                 { "ist", "¥Ä¥£" },
457                 { "ust", "¥Ä" },
458                 { "est", "¥Ä¥§" },
459                 { "ost", "¥Ä¥©" },
460                 { "ab", "¥Ð" },
461                 { "ib", "¥Ó" },
462                 { "ub", "¥Ö" },
463                 { "eb", "¥Ù" },
464                 { "ob", "¥Ü" },
465                 { "ac", "¥«" },
466                 { "ic", "¥­" },
467                 { "uc", "¥¯" },
468                 { "ec", "¥±" },
469                 { "oc", "¥³" },
470                 { "ad", "¥À" },
471                 { "id", "¥Â" },
472                 { "ud", "¥Å" },
473                 { "ed", "¥Ç" },
474                 { "od", "¥É" },
475                 { "af", "¥Õ¥¡" },
476                 { "if", "¥Õ¥£" },
477                 { "uf", "¥Õ" },
478                 { "ef", "¥Õ¥§" },
479                 { "of", "¥Õ¥©" },
480                 { "ag", "¥¬" },
481                 { "ig", "¥®" },
482                 { "ug", "¥°" },
483                 { "eg", "¥²" },
484                 { "og", "¥´" },
485                 { "ah", "¥Ï" },
486                 { "ih", "¥Ò" },
487                 { "uh", "¥Õ" },
488                 { "eh", "¥Ø" },
489                 { "oh", "¥Û" },
490                 { "aj", "¥¸¥ã" },
491                 { "ij", "¥¸" },
492                 { "uj", "¥¸¥å" },
493                 { "ej", "¥¸¥§" },
494                 { "oj", "¥¸¥ç" },
495                 { "ak", "¥«" },
496                 { "ik", "¥­" },
497                 { "uk", "¥¯" },
498                 { "ek", "¥±" },
499                 { "ok", "¥³" },
500                 { "al", "¥¡" },
501                 { "il", "¥£" },
502                 { "ul", "¥¥" },
503                 { "el", "¥§" },
504                 { "ol", "¥©" },
505                 { "am", "¥Þ" },
506                 { "im", "¥ß" },
507                 { "um", "¥à" },
508                 { "em", "¥á" },
509                 { "om", "¥â" },
510                 { "an", "¥Ê" },
511                 { "in", "¥Ë" },
512                 { "un", "¥Ì" },
513                 { "en", "¥Í" },
514                 { "on", "¥Î" },
515                 { "nn", "¥ó" },
516                 { "ap", "¥Ñ" },
517                 { "ip", "¥Ô" },
518                 { "up", "¥×" },
519                 { "ep", "¥Ú" },
520                 { "op", "¥Ý" },
521                 { "aq", "¥¯¥¡" },
522                 { "iq", "¥¯¥£" },
523                 { "uq", "¥¯¥¥" },
524                 { "eq", "¥¯¥§" },
525                 { "oq", "¥¯¥©" },
526                 { "ar", "¥é" },
527                 { "ir", "¥ê" },
528                 { "ur", "¥ë" },
529                 { "er", "¥ì" },
530                 { "or", "¥í" },
531                 { "as", "¥µ" },
532                 { "is", "¥·" },
533                 { "us", "¥¹" },
534                 { "es", "¥»" },
535                 { "os", "¥½" },
536                 { "at", "¥¿" },
537                 { "it", "¥Á" },
538                 { "ut", "¥Ä" },
539                 { "et", "¥Æ" },
540                 { "ot", "¥È" },
541                 { "av", "¥ô¥¡" },
542                 { "iv", "¥ô¥£" },
543                 { "uv", "¥ô" },
544                 { "ev", "¥ô¥§" },
545                 { "ov", "¥ô¥©" },
546                 { "aw", "¥ï" },
547                 { "iw", "¥ð" },
548                 { "uw", "¥¦" },
549                 { "ew", "¥¦¥§" },
550                 { "ow", "¥ò" },
551                 { "ax", "¥¡" },
552                 { "ix", "¥£" },
553                 { "ux", "¥¥" },
554                 { "ex", "¥§" },
555                 { "ox", "¥©" },
556                 { "ay", "¥ä" },
557                 { "iy", "¥¤" },
558                 { "uy", "¥æ" },
559                 { "ey", "¥¤¥§" },
560                 { "oy", "¥è" },
561                 { "az", "¥¶" },
562                 { "iz", "¥¸" },
563                 { "uz", "¥º" },
564                 { "ez", "¥¼" },
565                 { "oz", "¥¾" },
566                 { "'n", "¥ó" },
567                 { "a", "¥¢" },
568                 { "i", "¥¤" },
569                 { "u", "¥¦" },
570                 { "e", "¥¨" },
571                 { "o", "¥ª" },
572                 { " ", "¡¡" },
573                 { "!", "¡ª" },
574                 { "\"", "¡É" },
575                 { "#", "¡ô" },
576                 { "$", "¡ð" },
577                 { "%", "¡ó" },
578                 { "&", "¡õ" },
579                 { "'", "¡Ç" },
580                 { "(", "¡Ê" },
581                 { ")", "¡Ë" },
582                 { "*", "¡ö" },
583                 { "+", "¡Ü" },
584                 { ",", "¡¢" },
585                 { "-", "¡¼" },
586                 { ".", "¡£" },
587                 { "/", "¡¦" },
588                 { "0", "£°" },
589                 { "1", "£±" },
590                 { "2", "£²" },
591                 { "3", "£³" },
592                 { "4", "£´" },
593                 { "5", "£µ" },
594                 { "6", "£¶" },
595                 { "7", "£·" },
596                 { "8", "£¸" },
597                 { "9", "£¹" },
598                 { ":", "¡§" },
599                 { ";", "¡¨" },
600                 { "<", "¡ã" },
601                 { "=", "¡á" },
602                 { ">", "¡ä" },
603                 { "?", "¡©" },
604                 { "@", "¡÷" },
605                 { "[", "¡Ö" },
606                 { "\\", "¡ï" },
607                 { "]", "¡×" },
608                 { "^", "¡°" },
609                 { "_", "¡²" },
610                 { "`", "¡Æ" },
611                 { "{", "¡Ð" },
612                 { "|", "¡Ã" },
613                 { "}", "¡Ñ" },
614                 { "~", "¡Á" },
615                 { NULL, NULL }
616         };
617         static int roman = true;
618         static char roman_buf[] = { "\0\0\0\0\0" };
619         int i;
620         int len;
621         int n;
622         int soku;
623
624         if (key == 0) { /* Clear roman buffer */
625                 memset(roman_buf, 0, sizeof(roman_buf));
626                 return 0;
627         }
628         if (key == -1) { /* Roman mode off */
629                 roman = false;
630                 return 0;
631         }
632         if (key == '\t') { /* Toggle roman mode */
633                 roman = !roman;
634                 memset(roman_buf, 0, sizeof(roman_buf));
635                 return 0;
636         }
637
638         if (!roman || (key & 0x80) || !isprint(key)) {
639                 memset(roman_buf, 0, sizeof(roman_buf));
640                 return 0;
641         }
642
643         memmove(roman_buf + 1, roman_buf, sizeof (roman_buf) - 1);
644         roman_buf[0] = key;
645
646         for (i = 0; kana[i].alpha != NULL; i++) {
647                 len = strlen(kana[i].alpha);
648
649                 if (!strncasecmp(roman_buf, kana[i].alpha, len)) {
650                         soku = (roman_buf[len - 1] == roman_buf[len]);
651
652                         if(soku)
653                                 n = (roman_buf[len + 1] == 'n');
654                         else
655                                 n = (roman_buf[len] == 'n');
656
657                         sprintf (buf, "%.*s%s%s%s", len + n + soku, "\b\b\b\b\b", (n ? "¥ó": ""), (soku ? "¥Ã": ""), kana[i].kana);
658
659                         memset(roman_buf, 0, sizeof (roman_buf));
660                         return strlen(buf);
661                 }
662         }
663         return 0;
664 }