DECLARE FUNCTION vsinsaft% (i%) DECLARE FUNCTION vsinsbef% (i%) DECLARE SUB vsdel (i%) DECLARE SUB fillconvpoly (x!(), y!(), n%, col%, bcol%) DECLARE SUB drawtri (x0!, y0!, x1!, y1!, x2!, y2!, col%, bcol%) DECLARE SUB drawquad (x0!, y0!, x1!, y1!, x2!, y2!, x3!, y3!, col%, bcol%) DECLARE SUB domost (x0!, y0!, x1!, y1!, upd%) DECLARE SUB initmosts () DECLARE SUB printsmall (bx%, y%, c%, nam$) SCREEN 9: CONST XDIM = 640, YDIM = 350 DIM SHARED pag%, lastx%(YDIM + 2), maskhack% DIM SHARED regs%(7): regs%(0) = 11: CALL int86old(&H33, regs%(), regs%()) mousx% = XDIM \ 2: mousy% = YDIM \ 2 DIM SHARED smallfnt(64 - 1) AS LONG '0-63 represent chars: 32-95 FOR z% = 0 TO 63: READ smallfnt(z%): NEXT z% TYPE point2d x AS SINGLE: n AS INTEGER: p AS INTEGER: tag AS INTEGER cy0 AS SINGLE: cy1 AS SINGLE: ctag AS INTEGER fy0 AS SINGLE: fy1 AS SINGLE: ftag AS INTEGER END TYPE CONST VSPMAX = XDIM '<- careful! DIM SHARED vsp(VSPMAX) AS point2d, vcnt%, gtag% CALL initmosts 'CALL domost(320, 176, 128, 272, 1) 'CALL domost(128, 272, 320, 176, 1) pt% = 0 DO IF backcnt% > 0 THEN LINE (0, 0)-(XDIM - 1, YDIM - 1), 13, BF backcnt% = backcnt% - 1 END IF oz% = 0: z% = vsp(0).n: fcol% = 0: ccol% = 0 DO nz% = vsp(z%).n IF vsp(z%).ctag <> vsp(oz%).ctag THEN cx0 = vsp(z%).x: cy0 = vsp(z%).cy0 IF vsp(z%).ctag <> vsp(nz%).ctag THEN maskhack% = 8 CALL drawquad(cx0, 0, vsp(nz%).x, 0, vsp(nz%).x, vsp(z%).cy1, cx0, cy0, ccol%, ccol%) maskhack% = 0: ccol% = ccol% XOR 8 CALL printsmall((cx0 + vsp(nz%).x) \ 2, 2, 6, LTRIM$(STR$(vsp(z%).ctag))) END IF CALL drawquad(vsp(z%).x, vsp(z%).cy0, vsp(nz%).x, vsp(z%).cy1, vsp(nz%).x, vsp(z%).fy1, vsp(z%).x, vsp(z%).fy0, 6, 4) IF vsp(z%).ftag <> vsp(oz%).ftag THEN fx0 = vsp(z%).x: fy0 = vsp(z%).fy0 IF vsp(z%).ftag <> vsp(nz%).ftag THEN maskhack% = 8 CALL drawquad(fx0, fy0, vsp(nz%).x, vsp(z%).fy1, vsp(nz%).x, YDIM, fx0, YDIM, fcol%, fcol%) maskhack% = 0: fcol% = fcol% XOR 8 CALL printsmall((fx0 + vsp(nz%).x) \ 2, YDIM - 3, 6, LTRIM$(STR$(vsp(z%).ftag))) END IF oz% = z%: z% = nz% LOOP WHILE vsp(z%).n IF vsp(vsp(vsp(0).n).n).n = 0 AND vsp(vsp(0).n).ftag < 0 THEN LOCATE 1, 1: PRINT "done!"; END IF z$ = INKEY$ regs%(0) = 5: CALL int86old(&H33, regs%(), regs%()) obstatus% = bstatus%: bstatus% = regs%(0) regs%(0) = 11: CALL int86old(&H33, regs%(), regs%()) mousx% = mousx% + regs%(2): IF mousx% < 0 THEN mousx% = 0 mousy% = mousy% + regs%(3): IF mousy% < 0 THEN mousy% = 0 IF mousx% > XDIM THEN mousx% = XDIM IF mousy% > YDIM THEN mousy% = YDIM IF pt% = 0 THEN x0 = (mousx% + 3) AND NOT 7: y0 = (mousy% + 3) AND NOT 7 x1 = (mousx% + 3) AND NOT 7: y1 = (mousy% + 3) AND NOT 7 IF (bstatus% AND 1) > (obstatus% AND 1) THEN pt% = 1 IF (bstatus% AND 1) < (obstatus% AND 1) THEN DEF SEG = 0: IF (PEEK(&H417) AND 3) THEN upd% = 0 ELSE upd% = 1 IF x0 <> x1 THEN CALL domost(x0, y0, x1, y1, upd%): pt% = 2 ELSE pt% = 0 END IF CALL printsmall(8, 8, 15, LTRIM$(STR$((mousx% + 3) AND NOT 7))) CALL printsmall(24, 8, 15, LTRIM$(STR$((mousy% + 3) AND NOT 7))) IF pt% THEN IF x0 < x1 THEN LINE (x1, y1)-(x1, YDIM - 1), 15 ELSEIF x0 > x1 THEN LINE (x1, y1)-(x1, 0), 15 END IF LINE (x0, y0)-(x1, y1), 15 CIRCLE (x1, y1), 1, 12, , , 1 END IF IF x0 < x1 THEN LINE (x0, y0)-(x0, YDIM - 1), 15 ELSEIF x0 > x1 THEN LINE (x0, y0)-(x0, 0), 15 END IF CIRCLE (x0, y0), 1, 15, , , 1 IF 0 THEN z% = vsp(0).n: c% = 1 DO nz% = vsp(z%).n c% = c% + 1: LOCATE c%, 1 PRINT "z"; z%; PRINT "x"; vsp(z%).x; ; "n"; vsp(z%).n; "p"; vsp(z%).p; "tag"; vsp(z%).tag; IF nz% THEN PRINT "cy0"; vsp(z%).cy0; "cy1"; vsp(z%).cy1; "ctag"; vsp(z%).ctag; PRINT "fy0"; vsp(z%).fy0; "fy1"; vsp(z%).fy1; "ftag"; vsp(z%).ftag END IF z% = nz% LOOP WHILE z% END IF SCREEN , , pag%, 1 - pag%: pag% = 1 - pag% WAIT &H3DA, &H8, &H8: WAIT &H3DA, &H8 OUT &H3C8, 2 IF pt% = 2 THEN OUT &H3C9, 32: OUT &H3C9, 0: OUT &H3C9, 0 ELSE OUT &H3C9, 0: OUT &H3C9, 63: OUT &H3C9, 0 END IF IF pt% = 2 THEN p = 2.2: dt = 1 / 16 r0 = 42: g0 = 0: b0 = 0 '"apparent" average of colors 4&6 r1 = 0: g1 = 63: b1 = 0: dt = 1 / 16 FOR t = 0 TO 1 STEP dt OUT &H3C8, 2 OUT &H3C9, ((r1 ^ p - r0 ^ p) * t + r0 ^ p) ^ (1 / p) OUT &H3C9, ((g1 ^ p - g0 ^ p) * t + g0 ^ p) ^ (1 / p) OUT &H3C9, ((b1 ^ p - b0 ^ p) * t + b0 ^ p) ^ (1 / p) WAIT &H3DA, &H8, &H8: WAIT &H3DA, &H8 NEXT t DO z$ = INKEY$ regs%(0) = 5: CALL int86old(&H33, regs%(), regs%()) obstatus% = bstatus%: bstatus% = regs%(0) LOOP WHILE z$ = "" AND bstatus% = 0 FOR z% = 15 TO 0 STEP -1 OUT &H3C8, 2: OUT &H3C9, 0: OUT &H3C9, z% * 4: OUT &H3C9, 0 WAIT &H3DA, &H8, &H8: WAIT &H3DA, &H8 NEXT z% backcnt% = 2 pt% = 0 END IF LOOP WHILE z$ <> CHR$(27) '3*5 font, chars:32-95. HACK: ; looks like a , (Should be &H40480) DATA 0,&H444040,&HAA0000,&HAFAFA0,&H6C46C0,&HA248A0,&H4A4CE0,&H240000 DATA &H488840,&H422240,&HA4A00,&H4E400,&H224,&HE000,&H40,&H224480 DATA &HEAAAE0,&H444440,&HE2E8E0,&HE2E2E0,&HAAE220,&HE8E2E0,&HE8EAE0,&HE22220 DATA &HEAEAE0,&HEAE220,&H40400,&H224,&H248420,&HE0E00,&H842480,&HC24040 DATA &HEAECE0,&H4AEAA0,&HCACAC0,&H688860,&HCAAAC0,&HE8C8E0,&HE8C880,&HE8AAE0 DATA &HAAEAA0,&HE444E0,&HE22A60,&HAACAA0,&H8888E0,&HAEEAA0,&HAEEEA0,&HEAAAE0 DATA &HEAE880,&HEAAE60,&HEACAA0,&HE8E2E0,&HE44440,&HAAAAE0,&HAAA440,&HAAEEA0 DATA &HAA4AA0,&HAAE440,&HE248E0,&HC888C0,&H844220,&H622260,&H4A0000,&HE0 SUB domost (bx0, by0, bx1, by1, upd%) DIM spx(4), spy(4), spt%(4), cy(2), cv(2) x0 = bx0: y0 = by0: x1 = bx1: y1 = by1 IF bx0 < bx1 THEN dir% = 1 y0 = y0 - .01: y1 = y1 - .01 ELSE IF bx0 = bx1 THEN EXIT SUB SWAP x0, x1: SWAP y0, y1: dir% = 0 y0 = y0 + .01: y1 = y1 + .01 END IF i% = vsp(0).n: slop = (y1 - y0) / (x1 - x0) DO WHILE i% newi% = vsp(i%).n nx0 = vsp(i%).x: nx1 = vsp(newi%).x IF x0 >= nx1 OR nx0 >= x1 OR vsp(i%).ctag <= 0 THEN GOTO domostcont dx = nx1 - nx0 cy(0) = vsp(i%).cy0: cv(0) = vsp(i%).cy1 - cy(0) cy(1) = vsp(i%).fy0: cv(1) = vsp(i%).fy1 - cy(1) scnt% = 0 'Test if left edge requires split (x0,y0) (nx0,cy(0)), IF x0 > nx0 AND x0 < nx1 THEN t = (x0 - nx0) * cv(dir%) - (y0 - cy(dir%)) * dx IF ((dir% = 0) AND (t < 0)) OR ((dir% = 1) AND (t > 0)) THEN spx(scnt%) = x0: spy(scnt%) = y0 spt%(scnt%) = -1: scnt% = scnt% + 1 END IF END IF 'Test for intersection on umost (j% == 0) and dmost (j% == 1) FOR j% = 0 TO 1 d = (y0 - y1) * dx - (x0 - x1) * cv(j%) n = (y0 - cy(j%)) * dx - (x0 - nx0) * cv(j%) IF ABS(n) <= ABS(d) AND d * n >= 0 AND d <> 0 THEN t = n / d: nx = (x1 - x0) * t + x0 IF nx > nx0 AND nx < nx1 THEN spx(scnt%) = nx: spy(scnt%) = (y1 - y0) * t + y0 spt%(scnt%) = j%: scnt% = scnt% + 1 END IF END IF NEXT j% 'Nice hack to avoid full sort later :) IF scnt% >= 2 THEN IF spx(scnt% - 1) < spx(scnt% - 2) THEN SWAP spx(scnt% - 1), spx(scnt% - 2) SWAP spy(scnt% - 1), spy(scnt% - 2) SWAP spt%(scnt% - 1), spt%(scnt% - 2) END IF END IF 'Test if right edge requires split IF x1 > nx0 AND x1 < nx1 THEN t = (x1 - nx0) * cv(dir%) - (y1 - cy(dir%)) * dx IF ((dir% = 0) AND (t < 0)) OR ((dir% = 1) AND (t > 0)) THEN spx(scnt%) = x1: spy(scnt%) = y1 spt%(scnt%) = -1: scnt% = scnt% + 1 END IF END IF vsp(i%).tag = -1: vsp(newi%).tag = -1 IF upd% = 0 THEN oi% = i%: ocy1 = vsp(i%).cy1: ofy1 = vsp(i%).fy1 FOR z% = 0 TO scnt% IF z% < scnt% THEN vcnt% = vsinsaft%(i%) CIRCLE (spx(z%), spy(z%)), 3, 15 - spt%(z%), , , 1 t = (spx(z%) - nx0) / dx vsp(i%).cy1 = t * cv(0) + cy(0) vsp(i%).fy1 = t * cv(1) + cy(1) vsp(vcnt%).x = spx(z%) vsp(vcnt%).cy0 = vsp(i%).cy1 vsp(vcnt%).fy0 = vsp(i%).fy1 vsp(vcnt%).tag = spt%(z%) IF upd% = 0 THEN spt%(z%) = vcnt% 'save vcnt% for deletion END IF ni% = vsp(i%).n: dx0 = vsp(i%).x: dx1 = vsp(ni%).x IF ni% AND x0 <= dx0 AND x1 >= dx1 THEN ny0 = (dx0 - x0) * slop + y0 ny1 = (dx1 - x0) * slop + y0 ' dx0 dx1 ' ³ ³ '----------------------------- ' t0%+=0 t1%+=0 ' vsp(i%).cy0 vsp(i%).cy1 '============================= ' t0%+=1 t1%+=3 '============================= ' vsp(i%).fy0 vsp(i%).fy1 ' t0%+=2 t1%+=6 ' ' ny0 ? ny1 ? t% = 1 + 3 IF vsp(i%).tag = 0 OR ny0 <= vsp(i%).cy0 THEN t% = t% - 1 IF vsp(i%).tag = 1 OR ny0 >= vsp(i%).fy0 THEN t% = t% + 1 IF vsp(ni%).tag = 0 OR ny1 <= vsp(i%).cy1 THEN t% = t% - 3 IF vsp(ni%).tag = 1 OR ny1 >= vsp(i%).fy1 THEN t% = t% + 3 IF dir% = 0 THEN SELECT CASE t% CASE 1, 2: CALL drawtri(dx0, vsp(i%).cy0, dx1, vsp(i%).cy1, dx0, ny0, 2, 14) IF upd% THEN vsp(i%).cy0 = ny0: vsp(i%).ctag = gtag% CASE 3, 6: CALL drawtri(dx0, vsp(i%).cy0, dx1, vsp(i%).cy1, dx1, ny1, 2, 14) IF upd% THEN vsp(i%).cy1 = ny1: vsp(i%).ctag = gtag% CASE 4, 5, 7: CALL drawquad(dx0, vsp(i%).cy0, dx1, vsp(i%).cy1, dx1, ny1, dx0, ny0, 2, 14) IF upd% THEN vsp(i%).cy0 = ny0: vsp(i%).cy1 = ny1: vsp(i%).ctag = gtag% CASE 8: CALL drawquad(dx0, vsp(i%).cy0, dx1, vsp(i%).cy1, dx1, vsp(i%).fy1, dx0, vsp(i%).fy0, 2, 14) IF upd% THEN vsp(i%).cy0 = YDIM \ 2: vsp(i%).cy1 = YDIM \ 2: vsp(i%).ctag = -1 vsp(i%).fy0 = YDIM \ 2: vsp(i%).fy1 = YDIM \ 2: vsp(i%).ftag = -1 END IF END SELECT ELSE SELECT CASE t% CASE 7, 6: CALL drawtri(dx0, ny0, dx1, vsp(i%).fy1, dx0, vsp(i%).fy0, 2, 14) IF upd% THEN vsp(i%).fy0 = ny0: vsp(i%).ftag = gtag% CASE 5, 2: CALL drawtri(dx0, vsp(i%).fy0, dx1, ny1, dx1, vsp(i%).fy1, 2, 14) IF upd% THEN vsp(i%).fy1 = ny1: vsp(i%).ftag = gtag% CASE 4, 3, 1: CALL drawquad(dx0, ny0, dx1, ny1, dx1, vsp(i%).fy1, dx0, vsp(i%).fy0, 2, 14) IF upd% THEN vsp(i%).fy0 = ny0: vsp(i%).fy1 = ny1: vsp(i%).ftag = gtag% CASE 0: CALL drawquad(dx0, vsp(i%).cy0, dx1, vsp(i%).cy1, dx1, vsp(i%).fy1, dx0, vsp(i%).fy0, 2, 14) IF upd% THEN vsp(i%).cy0 = YDIM \ 2: vsp(i%).cy1 = YDIM \ 2: vsp(i%).ctag = -1 vsp(i%).fy0 = YDIM \ 2: vsp(i%).fy1 = YDIM \ 2: vsp(i%).ftag = -1 END IF END SELECT END IF END IF i% = vcnt% NEXT z% IF upd% = 0 THEN FOR z% = scnt% - 1 TO 0 STEP -1: CALL vsdel(spt%(z%)): NEXT z% vsp(oi%).cy1 = ocy1: vsp(oi%).fy1 = ofy1 END IF domostcont: i% = newi% LOOP gtag% = gtag% + 1 IF upd% THEN i% = vsp(0).n DO WHILE i% ni% = vsp(i%).n IF vsp(i%).cy0 >= vsp(i%).fy0 AND vsp(i%).cy1 >= vsp(i%).fy1 THEN vsp(i%).ctag = -1: vsp(i%).ftag = -1 END IF IF vsp(i%).ctag = vsp(ni%).ctag AND vsp(i%).ftag = vsp(ni%).ftag THEN vsp(i%).cy1 = vsp(ni%).cy1 vsp(i%).fy1 = vsp(ni%).fy1 CALL vsdel(ni%) ELSE i% = ni% END IF LOOP END IF END SUB SUB drawquad (x0, y0, x1, y1, x2, y2, x3, y3, col%, bcol%) DIM x(4 - 1), y(4 - 1) x(0) = x0: y(0) = y0 x(1) = x1: y(1) = y1 x(2) = x2: y(2) = y2 x(3) = x3: y(3) = y3 CALL fillconvpoly(x(), y(), 4, col%, bcol%) '2 triangles IF col% <> bcol% THEN IF ABS(y0 - y2) < ABS(y1 - y3) THEN LINE (x0, y0)-(x2, y2), bcol%, , &H6666 ELSE LINE (x1, y1)-(x3, y3), bcol%, , &H6666 END IF END IF END SUB SUB drawtri (x0, y0, x1, y1, x2, y2, col%, bcol%) DIM x(3 - 1), y(3 - 1) x(0) = x0: y(0) = y0 x(1) = x1: y(1) = y1 x(2) = x2: y(2) = y2 CALL fillconvpoly(x(), y(), 3, col%, bcol%) END SUB SUB fillconvpoly (x(), y(), n%, col%, bcol%) mini% = ABS(y(0) >= y(1)): maxi% = 1 - mini% FOR z% = 2 TO n% - 1 IF y(z%) < y(mini%) THEN mini% = z% IF y(z%) > y(maxi%) THEN maxi% = z% NEXT z% area = 0: zz% = n% - 1 FOR z% = 0 TO n% - 1 area = area + (x(zz%) - x(z%)) * (y(z%) + y(zz%)): zz% = z% NEXT z% IF area <= 0 THEN EXIT SUB i% = maxi%: y2% = INT(y(i%) - .5) DO j% = i% + 1: IF j% = n% THEN j% = 0 y% = INT(y(j%) + .5) IF y% <= y2% THEN xi = (x(j%) - x(i%)) / (y(j%) - y(i%)) x = (y2% - y(j%)) * xi + x(j%) + .5 FOR y2% = y2% TO y% STEP -1 lastx%(y2%) = INT(x): x = x - xi NEXT y2% END IF i% = j% LOOP WHILE i% <> mini% DO j% = i% + 1: IF j% = n% THEN j% = 0 y2% = INT(y(j%) - .5) IF y2% >= y% THEN xi = (x(j%) - x(i%)) / (y(j%) - y(i%)) x = (y% - y(i%)) * xi + x(i%) + .5 ncol% = col%: IF (y% AND 1) THEN ncol% = ncol% XOR maskhack% FOR y% = y% TO y2% LINE (lastx%(y%), y%)-(INT(x), y%), ncol%: x = x + xi ncol% = ncol% XOR maskhack% NEXT y% END IF i% = j% LOOP WHILE i% <> maxi% IF col% <> bcol% THEN oz% = n% - 1 FOR z% = 0 TO n% - 1 LINE (x(oz%), y(oz%))-(x(z%), y(z%)), bcol% oz% = z% NEXT z% END IF END SUB SUB initmosts '0 is dummy solid node vsp(1).x = 0: vsp(1).cy0 = YDIM * .25: vsp(1).fy0 = YDIM * .75 IF 1 THEN vsp(2).x = XDIM: vsp(2).cy0 = YDIM * .25: vsp(2).fy0 = YDIM * .75 vsp(3).x = XDIM vcnt% = 3 ELSE vsp(2).x = 160: vsp(2).cy0 = 48 + 50: vsp(2).fy0 = YDIM - 48 - 50 vsp(3).x = 224: vsp(3).cy0 = 16 + 50: vsp(3).fy0 = YDIM - 16 - 50 vsp(4).x = 384: vsp(4).cy0 = 96 + 50: vsp(4).fy0 = YDIM - 96 - 50 vsp(5).x = XDIM: vsp(5).cy0 = 0: vsp(5).fy0 = YDIM vsp(6).x = XDIM vcnt% = 6 END IF FOR z% = 0 TO vcnt% - 1 vsp(z%).cy1 = vsp(z% + 1).cy0: vsp(z%).ctag = z% vsp(z%).fy1 = vsp(z% + 1).fy0: vsp(z%).ftag = z% vsp(z%).n = z% + 1: vsp(z%).p = z% - 1 NEXT z% vsp(vcnt% - 1).n = 0: vsp(0).p = vcnt% - 1 gtag% = vcnt% 'VSPMAX-1 is dummy empty node FOR z% = vcnt% TO VSPMAX - 1 vsp(z%).n = z% + 1: vsp(z%).p = z% - 1 NEXT z% vsp(VSPMAX - 1).n = vcnt%: vsp(vcnt%).p = VSPMAX - 1 END SUB DEFDBL A-Z SUB printsmall (bx%, y%, c%, nam$) l% = LEN(nam$): IF l% = 0 THEN EXIT SUB x% = bx% - l% - l%: LINE (x% - 1, y% - 3)-STEP(l% * 4, 6), 0, BF FOR z% = 1 TO l% i& = smallfnt((ASC(MID$(nam$, z%, 1)) - 32) AND 63) FOR yy% = y% + 3 TO y% - 2 STEP -1 IF (i& AND 8) THEN PSET (x% + 0, yy%), c% IF (i& AND 4) THEN PSET (x% + 1, yy%), c% IF (i& AND 2) THEN PSET (x% + 2, yy%), c% IF (i& AND 1) THEN PSET (x% + 3, yy%), c% i& = i& \ 16 NEXT yy% x% = x% + 4 NEXT z% END SUB DEFSNG A-Z SUB vsdel (i%) 'Delete i% pi% = vsp(i%).p ni% = vsp(i%).n vsp(ni%).p = pi% vsp(pi%).n = ni% 'Add i% to empty list vsp(i%).n = vsp(VSPMAX - 1).n vsp(i%).p = VSPMAX - 1 vsp(vsp(VSPMAX - 1).n).p = i% vsp(VSPMAX - 1).n = i% END SUB FUNCTION vsinsaft% (i%) 'i% = next element from empty list r% = vsp(VSPMAX - 1).n vsp(vsp(r%).n).p = VSPMAX - 1 vsp(VSPMAX - 1).n = vsp(r%).n vsp(r%) = vsp(i%) 'copy i% to r% 'insert r% after i% vsp(r%).p = i%: vsp(r%).n = vsp(i%).n vsp(vsp(i%).n).p = r%: vsp(i%).n = r% vsinsaft% = r% END FUNCTION FUNCTION vsinsbef% (i%) 'i% = next element from empty list r% = vsp(VSPMAX - 1).n vsp(vsp(r%).n).p = VSPMAX - 1 vsp(VSPMAX - 1).n = vsp(r%).n vsp(r%) = vsp(i%) 'copy i% to r% 'insert r% before i% vsp(r%).p = vsp(i%).p: vsp(r%).n = i% vsp(vsp(i%).p).n = r%: vsp(i%).p = r% vsinsbef% = r% END FUNCTION