Source:NetHack 3.0.0/termcap.c
Revision as of 05:34, 4 March 2008 by Kernigh bot (talk | contribs) (NetHack 3.0.0/termcap.c moved to Source:NetHack 3.0.0/termcap.c: Robot: moved page)
Below is the full text to termcap.c from the source code of NetHack 3.0.0. To link to a particular line, write [[NetHack 3.0.0/termcap.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)termcap.c 3.0 88/11/20 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #include <ctype.h> /* for isdigit() */ 6. 7. /* block some unused #defines to avoid overloading some cpp's */ 8. #define MONATTK_H 9. #include "hack.h" /* for ROWNO, COLNO, *HI, *HE, *AS, *AE */ 10. 11. #if !defined(SYSV) || defined(TOS) || defined(UNIXPC) 12. # ifndef LINT 13. extern /* it is defined in libtermlib (libtermcap) */ 14. # endif 15. short ospeed; /* terminal baudrate; used by tputs */ 16. #else 17. short ospeed = 0; /* gets around "not defined" error message */ 18. #endif 19. 20. static void nocmov(); 21. #ifdef MSDOSCOLOR 22. static void init_hilite(); 23. #endif /* MSDOSCOLOR */ 24. 25. static char tbuf[512]; 26. static char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; 27. static char *VS, *VE, *US, *UE; 28. static char *MR, *ME; 29. #if 0 30. static char *MB, *MD, *MH; 31. #endif 32. static int SG; 33. static char PC = '\0'; 34. 35. #if defined(MSDOS) && !defined(TERMLIB) 36. static char tgotobuf[20]; 37. #ifdef TOS 38. #define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+' ', x+' '), tgotobuf) 39. #else 40. #define tgoto(fmt, x, y) (Sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf) 41. #endif 42. #endif /* MSDOS /**/ 43. 44. void 45. startup() 46. { 47. #ifdef TOS 48. HO = "\033H"; 49. CL = "\033E"; /* the VT52 termcap */ 50. CE = "\033K"; 51. UP = "\033A"; 52. CM = "\033Y%c%c"; /* used with function tgoto() */ 53. ND = "\033C"; 54. XD = "\033B"; 55. BC = "\033D"; 56. SO = "\033p"; 57. SE = "\033q"; 58. HI = "\033p"; 59. HE = "\033q"; 60. #else 61. register char *term; 62. register char *tptr; 63. char *tbufptr, *pc; 64. register int i; 65. 66. tptr = (char *) alloc(1024); 67. 68. tbufptr = tbuf; 69. if(!(term = getenv("TERM"))) 70. # ifdef ANSI_DEFAULT 71. { 72. HO = "\033[H"; 73. CL = "\033[2J"; /* the ANSI termcap */ 74. /* CD = "\033[J"; */ 75. CE = "\033[K"; 76. CM = "\033[%i%d;%dH"; 77. UP = "\033[A"; 78. ND = "\033[C"; 79. XD = "\033[B"; 80. BC = "\033[D"; 81. HI = SO = "\033[1m"; 82. US = "\033[4m"; 83. TI = HE = SE = UE = "\033[0m"; 84. /* strictly, SE should be 2, and UE should be 24, 85. but we can't trust all ANSI emulators to be 86. that complete. -3. */ 87. AS = "\016"; 88. AE = "\017"; 89. VS = VE = ""; 90. } else { 91. # else 92. error("Can't get TERM."); 93. # endif 94. if(!strncmp(term, "5620", 4)) 95. flags.nonull = 1; /* this should be a termcap flag */ 96. if(tgetent(tptr, term) < 1) 97. error("Unknown terminal type: %s.", term); 98. if(pc = tgetstr("pc", &tbufptr)) 99. PC = *pc; 100. #ifdef TERMINFO 101. if(!(BC = tgetstr("le", &tbufptr))) { 102. #else 103. if(!(BC = tgetstr("bc", &tbufptr))) { 104. #endif 105. #if !defined(MINIMAL_TERM) && !defined(HISX) 106. if(!tgetflag("bs")) 107. error("Terminal must backspace."); 108. #endif 109. BC = tbufptr; 110. tbufptr += 2; 111. *BC = '\b'; 112. } 113. #ifdef MINIMAL_TERM 114. HO = NULL; 115. #else 116. HO = tgetstr("ho", &tbufptr); 117. #endif 118. CO = tgetnum("co"); 119. LI = tgetnum("li"); 120. if(CO < COLNO || LI < ROWNO+2) 121. setclipped(); 122. if(!(CL = tgetstr("cl", &tbufptr))) 123. error("Hack needs CL."); 124. ND = tgetstr("nd", &tbufptr); 125. if(tgetflag("os")) 126. error("Hack can't have OS."); 127. CE = tgetstr("ce", &tbufptr); 128. UP = tgetstr("up", &tbufptr); 129. /* It seems that xd is no longer supported, and we should use 130. a linefeed instead; unfortunately this requires resetting 131. CRMOD, and many output routines will have to be modified 132. slightly. Let's leave that till the next release. */ 133. XD = tgetstr("xd", &tbufptr); 134. /* not: XD = tgetstr("do", &tbufptr); */ 135. if(!(CM = tgetstr("cm", &tbufptr))) { 136. if(!UP && !HO) 137. error("Hack needs CM or UP or HO."); 138. Printf("Playing hack on terminals without cm is suspect...\n"); 139. getret(); 140. } 141. SO = tgetstr("so", &tbufptr); 142. SE = tgetstr("se", &tbufptr); 143. US = tgetstr("us", &tbufptr); 144. UE = tgetstr("ue", &tbufptr); 145. SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */ 146. if(!SO || !SE || (SG > 0)) SO = SE = US = UE = ""; 147. TI = tgetstr("ti", &tbufptr); 148. TE = tgetstr("te", &tbufptr); 149. VS = VE = ""; 150. #if 0 151. MB = tgetstr("mb", &tbufptr); /* blink */ 152. MD = tgetstr("md", &tbufptr); /* boldface */ 153. MH = tgetstr("mh", &tbufptr); /* dim */ 154. #endif 155. MR = tgetstr("mr", &tbufptr); /* reverse */ 156. ME = tgetstr("me", &tbufptr); 157. 158. /* Get rid of padding numbers for HI and HE. Hope they 159. * aren't really needed!!! HI and HE are ouputted to the 160. * pager as a string - so how can you send it NULLS??? 161. * -jsb 162. */ 163. HI = (char *) alloc((unsigned)(strlen(SO)+1)); 164. HE = (char *) alloc((unsigned)(strlen(SE)+1)); 165. i = 0; 166. while(isdigit(SO[i])) i++; 167. Strcpy(HI, &SO[i]); 168. i = 0; 169. while(isdigit(SE[i])) i++; 170. Strcpy(HE, &SE[i]); 171. AS = tgetstr("as", &tbufptr); 172. AE = tgetstr("ae", &tbufptr); 173. CD = tgetstr("cd", &tbufptr); 174. # ifdef ANSI_DEFAULT 175. } 176. # endif 177. set_whole_screen(); /* uses LI and CD */ 178. if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n"); 179. free((genericptr_t)tptr); 180. #ifdef MSDOSCOLOR 181. init_hilite(); 182. #endif 183. #endif /* TOS /* */ 184. } 185. 186. void 187. start_screen() 188. { 189. xputs(TI); 190. xputs(VS); 191. #ifdef DECRAINBOW 192. /* Select normal ASCII and line drawing character sets. 193. */ 194. if (flags.DECRainbow) { 195. xputs("\033(B\033)0"); 196. if (!AS) { 197. AS = "\016"; 198. AE = "\017"; 199. } 200. } 201. #endif /* DECRAINBOW */ 202. } 203. 204. void 205. end_screen() 206. { 207. clear_screen(); 208. xputs(VE); 209. xputs(TE); 210. } 211. 212. /* Cursor movements */ 213. 214. void 215. curs(x, y) 216. register int x, y; /* not xchar: perhaps xchar is unsigned and 217. curx-x would be unsigned as well */ 218. { 219. 220. if (y == cury && x == curx) 221. return; 222. if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */ 223. cmov(x, y); /* bunker!wtm */ 224. return; 225. } 226. if(abs(cury-y) <= 3 && abs(curx-x) <= 3) 227. nocmov(x, y); 228. else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) { 229. (void) putchar('\r'); 230. curx = 1; 231. nocmov(x, y); 232. } else if(!CM) { 233. nocmov(x, y); 234. } else 235. cmov(x, y); 236. } 237. 238. static void 239. nocmov(x, y) 240. { 241. if (cury > y) { 242. if(UP) { 243. while (cury > y) { /* Go up. */ 244. xputs(UP); 245. cury--; 246. } 247. } else if(CM) { 248. cmov(x, y); 249. } else if(HO) { 250. home(); 251. curs(x, y); 252. } /* else impossible("..."); */ 253. } else if (cury < y) { 254. if(XD) { 255. while(cury < y) { 256. xputs(XD); 257. cury++; 258. } 259. } else if(CM) { 260. cmov(x, y); 261. } else { 262. while(cury < y) { 263. xputc('\n'); 264. curx = 1; 265. cury++; 266. } 267. } 268. } 269. if (curx < x) { /* Go to the right. */ 270. if(!ND) cmov(x, y); else /* bah */ 271. /* should instead print what is there already */ 272. while (curx < x) { 273. xputs(ND); 274. curx++; 275. } 276. } else if (curx > x) { 277. while (curx > x) { /* Go to the left. */ 278. xputs(BC); 279. curx--; 280. } 281. } 282. } 283. 284. void 285. cmov(x, y) 286. register int x, y; 287. { 288. xputs(tgoto(CM, x-1, y-1)); 289. cury = y; 290. curx = x; 291. } 292. 293. void 294. xputc(c) 295. char c; 296. { 297. (void) fputc(c, stdout); 298. } 299. 300. void 301. xputs(s) 302. char *s; 303. { 304. #if defined(MSDOS) && !defined(TERMLIB) 305. (void) fputs(s, stdout); 306. #else 307. # ifdef __STDC__ 308. tputs(s, 1, (int (*)())xputc); 309. # else 310. tputs(s, 1, xputc); 311. # endif 312. #endif 313. } 314. 315. void 316. cl_end() { 317. if(CE) 318. xputs(CE); 319. else { /* no-CE fix - free after Harold Rynes */ 320. /* this looks terrible, especially on a slow terminal 321. but is better than nothing */ 322. register int cx = curx, cy = cury; 323. 324. while(curx < COLNO) { 325. xputc(' '); 326. curx++; 327. } 328. curs(cx, cy); 329. } 330. } 331. 332. void 333. clear_screen() { 334. xputs(CL); 335. home(); 336. } 337. 338. void 339. home() 340. { 341. if(HO) 342. xputs(HO); 343. else if(CM) 344. xputs(tgoto(CM, 0, 0)); 345. else 346. curs(1, 1); /* using UP ... */ 347. curx = cury = 1; 348. } 349. 350. void 351. standoutbeg() 352. { 353. if(SO) xputs(SO); 354. } 355. 356. void 357. standoutend() 358. { 359. if(SE) xputs(SE); 360. } 361. 362. void 363. revbeg() 364. { 365. if(MR) xputs(MR); 366. } 367. 368. #if 0 /* if you need one of these, uncomment it (here and in extern.h) */ 369. void 370. boldbeg() 371. { 372. if(MD) xputs(MD); 373. } 374. 375. void 376. blinkbeg() 377. { 378. if(MB) xputs(MB); 379. } 380. 381. void 382. dimbeg() 383. /* not in most termcap entries */ 384. { 385. if(MH) xputs(MH); 386. } 387. #endif 388. 389. void 390. m_end() 391. { 392. if(ME) xputs(ME); 393. } 394. 395. void 396. backsp() 397. { 398. xputs(BC); 399. } 400. 401. void 402. bell() 403. { 404. if (flags.silent) return; 405. (void) putchar('\007'); /* curx does not change */ 406. (void) fflush(stdout); 407. } 408. 409. void 410. graph_on() { 411. if (AS) xputs(AS); 412. } 413. 414. void 415. graph_off() { 416. if (AE) xputs(AE); 417. } 418. 419. #ifndef MSDOS 420. static const short tmspc10[] = { /* from termcap */ 421. 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5 422. }; 423. #endif 424. 425. void 426. delay_output() { 427. /* delay 50 ms - could also use a 'nap'-system call */ 428. /* BUG: if the padding character is visible, as it is on the 5620 429. then this looks terrible. */ 430. #ifdef MSDOS 431. /* simulate the delay with "cursor here" */ 432. register int i; 433. for (i = 0; i < 3; i++) { 434. cmov(curx, cury); 435. (void) fflush(stdout); 436. } 437. #else /* MSDOS /**/ 438. if(!flags.nonull) 439. #ifdef TERMINFO 440. /* cbosgd!cbcephus!pds for SYS V R2 */ 441. # ifdef __STDC__ 442. tputs("$<50>", 1, (int (*)())xputc); 443. # else 444. tputs("$<50>", 1, xputc); 445. # endif 446. #else 447. tputs("50", 1, xputs); 448. #endif 449. 450. else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) { 451. /* delay by sending cm(here) an appropriate number of times */ 452. register int cmlen = strlen(tgoto(CM, curx-1, cury-1)); 453. register int i = 500 + tmspc10[ospeed]/2; 454. 455. while(i > 0) { 456. cmov(curx, cury); 457. i -= cmlen*tmspc10[ospeed]; 458. } 459. } 460. #endif /* MSDOS /**/ 461. } 462. 463. void 464. cl_eos() /* free after Robert Viduya */ 465. { /* must only be called with curx = 1 */ 466. 467. if(CD) 468. xputs(CD); 469. else { 470. register int cx = curx, cy = cury; 471. while(cury <= LI-2) { 472. cl_end(); 473. xputc('\n'); 474. curx = 1; 475. cury++; 476. } 477. cl_end(); 478. curs(cx, cy); 479. } 480. } 481. 482. #ifdef MSDOSCOLOR 483. /* Sets up highlighting, using ANSI escape sequences, for monsters, 484. * objects, and gold (highlight code found in pri.c). 485. * The termcap entry for HI (from SO) is scanned to find the background 486. * color. If everything is OK, monsters are displayed in the color 487. * used to define HILITE_MONSTER, objects are displayed in the color 488. * used to define HILITE_OBJECT, and gold is displayed in the color 489. * used to define HILITE_GOLD. -3. */ 490. 491. #define ESC 0x1b 492. #define NONE 0 493. #define HIGH_INTENSITY 1 494. #define BLACK 0 495. #define RED 1 496. #define GREEN 2 497. #define YELLOW 3 498. #define BLUE 4 499. #define MAGENTA 5 500. #define CYAN 6 501. #define WHITE 7 502. 503. #define HILITE_ATTRIB HIGH_INTENSITY 504. 505. static void 506. init_hilite() 507. { 508. int backg = BLACK, foreg = WHITE, len; 509. register int c, color; 510. 511. HI_RED = HI_YELLOW = HI_GREEN = HI_BLUE = HI_WHITE = HI; 512. 513. /* find the background color, HI[len] == 'm' */ 514. len = strlen(HI) - 1; 515. 516. if (HI[len] != 'm' || len < 3) return; 517. 518. c = 2; 519. while (c < len) { 520. if ((color = atoi(&HI[c])) == 0) { 521. /* this also catches errors */ 522. foreg = WHITE; backg = BLACK; 523. } else if (color >= 30 && color <= 37) { 524. foreg = color - 30; 525. } else if (color >= 40 && color <= 47) { 526. backg = color - 40; 527. } 528. while (isdigit(HI[++c])); 529. c++; 530. } 531. 532. /* avoid invisibility */ 533. if (foreg != RED && backg != RED) { 534. HI_RED = (char *) alloc(sizeof("E[0;33;44;54m")); 535. Sprintf(HI_RED, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 536. RED, backg); 537. } 538. 539. if (foreg != YELLOW && backg != YELLOW) { 540. HI_YELLOW = (char *) alloc(sizeof("E[0;33;44;54m")); 541. Sprintf(HI_YELLOW, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 542. YELLOW, backg); 543. } 544. 545. if (foreg != GREEN && backg != GREEN) { 546. HI_GREEN = (char *) alloc(sizeof("E[0;33;44;54m")); 547. Sprintf(HI_GREEN, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 548. GREEN, backg); 549. } 550. 551. if (foreg != BLUE && backg != BLUE) { 552. HI_BLUE = (char *) alloc(sizeof("E[0;33;44;54m")); 553. Sprintf(HI_BLUE, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 554. BLUE, backg); 555. } 556. 557. if (foreg != WHITE && backg != WHITE) { 558. HI_WHITE = (char *) alloc(sizeof("E[0;33;44;54m")); 559. Sprintf(HI_WHITE, "%c[%d;3%d;4%dm", ESC, HILITE_ATTRIB, 560. WHITE, backg); 561. } 562. } 563. 564. #endif