OSDN Git Service

Merge remote-tracking branch 'remotes/origin/feature/Refactor-Unnecessary-Files-Remov...
[hengband/hengband.git] / src / main-cap.c
1 /* File: main-cap.c */
2
3 /* Purpose: Support for "term.c" using "termcap" calls */
4
5 #include "system/angband.h"
6 #include "io/exit-panic.h"
7
8 #ifdef USE_CAP
9
10
11 /*
12  * This file is a total hack, but is often very helpful.  :-)
13  *
14  * This file allows use of the terminal without requiring the
15  * "curses" routines.  In fact, if "USE_HARDCODE" is defined,
16  * this file will attempt to use various hard-coded "vt100"
17  * escape sequences to also avoid the use of the "termcap"
18  * routines.  I do not know if this will work on System V.
19  *
20  * This file is intended for use only on those machines which are
21  * unable, for whatever reason, to compile the "main-gcu.c" file,
22  * but which seem to be able to support the "termcap" library, or
23  * which at least seem able to support "vt100" terminals.
24  *
25  * Large portions of this file were stolen from "main-gcu.c"
26  *
27  * This file incorrectly handles output to column 80, I think.
28  */
29
30
31 /*
32  * Require a "system"
33  */
34 #if !defined(USE_TERMCAP) && !defined(USE_HARDCODE)
35 # define USE_TERMCAP
36 #endif
37
38 /*
39  * Hack -- try to guess which systems use what commands
40  * Hack -- allow one of the "USE_Txxxxx" flags to be pre-set.
41  * Mega-Hack -- try to guess when "POSIX" is available.
42  * If the user defines two of these, we will probably crash.
43  */
44 #  if defined(_POSIX_VERSION)
45 #   define USE_TPOSIX
46 #  else
47 #   if defined(linux)
48 #    define USE_TERMIO
49 #   else
50 #    define USE_TCHARS
51 #   endif
52 #  endif
53
54 /*
55  * POSIX stuff
56  */
57 #ifdef USE_TPOSIX
58 # include <sys/ioctl.h>
59 # include <termios.h>
60 #endif
61
62 /*
63  * One version needs these files
64  */
65 #ifdef USE_TERMIO
66 # include <sys/ioctl.h>
67 # include <termio.h>
68 #endif
69
70 /*
71  * The other needs these files
72  */
73 #ifdef USE_TCHARS
74 # include <sys/ioctl.h>
75 # include <sys/resource.h>
76 # include <sys/param.h>
77 # include <sys/file.h>
78 # include <sys/types.h>
79 #endif
80
81
82 /*
83  * XXX XXX Hack -- POSIX uses "O_NONBLOCK" instead of "O_NDELAY"
84  *
85  * They should both work due to the "(i != 1)" test in the code
86  * which checks for the result of the "read()" command.
87  */
88 #ifndef O_NDELAY
89 # define O_NDELAY O_NONBLOCK
90 #endif
91
92
93
94
95 #ifdef USE_TERMCAP
96
97 /*
98  * Termcap string information
99  */
100
101 static char blob[1024];         /* The "termcap" entry */
102 static char area[1024];         /* The string extraction buffer */
103 static char *next = area;       /* The current "index" into "area" */
104 static char *desc;              /* The terminal name */
105
106 #endif
107
108
109 /*
110  * Pointers into the "area"
111  */
112
113 static char *cm;        /* Move cursor */
114 static char *ch;        /* Move cursor to horizontal location */
115 static char *cv;        /* Move cursor to vertical location */
116 static char *ho;        /* Move cursor to top left */
117 static char *ll;        /* Move cursor to bottom left */
118 static char *cs;        /* Set scroll area */
119 static char *cl;        /* Clear screen */
120 static char *cd;        /* Clear to end of display */
121 static char *ce;        /* Clear to end of line */
122 static char *cr;        /* Move to start of line */
123 static char *so;        /* Turn on standout */
124 static char *se;        /* Turn off standout */
125 static char *md;        /* Turn on bold */
126 static char *me;        /* Turn off bold */
127 static char *vi;        /* Cursor - invisible */
128 static char *ve;        /* Cursor - normal */
129 static char *vs;        /* Cursor - bright */
130
131
132 /*
133  * State variables
134  */
135
136 static int rows;        /* Screen size (Y) */
137 static int cols;        /* Screen size (X) */
138 static int curx;        /* Cursor location (X) */
139 static int cury;        /* Cursor location (Y) */
140 static int curv;        /* Cursor visibility */
141
142
143 /*
144  * Extern functions
145  */
146 extern char *getenv();
147 extern char *tgoto();
148 extern char *tgetstr();
149
150
151 /*
152  * Write some chars to the terminal
153  */
154 static void ewrite(char *str)
155 {
156         int numtowrite, numwritten;
157
158         /* See how much work we have */
159         numtowrite = strlen(str);
160
161         /* Write until done */
162         while (numtowrite > 0)
163         {
164                 /* Try to write the chars */
165                 numwritten = write(1, str, numtowrite);
166
167                 /* Handle FIFOs and EINTR */
168                 if (numwritten < 0) numwritten = 0;
169
170                 /* See what we completed */
171                 numtowrite -= numwritten;
172                 str += numwritten;
173
174                 /* Hack -- sleep if not done */
175                 if (numtowrite > 0) sleep(1);
176         }
177 }
178
179
180
181 #ifdef USE_TERMCAP
182
183 static char write_buffer[128];
184 static char *write_buffer_ptr;
185
186 static void output_one(char c)
187 {
188         *write_buffer_ptr++ = c;
189 }
190
191 static void tp(char *s)
192 {
193         /* Dump the string into us */
194         write_buffer_ptr = write_buffer;
195
196         /* Write the string with padding */
197         tputs (s, 1, output_one);
198
199         /* Finish the string */
200         *write_buffer_ptr = '\0';
201
202         /* Dump the recorded buffer */
203         ewrite (write_buffer);
204 }
205
206 #endif
207
208 #ifdef USE_HARDCODE
209
210 static void tp(char *s)
211 {
212         ewrite(s);
213 }
214
215 #endif
216
217
218
219
220
221
222
223 /*
224  * Clear the screen
225  */
226 static void do_cl(void)
227 {
228         if (cl) tp (cl);
229 }
230
231 /*
232  * Clear to the end of the line
233  */
234 static void do_ce(void)
235 {
236         if (ce) tp(ce);
237 }
238
239
240 /*
241  * Set the cursor visibility (0 = invis, 1 = normal, 2 = bright)
242  */
243 static void curs_set(int vis)
244 {
245         char *v = NULL;
246
247         if (!vis)
248         {
249                 v = vi;
250         }
251         else if (vis > 1)
252         {
253                 v = vs ? vs : ve;
254         }
255         else
256         {
257                 v = ve ? ve : vs;
258         }
259
260         if (v) tp(v);
261 }
262
263
264
265 /*
266  * Restrict scrolling to within these rows
267  */
268 static void do_cs(int y1, int y2)
269 {
270
271 #ifdef USE_TERMCAP
272         if (cs) tp(tgoto(cs, y2, y1));
273 #endif
274
275 #ifdef USE_HARDCODE
276         char temp[64];
277         sprintf(temp, cs, y1, y2);
278         tp (temp);
279 #endif
280
281 }
282
283
284
285 /*
286  * Go to the given screen location directly
287  */
288 static void do_cm(int x, int y)
289 {
290
291 #ifdef USE_TERMCAP
292         if (cm) tp(tgoto(cm, x, y));
293 #endif
294
295 #ifdef USE_HARDCODE
296         char temp[64];
297         sprintf(temp, cm, y+1, x+1);
298         tp(temp);
299 #endif
300
301 }
302
303
304 /*
305  * Go to the given screen location in a "clever" manner
306  *
307  * XXX XXX XXX This function could use some work!
308  */
309 static void do_move(int x1, int y1, int x2, int y2)
310 {
311         /* Hack -- unknown start location */
312         if ((x1 == x2) && (y1 == y2)) do_cm(x2, y2);
313
314         /* Left edge */
315         else if (x2 == 0)
316         {
317                 if ((y2 <= 0) && ho) tp(ho);
318                 else if ((y2 >= rows-1) && ll) tp(ll);
319                 else if ((y2 == y1) && cr) tp(cr);
320                 else do_cm(x2, y2);
321         }
322
323         /* Default -- go directly there */
324         else do_cm(x2, y2);
325 }
326
327
328
329
330 /*
331  * Help initialize this file (see below)
332  */
333 errr init_cap_aux(void)
334 {
335
336 #ifdef USE_TERMCAP
337
338         /* Get the terminal name (if possible) */
339         desc = getenv("TERM");
340         if (!desc) return (1);
341
342         /* Get the terminal info */
343         if (tgetent(blob, desc) != 1) return (2);
344
345         /* Get the (initial) columns and rows, or default */
346         if ((cols = tgetnum("co")) == -1) cols = 80;
347         if ((rows = tgetnum("li")) == -1) rows = 24;
348
349         /* Find out how to move the cursor to a given location */
350         cm = tgetstr("cm", &next);
351         if (!cm) return (10);
352
353         /* Find out how to move the cursor to a given position */
354         ch = tgetstr("ch", &next);
355         cv = tgetstr("cv", &next);
356
357         /* Find out how to "home" the screen */
358         ho = tgetstr("ho", &next);
359
360         /* Find out how to "last-line" the screen */
361         ll = tgetstr("ll", &next);
362
363         /* Find out how to do a "carriage return" */
364         cr = tgetstr("cr", &next);
365         if (!cr) cr = "\r";
366
367         /* Find out how to clear the screen */
368         cl = tgetstr("cl", &next);
369         if (!cl) return (11);
370
371         /* Find out how to clear to the end of display */
372         cd = tgetstr("cd", &next);
373
374         /* Find out how to clear to the end of the line */
375         ce = tgetstr("ce", &next);
376
377         /* Find out how to scroll (set the scroll region) */
378         cs = tgetstr("cs", &next);
379
380         /* Find out how to hilite */
381         so = tgetstr("so", &next);
382         se = tgetstr("se", &next);
383         if (!so || !se) so = se = NULL;
384
385         /* Find out how to bold */
386         md = tgetstr("md", &next);
387         me = tgetstr("me", &next);
388         if (!md || !me) md = me = NULL;
389
390         /* Check the cursor visibility stuff */
391         vi = tgetstr("vi", &next);
392         vs = tgetstr("vs", &next);
393         ve = tgetstr("ve", &next);
394
395 #endif
396
397 #ifdef USE_HARDCODE
398
399         /* Assume some defualt information */
400         rows = 24;
401         cols = 80;
402
403         /* Clear screen */
404         cl = "\033[2J\033[H";   /* --]--]-- */
405
406         /* Clear to end of line */
407         ce = "\033[K";  /* --]-- */
408
409         /* Hilite on/off */
410         so = "\033[7m"; /* --]-- */
411         se = "\033[m";  /* --]-- */
412
413         /* Scroll region */
414         cs = "\033[%d;%dr";     /* --]-- */
415
416         /* Move cursor */
417         cm = "\033[%d;%dH";     /* --]-- */
418
419 #endif
420
421         /* Success */
422         return (0);
423 }
424
425
426
427
428
429
430
431 /*
432  * Save the "normal" and "angband" terminal settings
433  */
434
435 #ifdef USE_TPOSIX
436
437 static struct termios  norm_termios;
438
439 static struct termios  game_termios;
440
441 #endif
442
443 #ifdef USE_TERMIO
444
445 static struct termio  norm_termio;
446
447 static struct termio  game_termio;
448
449 #endif
450
451 #ifdef USE_TCHARS
452
453 static struct sgttyb  norm_ttyb;
454 static struct tchars  norm_tchars;
455 static struct ltchars norm_ltchars;
456 static int            norm_local_chars;
457
458 static struct sgttyb  game_ttyb;
459 static struct tchars  game_tchars;
460 static struct ltchars game_ltchars;
461 static int            game_local_chars;
462
463 #endif
464
465
466
467 /*
468  * Are we active?  Not really needed.
469  */
470 static int active = FALSE;
471
472
473 /*
474  * The main screen (no sub-screens)
475  */
476 static term term_screen_body;
477
478
479
480 /*
481  * Place the "keymap" into its "normal" state
482  */
483 static void keymap_norm(void)
484 {
485
486 #ifdef USE_TPOSIX
487
488         /* restore the saved values of the special chars */
489         (void)tcsetattr(0, TCSAFLUSH, &norm_termios);
490
491 #endif
492
493 #ifdef USE_TERMIO
494
495         /* restore the saved values of the special chars */
496         (void)ioctl(0, TCSETA, (char *)&norm_termio);
497
498 #endif
499
500 #ifdef USE_TCHARS
501
502         /* restore the saved values of the special chars */
503         (void)ioctl(0, TIOCSETP, (char *)&norm_ttyb);
504         (void)ioctl(0, TIOCSETC, (char *)&norm_tchars);
505         (void)ioctl(0, TIOCSLTC, (char *)&norm_ltchars);
506         (void)ioctl(0, TIOCLSET, (char *)&norm_local_chars);
507
508 #endif
509
510 }
511
512
513 /*
514  * Place the "keymap" into the "game" state
515  */
516 static void keymap_game(void)
517 {
518
519 #ifdef USE_TPOSIX
520
521         /* restore the saved values of the special chars */
522         (void)tcsetattr(0, TCSAFLUSH, &game_termios);
523
524 #endif
525
526 #ifdef USE_TERMIO
527
528         /* restore the saved values of the special chars */
529         (void)ioctl(0, TCSETA, (char *)&game_termio);
530
531 #endif
532
533 #ifdef USE_TCHARS
534
535         /* restore the saved values of the special chars */
536         (void)ioctl(0, TIOCSETP, (char *)&game_ttyb);
537         (void)ioctl(0, TIOCSETC, (char *)&game_tchars);
538         (void)ioctl(0, TIOCSLTC, (char *)&game_ltchars);
539         (void)ioctl(0, TIOCLSET, (char *)&game_local_chars);
540
541 #endif
542
543 }
544
545
546 /*
547  * Save the normal keymap
548  */
549 static void keymap_norm_prepare(void)
550 {
551
552 #ifdef USE_TPOSIX
553
554         /* Get the normal keymap */
555         tcgetattr(0, &norm_termios);
556
557 #endif
558
559 #ifdef USE_TERMIO
560
561         /* Get the normal keymap */
562         (void)ioctl(0, TCGETA, (char *)&norm_termio);
563
564 #endif
565
566 #ifdef USE_TCHARS
567
568         /* Get the normal keymap */
569         (void)ioctl(0, TIOCGETP, (char *)&norm_ttyb);
570         (void)ioctl(0, TIOCGETC, (char *)&norm_tchars);
571         (void)ioctl(0, TIOCGLTC, (char *)&norm_ltchars);
572         (void)ioctl(0, TIOCLGET, (char *)&norm_local_chars);
573
574 #endif
575
576 }
577
578
579 /*
580  * Save the keymaps (normal and game)
581  */
582 static void keymap_game_prepare(void)
583 {
584
585 #ifdef USE_TPOSIX
586
587         /* Acquire the current mapping */
588         tcgetattr(0, &game_termios);
589
590         /* Force "Ctrl-C" to interupt */
591         game_termios.c_cc[VINTR] = (char)3;
592
593         /* Force "Ctrl-Z" to suspend */
594         game_termios.c_cc[VSUSP] = (char)26;
595
596         /* Hack -- Leave "VSTART/VSTOP" alone */
597
598         /* Disable the standard control characters */
599         game_termios.c_cc[VQUIT] = (char)-1;
600         game_termios.c_cc[VERASE] = (char)-1;
601         game_termios.c_cc[VKILL] = (char)-1;
602         game_termios.c_cc[VEOF] = (char)-1;
603         game_termios.c_cc[VEOL] = (char)-1;
604
605         /* Normally, block until a character is read */
606         game_termios.c_cc[VMIN] = 1;
607         game_termios.c_cc[VTIME] = 0;
608
609         /* Hack -- Turn off "echo" and "canonical" mode */
610         game_termios.c_lflag &= ~(ECHO | ICANON);
611
612         /* Turn off flow control */
613         game_termios.c_iflag &= ~IXON;
614
615 #endif
616
617 #ifdef USE_TERMIO
618
619         /* Acquire the current mapping */
620         (void)ioctl(0, TCGETA, (char *)&game_termio);
621
622         /* Force "Ctrl-C" to interupt */
623         game_termio.c_cc[VINTR] = (char)3;
624
625         /* Force "Ctrl-Z" to suspend */
626         game_termio.c_cc[VSUSP] = (char)26;
627
628         /* Hack -- Leave "VSTART/VSTOP" alone */
629
630         /* Disable the standard control characters */
631         game_termio.c_cc[VQUIT] = (char)-1;
632         game_termio.c_cc[VERASE] = (char)-1;
633         game_termio.c_cc[VKILL] = (char)-1;
634         game_termio.c_cc[VEOF] = (char)-1;
635         game_termio.c_cc[VEOL] = (char)-1;
636
637         /* Normally, block until a character is read */
638         game_termio.c_cc[VMIN] = 1;
639         game_termio.c_cc[VTIME] = 0;
640
641         /* Hack -- Turn off "echo" and "canonical" mode */
642         game_termio.c_lflag &= ~(ECHO | ICANON);
643
644         /* Turn off flow control */
645         game_termio.c_iflag &= ~IXON;
646
647 #endif
648
649 #ifdef USE_TCHARS
650
651         /* Get the default game characters */
652         (void)ioctl(0, TIOCGETP, (char *)&game_ttyb);
653         (void)ioctl(0, TIOCGETC, (char *)&game_tchars);
654         (void)ioctl(0, TIOCGLTC, (char *)&game_ltchars);
655         (void)ioctl(0, TIOCLGET, (char *)&game_local_chars);
656
657         /* Force interupt (^C) */
658         game_tchars.t_intrc = (char)3;
659
660         /* Force start/stop (^Q, ^S) */
661         game_tchars.t_startc = (char)17;
662         game_tchars.t_stopc = (char)19;
663
664         /* Cancel some things */
665         game_tchars.t_quitc = (char)-1;
666         game_tchars.t_eofc = (char)-1;
667         game_tchars.t_brkc = (char)-1;
668
669         /* Force suspend (^Z) */
670         game_ltchars.t_suspc = (char)26;
671
672         /* Cancel some things */
673         game_ltchars.t_dsuspc = (char)-1;
674         game_ltchars.t_rprntc = (char)-1;
675         game_ltchars.t_flushc = (char)-1;
676         game_ltchars.t_werasc = (char)-1;
677         game_ltchars.t_lnextc = (char)-1;
678
679         /* XXX XXX XXX XXX Verify this before use */
680         /* Hack -- Turn off "echo" and "canonical" mode */
681         /* game_termios.c_lflag &= ~(ECHO | ICANON); */
682         game_ttyb.flag &= ~(ECHO | ICANON);
683
684         /* XXX XXX XXX  Should maybe turn off flow control too.  How? */
685
686 #endif
687
688 }
689
690
691
692
693
694
695
696
697 /*
698  * Suspend/Resume
699  */
700 static errr Term_xtra_cap_alive(int v)
701 {
702         /* Suspend */
703         if (!v)
704         {
705                 if (!active) return (1);
706
707                 /* Hack -- make sure the cursor is visible */
708                 curs_set(1);
709
710                 /* Move to bottom right */
711                 do_move(0, rows - 1, 0, rows - 1);
712
713                 /* Go to normal keymap mode */
714                 keymap_norm();
715
716                 /* No longer active */
717                 active = FALSE;
718         }
719
720         /* Resume */
721         else
722         {
723                 if (active) return (1);
724
725                 /* Hack -- restore the cursor location */
726                 do_move(curx, cury, curx, cury);
727
728                 /* Hack -- restore the cursor visibility */
729                 curs_set(curv);
730
731                 /* Go to angband keymap mode */
732                 keymap_game();
733
734                 /* Now we are active */
735                 active = TRUE;
736         }
737
738         /* Success */
739         return (0);
740 }
741
742
743
744 /*
745  * Process an event
746  */
747 static errr Term_xtra_cap_event(int v)
748 {
749         int i, arg;
750         char buf[2];
751
752         /* Wait */
753         if (v)
754         {
755                 /* Wait for one byte */
756                 i = read(0, buf, 1);
757
758                 /* Hack -- Handle "errors" */
759                 if ((i <= 0) && (errno != EINTR)) exit_game_panic(p_ptr);
760         }
761
762         /* Do not wait */
763         else
764         {
765                 /* Get the current flags for stdin */
766                 if ((arg = fcntl(0, F_GETFL, 0)) < 1) return (1);
767
768                 /* Tell stdin not to block */
769                 if (fcntl(0, F_SETFL, arg | O_NDELAY) < 0) return (1);
770
771                 /* Read one byte, if possible */
772                 i = read(0, buf, 1);
773
774                 /* Replace the flags for stdin */
775                 if (fcntl(0, F_SETFL, arg)) return (1);
776         }
777
778         /* No keys ready */
779         if ((i != 1) || (!buf[0])) return (1);
780
781         /* Enqueue the keypress */
782         Term_keypress(buf[0]);
783
784         /* Success */
785         return (0);
786 }
787
788
789
790
791 /*
792  * Actually move the hardware cursor
793  */
794 static errr Term_curs_cap(int x, int y)
795 {
796         /* Literally move the cursor */
797         do_move(curx, cury, x, y);
798
799         /* Save the cursor location */
800         curx = x;
801         cury = y;
802
803         /* Success */
804         return (0);
805 }
806
807
808 /*
809  * Erase a grid of space
810  *
811  * XXX XXX XXX Note that we will never be asked to clear the
812  * bottom line all the way to the bottom right edge, since we
813  * have set the "avoid the bottom right corner" flag.
814  */
815 static errr Term_wipe_cap(int x, int y, int n)
816 {
817         int dx;
818
819         /* Place the cursor */
820         Term_curs_cap(x, y);
821
822         /* Wipe to end of line */
823         if (x + n >= 80)
824         {
825                 do_ce();
826         }
827
828         /* Wipe region */
829         else
830         {
831                 for (dx = 0; dx < n; ++dx)
832                 {
833                         putc(' ', stdout);
834                         curx++;
835                 }
836         }
837
838         /* Success */
839         return (0);
840 }
841
842
843 /*
844  * Place some text on the screen using an attribute
845  */
846 static errr Term_text_cap(int x, int y, int n, byte a, concptr s)
847 {
848         int i;
849
850         /* Move the cursor */
851         Term_curs_cap(x, y);
852
853         /* Dump the text, advance the cursor */
854         for (i = 0; s[i]; i++)
855         {
856                 /* Dump the char */
857                 putc(s[i], stdout);
858
859                 /* Advance cursor 'X', and wrap */
860                 if (++curx >= cols)
861                 {
862                         /* Reset cursor 'X' */
863                         curx = 0;
864
865                         /* Hack -- Advance cursor 'Y', and wrap */
866                         if (++cury == rows) cury = 0;
867                 }
868         }
869
870         /* Success */
871         return (0);
872 }
873
874
875 /*
876  * Handle a "special request"
877  */
878 static errr Term_xtra_cap(int n, int v)
879 {
880         /* Analyze the request */
881         switch (n)
882         {
883                 /* Clear the screen */
884                 case TERM_XTRA_CLEAR:
885                 do_cl();
886                 do_move(0, 0, 0, 0);
887                 return (0);
888
889                 /* Make a noise */
890                 case TERM_XTRA_NOISE:
891                 (void)write(1, "\007", 1);
892                 return (0);
893
894                 /* Change the cursor visibility */
895                 case TERM_XTRA_SHAPE:
896                 curv = v;
897                 curs_set(v);
898                 return (0);
899
900                 /* Suspend/Resume */
901                 case TERM_XTRA_ALIVE:
902                 return (Term_xtra_cap_alive(v));
903
904                 /* Process events */
905                 case TERM_XTRA_EVENT:
906                 return (Term_xtra_cap_event(v));
907
908                 /* Flush events */
909                 case TERM_XTRA_FLUSH:
910                 while (!Term_xtra_cap_event(FALSE));
911                 return (0);
912
913                 /* Delay */
914                 case TERM_XTRA_DELAY:
915                 usleep(1000 * v);
916                 return (0);
917         }
918
919         /* Not parsed */
920         return (1);
921 }
922
923
924
925
926 /*
927  * Init a "term" for this file
928  */
929 static void Term_init_cap(term *t)
930 {
931         if (active) return;
932
933         /* Assume cursor at top left */
934         curx = 0;
935         cury = 0;
936
937         /* Assume visible cursor */
938         curv = 1;
939
940         /* Clear the screen */
941         do_cl();
942
943         /* Hack -- visible cursor */
944         curs_set(1);
945
946         /* Assume active */
947         active = TRUE;
948 }
949
950
951 /*
952  * Nuke a "term" for this file
953  */
954 static void Term_nuke_cap(term *t)
955 {
956         if (!active) return;
957
958         /* Hack -- make sure the cursor is visible */
959         curs_set(1);
960
961         /* Move to bottom right */
962         do_move(0, rows - 1, 0, rows - 1);
963
964         /* Normal keymap */
965         keymap_norm();
966
967         /* No longer active */
968         active = FALSE;
969 }
970
971
972
973
974
975
976
977
978
979
980 /*
981  * Prepare this file for Angband usage
982  */
983 errr init_cap(void)
984 {
985         term *t = &term_screen_body;
986
987
988         /*** Initialize ***/
989
990         /* Initialize the screen */
991         if (init_cap_aux()) return (-1);
992
993         /* Hack -- Require large screen, or Quit with message */
994         if ((rows < 24) || (cols < 80)) quit("Screen too small!");
995
996
997         /*** Prepare to play ***/
998
999         /* Extract the normal keymap */
1000         keymap_norm_prepare();
1001
1002         /* Extract the game keymap */
1003         keymap_game_prepare();
1004
1005         /* Hack -- activate the game keymap */
1006         keymap_game();
1007
1008         /* Hack -- Do NOT buffer stdout */
1009         setbuf(stdout, NULL);
1010
1011
1012         /*** Now prepare the term ***/
1013
1014         /* Initialize the term */
1015         term_init(t, 80, 24, 256);
1016
1017         /* Avoid the bottom right corner */
1018         t->icky_corner = TRUE;
1019
1020         /* Erase with "white space" */
1021         t->attr_blank = TERM_WHITE;
1022         t->char_blank = ' ';
1023
1024         /* Set some hooks */
1025         t->init_hook = Term_init_cap;
1026         t->nuke_hook = Term_nuke_cap;
1027
1028         /* Set some more hooks */
1029         t->text_hook = Term_text_cap;
1030         t->wipe_hook = Term_wipe_cap;
1031         t->curs_hook = Term_curs_cap;
1032         t->xtra_hook = Term_xtra_cap;
1033
1034         /* Save the term */
1035         term_screen = t;
1036
1037         /* Activate it */
1038         Term_activate(term_screen);
1039
1040         /* Success */
1041         return (0);
1042 }
1043
1044
1045 #endif /* USE_CAP */
1046
1047