home *** CD-ROM | disk | FTP | other *** search
/ Liren Large Software Subsidy 7 / 07.iso / c / c100 / 1.ddi / SNAV0111.ZIP / DEMO1.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1990-04-16  |  8.1 KB  |  280 lines

  1. //          ┌───────┐
  2. //    ─────────>│ AVNER │
  3. //    ─────────>│  BEN  │──────> Software Engineering Method
  4. //          └───────┘
  5. //    10 Dov-Hoz st. Tel-Aviv 63416 Israel tel. 972-3-221535
  6.  
  7. // The Screen NAVigator, ver 1.10 April 1990
  8. // Copyright (c) 1989 by Avner Ben
  9. // Snav is not, and never was, free software.
  10. // for conditions for use refer to file "copyrigh.txt"
  11.  
  12. // The Screen Navigator is an object-oriented device-independent
  13. // character-graphics driver package, written in the C++ language,
  14. // distributed in the form of C++ source code.
  15. // For further information refer to the documentation files.
  16.  
  17. // this simple example is intended as a template to be extended and modified
  18. // by the user, provided the above title and copyright notice are unchanged
  19. // and are not ommitted.
  20.  
  21. /***************************************************************************/
  22.  
  23. // demonstration part 1 - source code.
  24. // a simplistic screen driver for the IBM-PC/compatiable running MS-DOS,
  25. // implementing the virtual functions of the generic screen-driver supplied
  26. // in snav-2.
  27. // This simple demo is very device-specific, addressing the machine's
  28. // internal architecture (it is a "misbehaved" program). It is also
  29. // Zortech-specific, in assuming the existence of some names and include
  30. // files.
  31. // Do not compile with the /Ansi switch on, because dos.h uses far-pointers.
  32.  
  33. // 28.8.89 avner ben coded.
  34. /////////// snav v1.0
  35. // 26.10.89 avner ben - adpated for snav demo.
  36. /////////// snav v1.1
  37. // 8.3.90-11.4.90 avner ben:
  38.  
  39. // *  C++  v2.0  upgrade   *  language=1  makes  Hebrew   screen  (inverted
  40. // left-right). warning - this feature is not supported by query functions!
  41. // * adapted to new color indication * added (internal) cursor processing *
  42. // removed some function to generic driver *
  43.  
  44. // Site history (of this copy):
  45. // __.__.__ ____________ : __________________.
  46.  
  47. #include <stdio.h>
  48. #include <dos.h>  // Do not compile with ANSI switch
  49. #include <stdlib.h>
  50.  
  51. #include "demo1.hpp"
  52.  
  53. #define calc_vdc() \
  54.     if (lang==1) \
  55.         vdc=stvdc+(pt->y()-1)*80+hlen-pt->x(); \
  56.     else vdc=stvdc+(pt->y()-1)*80+pt->x()-1; \
  57.  
  58. memory_mapped_pc_screen :: memory_mapped_pc_screen(square_pos *window,
  59.  boolean inwrap) : panel(window,NULL,NULL,TRUE,inwrap)
  60. {
  61.     color_code=encode_color(color);
  62.     union REGS reg; reg.h.ah=15;
  63.     int86(0x10,®,®);            // call dos routine #10
  64.     if (reg.h.al!=7) stvdc=(vd_char *)0xb8000000L;    // cga
  65.     else stvdc=(vd_char *)0xb0000000L;        // mda
  66.     vdc=stvdc;
  67.     svbuf=NULL;
  68.     fix();
  69. }
  70.  
  71. void memory_mapped_pc_screen :: fix()
  72. {
  73.     color_code=encode_color(color);
  74.     panel::fix();
  75. }
  76.  
  77. unsigned int memory_mapped_pc_screen :: encode_color(const color_ind &color)
  78. {
  79.     unsigned int result=0;
  80.     int at=color.attr;
  81.     if (at&VD_REV)
  82.         result=color.backgnd|(color.forgnd*0x10);
  83.     else if (at&VD_HID)
  84.         result=color.backgnd|(color.backgnd*0x10);
  85.     else result=color.forgnd|(color.backgnd*0x10);
  86.     if (at) {
  87.         if (at&VD_HI) result|=0x08;             // forground only
  88.         if (at&VD_UNDLN) result|=0x01;              // blue in color
  89.         if (at&VD_BLNK) result|=0x80;
  90.     }
  91.     return result;
  92. }
  93.  
  94. color_ind memory_mapped_pc_screen :: decode_color(unsigned int code)
  95. {
  96.     color_ind result;
  97.     if (code) {
  98.         if (code&0x08) result.attr|=VD_HI;
  99. //        if (code&0x01) result.attr|=VD_UNDLN; underline or blue?
  100.         if (code&0x80) result.attr|=VD_BLNK;
  101.     }
  102.     result.forgnd=(vd_clr)code&0x07;
  103.     result.backgnd=(vd_clr)((code&0x70)/0x10);
  104.     if (result.forgnd==result.backgnd) result.attr|=VD_HID;
  105.     if (result.forgnd==def_color.backgnd && result.backgnd==def_color.forgnd)
  106.         result.attr|=VD_REV;
  107.     return result;
  108. }
  109.  
  110. void memory_mapped_pc_screen :: put_c(char c, point_pos *pt0, direction *dir)
  111. { // write a character on console
  112.  
  113.     point_pos *pt=(pt0? pt0 : &cursor);
  114.     if (!ask_legal(pt)) return;
  115.     calc_vdc();
  116.     if (vdc->c!=c) vdc->c=c;                  // poke char
  117.     if (vdc->color!=color_code)
  118.         vdc->color=color_code;                 // poke attribute
  119.     if (!pt0) wpnext((dir? dir : &curdir));    // advance cursor with wrap
  120. }
  121.  
  122. void memory_mapped_pc_screen :: put_color(const color_ind &clr, point_pos *pt)
  123. { // write a character on console
  124.  
  125.     if (!pt) pt=&cursor;
  126.     if (!ask_legal(pt)) return;
  127.     calc_vdc();
  128.     unsigned int icolor=encode_color(clr);
  129.     if (vdc->color!=icolor) vdc->color=icolor;         // poke attribute
  130. }
  131.  
  132. void memory_mapped_pc_screen :: put_attr(vd_attr at, point_pos *pt)
  133. { // write a character on console
  134.  
  135.     if (!pt) pt=&cursor;
  136.     if (!ask_legal(pt)) return;
  137.     calc_vdc();
  138.     color_ind clr=decode_color((unsigned)vdc->color);
  139.     clr.toggle_attr(at);
  140.     unsigned int icolor=encode_color(clr);
  141.     vdc->color=icolor;                     // poke attribute
  142. }
  143.  
  144. void memory_mapped_pc_screen :: put_background(vd_clr colornum, point_pos *pt)
  145. { // set background color in specified/cursor position
  146.  
  147.     if (!pt) pt=&cursor;
  148.     if (!ask_legal(pt)) return;
  149.     calc_vdc();
  150.     color_ind clr=decode_color((unsigned)vdc->color);
  151.     clr.backgnd=colornum;
  152.     unsigned int icolor=encode_color(clr);
  153.     vdc->color=icolor;                     // poke attribute
  154. }
  155.  
  156. void memory_mapped_pc_screen :: put_forground(vd_clr colornum, point_pos *pt)
  157. { // set forground color in specified/cursor position
  158.  
  159.     if (!pt) pt=&cursor;
  160.     if (!ask_legal(pt)) return;
  161.     calc_vdc();
  162.     color_ind clr=decode_color((unsigned)vdc->color);
  163.     clr.forgnd=colornum;
  164.     unsigned int icolor=encode_color(clr);
  165.     vdc->color=icolor;                     // poke attribute
  166. }
  167.  
  168. void memory_mapped_pc_screen :: posit(point_pos *pt)
  169. { // position cursor
  170.  
  171.     if (pt) {
  172.         if (!ask_legal(pt)) return;
  173.         cursor=*pt;
  174.     }
  175.     union REGS reg; reg.h.ah=2; reg.h.bh=0;
  176.     int y=cursor.y()-1, x;
  177.     if (lang==1) x=bot.x()+2-cursor.x();
  178.     else x=cursor.x()-1;
  179.     reg.x.dx=(y<<8)+x;
  180.     int86(0x10,®,®);            // call dos routine #10
  181. }
  182.  
  183. char memory_mapped_pc_screen :: get_c(point_pos *pt)
  184. { // read character currently on console (no keyboard input)
  185.  
  186.     if (!pt) pt=&cursor;
  187.     if (!ask_legal(pt)) return ' ';
  188.     calc_vdc();
  189.     return vdc->c;
  190. }
  191.  
  192. color_ind memory_mapped_pc_screen :: get_color(point_pos *pt)
  193. { // read character attribute currently on console (no keyboard input)
  194.  
  195.     if (!pt) pt=&cursor;
  196.     if (!ask_legal(pt)) return color_ind();
  197.     calc_vdc();
  198.     return decode_color((unsigned)vdc->color);
  199. }
  200.  
  201. boolean memory_mapped_pc_screen :: get_attr(vd_attr at, point_pos *pt)
  202. { // match character attribute currently on console
  203.  
  204.     if (!pt) pt=&cursor;
  205.     if (!ask_legal(pt)) return 0;
  206.     calc_vdc();
  207.     return (decode_color((unsigned)vdc->color).attr) & at;
  208. }
  209.  
  210. void save_screen :: kill()
  211. {
  212.     save_screen *nxt=next;
  213.     for (save_screen *buf=this; nxt; buf=buf->next) {
  214.         nxt=buf->next;
  215.         delete(buf->s);
  216.         delete buf;
  217.     }
  218. }
  219.  
  220. void memory_mapped_pc_screen :: save(void)
  221. { // this may be the most machine-dependent code you have ever seen...
  222.  
  223.     if (svbuf) { svbuf->kill(); svbuf=NULL; }
  224.     const int wd=sizeof(vd_char);
  225.     int len=(ask_limit(rt)-ask_limit(lt)+1)*wd;
  226.     char *stsv=(char *)stvdc+((ask_limit(up)-1)*80*wd+ask_limit(lt)*wd-wd);
  227.     int maxy=ask_limit(dn);
  228.     save_screen *buf;
  229.     for (int y=ask_limit(up); y<=maxy; y++) {
  230.         if (!svbuf) buf=svbuf=new save_screen;
  231.         else buf=buf->next=new save_screen;
  232.         buf->s=new char[len];
  233.         buf->next=NULL;
  234.         if (!svbuf) {
  235.             clear();
  236.             puts("fatal error: out of memory (while saving scren)");
  237.             exit(1);
  238.         }
  239.         memcpy(buf->s,stsv,len);
  240.         stsv+=80*wd;
  241.     }
  242. }
  243.  
  244. void memory_mapped_pc_screen :: restore(void)
  245. { // warning: user must not modify screen dimensions after "save"
  246.   // operation, or restore will smear the screen!
  247.  
  248.     if (!svbuf) return;
  249.     const int wd=sizeof(vd_char);
  250.     int len=(ask_limit(rt)-ask_limit(lt)+1)*wd;
  251.     char *stsv=(char *)stvdc+((ask_limit(up)-1)*80*wd+ask_limit(lt)*wd-wd);
  252.     for (save_screen *buf=svbuf; buf; buf=buf->next) {
  253.         memcpy(stsv,buf->s,len);
  254.         stsv+=80*wd;
  255.     }
  256.     svbuf->kill(); svbuf=NULL;
  257. }
  258.  
  259. unsigned int  memory_mapped_pc_screen :: ask_cursor()
  260. {
  261.      union REGS reg; reg.h.ah = 3; reg.h.bh = 0;
  262.      int86(0X10, ®, ®);
  263.      return(reg.x.cx);
  264. }
  265.  
  266. void memory_mapped_pc_screen :: set_cursor(unsigned int cursor_type)
  267. {
  268.      union REGS reg; reg.h.ah = 1; reg.x.cx = cursor_type;
  269.      int86(0X10, ®, ®);
  270. }
  271.  
  272. unsigned int memory_mapped_pc_screen :: hide_cursor()
  273. {
  274.     unsigned int result=ask_cursor();
  275.     set_cursor(0x2000);
  276.     return result;
  277. }
  278.  
  279.  
  280.