home *** CD-ROM | disk | FTP | other *** search
Text File | 1986-01-06 | 23.2 KB | 1,083 lines |
- /*
- gpc - integer interface to graphics on IBM video card
-
- mode 4 (200 by 320 pixels, 4 colors
- mode 5 (200 by 320 pixels, 4 levels of grey)
- mode 6 (200 by 640 pixels, black and white)
-
- history...
- 12 Sep 85 Modes 4, 5 and 6 implemented.
- 6 Aug 85 Loading cx with *inverted* shifted color code.
- 4 Aug 85 Converted from mode 6 to mode 5.
- 11 May 85 Declaring that cursor keys are preceded by 0.
- 2 May 85 Corrected aspect ratio, corrected gotoxy().
- 27 Apr 85 Exporting "down_arrow", etc.
- 20 Apr 85 Added character definition variables
-
- bugs...
- Part of the code for mode 6 is in C because I couldn't get
- the assembly version running. The assembly version would
- be much faster. To get the (buggy) assembly version, don't
- #define CCODE.
-
- */
-
- /* exported graphics variables */
-
- char *machine = "IBM PC";
-
- int max_color = 3;
-
- int current_color = 0;
- int pixels_wide = 320; /* width in pixels of screen */
- int pixels_high = 200; /* height in pixels of screen */
- double best_width = 1.;
- double best_height = .648; /* relative height/width parameters */
-
- int char_rows = 25; /* text parameters */
- int char_columns = 40;
- int char_height = 8;
- int char_width = 8;
- int x_offset = 0;
- int y_offset = 7;
-
- int up_arrow = 0x48; /* cursor keys */
- int down_arrow = 0x50;
- int left_arrow = 0x4b;
- int right_arrow = 0x4d;
- int escaped_arrows = 1; /* cursor keys are preceded by 0 */
- int escape_char = 0;
-
- /* an 'A' on row r, column c has lower left corner on raster
- r*char_height + y_offset
- at pixel
- c*char_width + x_offset */
-
- static int draw5();
- static int erase5();
- static int draw6();
- static int erase6();
-
- static int color_code=3;
- static int shifted_color_code=0xc0;
-
- set_color(color) int color;
- { color_code=color&max_color;
- shifted_color_code=color_code<<6;
- }
-
- static int colors[4]={0,2,1,3};
-
- set_intensity(intensity) double intensity;
- { int i;
- i=(int)(4.*intensity);
- if(i<0) i=0;
- else if(i>max_color) i=max_color;
- color_code=colors[i];
- shifted_color_code=color_code<<6;
- }
-
- inquire_color() {return (color_code);}
- double inquire_intensity() {return (colors[color_code]);}
-
- /* idraw - draw a straight line using Bresenham's algorithm */
-
- #define OVER mask>>=2; if(mask==0) {mask=shifted_color_code; addr++;}
- #define UP addr+=step; step=sum-step;
-
- int pattern5[8]={0,128,192,224,240,248,252,254};
-
- static int draw5(x1,y1,x2,y2) int x1,y1,x2,y2;
- { static int dx,dy,i;
- static int mask,step,accum,cnt,down,up,sum;
- static char *addr;
-
- dx=x2-x1;
- if(dx<0)
- {dx=-dx; dy=y1-y2;
- x1=x2; y1=y2; /* the new cursor position */
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=( (x1&511) >> 2) + (y1 >> 1)*80;
- mask=shifted_color_code >> ( (x1&3) << 1 );
- }
- else
- {dy=y2-y1;
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=( (x1&511) >> 2) + (y1 >> 1)*80;
- mask=shifted_color_code >> ( (x1&3) << 1 );
- x1=x2; y1=y2; /* the new cursor position */
- }
- pixel_insert5(addr,mask);
- if(dy<0) {dy=-dy; step-=80; sum=-80;}
- else {sum=80;}
- if(dx==0) /* vertical */
- {cnt=dy;
- while(cnt--) {UP pixel_insert5(addr,mask);}
- return;
- }
- if(dy==0) /* horizontal */
- {cnt=dx;
- while(mask!=color_code)
- {if(cnt-- ==0)return;
- mask>>=2;
- pixel_insert5(addr,mask);
- }
- i=cnt>>2;
- mask = color_code | color_code<<2;
- mask |= mask<<4;
- while(i--) {byte_insert5(++addr,mask);}
- cnt&=3;
- ++addr;
- mask=shifted_color_code;
- while(cnt--) {pixel_insert5(addr,mask); mask>>=2;} /* slow version */
- /* pixel_insert5(addr,pattern5[cnt]); fast version */
- }
- else
- #ifdef CCODE
- {if(dx<dy) /* steep slope */
- {accum=dy-dx-dx; cnt=dy;
- down=dx+dx; up=2*(dy-dx);
- while(cnt--)
- {UP
- if(accum>0) {accum-=down;}
- else {accum+=up; OVER}
- pixel_insert5(addr,mask);
- }
- }
- else /* shallow slope */
- {accum=dx-dy-dy; cnt=dx;
- down=dy+dy; up=2*(dx-dy);
- while(cnt--)
- {OVER
- if(accum>0) {accum-=down;}
- else {accum+=up; UP}
- pixel_insert5(addr,mask);
- }
- }
-
- }
- #else
- #asm
- ; {if(dx<dy) /* steep slope */
- MOV AX,WORD draw5_dx_
- CMP AX,WORD draw5_dy_
- JGE x5_l35
- ; {accum=dy-dx-dx; cnt=dy;
- MOV dx,WORD draw5_dy_
- SUB dx,WORD draw5_dx_
- SUB dx,WORD draw5_dx_
- MOV AX,WORD draw5_dy_
- MOV WORD draw5_cnt_,AX
- ; down=dx+dx; up=2*(dy-dx);
- MOV AX,WORD draw5_dx_
- ADD AX,WORD draw5_dx_
- MOV WORD draw5_down_,AX
- MOV AX,WORD draw5_dy_
- SUB AX,WORD draw5_dx_
- SHL AX,1
- MOV WORD draw5_up_,AX
- mov bx,WORD draw5_addr_
- mov cx,WORD draw5_mask_
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- x5_l36:
- MOV AX,WORD draw5_cnt_
- DEC WORD draw5_cnt_
- CMP AX,0
- JZ x5_l37
- ; {UP
- add bx,WORD draw5_step_
- MOV AX,WORD draw5_sum_
- SUB AX,WORD draw5_step_
- MOV WORD draw5_step_,AX
- ; if(accum>0) {accum-=down;}
- cmp dx,0
- JLE x5_l38
- sub dx,WORD draw5_down_
- JMP x5_l39
- ; else {accum+=up; OVER}
- x5_l38:
- add dx,WORD draw5_up_
- shr cx,1
- shr cx,1
- JNZ x5_l40
- mov cx,WORD shifted_color_code_
- inc bx
- ; pixel_insert5(addr,mask);
- x5_l40:
- x5_l39:
- or es:[bx],cl
- ; }
- ; }
- JMP x5_l36
- x5_l37:
- JMP x5_l41
- ; else /* shallow slope */
- ; {accum=dx-dy-dy; cnt=dx;
- x5_l35:
- MOV dx,WORD draw5_dx_
- SUB dx,WORD draw5_dy_
- SUB dx,WORD draw5_dy_
- MOV AX,WORD draw5_dx_
- MOV WORD draw5_cnt_,AX
- ; down=dy+dy; up=2*(dx-dy);
- MOV AX,WORD draw5_dy_
- ADD AX,WORD draw5_dy_
- MOV WORD draw5_down_,AX
- MOV AX,WORD draw5_dx_
- SUB AX,WORD draw5_dy_
- SHL AX,1
- MOV WORD draw5_up_,AX
- mov cx,WORD draw5_mask_ ;get mask
- mov bx,WORD draw5_addr_ ;get addr
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- x5_l42:
- MOV AX,WORD draw5_cnt_
- DEC WORD draw5_cnt_
- CMP AX,0
- JZ x5_l43
- ; {OVER
- shr cx,1
- shr cx,1
- JNZ x5_l44
- mov cx,shifted_color_code_
- inc bx
- ; if(accum>0) {accum-=down;}
- x5_l44:
- cmp dx,0
- JLE x5_l45
- sub dx,WORD draw5_down_
- JMP x5_l46
- ; else {accum+=up; UP}
- x5_l45:
- add dx,WORD draw5_up_
- add bx,WORD draw5_step_
- MOV AX,WORD draw5_sum_
- SUB AX,WORD draw5_step_
- MOV WORD draw5_step_,AX
- ; pixel_insert5(addr,mask);
- x5_l46:
- or es:[bx],cl
- ; }
- ; }
- ; }
-
- JMP x5_l42
- x5_l41:
- x5_l43:
- #endasm
- #endif
- }
-
- /* erase - erase a straight line */
- static int erase5(x1,y1,x2,y2) int x1,y1,x2,y2;
- { static int dx,dy,i;
- static int mask,step,accum,cnt,down,up,sum;
- static char *addr;
-
- dx=x2-x1;
- if(dx<0)
- {dx=-dx; dy=y1-y2;
- x1=x2; y1=y2; /* the new cursor position */
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=(x1>>2) + (y1>>1)*80;
- mask=(0xffff ^ ( shifted_color_code >> ((x1&3)<<1) ) );
- }
- else
- {dy=y2-y1;
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=(x1>>2) + (y1>>1)*80;
- mask=(0xffff ^ ( shifted_color_code >> ((x1&3)<<1) ) );
- x1=x2; y1=y2; /* the new cursor position */
- }
- /* now: dx >= 0 */
- pixel_delete5(addr,mask);
- if(dy<0) {dy=-dy; step-=80; sum=-80;}
- else {sum=80;}
- if(dx==0) /* vertical */
- {cnt=dy;
- while(cnt--) {UP pixel_delete5(addr,mask);}
- return;
- }
- /* now: dx > 0 */
- if(dy==0) /* horizontal */
- {cnt=dx;
- while((mask&0xff)!=(0xff^color_code))
- {if(cnt-- ==0)return;
- mask>>=2;
- pixel_delete5(addr,mask);
- }
- i=cnt>>2;
- mask = color_code | color_code<<2;
- mask |= mask<<4; mask ^= 0xffff;
- while(i--) {byte_delete5(++addr,mask);}
- cnt&=3;
- ++addr;
- mask=shifted_color_code^0xffff;
- while(cnt--) {pixel_delete5(addr,mask); mask>>=2;} /* slow version */
- /* pixel_delete5(addr,0xffff^pattern5[cnt]); fast version */
- }
- else
- #ifdef CCODE
- #define OVER mask>>=2; if((mask&0xff)==0xff) {mask=0xffff^shifted_color_code; addr++;}
- {if(dx<dy) /* steep slope */
- {accum=dy-dx-dx; cnt=dy;
- down=dx+dx; up=2*(dy-dx);
- while(cnt--)
- {UP
- if(accum>0) {accum-=down;}
- else {accum+=up; OVER}
- pixel_delete5(addr,mask);
- }
- }
- else /* shallow slope */
- {accum=dx-dy-dy; cnt=dx;
- down=dy+dy; up=2*(dx-dy);
- while(cnt--)
- {OVER
- if(accum>0) {accum-=down;}
- else {accum+=up; UP}
- pixel_delete5(addr,mask);
- }
- }
- }
- #else
- #asm
- ; {if(dx<dy) /* steep slope */
- MOV AX,WORD erase5_dx_
- CMP AX,WORD erase5_dy_
- JGE erase5_l35
- ; {accum=dy-dx-dx; cnt=dy;
- MOV dx,WORD erase5_dy_
- SUB dx,WORD erase5_dx_
- SUB dx,WORD erase5_dx_
- MOV AX,WORD erase5_dy_
- MOV WORD erase5_cnt_,AX
- ; down=dx+dx; up=2*(dy-dx);
- MOV AX,WORD erase5_dx_
- ADD AX,WORD erase5_dx_
- MOV WORD erase5_down_,AX
- MOV AX,WORD erase5_dy_
- SUB AX,WORD erase5_dx_
- SHL AX,1
- MOV WORD erase5_up_,AX
- mov bx,WORD erase5_addr_
- mov cx,WORD erase5_mask_
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- erase5_l36:
- MOV AX,WORD erase5_cnt_
- DEC WORD erase5_cnt_
- CMP AX,0
- JZ erase5_l37
- ; {UP
- add bx,WORD erase5_step_
- MOV AX,WORD erase5_sum_
- SUB AX,WORD erase5_step_
- MOV WORD erase5_step_,AX
- ; if(accum>0) {accum-=down;}
- cmp dx,0
- JLE erase5_l38
- sub dx,WORD erase5_down_
- JMP erase5_l39
- ; else {accum+=up; OVER}
- erase5_l38:
- add dx,WORD erase5_up_
- sar cx,1
- sar cx,1
- cmp cx,0ffffh
- JNZ erase5_l40
- mov cx,shifted_color_code_
- xor cx,0ffffh
- inc bx
- ; pixel_delete5(addr,mask);
- erase5_l40:
- erase5_l39:
- and es:[bx],cl
- ; }
- ; }
- JMP erase5_l36
- erase5_l37:
- JMP erase5_l41
- ; else /* shallow slope */
- ; {accum=dx-dy-dy; cnt=dx;
- erase5_l35:
- MOV dx,WORD erase5_dx_
- SUB dx,WORD erase5_dy_
- SUB dx,WORD erase5_dy_
- MOV AX,WORD erase5_dx_
- MOV WORD erase5_cnt_,AX
- ; down=dy+dy; up=2*(dx-dy);
- MOV AX,WORD erase5_dy_
- ADD AX,WORD erase5_dy_
- MOV WORD erase5_down_,AX
- MOV AX,WORD erase5_dx_
- SUB AX,WORD erase5_dy_
- SHL AX,1
- MOV WORD erase5_up_,AX
- mov cx,WORD erase5_mask_ ;get mask
- mov bx,WORD erase5_addr_ ;get addr
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- erase5_l42:
- MOV AX,WORD erase5_cnt_
- DEC WORD erase5_cnt_
- CMP AX,0
- JZ erase5_l43
- ; {OVER
- sar cx,1
- sar cx,1
- cmp cx,0ffffh
- JNZ erase5_l44
- mov cx,shifted_color_code_
- xor cx,0ffffh
- inc bx
- ; if(accum>0) {accum-=down;}
- erase5_l44:
- cmp dx,0
- JLE erase5_l45
- sub dx,WORD erase5_down_
- JMP erase5_l46
- ; else {accum+=up; UP}
- erase5_l45:
- add dx,WORD erase5_up_
- add bx,WORD erase5_step_
- MOV AX,WORD erase5_sum_
- SUB AX,WORD erase5_step_
- MOV WORD erase5_step_,AX
- ; pixel_insert5(addr,mask);
- erase5_l46:
- and es:[bx],cl
- ; }
- ; }
- ; }
-
- JMP erase5_l42
- erase5_l41:
- erase5_l43:
- #endasm
- #endif
- }
-
-
- static dummy()
- {
- #asm
- ; insert - insert pixels or bytes into graphics memory
- ;
- cseg
- public pixel_insert5_,pixel_delete5_,byte_delete5_,byte_insert5_
- ;
- pixel_insert5_: ; pixel_insert5(offset,byte)
- mov dx,bp
- mov bp,sp
- mov bx,[bp+2]
- mov ax,0b800h
- mov es,ax
- mov al,[bp+4]
- or es:[bx],al
- mov bp,dx
- ret
- ;
- pixel_delete5_: ; pixel_delete5(offset,byte)
- mov dx,bp
- mov bp,sp
- mov bx,[bp+2]
- mov ax,0b800h
- mov es,ax
- mov al,[bp+4]
- and es:[bx],al
- mov bp,dx
- ret
- ;
- byte_insert5_: ; byte_insert5(offset,byte)
- push bp
- mov bp,sp
- mov bx,[bp+4]
- mov ax,0b800h
- mov es,ax
- mov al,[bp+6]
- or es:[bx],al
- pop bp
- ret
- ;
- byte_delete5_: ; byte_delete5(offset,byte)
- push bp
- mov bp,sp
- mov bx,[bp+4]
- mov ax,0b800h
- mov es,ax
- mov al,[bp+6]
- and es:[bx],al
- pop bp
- ret
-
- #endasm
- }
-
-
-
- /* ---------------------------------------------------------------------- */
-
- #define CCODE
- /*
- integer interface to graphics on IBM video card,
- mode 6 (200 by 640 pixels, black and white)
-
- history...
- 16 Aug 85 Test for being PC works even in graphics mode 6.
- 11 May 85 Declaring that cursor keys are preceded by 0.
- 2 May 85 Corrected aspect ratio, corrected gotoxy().
- 27 Apr 85 Exporting "down_arrow", etc.
- 20 Apr 85 Added character definition variables
- bugs...
- CCODE: 30 lines/sec
-
- !CCODE:
- doesn't erase anything but horizontal lines on right.
- on left, erases in vertical bars (not loading correct mask?)
- */
-
- /* idraw - draw a straight line using Bresenham's algorithm */
-
- #define OVER mask>>=1; if(mask==0) {mask=128; addr++;}
- #define UP addr+=step; step=sum-step;
-
- int pattern[8]={0,128,192,224,240,248,252,254};
-
- static int draw6(x1,y1,x2,y2) int x1,y1,x2,y2;
- { static int dx,dy,i;
- static int mask,step,accum,cnt,down,up,sum;
- static char *addr;
-
- dx=x2-x1;
- if(dx<0)
- {dx=-dx; dy=y1-y2;
- x1=x2; y1=y2; /* the new cursor position */
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=(x1>>3) + (y1>>1)*80; mask=128>>(x1&7);
- }
- else
- {dy=y2-y1;
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=(x1>>3) + (y1>>1)*80; mask=128>>(x1&7);
- x1=x2; y1=y2; /* the new cursor position */
- }
- pixel_insert6(addr,mask);
- if(dy<0) {dy=-dy; step-=80; sum=-80;}
- else {sum=80;}
- if(dx==0) /* vertical */
- {cnt=dy;
- while(cnt--) {UP pixel_insert6(addr,mask);}
- return;
- }
- if(dy==0) /* horizontal */
- {cnt=dx;
- while(mask!=1)
- {if(cnt-- ==0)return;
- mask>>=1;
- pixel_insert6(addr,mask);
- }
- i=cnt>>3;
- while(i--) {byte_insert6(++addr,255);}
- cnt&=7;
- ++addr;
- /* mask=128;
- while(cnt--) {pixel_insert6(addr,mask); mask>>=1;} slow version */
- pixel_insert6(addr,pattern[cnt]); /* fast version */
- }
- else
-
-
- /* {if(dx<dy) /* steep slope
- {accum=dy-dx-dx; cnt=dy;
- down=dx+dx; up=2*(dy-dx);
- while(cnt--)
- {UP
- if(accum>0) {accum-=down;}
- else {accum+=up; OVER}
- pixel_insert6(addr,mask);
- }
- }
- else /* shallow slope
- {accum=dx-dy-dy; cnt=dx;
- down=dy+dy; up=2*(dx-dy);
- while(cnt--)
- {OVER
- if(accum>0) {accum-=down;}
- else {accum+=up; UP}
- pixel_insert6(addr,mask);
- }
- }
- */
- #asm
- ; {if(dx<dy) /* steep slope */
- MOV AX,WORD draw6_dx_
- CMP AX,WORD draw6_dy_
- JGE x6_l35
- ; {accum=dy-dx-dx; cnt=dy;
- MOV dx,WORD draw6_dy_
- SUB dx,WORD draw6_dx_
- SUB dx,WORD draw6_dx_
- MOV AX,WORD draw6_dy_
- MOV WORD draw6_cnt_,AX
- ; down=dx+dx; up=2*(dy-dx);
- MOV AX,WORD draw6_dx_
- ADD AX,WORD draw6_dx_
- MOV WORD draw6_down_,AX
- MOV AX,WORD draw6_dy_
- SUB AX,WORD draw6_dx_
- SHL AX,1
- MOV WORD draw6_up_,AX
- mov bx,WORD draw6_addr_
- mov cx,WORD draw6_mask_
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- x6_l36:
- MOV AX,WORD draw6_cnt_
- DEC WORD draw6_cnt_
- CMP AX,0
- JZ x6_l37
- ; {UP
- add bx,WORD draw6_step_
- MOV AX,WORD draw6_sum_
- SUB AX,WORD draw6_step_
- MOV WORD draw6_step_,AX
- ; if(accum>0) {accum-=down;}
- cmp dx,0
- JLE x6_l38
- sub dx,WORD draw6_down_
- JMP x6_l39
- ; else {accum+=up; OVER}
- x6_l38:
- add dx,WORD draw6_up_
- shr cx,1
- JNZ x6_l40
- mov cx,128
- inc bx
- ; pixel_insert6(addr,mask);
- x6_l40:
- x6_l39:
- or es:[bx],cl
- ; }
- ; }
- JMP x6_l36
- x6_l37:
- JMP x6_l41
- ; else /* shallow slope */
- ; {accum=dx-dy-dy; cnt=dx;
- x6_l35:
- MOV dx,WORD draw6_dx_
- SUB dx,WORD draw6_dy_
- SUB dx,WORD draw6_dy_
- MOV AX,WORD draw6_dx_
- MOV WORD draw6_cnt_,AX
- ; down=dy+dy; up=2*(dx-dy);
- MOV AX,WORD draw6_dy_
- ADD AX,WORD draw6_dy_
- MOV WORD draw6_down_,AX
- MOV AX,WORD draw6_dx_
- SUB AX,WORD draw6_dy_
- SHL AX,1
- MOV WORD draw6_up_,AX
- mov cx,WORD draw6_mask_ ;get mask
- mov bx,WORD draw6_addr_ ;get addr
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- x6_l42:
- MOV AX,WORD draw6_cnt_
- DEC WORD draw6_cnt_
- CMP AX,0
- JZ x6_l43
- ; {OVER
- shr cx,1
- JNZ x6_l44
- mov cx,128
- inc bx
- ; if(accum>0) {accum-=down;}
- x6_l44:
- cmp dx,0
- JLE x6_l45
- sub dx,WORD draw6_down_
- JMP x6_l46
- ; else {accum+=up; UP}
- x6_l45:
- add dx,WORD draw6_up_
- add bx,WORD draw6_step_
- MOV AX,WORD draw6_sum_
- SUB AX,WORD draw6_step_
- MOV WORD draw6_step_,AX
- ; pixel_insert6(addr,mask);
- x6_l46:
- or es:[bx],cl
- ; }
- ; }
- ; }
-
- JMP x6_l42
- x6_l41:
- x6_l43:
- #endasm
- }
- #define OVER mask>>=1; if((mask&0xff)==0xff) {mask=0xff7f; addr++;}
-
- /* erase - erase a straight line */
- static int erase6(x1,y1,x2,y2) int x1,y1,x2,y2;
- { static int dx,dy,i;
- static int mask,step,accum,cnt,down,up,sum;
- static char *addr;
-
- dx=x2-x1;
- if(dx<0)
- {dx=-dx; dy=y1-y2;
- x1=x2; y1=y2; /* the new cursor position */
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=(x1>>3) + (y1>>1)*80; mask=0xff7f>>(x1&7);
- }
- else
- {dy=y2-y1;
- if(y1&1) {step=-8112; addr=8192;}
- else {step=8192; addr=0;}
- addr+=(x1>>3) + (y1>>1)*80; mask=0xff7f>>(x1&7);
- x1=x2; y1=y2; /* the new cursor position */
- }
- pixel_delete6(addr,mask);
- if(dy<0) {dy=-dy; step-=80; sum=-80;}
- else {sum=80;}
- if(dx==0) /* vertical */
- {cnt=dy;
- while(cnt--) {UP pixel_delete6(addr,mask);}
- return;
- }
- if(dy==0) /* horizontal */
- {cnt=dx;
- while((mask&0xff)!=0xfe)
- {if(cnt-- ==0)return;
- mask>>=1;
- pixel_delete6(addr,mask);
- }
- i=cnt>>3;
- while(i--) {byte_insert6(++addr,0);}
- cnt&=7;
- ++addr;
- mask=0xff7f;
- while(cnt--) {pixel_delete6(addr,mask); mask>>=1;} /* slow version */
- /* pixel_delete6(addr,255^pattern[cnt]); fast version */
- }
- else
- {
- #ifdef CCODE
- if(dx<dy) /* steep slope */
- {accum=dy-dx-dx; cnt=dy;
- down=dx+dx; up=2*(dy-dx);
- while(cnt--)
- {UP
- if(accum>0) {accum-=down;}
- else {accum+=up; OVER}
- pixel_delete6(addr,mask);
- }
- }
- else /* shallow slope */
- {accum=dx-dy-dy; cnt=dx;
- down=dy+dy; up=2*(dx-dy);
- while(cnt--)
- {OVER
- if(accum>0) {accum-=down;}
- else {accum+=up; UP}
- pixel_delete6(addr,mask);
- }
- }
- #else
- #asm
- ; {if(dx<dy) /* steep slope */
- MOV AX,WORD erase6_dx_
- CMP AX,WORD erase6_dy_
- JGE erase6_l35
- ; {accum=dy-dx-dx; cnt=dy;
- MOV dx,WORD erase6_dy_
- SUB dx,WORD erase6_dx_
- SUB dx,WORD erase6_dx_
- MOV AX,WORD erase6_dy_
- MOV WORD erase6_cnt_,AX
- ; down=dx+dx; up=2*(dy-dx);
- MOV AX,WORD erase6_dx_
- ADD AX,WORD erase6_dx_
- MOV WORD WORD erase6_down_,AX
- MOV AX,WORD erase6_dy_
- SUB AX,WORD erase6_dx_
- SHL AX,1
- MOV WORD erase6_up_,AX
- mov bx,WORD erase6_addr_
- mov cx,WORD erase6_mask_
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- erase6_l36:
- MOV AX,WORD erase6_cnt_
- DEC WORD erase6_cnt_
- CMP AX,0
- JZ erase6_l37
- ; {UP
- add bx,WORD erase6_step_
- MOV AX,WORD erase6_sum_
- SUB AX,WORD erase6_step_
- MOV WORD erase6_step_,AX
- ; if(accum>0) {accum-=down;}
- cmp dx,0
- JLE erase6_l38
- sub dx,WORD erase6_down_
- JMP erase6_l39
- ; else {accum+=up; OVER}
- erase6_l38:
- add dx,WORD erase6_up_
- sar cx,1
- cmp cx,0ffffh ;
- JNZ erase6_l40 ; replace these two lines with " JC erase6_l40" ?
- mov cx,0ff7fh
- inc bx
- ; pixel_delete6(addr,mask);
- erase6_l40:
- erase6_l39:
- and es:[bx],cl
- ; }
- ; }
- JMP erase6_l36
- erase6_l37:
- JMP erase6_l41
- ; else /* shallow slope */
- ; {accum=dx-dy-dy; cnt=dx;
- erase6_l35:
- MOV dx,WORD erase6_dx_
- SUB dx,WORD erase6_dy_
- SUB dx,WORD erase6_dy_
- MOV AX,WORD erase6_dx_
- MOV WORD erase6_cnt_,AX
- ; down=dy+dy; up=2*(dx-dy);
- MOV AX,WORD erase6_dy_
- ADD AX,WORD erase6_dy_
- MOV WORD WORD erase6_down_,AX
- MOV AX,WORD erase6_dx_
- SUB AX,WORD erase6_dy_
- SHL AX,1
- MOV WORD erase6_up_,AX
- mov cx,WORD erase6_mask_ ;get mask
- mov bx,WORD erase6_addr_ ;get addr
- mov ax,0b800h
- mov es,ax
- ; while(cnt--)
- erase6_l42:
- MOV AX,WORD erase6_cnt_
- DEC WORD erase6_cnt_
- CMP AX,0
- JZ erase6_l43
- ; {OVER
- sar cx,1
- cmp cx,0ffffh
- JNZ erase6_l44
- mov cx,0ff7fh
- inc bx
- ; if(accum>0) {accum-=down;}
- erase6_l44:
- cmp dx,0
- JLE erase6_l45
- sub dx,WORD erase6_down_
- JMP erase6_l46
- ; else {accum+=up; UP}
- erase6_l45:
- add dx,WORD erase6_up_
- add bx,WORD erase6_step_
- MOV AX,WORD erase6_sum_
- SUB AX,WORD erase6_step_
- MOV WORD erase6_step_,AX
- ; pixel_delete6(addr,mask);
- erase6_l46:
- and es:[bx],cl
- ; }
- ; }
- ; }
-
- JMP erase6_l42
- erase6_l41:
- erase6_l43:
- #endasm
- #endif
- }
- }
-
- #define APORT 0x3d4 /* address port of 6845 video controller */
- #define VDATA(x) (_outb((x),APORT),_inb(APORT+1)) /* read register x */
- #define CURSOR ((VDATA(14)<<8)+VDATA(15)) /* get cursor location */
-
- /* exported function pointers */
- int (*draw_line)()=draw5, (*erase_line)()=erase5;
-
- /* init - initialize the graphics system */
- init_graphics()
- { int d1,d2;
- char buf[80];
- d1=CURSOR; putchar(' '); d2=CURSOR;
- /* complain if displaying a character didn't change the cursor
- location and address and data ports return the same value */
- if((d1==d2) && (_inb(APORT)==_inb(APORT+1)))
- {puts("This version is for the IBM PC!\007\n");
- exit();
- }
- envsearch("graphics",buf);
- if(strcmp(buf,"4")==0)
- {mode(4); /* 320 by 200 pixels, 4 colors */
- draw_line=draw5; erase_line=erase5;
- max_color=3;
- pixels_wide=320;
- char_columns=40;
- }
- else if(strcmp(buf,"5")==0)
- {mode(5); /* 320 by 200 pixels, 4 levels of gray */
- draw_line=draw5; erase_line=erase5;
- max_color=3;
- pixels_wide=320;
- char_columns=40;
- }
- else
- {mode(6); /* 640 by 200 pixels, black & white */
- draw_line=draw6; erase_line=erase6;
- max_color=0;
- pixels_wide=640;
- char_columns=80;
- }
- }
-
- /* envsearch - search environment for given string */
-
- envsearch(target,value) char *target,*value;
- { char buf[256],*s,t[25],*env;
- int nt,offset;
-
- s=t;
- while(*target) *s++=toupper(*target++);
- *s++= '='; *s=0;
- nt = strlen(t);
- offset=0;
- _lmove(2,44,_showcs()-0x10,&env,_showds());
- while(1)
- {_lmove(256,offset,env,buf,_showds());
- s=buf;
- if(*s)
- {/* printf("examining entry: %s \n",s); getchar(); */
- if (strncmp(t,s,nt)==0) return (strcpy(value,s+nt));
- }
- else
- {*value=0;
- return;
- }
- offset+=strlen(buf)+1;
- }
- }
-
- /* finish - close down the graphics system */
-
- finish_graphics()
- { mode(3); /* 80 by 25 characters, color */
- }
-
-
- static dummy6()
- {
- #asm
- ; insert - insert pixels or bytes into graphics memory
- ;
- cseg
- public pixel_insert6_,pixel_delete6_,byte_insert6_,MODE_,CLEAR_GRAPHICS_
- ;
- pixel_insert6_: ; pixel_insert6(offset,byte)
- mov dx,bp
- mov bp,sp
- mov bx,[bp+2]
- mov ax,0b800h
- mov es,ax
- mov al,[bp+4]
- or es:[bx],al
- mov bp,dx
- ret
- ;
- pixel_delete6_: ; pixel_delete6(offset,byte)
- mov dx,bp
- mov bp,sp
- mov bx,[bp+2]
- mov ax,0b800h
- mov es,ax
- mov al,[bp+4]
- and es:[bx],al
- mov bp,dx
- ret
- ;
- byte_insert6_: ; byte_insert6(offset,byte)
- push bp
- mov bp,sp
- mov bx,[bp+4]
- mov ax,0b800h
- mov es,ax
- mov al,[bp+6]
- mov es:[bx],al
- pop bp
- ret
- ;
- ; set video mode
- ;
- MODE_: ; mode(new_mode)
- pop bx
- pop ax
- push ax
- push bx
- mov ah,0
- int 10h
- ret
- ;
- CLEAR_GRAPHICS_: ; clear_graphics()
- mov ax,0b800h
- mov es,ax
- xor ax,ax
- mov di,ax
- mov cx,8192
- cld ; clear direction flag
- rep stosw
- ret
-
- video equ 10h ;interrupt for dealing with screen
- setcur equ 2 ;code for addressing cursor
- state equ 15 ;code to find current screen status
-
- ; gotoxy_ sets cursor at any location.
-
- ; Usage: gotoxy(new column, new row);
-
- public gotoxy_
- gotoxy_: ; move cursor to x,y
- push bp ; save from bios
- mov ah,state ;get current state
- int video
- mov bp,sp
- mov dx,[bp+4] ; column
- mov ax,[bp+6] ; row
- mov dh,al
- mov ah,setcur ; set cursor location
- int video ; call bios
- pop bp
- ret
-
- #endasm
- }