home *** CD-ROM | disk | FTP | other *** search
- // ┌───────┐
- // ─────────>│ AVNER │
- // ─────────>│ BEN │──────> Software Engineering Method
- // └───────┘
- // 10 Dov-Hoz st. Tel-Aviv 63416 Israel tel. 972-3-221535
-
- // The Screen NAVigator, ver 1.10 April 1990
- // Copyright (c) 1989 by Avner Ben
- // Snav is not, and never was, free software.
- // for conditions for use refer to file "copyrigh.txt"
-
- // The Screen Navigator is an object-oriented device-independent
- // character-graphics driver package, written in the C++ language,
- // distributed in the form of C++ source code.
- // For further information refer to the documentation files.
-
- // this simple example is intended as a template to be extended and modified
- // by the user, provided the above title and copyright notice are unchanged
- // and are not ommitted.
-
- /***************************************************************************/
-
- // demonstration part 1 - source code.
- // a simplistic screen driver for the IBM-PC/compatiable running MS-DOS,
- // implementing the virtual functions of the generic screen-driver supplied
- // in snav-2.
- // This simple demo is very device-specific, addressing the machine's
- // internal architecture (it is a "misbehaved" program). It is also
- // Zortech-specific, in assuming the existence of some names and include
- // files.
- // Do not compile with the /Ansi switch on, because dos.h uses far-pointers.
-
- // 28.8.89 avner ben coded.
- /////////// snav v1.0
- // 26.10.89 avner ben - adpated for snav demo.
- /////////// snav v1.1
- // 8.3.90-11.4.90 avner ben:
-
- // * C++ v2.0 upgrade * language=1 makes Hebrew screen (inverted
- // left-right). warning - this feature is not supported by query functions!
- // * adapted to new color indication * added (internal) cursor processing *
- // removed some function to generic driver *
-
- // Site history (of this copy):
- // __.__.__ ____________ : __________________.
-
- #include <stdio.h>
- #include <dos.h> // Do not compile with ANSI switch
- #include <stdlib.h>
-
- #include "demo1.hpp"
-
- #define calc_vdc() \
- if (lang==1) \
- vdc=stvdc+(pt->y()-1)*80+hlen-pt->x(); \
- else vdc=stvdc+(pt->y()-1)*80+pt->x()-1; \
-
- memory_mapped_pc_screen :: memory_mapped_pc_screen(square_pos *window,
- boolean inwrap) : panel(window,NULL,NULL,TRUE,inwrap)
- {
- color_code=encode_color(color);
- union REGS reg; reg.h.ah=15;
- int86(0x10,®,®); // call dos routine #10
- if (reg.h.al!=7) stvdc=(vd_char *)0xb8000000L; // cga
- else stvdc=(vd_char *)0xb0000000L; // mda
- vdc=stvdc;
- svbuf=NULL;
- fix();
- }
-
- void memory_mapped_pc_screen :: fix()
- {
- color_code=encode_color(color);
- panel::fix();
- }
-
- unsigned int memory_mapped_pc_screen :: encode_color(const color_ind &color)
- {
- unsigned int result=0;
- int at=color.attr;
- if (at&VD_REV)
- result=color.backgnd|(color.forgnd*0x10);
- else if (at&VD_HID)
- result=color.backgnd|(color.backgnd*0x10);
- else result=color.forgnd|(color.backgnd*0x10);
- if (at) {
- if (at&VD_HI) result|=0x08; // forground only
- if (at&VD_UNDLN) result|=0x01; // blue in color
- if (at&VD_BLNK) result|=0x80;
- }
- return result;
- }
-
- color_ind memory_mapped_pc_screen :: decode_color(unsigned int code)
- {
- color_ind result;
- if (code) {
- if (code&0x08) result.attr|=VD_HI;
- // if (code&0x01) result.attr|=VD_UNDLN; underline or blue?
- if (code&0x80) result.attr|=VD_BLNK;
- }
- result.forgnd=(vd_clr)code&0x07;
- result.backgnd=(vd_clr)((code&0x70)/0x10);
- if (result.forgnd==result.backgnd) result.attr|=VD_HID;
- if (result.forgnd==def_color.backgnd && result.backgnd==def_color.forgnd)
- result.attr|=VD_REV;
- return result;
- }
-
- void memory_mapped_pc_screen :: put_c(char c, point_pos *pt0, direction *dir)
- { // write a character on console
-
- point_pos *pt=(pt0? pt0 : &cursor);
- if (!ask_legal(pt)) return;
- calc_vdc();
- if (vdc->c!=c) vdc->c=c; // poke char
- if (vdc->color!=color_code)
- vdc->color=color_code; // poke attribute
- if (!pt0) wpnext((dir? dir : &curdir)); // advance cursor with wrap
- }
-
- void memory_mapped_pc_screen :: put_color(const color_ind &clr, point_pos *pt)
- { // write a character on console
-
- if (!pt) pt=&cursor;
- if (!ask_legal(pt)) return;
- calc_vdc();
- unsigned int icolor=encode_color(clr);
- if (vdc->color!=icolor) vdc->color=icolor; // poke attribute
- }
-
- void memory_mapped_pc_screen :: put_attr(vd_attr at, point_pos *pt)
- { // write a character on console
-
- if (!pt) pt=&cursor;
- if (!ask_legal(pt)) return;
- calc_vdc();
- color_ind clr=decode_color((unsigned)vdc->color);
- clr.toggle_attr(at);
- unsigned int icolor=encode_color(clr);
- vdc->color=icolor; // poke attribute
- }
-
- void memory_mapped_pc_screen :: put_background(vd_clr colornum, point_pos *pt)
- { // set background color in specified/cursor position
-
- if (!pt) pt=&cursor;
- if (!ask_legal(pt)) return;
- calc_vdc();
- color_ind clr=decode_color((unsigned)vdc->color);
- clr.backgnd=colornum;
- unsigned int icolor=encode_color(clr);
- vdc->color=icolor; // poke attribute
- }
-
- void memory_mapped_pc_screen :: put_forground(vd_clr colornum, point_pos *pt)
- { // set forground color in specified/cursor position
-
- if (!pt) pt=&cursor;
- if (!ask_legal(pt)) return;
- calc_vdc();
- color_ind clr=decode_color((unsigned)vdc->color);
- clr.forgnd=colornum;
- unsigned int icolor=encode_color(clr);
- vdc->color=icolor; // poke attribute
- }
-
- void memory_mapped_pc_screen :: posit(point_pos *pt)
- { // position cursor
-
- if (pt) {
- if (!ask_legal(pt)) return;
- cursor=*pt;
- }
- union REGS reg; reg.h.ah=2; reg.h.bh=0;
- int y=cursor.y()-1, x;
- if (lang==1) x=bot.x()+2-cursor.x();
- else x=cursor.x()-1;
- reg.x.dx=(y<<8)+x;
- int86(0x10,®,®); // call dos routine #10
- }
-
- char memory_mapped_pc_screen :: get_c(point_pos *pt)
- { // read character currently on console (no keyboard input)
-
- if (!pt) pt=&cursor;
- if (!ask_legal(pt)) return ' ';
- calc_vdc();
- return vdc->c;
- }
-
- color_ind memory_mapped_pc_screen :: get_color(point_pos *pt)
- { // read character attribute currently on console (no keyboard input)
-
- if (!pt) pt=&cursor;
- if (!ask_legal(pt)) return color_ind();
- calc_vdc();
- return decode_color((unsigned)vdc->color);
- }
-
- boolean memory_mapped_pc_screen :: get_attr(vd_attr at, point_pos *pt)
- { // match character attribute currently on console
-
- if (!pt) pt=&cursor;
- if (!ask_legal(pt)) return 0;
- calc_vdc();
- return (decode_color((unsigned)vdc->color).attr) & at;
- }
-
- void save_screen :: kill()
- {
- save_screen *nxt=next;
- for (save_screen *buf=this; nxt; buf=buf->next) {
- nxt=buf->next;
- delete(buf->s);
- delete buf;
- }
- }
-
- void memory_mapped_pc_screen :: save(void)
- { // this may be the most machine-dependent code you have ever seen...
-
- if (svbuf) { svbuf->kill(); svbuf=NULL; }
- const int wd=sizeof(vd_char);
- int len=(ask_limit(rt)-ask_limit(lt)+1)*wd;
- char *stsv=(char *)stvdc+((ask_limit(up)-1)*80*wd+ask_limit(lt)*wd-wd);
- int maxy=ask_limit(dn);
- save_screen *buf;
- for (int y=ask_limit(up); y<=maxy; y++) {
- if (!svbuf) buf=svbuf=new save_screen;
- else buf=buf->next=new save_screen;
- buf->s=new char[len];
- buf->next=NULL;
- if (!svbuf) {
- clear();
- puts("fatal error: out of memory (while saving scren)");
- exit(1);
- }
- memcpy(buf->s,stsv,len);
- stsv+=80*wd;
- }
- }
-
- void memory_mapped_pc_screen :: restore(void)
- { // warning: user must not modify screen dimensions after "save"
- // operation, or restore will smear the screen!
-
- if (!svbuf) return;
- const int wd=sizeof(vd_char);
- int len=(ask_limit(rt)-ask_limit(lt)+1)*wd;
- char *stsv=(char *)stvdc+((ask_limit(up)-1)*80*wd+ask_limit(lt)*wd-wd);
- for (save_screen *buf=svbuf; buf; buf=buf->next) {
- memcpy(stsv,buf->s,len);
- stsv+=80*wd;
- }
- svbuf->kill(); svbuf=NULL;
- }
-
- unsigned int memory_mapped_pc_screen :: ask_cursor()
- {
- union REGS reg; reg.h.ah = 3; reg.h.bh = 0;
- int86(0X10, ®, ®);
- return(reg.x.cx);
- }
-
- void memory_mapped_pc_screen :: set_cursor(unsigned int cursor_type)
- {
- union REGS reg; reg.h.ah = 1; reg.x.cx = cursor_type;
- int86(0X10, ®, ®);
- }
-
- unsigned int memory_mapped_pc_screen :: hide_cursor()
- {
- unsigned int result=ask_cursor();
- set_cursor(0x2000);
- return result;
- }
-
-
-