1 /* 2 * Cursor motion stuff to simulate a "no refresh" version of curses 3 */ 4 #include "rogue.h" 5 #include "curses.h" 6 7 char *sbrk(); 8 /* 9 * Globals for curses 10 */ 11 int LINES=25, COLS=80; 12 int is_saved = FALSE; 13 int iscuron = TRUE; 14 int ch_attr = 0x7; 15 int old_page_no; 16 int no_check = FALSE; 17 18 int scr_ds=0xB800; 19 int svwin_ds; 20 21 char *savewin; 22 int scr_type = -1; 23 int tab_size = 8; 24 int page_no = 0; 25 26 #define MAXATTR 17 27 byte color_attr[] = { 28 7, /* 0 normal */ 29 2, /* 1 green */ 30 3, /* 2 cyan */ 31 4, /* 3 red */ 32 5, /* 4 magenta */ 33 6, /* 5 brown */ 34 8, /* 6 dark grey */ 35 9, /* 7 light blue */ 36 10, /* 8 light green */ 37 12, /* 9 light red */ 38 13, /* 10 light magenta */ 39 14, /* 11 yellow */ 40 15, /* 12 uline */ 41 1, /* 13 blue */ 42 112,/* 14 reverse */ 43 15, /* 15 high intensity */ 44 112, /* bold */ 45 0 /* no more */ 46 } ; 47 48 byte monoc_attr[] = { 49 7, /* 0 normal */ 50 7, /* 1 green */ 51 7, /* 2 cyan */ 52 7, /* 3 red */ 53 7, /* 4 magenta */ 54 7, /* 5 brown */ 55 7, /* 6 dark grey */ 56 7, /* 7 light blue */ 57 7, /* 8 light green */ 58 7, /* 9 light red */ 59 7, /* 10 light magenta */ 60 7, /* 11 yellow */ 61 17, /* 12 uline */ 62 7, /* 13 blue */ 63 120, /* 14 reverse */ 64 7, /* 15 white/hight */ 65 120, /* 16 bold */ 66 0 /* no more */ 67 } ; 68 69 byte *at_table; 70 71 int c_row, c_col; /* Save cursor positions so we don't ask dos */ 72 int scr_row[25]; 73 74 byte dbl_box[BX_SIZE] = { 75 0xc9, 0xbb, 0xc8, 0xbc, 0xba, 0xcd, 0xcd 76 }; 77 78 byte sng_box[BX_SIZE] = { 79 0xda, 0xbf, 0xc0, 0xd9, 0xb3, 0xc4, 0xc4 80 }; 81 82 byte fat_box[BX_SIZE] = { 83 0xdb, 0xdb, 0xdb, 0xdb, 0xdb, 0xdf, 0xdc 84 }; 85 86 byte spc_box[BX_SIZE] = { 87 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 88 }; 89 90 /* 91 * clear screen 92 */ 93 clear() 94 { 95 if (scr_ds == svwin_ds) 96 wsetmem(savewin, LINES*COLS, 0x0720); 97 else 98 blot_out(0,0,LINES-1,COLS-1); 99 } 100 101 102 /* 103 * Turn cursor on and off 104 */ 105 cursor(ison) 106 bool ison; 107 { 108 register int oldstate; 109 register int w_state; 110 111 112 if (iscuron == ison) 113 return ison; 114 oldstate = iscuron; 115 iscuron = ison; 116 117 regs->ax = 0x100; 118 if (ison) 119 { 120 regs->cx = (is_color ? 0x607 : 0xb0c); 121 swint(SW_SCR, regs); 122 move(c_row, c_col); 123 } 124 else 125 { 126 regs->cx = 0xf00; 127 swint(SW_SCR, regs); 128 } 129 return(oldstate); 130 } 131 132 133 /* 134 * get curent cursor position 135 */ 136 getrc(rp,cp) 137 int *rp, *cp; 138 { 139 *rp = c_row; 140 *cp = c_col; 141 } 142 143 real_rc(pn, rp,cp) 144 int *rp, *cp; 145 { 146 /* 147 * pc bios: read current cursor position 148 */ 149 regs->ax = 0x300; 150 regs->bx = pn << 8; 151 152 swint(SW_SCR, regs); 153 154 *rp = regs->dx >> 8; 155 *cp = regs->dx & 0xff; 156 } 157 158 /* 159 * clrtoeol 160 */ 161 clrtoeol() 162 { 163 int r,c; 164 165 if (scr_ds == svwin_ds) 166 return; 167 getrc(&r,&c); 168 blot_out(r,c,r,COLS-1); 169 } 170 171 mvaddstr(r,c,s) 172 int r,c; 173 char *s; 174 { 175 move(r, c); 176 addstr(s); 177 } 178 179 mvaddch(r,c,chr) 180 int r, c; 181 char chr; 182 { 183 move(r, c); 184 addch(chr); 185 } 186 187 mvinch(r, c) 188 int r, c; 189 { 190 move(r, c); 191 return(curch()&0xff); 192 } 193 194 /* 195 * put the character on the screen and update the 196 * character position 197 */ 198 199 addch(chr) 200 byte chr; 201 { 202 int r, c; 203 register int newc, newr; 204 byte old_attr; 205 206 old_attr = ch_attr; 207 208 if (at_table == color_attr) 209 { 210 /* if it is inside a room */ 211 if (ch_attr == 7) 212 switch(chr) 213 { 214 case DOOR: 215 case VWALL: 216 case HWALL: 217 case ULWALL: 218 case URWALL: 219 case LLWALL: 220 case LRWALL: 221 ch_attr = 6; /* brown */ 222 break; 223 case FLOOR: 224 ch_attr = 10; /* light green */ 225 break; 226 case STAIRS: 227 ch_attr = 160; /* black on green*/ 228 break; 229 case TRAP: 230 ch_attr = 5; /* magenta */ 231 break; 232 case GOLD: 233 case PLAYER: 234 ch_attr = 14; /* yellow */ 235 break; 236 case POTION: 237 case SCROLL: 238 case STICK: 239 case ARMOR: 240 case AMULET: 241 case RING: 242 case WEAPON: 243 ch_attr = 9; 244 break; 245 case FOOD: 246 ch_attr = 4; 247 break; 248 } 249 /* if inside a passage or a maze */ 250 else if (ch_attr == 112) 251 switch(chr) 252 { 253 case FOOD: 254 ch_attr = 116; /* red */ 255 break; 256 case GOLD: 257 case PLAYER: 258 ch_attr = 126; /* yellow on white */ 259 break; 260 case POTION: 261 case SCROLL: 262 case STICK: 263 case ARMOR: 264 case AMULET: 265 case RING: 266 case WEAPON: 267 ch_attr = 113; /* blue on white */ 268 break; 269 } 270 else if (ch_attr == 15 && chr == STAIRS) 271 ch_attr = 160; 272 } 273 274 getrc(&r,&c); 275 if (chr == '\n') { 276 if (r == LINES-1) { 277 scroll_up(0, LINES-1, 1); 278 move(LINES-1, 0); 279 } else 280 move(r+1, 0); 281 ch_attr = old_attr; 282 return c_row; 283 } 284 putchr(chr); 285 move(r,c+1); 286 ch_attr = old_attr; 287 /* 288 * if you have gone of the screen scroll the whole window 289 */ 290 return(c_row); 291 } 292 293 addstr(s) 294 char *s; 295 { 296 while(*s) 297 addch(*s++); 298 } 299 300 set_attr(bute) 301 int bute; 302 { 303 if (bute < MAXATTR) 304 ch_attr = at_table[bute]; 305 else 306 ch_attr = bute; 307 } 308 309 error(mline,msg,a1,a2,a3,a4,a5) 310 int mline; 311 char *msg; 312 int a1,a2,a3,a4,a5; 313 { 314 int row, col; 315 316 getrc(&row,&col); 317 move(mline,0); 318 clrtoeol(); 319 printw(msg,a1,a2,a3,a4,a5); 320 move(row,col); 321 } 322 323 /* 324 * Called when rogue runs to move our cursor to be where DOS thinks 325 * the cursor is 326 */ 327 328 set_cursor() 329 { 330 /* 331 regs->ax = 15 << 8; 332 swint(SW_SCR, regs); 333 real_rc(regs->bx >> 8, &c_row, &c_col); 334 */ 335 } 336 337 /* 338 * winit(win_name): 339 * initialize window -- open disk window 340 * -- determine type of moniter 341 * -- determine screen memory location for dma 342 */ 343 winit(drive) 344 char drive; 345 { 346 register int i, cnt; 347 extern int _dsval; 348 349 /* 350 * Get monitor type 351 */ 352 regs->ax = 15 << 8; 353 swint(SW_SCR, regs); 354 old_page_no = regs->bx >> 8; 355 scr_type = regs->ax = 0xff & regs->ax; 356 /* 357 * initialization is any good because restarting game 358 * has old values!!! 359 * So reassign defaults 360 */ 361 LINES = 25; 362 COLS = 80; 363 scr_ds = 0xB800; 364 at_table = monoc_attr; 365 366 switch (scr_type) { 367 /* 368 * It is a TV 369 */ 370 case 1: 371 at_table = color_attr; 372 case 0: 373 COLS = 40; 374 break; 375 376 /* 377 * Its a high resolution monitor 378 */ 379 case 3: 380 at_table = color_attr; 381 case 2: 382 break; 383 case 7: 384 scr_ds = 0xB000; 385 no_check = TRUE; 386 break; 387 /* 388 * Just to save text space lets eliminate these 389 * 390 case 4: 391 case 5: 392 case 6: 393 move(24,0); 394 fatal("Program can't be run in graphics mode"); 395 */ 396 default: 397 move(24,0); 398 fatal("Unknown screen type (%d)",regs->ax); 399 } 400 /* 401 * Read current cursor position 402 */ 403 real_rc(old_page_no, &c_row, &c_col); 404 if ((savewin = sbrk(4096)) == -1) { 405 svwin_ds = -1; 406 savewin = (char *) _flags; 407 if (scr_type == 7) 408 fatal(no_mem); 409 } else { 410 savewin = (char *) (((int) savewin + 0xf) & 0xfff0); 411 svwin_ds = (((int) savewin >> 4) & 0xfff) + _dsval; 412 } 413 for (i = 0, cnt = 0; i < 25; cnt += 2*COLS, i++) 414 scr_row[i] = cnt; 415 newmem(2); 416 switch_page(3); 417 if (old_page_no != page_no) 418 clear(); 419 move(c_row, c_col); 420 if (isjr()) 421 no_check = TRUE; 422 } 423 424 forcebw() 425 { 426 at_table = monoc_attr; 427 } 428 429 /* 430 * wdump(windex) 431 * dump the screen off to disk, the window is save so that 432 * it can be retieved using windex 433 */ 434 wdump() 435 { 436 sav_win(); 437 dmain(savewin,LINES*COLS,scr_ds,0); 438 is_saved = TRUE; 439 } 440 441 sav_win() 442 { 443 if (savewin == _flags) 444 dmaout(savewin,LINES*COLS,0xb800,8192); 445 return(savewin); 446 } 447 448 res_win() 449 { 450 if (savewin == _flags) 451 dmain(savewin,LINES*COLS,0xb800,8192); 452 } 453 454 /* 455 * wrestor(windex): 456 * restor the window saved on disk 457 */ 458 wrestor() 459 { 460 dmaout(savewin,LINES*COLS,scr_ds,0); 461 res_win(); 462 is_saved = FALSE; 463 } 464 465 /* 466 * wclose() 467 * close the window file 468 */ 469 wclose() 470 { 471 472 /* 473 * Restor cursor (really you want to restor video state, but be carefull) 474 */ 475 if (scr_type >= 0) 476 cursor(TRUE); 477 if (page_no != old_page_no) 478 switch_page(old_page_no); 479 } 480 481 /* 482 * Some general drawing routines 483 */ 484 485 box(ul_r, ul_c, lr_r, lr_c) 486 { 487 vbox(dbl_box, ul_r, ul_c, lr_r, lr_c); 488 } 489 490 /* 491 * box: draw a box using given the 492 * upper left coordinate and the lower right 493 */ 494 495 vbox(box, ul_r,ul_c,lr_r,lr_c) 496 byte box[BX_SIZE]; 497 int ul_r,ul_c,lr_r,lr_c; 498 { 499 register int i, wason; 500 int r,c; 501 502 wason = cursor(FALSE); 503 getrc(&r,&c); 504 505 /* 506 * draw horizontal boundry 507 */ 508 move(ul_r, ul_c+1); 509 repchr(box[BX_HT], i = (lr_c - ul_c - 1)); 510 move(lr_r, ul_c+1); 511 repchr(box[BX_HB], i); 512 /* 513 * draw vertical boundry 514 */ 515 for (i=ul_r+1;iax = 0x600 + nlines; 558 regs->bx = 0x700; 559 regs->cx = start_row << 8; 560 regs->dx = (end_row << 8) + COLS - 1; 561 swint(SW_SCR,regs); 562 move(end_row,c_col); 563 } 564 scroll_dn(start_row,end_row,nlines) 565 int start_row,end_row,nlines; 566 { 567 regs->ax = 0x700 + nlines; 568 regs->bx = 0x700; 569 regs->cx = start_row << 8; 570 regs->dx = (end_row << 8) + COLS - 1; 571 swint(SW_SCR,regs); 572 move(start_row,c_col); 573 } 574 575 scroll() 576 { 577 scroll_up(0,24,1); 578 } 579 580 581 582 /* 583 * blot_out region 584 * (upper left row, upper left column) 585 * (lower right row, lower right column) 586 */ 587 blot_out(ul_row,ul_col,lr_row,lr_col) 588 { 589 regs->ax = 0x600; 590 regs->bx = 0x700; 591 regs->cx = (ul_row<<8) + ul_col; 592 regs->dx = (lr_row<<8) + lr_col; 593 swint(SW_SCR,regs); 594 move(ul_row,ul_col); 595 } 596 597 repchr(chr,cnt) 598 int chr, cnt; 599 { 600 while(cnt-- > 0) { 601 putchr(chr); 602 c_col++; 603 } 604 } 605 606 /* 607 * try to fixup screen after we get a control break 608 */ 609 fixup() 610 { 611 blot_out(c_row,c_col,c_row,c_col+1); 612 } 613 614 /* 615 * Clear the screen in an interesting fashion 616 */ 617 618 implode() 619 { 620 int j, delay, r, c, cinc = COLS/10/2, er, ec; 621 622 er = (COLS == 80 ? LINES-3 : LINES-4); 623 /* 624 * If the curtain is down, just clear the memory 625 */ 626 if (scr_ds == svwin_ds) { 627 wsetmem(savewin, (er + 1) * COLS, 0x0720); 628 return; 629 } 630 delay = scr_type == 7 ? 500 : 10; 631 for (r = 0,c = 0,ec = COLS-1; r < 10; r++,c += cinc,er--,ec -= cinc) { 632 vbox(sng_box, r, c, er, ec); 633 for (j = delay; j--; ) 634 ; 635 for (j = r+1; j <= er-1; j++) { 636 move(j, c+1); repchr(' ', cinc-1); 637 move(j, ec-cinc+1); repchr(' ', cinc-1); 638 } 639 vbox(spc_box, r, c, er, ec); 640 } 641 } 642 643 /* 644 * drop_curtain: 645 * Close a door on the screen and redirect output to the temporary buffer 646 */ 647 static int old_ds; 648 drop_curtain() 649 { 650 register int r, c, j, delay; 651 652 if (svwin_ds == -1) 653 return; 654 old_ds = scr_ds; 655 dmain(savewin, LINES * COLS, scr_ds, 0); 656 cursor(FALSE); 657 delay = (scr_type == 7 ? 3000 : 2000); 658 green(); 659 vbox(sng_box, 0, 0, LINES-1, COLS-1); 660 yellow(); 661 for (r = 1; r < LINES-1; r++) { 662 move(r, 1); 663 repchr(0xb1, COLS-2); 664 for (j = delay; j--; ) 665 ; 666 } 667 scr_ds = svwin_ds; 668 move(0,0); 669 standend(); 670 } 671 672 raise_curtain() 673 { 674 register int i, j, o, delay; 675 676 if (svwin_ds == -1) 677 return; 678 scr_ds = old_ds; 679 delay = (scr_type == 7 ? 3000 : 2000); 680 for (i = 0, o = (LINES-1)*COLS*2; i < LINES; i++, o -= COLS*2) { 681 dmaout(savewin + o, COLS, scr_ds, o); 682 for (j = delay; j--; ) 683 ; 684 } 685 } 686 687 switch_page(pn) 688 { 689 register int pgsize; 690 691 if (scr_type == 7) { 692 page_no = 0; 693 return; 694 } 695 if (COLS == 40) 696 pgsize = 2048; 697 else 698 pgsize = 4096; 699 regs->ax = 0x0500 | pn; 700 swint(SW_SCR, regs); 701 scr_ds = 0xb800 + ((pgsize * pn) >> 4); 702 page_no = pn; 703 } 704 705 get_mode(type) 706 { 707 struct sw_regs regs; 708 709 regs.ax = 0xF00; 710 swint(SW_SCR,®s); 711 return 0xff & regs.ax; 712 } 713 714 video_mode(type) 715 { 716 struct sw_regs regs; 717 718 regs.ax = type; 719 swint(SW_SCR,®s); 720 return regs.ax; 721 } 722 ÿ