Category : Files from Magazines
Archive   : DDJ0589.ZIP
Filename : VUPORT.ASC

 
Output of file : VUPORT.ASC contained in archive : DDJ0589.ZIP
_Graphics Programming_
by Kent Porter




[LISTING ONE]

1| ; DRAWPT.ASM: Writes pixel directly to 6845 Video Controller
2| ; Microsoft MASM 5.1
3| ; C prototype is
4| ; void far draw_point (int x, int y);
5| ; To be included in GRAFIX.LIB
6| ; K. Porter, ®MDUL¯DDJ®MDNM¯ Graphics Programming Column, February '89
7|
8| .MODEL LARGE
9| .CODE
10| PUBLIC _draw_point
11|
12| ; Externals in GRAFIX.LIB
13| EXTRN _color1 : BYTE ; Pixel color reg value
14| EXTRN _vuport : WORD ; far ptr to vuport structure
15|
16| ; Arguments passed from C
17| x EQU [bp+6] ; Arguments passed from C
18| y EQU [bp+8]
19|
20| _draw_point PROC FAR
21| push bp ; Entry processing
22| mov bp, sp
23|
24| ; Point ES:[BX] to vuport structure
25| mov ax, _vuport+2 ; get pointer segment
26| mov es, ax
27| mov bx, _vuport ; get offset
28|
29| ; Clip if coordinates outside viewport
30| mov cx, y ; get y
31| cmp cx, es:[bx+6] ; is y within viewport?
32| jl checkx ; ok if so
33| jmp exit ; else quit
34| checkx: mov ax, x ; get x
35| cmp ax, es:[bx+4] ; is x within viewport?
36| jl remap ; ok if so
37| jmp exit ; else quit
38|
39| ; Map pixel coordinates to current viewport
40| remap: add ax, es:[bx] ; offset x by vuport.left
41| mov x, ax ; save remapped X
42| add cx, es:[bx+2] ; offset y by vuport.top
43| mov y, cx ; save remapped Y
44|
45| ; Point ES to video memory segment
46| vmem: mov ax, 0A000h
47| mov es, ax
48|
49| ; Row offset = y * 80;
50| mov bx, y ; Get y argument
51| mov ax, 80
52| mul bx ; Result in AX
53| mov bx, ax ; Row offset in BX
54|
55| ; Column offset = x SHR 3
56| mov ax, x ; Get x
57| mov cl, 3 ; Shift operand
58| shr ax, cl ; Column offset
59|
60| ; Complete address of pixel byte
61| add bx, ax ; ES:BX = address
62|
63| ; Build bit mask for pixel
64| mov cx, x ; Get x again
65| and cx, 7 ; Isolate low-order bits
66| xor cl, 7 ; Number of bits to shift
67| mov ah, 1 ; Start bit mask
68| shl ah, cl ; Shift for pixel
69| mov cl, ah ; Save it
70|
71| ; Use write mode 2 (single-pixel update)
72| mov dx, 03CEh ; 6845 command register
73| mov al, 5 ; Specify mode register
74| mov ah, 2 ; Read mode 0, write mode 2
75| out dx, ax ; Send
76| ; Following added May '89
77| mov al, 3 ; Specify function select reg
78| xor ah, ah ; Replace-pixel mode
79| out dx, ax ; Send
80|
81| ; Set 6845 bit mask register
82| mov al, 8 ; Specify bit mask register
83| mov ah, cl ; al = mask
84| out dx, ax ; Send bit mask
85|
86| ; Draw the pixel
87| mov al, es:[bx] ; Load 6845 latch registers
88| xor al, al ; Clear
89| mov byte ptr es:[bx], al ; Zero the pixel for replace
90| mov al, _color1 ; Get the pixel value
91| mov es:[bx], al ; Write the pixel
92|
93| ; Restore video controller to default state
94| mov dx, 03CEh
95| mov ax, 0005h ; write mode 0, read mode 0
96| out dx, ax
97| mov ax, 0FF08h ; default bit mask
98| out dx, ax
99| mov ax, 0003h ; default function select
100| out dx, ax
101| xor ax, ax ; zero Set/Reset
102| out dx, ax
103| mov ax, 0001h ; zero Enable Set/Reset
104| out dx, ax
105| mov dx, 03C4h ; 6845 address reg
106| mov ax, 0F02h ; Data reg, enable all planes
107| out dx, ax
108|
109| exit:
110| mov sp, bp
111| pop bp
112| retf
113| _draw_point ENDP
114| END




[LISTING TWO]

1| ; HLINE.ASM: Fast horizontal line drawing routine
2| ; Uses 6845 Write Mode 0 to update 8 pixels at a time on EGA/VGA
3| ; C prototype is
4| ; void far hline (int x, int y, int length_in_pixels);
5| ; Writes in current color1 from GRAFIX.LIB
6| ; Microsoft MASM 5.1
7| ; K. Porter, ®MDUL¯DDJ®MDNM¯ Graphics Programming Column, March 89
8|
9| .MODEL LARGE
10| .CODE
11| PUBLIC _hline
12| EXTRN _color1 : BYTE ; Current palette reg for pixel
13| EXTRN _draw_point : PROC ; Pixel writing routine
14| EXTRN _vuport : WORD ; far ptr to vuport structure
15|
16| ; Declare arguments passed by caller
17| x EQU [bp+6]
18| y EQU [bp+8]
19| len EQU [bp+10]
20|
21| ; Declare auto variables
22| last EQU [bp- 2] ; Last byte to write
23| solbits EQU [bp- 4] ; Mask for start of line
24| oddsol EQU [bp- 6] ; # odd bits at start of line
25| eolbits EQU [bp- 8] ; Mask for end of line
26| oddeol EQU [bp-10] ; # odd bits at end of line
27| ; ----------------------------
28|
29| _hline PROC FAR ; ENTRY POINT TO PROC
30| push bp ; entry processing
31| mov bp, sp
32| sub sp, 10 ; make room for auto variables
33| xor ax, ax ; initialize auto variables
34| mov last, ax
35| mov solbits, ax
36| mov oddsol, ax
37| mov eolbits, ax
38| mov oddeol, ax
39|
40| ; Do nothing if line length is zero
41| mov bx, len ; get line length
42| cmp bx, 0 ; length = 0?
43| jnz chlen ; if not, go on
44| jmp quit ; else nothing to draw
45|
46| ; Call draw_point() with a loop if line length < 8
47| chlen: cmp bx, 8
48| jnb getvp ; go if len >= 8
49| mov ax, y ; get args
50| mov cx, x
51| drpt: push bx ; push remaining length
52| push ax ; push args to draw_point()
53| push cx
54| call _draw_point ; draw next pixel
55| pop cx ; clear args from stack
56| pop ax
57| pop bx ; fetch remaining length
58| inc cx ; next x
59| dec bx ; count pixel drawn
60| jnz drpt ; loop until thru
61| jmp quit ; then exit
62|
63| ; Point ES:[BX] to vuport structure
64| getvp: mov ax, _vuport+2 ; get pointer segment
65| mov es, ax
66| mov bx, _vuport ; get offset
67|
68| ; Clip if starting coordinates outside viewport
69| mov cx, y ; get y
70| cmp cx, es:[bx+6] ; is y within viewport?
71| jl checkx ; ok if so
72| jmp quit ; else quit
73| checkx: mov ax, x ; get x
74| cmp ax, es:[bx+4] ; is x within viewport?
75| jl remap ; ok if so
76| jmp quit ; else quit
77|
78| ; Map starting coordinates to current viewport
79| remap: add ax, es:[bx] ; offset x by vuport.left
80| mov x, ax ; save remapped X
81| add cx, es:[bx+2] ; offset y by vuport.top
82| mov y, cx ; save remapped Y
83|
84| ; Clip line length to viewport width
85| mov ax, es:[bx+4] ; get vuport.width
86| sub ax, x ; maxlength = width - starting x
87| add ax, es:[bx] ; + vuport.left
88| cmp ax, len ; if maxlength > length
89| jg wm0 ; length is ok
90| mov len, ax ; else length = maxlength
91|
92| ; Set 6845 for write mode 0, all planes enabled, color selected
93| wm0: mov dx, 03CEh
94| mov ax, 0005h ; Set write mode
95| out dx, ax
96| mov ax, 0FF00h ; Set/Reset reg, enable all planes
97| out dx, ax
98| mov ax, 0FF01h ; Enable set/reset reg, all planes
99| out dx, ax
100| mov dx, 03C4h ; 6845 address reg
101| mov al, 2 ; Data reg
102| mov ah, _color1 ; Palette reg planes enabled
103| out dx, ax ; Set color code
104| ; Following added May '89
105| mov ah, 3 ; Function select reg
106| xor al, al ; Pixel-replace mode
107| out dx, ax
108|
109| ; Compute x coord for last byte to be written
110| mov bx, x ; get start of line
111| add bx, len ; end = start + length
112| mov cx, bx
113| and cx, 0FFF8h ; x coordinate where odd bits
114| mov last, cx ; at end of line begin
115|
116| ; Compute number of odd pixels at end of line
117| sub bx, cx
118| mov oddeol, bx ; save it
119|
120| ; Construct pixel mask for last byte of line
121| cmp bx, 0
122| jz bsol ; go if no odd pixels
123| xor ax, ax
124| eolb: shr ax, 1 ; shift right and
125| or ax, 80h ; set H/O bit
126| dec bl ; until mask is built
127| jnz eolb
128| mov eolbits, ax ; then save mask
129|
130| ; Compute number of odd pixels at start of line
131| bsol: mov cx, x ; get starting X again
132| and cx, 7 ; # of pixels from start of byte
133| jz saddr ; go if none
134| mov bx, 8
135| sub bx, cx ; # of pixels to write
136| mov oddsol, bx ; save
137|
138| ; Construct pixel mask for first byte of line
139| xor ax, ax
140| solb: shl ax, 1 ; shift left and
141| or ax, 1 ; set L/O bit
142| dec bl ; until mask is built
143| jnz solb
144| mov solbits, ax ; then save mask
145|
146| ; Translate last byte X into an address
147| saddr: mov ax, 0A000h
148| mov es, ax ; ES ==> video buffer
149| mov bx, y ; get row
150| mov ax, 80
151| mul bx
152| mov bx, ax ; BX = row offset = row * 80
153| push bx ; save row offset
154| mov ax, last ; get last byte X
155| mov cl, 3
156| shr ax, cl ; shift for col offset
157| add bx, ax ; last offs = row offs + col offs
158| mov last, bx
159|
160| ; Compute address of first byte (ES:[BX])
161| pop bx ; fetch row offset
162| mov ax, x ; get col offset
163| mov cl, 3
164| shr ax, cl ; shift right 3 for col offset
165| add bx, ax ; offset = row offs + col offs
166| cmp bx, last ; is first byte also last?
167| jz weol ; skip to end mask if so
168|
169| ; Write start of line
170| mov dx, 03CEh ; 6845 port
171| mov ah, solbits ; start-of-line mask
172| cmp ah, 0
173| jz w8 ; go if empty mask
174| mov al, 8 ; set bit mask reg
175| out dx, ax
176| mov cl, es:[bx] ; load 6845 latches
177| mov ax, solbits
178| neg al ; complement
179| dec al ; for reversed bit mask
180| and al, cl ; filter previously unset pixels
181| mov es:[bx], al ; clear affected bits
182| mov al, _color1
183| mov es:[bx], al ; set affected bits
184| inc bx ; next byte
185| cmp bx, last ; ready for end of line yet?
186| jae weol ; go if so
187|
188| ; Write 8 pixels at a time until last byte in line
189| w8: mov ax, 0FF08h ; update all pixels in byte
190| out dx, ax ; set bit mask reg
191| mov al, es:[bx] ; load 6845 latches
192| xor al, al
193| mov es:[bx], al ; clear all pixels
194| mov al, _color1
195| mov es:[bx], al ; set all bits
196| inc bx ; next byte
197| cmp bx, last ; thru?
198| jnz w8 ; loop if not
199|
200| ; Write end of line
201| weol: mov dx, 03CEh ; 6845 port
202| mov ah, eolbits ; end-of-line mask
203| cmp ah, 0
204| jz rvc ; go if empty mask
205| mov al, 8 ; set bit mask reg
206| out dx, ax
207| mov cl, es:[bx] ; load 6845 latches
208| mov ax, eolbits
209| neg al ; complement
210| dec al ; for reversed bit mask
211| and al, cl ; filter previously unset pixels
212| mov es:[bx], al ; clear affected bits
213| mov al, _color1
214| mov es:[bx], al ; set affected bits
215|
216| ; Restore video controller to default state
217| rvc: mov dx, 03CEh
218| mov ax, 0005h ; write mode 0, read mode 0
219| out dx, ax
220| mov ax, 0FF08h ; default bit mask
221| out dx, ax
222| mov ax, 0003h ; default function select
223| out dx, ax
224| xor ax, ax ; zero Set/Reset
225| out dx, ax
226| mov ax, 0001h ; zero Enable Set/Reset
227| out dx, ax
228| mov dx, 03C4h ; 6845 address reg
229| mov ax, 0F02h ; Data reg, enable all planes
230| out dx, ax
231|
232| ; End of routine
233| quit: mov sp, bp
234| pop bp
235| retf
236| _hline ENDP
237| END
238|
239|




[LISTING THREE]


/* From May, '89 */
/* ------------- */
typedef int VP_HAN; /* viewport handle type */

void far default_viewport (int height); /* init default viewport */

VP_HAN far vp_open (int x, int y, int width, int height);
/* open viewport, make it active */

int far vp_use (VP_HAN vp); /* make vp active */

void far vp_close (VP_HAN vp); /* close viewport */

void far vp_outline (VP_HAN vp); /* outline vp */

VP_HAN far vp_active (void); /* get handle of active vp */

int far vp_width (void) /* get active vp width */

int far vp_height (void) /* get active vp height */





[LISTING FOUR]


/* VUPORT.C: Library source for viewport support */
/* This is part of the GRAFIX library */
/* K. Porter, ®MDUL¯DDJ®MDNM¯ Graphics Programming Column, May '89 */

#include
#include
#include "grafix.h"

typedef struct vpnode { /* viewport descriptor node */
int left, top, width, height,
handle;
struct vpnode far *next, far *prev;
} VPNODE;

#if !defined TRUE
#define FALSE 0
#define TRUE !FALSE
#endif

VPNODE far *vplist = NULL; /* pointer to list of vpnodes */
VPNODE def_vp = {0, 0, 640, 350, 0}; /* default viewport */
VPNODE far *vuport = &def_vp; /* ptr to current viewport */
/* -------------------------- */

void far default_viewport (int height)
{ /* initialize default viewport */
vuport->height = height;
} /* ------------------------ */

VP_HAN far vp_open (int x, int y, int width, int height)
{ /* open a viewport */
VPNODE far *newvp, far *listnode;

newvp = malloc (sizeof *newvp); /* make space */
newvp->next = newvp->prev = NULL; /* init list ptrs */
newvp->left = x; /* set descriptor */
newvp->top = y;
newvp->width = width;
newvp->height = height;
newvp->handle = 1;
if (vplist == NULL)
vplist = newvp; /* set first viewport */
else {
listnode = vplist; /* add viewport to list */
while (listnode->next != NULL)
listnode = listnode->next; /* find tail */
listnode->next = newvp; /* update pointers */
newvp->prev = listnode;
newvp->handle = listnode->handle + 1; /* and handle */
}
vuport = newvp; /* make new viewport active */
return newvp->handle;
} /* ------------------------------------------------------ */

int far vp_use (VP_HAN vp) /* make vp active */
{
VPNODE far *port;
int success = FALSE;

if (vp == 0) { /* switch to default viewport */
vuport = &def_vp;
success = TRUE;
} else { /* find desired viewport */
port = vplist;
do {
if (port->handle == vp) {
success = TRUE;
break; /* jump out of loop when found */
}
port = port->next;
} while (port != NULL);
if (success)
vuport = port; /* make active */
}
return success;
} /* ------------------------------------------------------ */

void far vp_close (VP_HAN vp) /* close a viewport */
{
VPNODE far *port;

if (vp == 0) return; /* can't close default vp */
port = vplist;
while (port->next != NULL) { /* find desired viewport */
if (port->handle == vp)
break;
port = port->next;
}
if (port != NULL) { /* viewport was found */
if (port->next != NULL) /* so remove from list */
port->next->prev = port->prev;
if (port->prev != NULL)
port->prev->next = port->next;
if (port == vplist) /* if removing head */
vplist = port->next;
if (port == vuport) /* if removing active vp */
vuport = &def_vp;
free (port);
}
} /* ------------------------------------------------------ */

void far vp_outline (VP_HAN vp) /* outline vp */
/* outline is immediately outside viewport area */
{
VP_HAN active;
int x, y, w, h;

active = vp_active(); /* save current viewport */
if (vp_use (vp)) {
x = vuport->left-1;
y = vuport->top-1;
w = vuport->width+1;
h = vuport->height+1;

/* draw outline */
vp_use (0); /* full screen */
draw_rect (x, y, w, h);
vp_use (active); /* restore active viewport */
}
} /* ------------------------------------------------------ */

VP_HAN far vp_active (void) /* get handle of active vp */
{
return vuport->handle;
} /* ------------------------------------------------------ */

int far vp_width (void) /* get active vp width */
{
return vuport->width;
} /* ------------------------------------------------------ */

int far vp_height (void) /* get active vp height */
{
return vuport->height;
} /* ------------------------------------------------------ */




[LISTING FIVE]


/* VP.C: Draws several viewports */
/* Hex star inside each */
/* K. Porter, ®MDUL¯DDJ®MDNM¯ Graphics Programming Col, 5/89 */

#include "grafix.h"
#include

int hex1[] = {25,55, 110,20, 110,90, 25,55};
int hex2[] = {55,20, 135,55, 55,90, 55,20};

void main()
{
VP_HAN vp1, vp2, vp3;

if (init_video (EGA)) {

/* Draw star in default viewport */
set_color1 (5); /* magenta */
polyline (3, hex1);
polyline (3, hex2);
set_color1 (9);

/* Draw star in unbordered viewport */
set_color1 (1); /* blue */
vp1 = vp_open (60, 250, 200, 95);
polyline (3, hex1);
polyline (3, hex2);

/* Draw star in small bordered viewport */
vp2 = vp_open (200, 150, 100, 75);
vp_outline (vp2);
set_color1 (15); /* white */
polyline (3, hex1);
polyline (3, hex2);

/* Draw star in filled bordered viewport */
vp3 = vp_open (400, 60, 140, 100);
vp_outline (vp3);
set_color1 (2); /* green */
fill_rect (0, 0, vp_width(), vp_height());
set_color1 (4); /* red */
polyline (3, hex1);
polyline (3, hex2);

/* Wait for keypress, then close vp's and quit */
getch();
vp_close (vp1);
vp_close (vp2);
vp_close (vp3);
}
}



[LISTING SIX]

/* LINEGRAF.C: Self-scaling viewports showing a line graph */
/* K. Porter, ®MDUL¯DDJ®MDNM¯ Graphics Programming Column, May '89 */

#include "grafix.h"
#include

int data [] = {30, 70, 10, 40, 30, 80, 60, 90, 40, 50, 40};

void main ()
{
void graph (void);
VP_HAN vp1, vp2, vp3;

if (init_video (EGA)) {

/* Open three viewports */
vp1 = vp_open ( 1, 1, 360, 150);
vp2 = vp_open ( 1, 170, 638, 170);
vp3 = vp_open (500, 50, 80, 50);

/* First version upper left quadrant */
vp_use (vp1);
set_color1 (14); /* yellow */
vp_outline (vp1);
graph();
getch(); /* wait for keypress */
vp_close (vp1);

/* Second across bottom */
vp_use (vp2);
set_color1 (2); /* green */
vp_outline (vp2);
graph();
getch(); /* wait for keypress */
vp_close (vp2);

/* Third at upper right */
vp_use (vp3);
set_color1 (3); /* cyan */
vp_outline (vp3);
graph();
getch(); /* wait for keypress */
vp_close (vp3);
}
} /* ------------------------ */

void graph (void) /* draw self-scaling line graph */
{
int npts, p, prevx, prevy, curx, cury;
double vint, hint;

npts = sizeof (data) / sizeof (int); /* # data points */

/* Scaling factors for data points */
hint = (double) vp_width() / (npts - 1); /* horizontal */
vint = (double) vp_height() / 100.0; /* vertical */

/* Draw the graph */
prevx = 0; prevy = vp_height() - (int)(data[0] * vint);
for (p = 1; p < npts; p++) {
curx = (int)(p * hint);
cury = vp_height() - (int)(data[p] * vint);
draw_line (prevx, prevy, curx, cury);
prevx = curx; prevy = cury;
}
}


[GRAFIX.C, NOT A NUMBER LISTING IN DDJ 5/89]

/* Library source file GRAFIX.C */
/* EGA/VGA graphics subsystem */
/* Following library routines are external: */
/* DRAWPT.ASM Feb '89 */
/* HLINE.ASM Mar '89 */
/* EGAPALET.C Apr '89 */
/* PIXEL.ASM May '89 */
/* VUPORT.C May '89 */
/* K. Porter, DDJ Graphics Programming Column */
/* ------------------------------------------ */

#include
#include
#include
#include
#include "grafix.h"

#if !defined TRUE
#define FALSE 0
#define TRUE !FALSE
#endif

/* Variables global to this library */
int color1, /* foreground color */
oldmode = 0, /* pre-graphics mode */
grafixmode = 0, /* default graphics mode */
ega = FALSE, /* equipment Booleans */
vga = FALSE,
colormonitor = FALSE,
curpos, /* text cursor position */
textpage; /* active text page */
unsigned vidmem; /* video buffer segment */
char far *vidsave; /* video buffer save area */
/* -------------------------------------------------------- */

int far init_video (int mode)

/* Initializes video adapter and defaults for mode */
/* Sets up pc_textmode() to be called on pgm termination */
/* Returns TRUE or FALSE indicating success */
/* This function will be expanded in a later version */
{
union REGS r;
int result = FALSE;

/* Determine attached adapter and monitor */
r.h.ah = 0x1A; /* VGA inquiry function */
r.h.al = 0;
int86 (0x10, &r, &r); /* ROM BIOS call */
if (r.h.al == 0x1A)
switch (r.h.bl) {
case 4 : ega = TRUE; /* EGA color */
colormonitor = TRUE;
break;
case 5 : ega = TRUE; /* EGA mono */
break;
case 7 : ega = TRUE; /* VGA mono */
vga = TRUE;
break;
case 8 : ega = TRUE; /* VGA color */
vga = TRUE;
colormonitor = TRUE;
}
else { /* No VGA, so check for EGA */
r.h.ah = 0x12;
r.x.bx = 0x10;
int86 (0x10, &r, &r);
if (r.x.bx != 0x10) { /* if EGA present... */
ega = TRUE; /* set flag */
r.h.ah = 0x12;
r.h.bl = 0x10; /* find out which monitor */
int86 (0x10, &r, &r);
if (r.h.bl != 0)
colormonitor = TRUE; /* EGA color */
}
}

/* Proceed only if EGA or VGA present */
if (ega | vga) {
set_color1 (15); /* default pixel color */
r.h.ah = 0x0F; /* get current screen mode */
int86 (0x10, &r, &r);
oldmode = r.h.al; /* store it */
textpage = r.h.bh; /* also active text page */

if (colormonitor) /* point to video memory */
vidmem = 0xB800;
else
vidmem = 0xB000;
vidsave = malloc (4096); /* allocate save area */
movedata /* save text screen contents */
(vidmem, 0, FP_SEG (vidsave), FP_OFF (vidsave), 4096);

r.h.ah = 3; /* get text cursor position */
r.h.bh = textpage;
int86 (0x10, &r, &r);
curpos = r.x.dx; /* and save it */

if ((mode == EGA) && ega) {
r.h.ah = 0;
r.h.al = mode; /* set EGA mode */
int86 (0x10, &r, &r);
grafixmode = mode; /* save mode */
atexit (pc_textmode); /* register exit function */

result = TRUE;
} else
if ((mode == VGA16) && vga) { /* typo fixed 5/89 */
r.h.ah = 0;
r.h.al = mode;
int86 (0x10, &r, &r);
grafixmode = mode;
atexit (pc_textmode);
result = TRUE;
}
}
if (!result) { /* unable to switch to graphics */
oldmode = 0; /* so cancel text screen save */
free (vidsave);
vidsave = 0;
}
if (mode == VGA16 && vga) /* viewport init added May '89 */
default_viewport (480);
return result;
} /* ------------------------------------------------------ */

void far pc_textmode (void)
/* SPECIFIC TO MS-DOS */
/* Restore text mode */
/* Automatically called on pgm termination */
{
union REGS r;

if (oldmode) { /* if not in text mode now... */
r.h.ah = 0;
r.h.al = oldmode; /* restore text mode */
int86 (0x10, &r, &r);
movedata /* restore text screen */
(FP_SEG (vidsave), FP_OFF (vidsave), vidmem, 0, 4096);
free (vidsave); /* free allocated memory */
vidsave = 0; /* zero pointer */
oldmode = 0; /* reset */
r.h.ah = 2; /* restore old cursor position */
r.h.bh = textpage;
r.x.dx = curpos;
int86 (0x10, &r, &r);
}
} /* ------------------------------------------------------ */

void far set_color1 (int palette_reg)
/* Select pixel color from palette register */
{
color1 = palette_reg;
} /* ------------------------------------------------------ */

void far draw_line (int x1, int y1, int x2, int y2)
/* Bresenham line drawing algorithm */
/* x1, y1 and x2, y2 are end points */
{
int w, h, d, dxd, dyd, dxn, dyn, dinc, ndinc, p;
register x, y;

/* Set up */
x = x1; y = y1; /* start of line */
w = x2 - x1; /* width domain of line */
h = y2 - y1; /* height domain of line */

/* Determine drawing direction */
if (w < 0) { /* drawing right to left */
w = -w; /* absolute width */
dxd = -1; /* x increment is negative */
} else /* drawing left to right */
dxd = 1; /* so x incr is positive */
if (h < 0) { /* drawing bottom to top */
h = -h; /* so get absolute height */
dyd = -1; /* y incr is negative */
} else /* drawing top to bottom */
dyd = 1; /* so y incr is positive */

/* Determine major axis of motion */
if (w < h) { /* major axis is Y */
p = h, h = w, w = p; /* exchange height and width */
dxn = 0;
dyn = dyd;
} else { /* major axis is X */
dxn = dxd;
dyn = 0;
}

/* Set control variables */
ndinc = h * 2; /* Non-diagonal increment */
d = ndinc - w; /* pixel selection variable */
dinc = d - w; /* Diagonal increment */

/* Loop to draw the line */
for (p = 0; p <= w; p++) {
draw_point (x, y);
if (d < 0) { /* step non-diagonally */
x += dxn;
y += dyn;
d += ndinc;
} else { /* step diagonally */
x += dxd;
y += dyd;
d += dinc;
}
}
} /* ------------------------------------------------------ */

void far draw_rect (int xleft, int ytop, int w, int h)
/* Draw outline rectangle in color1 from top left corner */
/* w and h are width and height */
/* xleft and ytop are top left corner */
{
draw_line (xleft, ytop, xleft+w, ytop); /* top */
draw_line (xleft+w, ytop, xleft+w, ytop+h); /* right */
draw_line (xleft+w, ytop+h, xleft, ytop+h); /* bottom */
draw_line (xleft, ytop+h, xleft, ytop); /* left */
} /* ------------------------------------------------------ */

void far polyline (int edges, int vertex[])
/* Draw multipoint line of n edges from n+1 vertices where: */
/* vertex [0] = x0 vertex [1] = y0 */
/* vertex [2] = x1 vertex [3] = y1 */
/* etc. */
{
int x1, y1, x2, y2, v;

x1 = vertex[0];
y1 = vertex[1];
for (v = 2; v < (edges+1)*2; v+= 2) {
x2 = vertex[v];
y2 = vertex[v+1];
draw_line (x1, y1, x2, y2);
x1 = x2;
y1 = y2;
}
} /* ------------------------------------------------------ */

void far fill_rect (int xleft, int ytop, int w, int h)
/* Draw solid rectangle in color1 from top left corner */
{
register y;

for (y = ytop; y < ytop+h; y++)
hline (xleft, y, w);
} /* ------------------------------------------------------ */


[GRAPHIX.H, NOT A NUMBERED LISTING IN DDJ, 5/89]


/* Include file for GRAFIX.LIB */
/* EGA/VGA graphics subsystem */
/* K. Porter, DDJ Graphics Programming Column */
/* ------------------------------------------ */

/* Color constants from April, 89 */
#define Black 0 /* standard colors */
#define Blue 1
#define Green 2
#define Cyan 3
#define Red 4
#define Magenta 5
#define Brown 0x14
#define LtGray 7
#define DkGray 0x38
#define LtBlue 0x39
#define LtGreen 0x3A
#define LtCyan 0x3B
#define LtRed 0x3C
#define LtMagenta 0x3D
#define Yellow 0x3E
#define White 0x3F

#define RED0 0x00 /* basic hues for mixing */
#define RED1 0x20
#define RED2 0x04
#define RED3 0x24
#define GRN0 0x00
#define GRN1 0x10
#define GRN2 0x02
#define GRN3 0x12
#define BLU0 0x00
#define BLU1 0x08
#define BLU2 0x01
#define BLU3 0x09

#if !defined byte
#define byte unsigned char
#endif

/* Supported video modes */
#define EGA 0x10 /* EGA 640 x 350, 16/64 colors */
#define VGA16 0x11 /* VGA 640 x 480, 16/64 colors */

/* Function prototypes */
/* From February, '89 */
/* ------------------ */
int far init_video (int mode); /* init display in video mode */

void far pc_textmode (void); /* PC text mode */

void far draw_point (int x, int y); /* write pixel in color1 */

void far set_color1 (int palette_reg); /* set foreground color */

/* From March, '89 */
/* --------------- */
void far draw_line (int x1, int y1, int x2, int y2);
/* Bresenham line drawing algorithm */

void far draw_rect (int left, int top, int width, int height);
/* draw rectangle from top left corner */

void far polyline (int edges, int vertices[]); /* draw polyline */

void far hline (int x, int y, int len); /* horizontal line */

void far fill_rect (int left, int top, int width, int height);
/* draw solid rectangle in color1 starting at top left corner */

/* From April, '89 */
/* --------------- */
byte far ega_palreg (int preg); /* color in EGA palette reg */

void far set_ega_palreg (int reg, int color); /* set palette reg */

byte far colorblend (byte r, byte g, byte b); /* blend hues */

void far get_ega_colormix (int preg, int *r, int *g, int *b);
/* get mix of red, green, and blue in EGA pal register preg */

/* From May, '89 */
/* ------------- */
typedef int VP_HAN; /* viewport handle type */

void far default_viewport (int height); /* init default viewport */

VP_HAN far vp_open (int x, int y, int width, int height);
/* open viewport, make it active */

int far vp_use (VP_HAN vp); /* make vp active */

void far vp_close (VP_HAN vp); /* close viewport */

VP_HAN far vp_active (void); /* get handle of active vp */

void far vp_outline (VP_HAN vp); /* outline vp */

int far vp_width (void); /* get active viewport width */

int far vp_height (void); /* and height */


  3 Responses to “Category : Files from Magazines
Archive   : DDJ0589.ZIP
Filename : VUPORT.ASC

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/