Scrap various ugly portability hacks. They're no longer needed as
[vms-empire.git] / term.c
1 /* %W% %G% %U% - (c) Copyright 1987, 1988 Chuck Simmons */
2
3 /*
4  *    Copyright (C) 1987, 1988 Chuck Simmons
5  * 
6  * See the file COPYING, distributed with empire, for restriction
7  * and warranty information.
8  */
9
10 /*
11 term.c -- this file contains various routines used to control the
12 user communications area of the terminal.  This area consists of
13 the top 3 lines of the terminal where messages are displayed to the
14 user and input is acquired from the user.
15
16 There are two types of output in this area.  One type is interactive
17 output.  This consists of a prompt line and an error message line.
18 The other type of output is informational output.  The user must
19 be given time to read informational output.
20
21 Whenever input is received, the top three lines are cleared and the
22 screen refreshed as the user has had time to read these lines.  We
23 also clear the 'need_delay' flag, saying that the user has read the
24 information on the screen.
25
26 When information is to be displayed, if the 'need_delay' flag is set,
27 we refresh the screen and pause momentarily to give the user a chance
28 to read the lines.  The new information is then displayed, and the
29 'need_delay' flag is set.
30 */
31
32 #include <stdio.h>
33 #include <string.h>
34 #include <stdlib.h>
35 #include <curses.h>
36 #include <ctype.h>
37
38 #include "empire.h"
39 #include "extern.h"
40
41 static int need_delay;
42 static FILE *my_stream;
43 void
44 /* VARARGS1 */
45 pdebug (s, a, b, c, d, e, f, g, h)
46 char *s;
47 int a, b, c, d, e, f, g, h;
48 {
49         if (!print_debug) return;
50         comment (s, a, b, c, d, e, f, g, h);
51 }
52
53 /*
54 Here are routines that handle printing to the top few lines of the
55 screen.  'topini' should be called at initialization, and whenever
56 we finish printing information to the screen.
57 */
58
59 void
60 topini()
61 {
62         info (0, 0, 0);
63 }
64 /*
65 Write a message to one of the top lines.
66 */
67
68 void
69 /* VARARGS2 */
70 topmsg(linep, buf, a, b, c, d, e, f, g, h)
71 int linep;
72 char *buf;
73 int a, b, c, d, e, f, g, h;
74 {
75         if (linep < 1 || linep > NUMTOPS)
76                 linep = 1;
77         (void) move (linep - 1, 0);
78         
79         if (buf != NULL && strlen (buf) > 0)
80                 addprintf (buf, a, b, c, d, e, f, g, h);
81         
82         (void) clrtoeol ();
83 }
84
85 void
86 topmsg1 (linep, buf, a, b, c, d, e, f, g, h)
87 int linep;
88 char *buf;
89 char *a;
90 int b, c, d, e, f, g, h;
91 {
92         if (linep < 1 || linep > NUMTOPS)
93                 linep = 1;
94         (void) move (linep - 1, 0);
95         
96         if (buf != NULL && strlen (buf) > 0)
97                 addprintf1 (buf, a, b, c, d, e, f, g, h);
98         
99         (void) clrtoeol ();
100 }
101 void
102 topmsg2 (linep, buf, a, b, c, d, e, f, g, h)
103 int linep;
104 char *buf;
105 char *a, *e, *f;
106 int b, c, d, g, h;
107 {
108         if (linep < 1 || linep > NUMTOPS)
109                 linep = 1;
110         (void) move (linep - 1, 0);
111         
112         if (buf != NULL && strlen (buf) > 0)
113                 addprintf2 (buf, a, b, c, d, e, f, g, h);
114         
115         (void) clrtoeol ();
116 }
117 /*
118 Print a prompt on the first message line.
119 */
120
121 void
122 /* VARARGS1 */
123 prompt (buf, a, b, c, d, e, f, g, h)
124 char *buf;
125 int a,b,c,d,e,f,g,h;
126 {
127         topmsg (1, buf, a, b, c, d, e, f, g, h);
128 }
129 void
130 prompt1 (buf, a, b, c, d, e, f, g, h)
131 char *buf, *a;
132 int b,c,d,e,f,g,h;
133 {
134         topmsg1 (1, buf, a, b, c, d, e, f, g, h);
135 }
136 void
137 prompt2 (buf, a, b, c, d, e, f, g, h)
138 char *buf, *a, *e, *f;
139 int b,c,d,g,h;
140 {
141         topmsg2 (1, buf, a, b, c, d, e, f, g, h);
142 }
143
144 /*
145 Print an error message on the second message line.
146 */
147
148 void
149 /* VARARGS1 */
150 error (buf, a, b, c, d, e, f, g, h)
151 char *buf;
152 int a, b, c, d, e, f, g, h;
153 {
154         topmsg (2, buf, a, b, c, d, e, f, g, h);
155 }
156
157 /*
158 Print out extra information.
159 */
160
161 void
162 /* VARARGS1 */
163 extra (buf, a, b, c, d, e, f, g, h)
164 char *buf;
165 int a, b, c, d, e, f, g, h;
166 {
167         topmsg (3, buf, a, b, c, d, e, f, g, h);
168 }
169
170 /*
171 Print out a generic error message.
172 */
173
174 void
175 huh ()
176 {
177         error ("Type H for Help.",0,0,0,0,0,0,0,0);
178 }
179
180 /*
181 Display information on the screen.  If the 'need_delay' flag is set,
182 we force a delay, then print the information.  After we print the
183 information, we set the need_delay flag.
184 */
185
186 void
187 info (a, b, c)
188 char *a, *b, *c;
189 {
190         if (need_delay) delay ();
191         topmsg (1, a,0,0,0,0,0,0,0,0);
192         topmsg (2, b,0,0,0,0,0,0,0,0);
193         topmsg (3, c,0,0,0,0,0,0,0,0);
194         need_delay = (a || b || c);
195 }
196
197 void
198 set_need_delay () {
199         need_delay = 1;
200 }
201
202 void
203 comment (buf, a, b, c, d, e, f, g, h)
204 char *buf;
205 int a, b, c, d, e, f, g, h;
206 {
207         if (need_delay) delay ();
208         topmsg (1, 0,0,0,0,0,0,0,0,0);
209         topmsg (2, 0,0,0,0,0,0,0,0,0);
210         topmsg (3, buf, a, b, c, d, e, f, g, h);
211         need_delay = (buf != 0);
212 }
213         
214 void
215 comment1 (buf, a, b, c, d, e, f, g, h)
216 char *buf, *a;
217 int b, c, d, e, f, g, h;
218 {
219         if (need_delay) delay ();
220         topmsg1 (1, 0,0,0,0,0,0,0,0,0);
221         topmsg1 (2, 0,0,0,0,0,0,0,0,0);
222         topmsg1 (3, buf, a, b, c, d, e, f, g, h);
223         need_delay = (buf != 0);
224 }
225         
226 /* kermyt begin */
227 void
228 ksend (buf, a, b, c, d, e, f, g, h)
229 char *buf;
230 int a,b,c,d,e,f,g,h;
231 {
232         if(!(my_stream=fopen("info_list.txt","a")))
233         {
234                 error("Cannot open info_list.txt",0,0,0,0,0,0,0,0);
235                 return;
236         }
237         fprintf(my_stream, buf, a, b, c, d, e, f, g, h);
238         fclose(my_stream);
239         return;
240 }
241 void
242 ksend1 (buf, a, b, c, d, e, f, g, h)
243 char *buf, *a;
244 int b,c,d,e,f,g,h;
245 {
246         if(!(my_stream=fopen("info_list.txt","a")))
247         {
248                 error("Cannot open info_list.txt",0,0,0,0,0,0,0,0);
249                 return;
250         }
251         fprintf(my_stream, buf, a, b, c, d, e, f, g, h);
252         fclose(my_stream);
253         return;
254 }
255 /* kermyt end */
256 /*
257 Get a string from the user, echoing characters all the while.
258 */
259
260 void
261 get_str (buf, sizep)
262 char *buf;
263 int sizep;
264 {
265         (void) echo();
266         get_strq(buf, sizep);
267         (void) noecho();
268 }
269
270 /*
271 Get a string from the user, ignoring the current echo mode.
272 */
273
274 void
275 get_strq (buf, sizep)
276 char *buf;
277 int sizep;
278 {
279         sizep = sizep; /* size of buf, currently unused */
280
281         (void) nocrmode ();
282         (void) refresh ();
283         (void) getstr (buf);
284         need_delay = FALSE;
285         info (0, 0, 0);
286         (void) crmode ();
287 }
288
289 /*
290 Get a character from the user and convert it to uppercase.
291 */
292
293 char
294 get_chx()
295 {
296         char c;
297
298         c = get_cq ();
299
300         if (islower(c))
301                 return (upper(c));
302         else
303                 return (c);
304 }
305
306 /*
307 Input an integer from the user.
308 */
309
310 int
311 getint (message)
312 char *message;
313 {
314         char buf[STRSIZE];
315         char *p;
316
317         for (;;) { /* until we get a legal number */
318                 prompt (message,0,0,0,0,0,0,0,0);
319                 get_str (buf, sizeof (buf));
320                 
321                 for (p = buf; *p; p++) {
322                         if (*p < '0' || *p > '9') {
323                                 error ("Please enter an integer.",0,0,0,0,0,0,0,0);
324                                 break;
325                         }
326                 }
327                 if (*p == 0) { /* no error yet? */
328                         if (p - buf > 7) /* too many digits? */
329                                 error ("Please enter a small integer.",0,0,0,0,0,0,0,0);
330                         else return (atoi (buf));
331                 }
332         }
333 }
334
335 /*
336 Input a character from the user with echoing.
337 */
338
339 char
340 get_c ()
341 {
342         char c; /* one char and a null */
343
344         (void) echo ();
345         c = get_cq ();
346         (void) noecho ();
347         return (c);
348 }
349
350 /*
351 Input a character quietly.
352 */
353
354 char
355 get_cq ()
356 {
357         char c;
358
359         (void) crmode ();
360         (void) refresh ();
361         c = getch ();
362         topini (); /* clear information lines */
363         (void) nocrmode ();
364         return (c);
365 }
366
367 /*
368 Input a yes or no response from the user.  We loop until we get
369 a valid response.  We return TRUE iff the user replies 'y'.
370 */
371
372 int
373 getyn (message)
374 char *message;
375 {
376         char c;
377
378         for (;;) {
379                 prompt (message,0,0,0,0,0,0,0,0);
380                 c = get_chx ();
381
382                 if (c == 'Y') return (TRUE);
383                 if (c == 'N') return (FALSE);
384
385                 error ("Please answer Y or N.",0,0,0,0,0,0,0,0);
386         }
387 }
388
389 /*
390 Input an integer in a range.
391 */
392
393 int
394 get_range (message, low, high)
395 char *message;
396 int low, high;
397 {
398         int result;
399
400         for (;;) {
401                 result = getint (message);
402
403                 if (result >= low && result <= high) return (result);
404
405                 error ("Please enter an integer in the range %d..%d.",low, high,0,0,0,0,0,0);
406         }
407 }
408
409 /*
410 Print a screen of help information.
411 */
412
413 void
414 help (text, nlines)
415 char **text;
416 int nlines;
417 {
418         int i, r, c;
419         int text_lines;
420
421         text_lines = (nlines + 1) / 2; /* lines of text */
422
423         clear_screen ();
424
425         pos_str (NUMTOPS, 1, text[0],0,0,0,0,0,0,0,0); /* mode */
426         pos_str (NUMTOPS, 41, "See empire(6) for more information.",0,0,0,0,0,0,0,0);
427
428         for (i = 1; i < nlines; i++) {
429                 if (i > text_lines)
430                         pos_str (i - text_lines + NUMTOPS + 1, 41, text[i],0,0,0,0,0,0,0,0);
431                 else pos_str (i + NUMTOPS + 1, 1, text[i],0,0,0,0,0,0,0,0);
432         }
433
434         pos_str (text_lines + NUMTOPS + 2,  1, "--Piece---Yours-Enemy-Moves-Hits-Cost",0,0,0,0,0,0,0,0);
435         pos_str (text_lines + NUMTOPS + 2, 41, "--Piece---Yours-Enemy-Moves-Hits-Cost",0,0,0,0,0,0,0,0);
436
437         for (i = 0; i < NUM_OBJECTS; i++) {
438                 if (i >= (NUM_OBJECTS+1)/2) {
439                         r = i - (NUM_OBJECTS+1)/2;
440                         c = 41;
441                 }
442                 else {
443                         r = i;
444                         c = 1;
445                 }
446                 pos_str1 (r + text_lines + NUMTOPS + 3, c,"%-12s%c     %c%6d%5d%6d",
447                         piece_attr[i].nickname,
448                         piece_attr[i].sname,
449                         tolower (piece_attr[i].sname),
450                         piece_attr[i].speed,
451                         piece_attr[i].max_hits,
452                         piece_attr[i].build_time,0,0);          //FLAG
453
454         }
455         (void) refresh ();
456 }
457
458 #define COL_DIGITS ((MAP_WIDTH <= 100) ? 2 : ((MAP_WIDTH <= 1000 ? 3 : (1 / 0))))
459
460 int
461 loc_disp (int loc)
462 {
463   int row = loc / MAP_WIDTH;
464   int nrow = row;
465   int col = loc % MAP_WIDTH;
466   ASSERT (loc == (row * MAP_WIDTH) + col);
467   int i;
468   for (i = COL_DIGITS; i > 0; i--) {
469     nrow *= 10; }
470   move (LINES - 1, 0);
471   /*
472   {
473     char junkbuf[STRSIZE];
474     (void) snprintf (junkbuf, STRSIZE, "loc: %d, row: %d, col: %d, nrow: %d, nrow+col: %d", loc, row, col, nrow, nrow + col);
475     (void) addstr (junkbuf);
476     napms(500);
477   }
478   */
479   return nrow + col;
480 }