1 /* 2 * Display abstraction. 3 * David Leonard <d@openbsd.org>, 1999. Public domain. 4 * 5 * $OpenBSD: display.c,v 1.4 2002/02/19 19:39:36 millert Exp $ 6 * $DragonFly: src/games/hunt/hunt/display.c,v 1.2 2008/09/04 16:12:51 swildner Exp $ 7 */ 8 9 #define USE_CURSES 10 11 #include <sys/cdefs.h> 12 #include "display.h" 13 14 #if !defined(USE_CURSES) 15 16 #include <stdlib.h> 17 #include <unistd.h> 18 #include <signal.h> 19 #include <stdio.h> 20 #include <termios.h> 21 #define _USE_OLD_CURSES_ 22 #include <curses.h> 23 #include <err.h> 24 #include "hunt.h" 25 26 static struct termios saved_tty; 27 28 char screen[SCREEN_HEIGHT][SCREEN_WIDTH2]; 29 char blanks[SCREEN_WIDTH]; 30 int cur_row, cur_col; 31 32 /* 33 * tstp: 34 * Handle stop and start signals 35 */ 36 static void 37 tstp(int dummy) 38 { 39 int y, x; 40 41 y = cur_row; 42 x = cur_col; 43 mvcur(cur_row, cur_col, HEIGHT, 0); 44 cur_row = HEIGHT; 45 cur_col = 0; 46 _puts(VE); 47 _puts(TE); 48 (void) fflush(stdout); 49 tcsetattr(0, TCSADRAIN, &__orig_termios); 50 (void) kill(getpid(), SIGSTOP); 51 (void) signal(SIGTSTP, tstp); 52 tcsetattr(0, TCSADRAIN, &saved_tty); 53 _puts(TI); 54 _puts(VS); 55 cur_row = y; 56 cur_col = x; 57 _puts(tgoto(CM, cur_row, cur_col)); 58 display_redraw_screen(); 59 (void) fflush(stdout); 60 } 61 62 /* 63 * display_open: 64 * open the display 65 */ 66 void 67 display_open(void) 68 { 69 char *term; 70 71 if (!isatty(0) || (term = getenv("TERM")) == NULL) 72 errx(1, "no terminal type"); 73 74 gettmode(); 75 (void) setterm(term); 76 (void) noecho(); 77 (void) cbreak(); 78 tcgetattr(0, &saved_tty); 79 _puts(TI); 80 _puts(VS); 81 #ifdef SIGTSTP 82 (void) signal(SIGTSTP, tstp); 83 #endif 84 } 85 86 /* 87 * display_beep: 88 * beep 89 */ 90 void 91 display_beep(void) 92 { 93 (void) putchar('\a'); 94 } 95 96 /* 97 * display_refresh: 98 * sync the display 99 */ 100 void 101 display_refresh(void) 102 { 103 (void) fflush(stdout); 104 } 105 106 /* 107 * display_clear_eol: 108 * clear to end of line, without moving cursor 109 */ 110 void 111 display_clear_eol(void) 112 { 113 if (CE != NULL) 114 tputs(CE, 1, __cputchar); 115 else { 116 fwrite(blanks, sizeof (char), SCREEN_WIDTH - cur_col, stdout); 117 if (COLS != SCREEN_WIDTH) 118 mvcur(cur_row, SCREEN_WIDTH, cur_row, cur_col); 119 else if (AM) 120 mvcur(cur_row + 1, 0, cur_row, cur_col); 121 else 122 mvcur(cur_row, SCREEN_WIDTH - 1, cur_row, cur_col); 123 } 124 memcpy(&screen[cur_row][cur_col], blanks, SCREEN_WIDTH - cur_col); 125 } 126 127 /* 128 * display_putchar: 129 * put one character on the screen, move the cursor right one, 130 * with wraparound 131 */ 132 void 133 display_put_ch(char ch) 134 { 135 if (!isprint(ch)) { 136 fprintf(stderr, "r,c,ch: %d,%d,%d", cur_row, cur_col, ch); 137 return; 138 } 139 screen[cur_row][cur_col] = ch; 140 putchar(ch); 141 if (++cur_col >= COLS) { 142 if (!AM || XN) 143 putchar('\n'); 144 cur_col = 0; 145 if (++cur_row >= LINES) 146 cur_row = LINES; 147 } 148 } 149 150 /* 151 * display_put_str: 152 * put a string of characters on the screen 153 */ 154 void 155 display_put_str(const char *s) 156 { 157 for( ; *s; s++) 158 display_put_ch(*s); 159 } 160 161 /* 162 * display_clear_the_screen: 163 * clear the screen; move cursor to top left 164 */ 165 void 166 display_clear_the_screen(void) 167 { 168 int i; 169 170 if (blanks[0] == '\0') 171 for (i = 0; i < SCREEN_WIDTH; i++) 172 blanks[i] = ' '; 173 174 if (CL != NULL) { 175 tputs(CL, LINES, __cputchar); 176 for (i = 0; i < SCREEN_HEIGHT; i++) 177 memcpy(screen[i], blanks, SCREEN_WIDTH); 178 } else { 179 for (i = 0; i < SCREEN_HEIGHT; i++) { 180 mvcur(cur_row, cur_col, i, 0); 181 cur_row = i; 182 cur_col = 0; 183 display_clear_eol(); 184 } 185 mvcur(cur_row, cur_col, 0, 0); 186 } 187 cur_row = cur_col = 0; 188 } 189 190 /* 191 * display_move: 192 * move the cursor 193 */ 194 void 195 display_move(int y, int x) 196 { 197 mvcur(cur_row, cur_col, y, x); 198 cur_row = y; 199 cur_col = x; 200 } 201 202 /* 203 * display_getyx: 204 * locate the cursor 205 */ 206 void 207 display_getyx(int *yp, int *xp) 208 { 209 *xp = cur_col; 210 *yp = cur_row; 211 } 212 213 /* 214 * display_end: 215 * close the display 216 */ 217 void 218 display_end(void) 219 { 220 tcsetattr(0, TCSADRAIN, &__orig_termios); 221 _puts(VE); 222 _puts(TE); 223 } 224 225 /* 226 * display_atyx: 227 * return a character from the screen 228 */ 229 char 230 display_atyx(int y, int x) 231 { 232 return screen[y][x]; 233 } 234 235 /* 236 * display_redraw_screen: 237 * redraw the screen 238 */ 239 void 240 display_redraw_screen(void) 241 { 242 int i; 243 244 mvcur(cur_row, cur_col, 0, 0); 245 for (i = 0; i < SCREEN_HEIGHT - 1; i++) { 246 fwrite(screen[i], sizeof (char), SCREEN_WIDTH, stdout); 247 if (COLS > SCREEN_WIDTH || (COLS == SCREEN_WIDTH && !AM)) 248 putchar('\n'); 249 } 250 fwrite(screen[SCREEN_HEIGHT - 1], sizeof (char), SCREEN_WIDTH - 1, 251 stdout); 252 mvcur(SCREEN_HEIGHT - 1, SCREEN_WIDTH - 1, cur_row, cur_col); 253 } 254 255 #else /* CURSES */ /* --------------------------------------------------- */ 256 257 #include <curses.h> 258 #include "hunt.h" 259 260 void 261 display_open(void) 262 { 263 initscr(); 264 (void) noecho(); 265 (void) cbreak(); 266 } 267 268 void 269 display_beep(void) 270 { 271 beep(); 272 } 273 274 void 275 display_refresh(void) 276 { 277 refresh(); 278 } 279 280 void 281 display_clear_eol(void) 282 { 283 clrtoeol(); 284 } 285 286 void 287 display_put_ch(char c) 288 { 289 addch(c); 290 } 291 292 void 293 display_put_str(const char *s) 294 { 295 addstr(s); 296 } 297 298 void 299 display_clear_the_screen(void) 300 { 301 clear(); 302 move(0, 0); 303 display_refresh(); 304 } 305 306 void 307 display_move(int y, int x) 308 { 309 move(y, x); 310 } 311 312 void 313 display_getyx(int *yp, int *xp) 314 { 315 getyx(stdscr, *yp, *xp); 316 } 317 318 void 319 display_end(void) 320 { 321 endwin(); 322 } 323 324 char 325 display_atyx(int y, int x) 326 { 327 int oy, ox; 328 char c; 329 330 display_getyx(&oy, &ox); 331 c = mvwinch(stdscr, y, x) & 0x7f; 332 display_move(oy, ox); 333 return (c); 334 } 335 336 void 337 display_redraw_screen(void) 338 { 339 clearok(stdscr, TRUE); 340 touchwin(stdscr); 341 } 342 343 int 344 display_iserasechar(char ch) 345 { 346 return ch == erasechar(); 347 } 348 349 int 350 display_iskillchar(char ch) 351 { 352 return ch == killchar(); 353 } 354 355 #endif 356