OSDN Git Service

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