I found this program on Toshi's webpage
'===========================================================================
' Subject: 3D TEXTURED POLYGON ENGINE V2.0 Date: 12-24-97 (15:25)
' Author: Sami Kyostila Code: QB, QBasic, PDS
' Origin: hiteck@freenet.hut.fi Packet: GRAPHICS.ABC
'===========================================================================
'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
' 3D Polygon Engine v2.0 (C) Sami Ky”stil„ 1997
'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
' Comments & questions can be sent to hiteck@freenet.hut.fi
'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
'
' Here's a new version of my previous 3d engine. Actually it's almost a
' complete rewrite, with tons of new features. Currently there are 4
' drawing modes:
'
' + Z-Shaded Wireframe
' + Z-Gouraud shaded and filled
' + Z-Shaded Flat, ASM-Filled
' + Z-Gouraud shaded and texturemapped
'
' These drawing modes can be selected with the F1-F4 keys. In addition
' there are also 4 animated textures:
'
' + Fire - Looks very kewl
' + BumpMap - Nice and fast bumpmap
' + Panning textures - Looks like flowing green ooze
' + Sinus plasma - An animated plasma
'
' These can be toggled on/off with the F9-F12 keys. NOTE: After you have
' selected an animated texture, you must press that same key again to
' disable it.
'
' The object is rotated with the arrow keys and the plus/minus keys. Zoom
' in/out with the A/Z keys. The object can be panned with the J/K/L/I keys.
' 5 stops movement, and 0 resets the object to the starting position.
' You can also rotate the object with the mouse by pressing the left mouse
' button.
'
' All of the drawing modes are shaded, and the ambient lighting level can
' be varied with the F5/F6 keys. F7 toggles point number display on/off
' F9 toggles FPS display on/off (this slows the engine down a bit, you can
' also see the FPS in the exit screen)
'
' If the texture mapping seems too slow, you can adjust the texture size
' by changing the TSize-constant below.
'
' See the end of the program to find out how to make your own objects
' If you want to save you objects to a file, insert the following
' statement to the SUB TheEnd:
'
' SaveObject "filename.dat"
'
' When you press ESC, the object is saved. To load a saved object, use the
' SUB LoadObject
'
'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
' You may use any of this code freely in you own programs, as long as you
' mention my name somewhere in you program.
'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
DEFINT A-Z
'$DYNAMIC
DECLARE SUB HiiriLue (vasen%, oikea%, keski%, x%, y%)
DECLARE SUB Hiiriajuri (ax%, bx%, cx%, dx%)
DECLARE FUNCTION Hiiritarkista% ()
DECLARE SUB LoadObject (File$)
DECLARE SUB SaveObject (File$)
DECLARE SUB HandleKeys ()
DECLARE SUB TheEnd ()
DECLARE SUB RotatePoints ()
DECLARE SUB ColPrint (Text$)
DECLARE FUNCTION ShadeName$ (Model%)
DECLARE SUB Separator (Col&, Char$)
DECLARE SUB MakePalette ()
DECLARE SUB MakeFirePalette (MaxColors%)
DECLARE SUB MakeTexture ()
DECLARE SUB Switch (Var%, Value1%, Value2%)
DECLARE SUB MakeLight ()
DECLARE SUB Fillchar (segment%, offset%, value%, bytes%)
DECLARE SUB Memcopy (fromseg%, fromoffset%, toseg%, tooffset%, bytes%)
DECLARE SUB t3d2d (x%, y%, z%, SX%, SY%)
DECLARE SUB RotatePoint (x%, y%, z%, Rx%, Ry%, Rz%, Nx%, Ny%, Nz%)
DECLARE SUB DrawPoly (x%, y%, x2%, y2%, x3%, y3%, P1%, P2%, P3%, Num)
DECLARE SUB DrawLine (x%, y%, x2%, y2%, Col1%, Col2%, Tx1, Ty1, Tx2, Ty2)
DEFINT A-Z
TYPE Filltype 'Buffer to hold polygon data
x1 AS INTEGER
x2 AS INTEGER
Col1 AS INTEGER
Col2 AS INTEGER
Tx AS INTEGER
Ty AS INTEGER
Tx2 AS INTEGER
Ty2 AS INTEGER
END TYPE
TYPE PointType
x3 AS INTEGER 'Original X
y3 AS INTEGER 'Original Y
z3 AS INTEGER 'Original Z
x AS INTEGER 'Screen X
y AS INTEGER 'Screen Y
Nx AS INTEGER 'New X
Ny AS INTEGER 'New Y
Nz AS INTEGER 'New Z
Shade AS INTEGER 'Shade
END TYPE
TYPE Polygontype
P1 AS INTEGER 'Point 1
P2 AS INTEGER 'Point 2
P3 AS INTEGER 'Point 3
Col AS INTEGER 'Color
Culled AS INTEGER 'Culled/Not Culled
AvgZ AS INTEGER
END TYPE
'----------------------------------------------------------------------------
' Constants
'----------------------------------------------------------------------------
CONST True = 0
CONST False = NOT True
CONST PI = 22 / 7
CONST TSize = 40
CONST LSize = TSize \ 2
DIM SHARED Polygons, Points
DIM SHARED Sine(360) AS INTEGER 'SIN table
DIM SHARED Cosine(360) AS INTEGER 'COS table
DIM SHARED Fill(199) AS Filltype 'Polygon data buffer
DIM SHARED Upper AS INTEGER
DIM SHARED Lower AS INTEGER
DIM SHARED SrX AS INTEGER
DIM SHARED SrY AS INTEGER
DIM SHARED Zoom AS INTEGER
DIM SHARED Buffer(319, 199) AS STRING * 1
DIM SHARED ShadingModel AS INTEGER
DIM SHARED Ambient AS INTEGER
DIM SHARED Mx, My
DIM SHARED Fire AS INTEGER
DIM SHARED Anim AS INTEGER
DIM SHARED AnimType AS INTEGER
DIM SHARED l(0 TO LSize, 0 TO LSize) AS INTEGER
DIM SHARED MaxPoints, MaxPolygons
DIM SHARED Xr AS INTEGER
DIM SHARED Yr AS INTEGER
DIM SHARED Zr AS INTEGER
DIM SHARED Vx, Vy, Vz
DIM SHARED FDisp, PDisp
DIM SHARED FPS&
DIM SHARED WaveSide1, WaveSide2, WaveSide3
DIM SHARED R1, R2, R3
FOR i = 0 TO 360
Sine(i) = SIN(i * PI / 180) * 1024
Cosine(i) = COS(i * PI / 180) * 1024
NEXT
SrX = 320 \ 2 'Screen center
SrY = 200 \ 2
Zoom = 700 'Initial values
Xr = 200
Yr = 315
Zr = 100
Mx = 0
My = 0
Ambient = 10
PDisp = False
FDisp = False
Fire = False
ShadingModel = 2
SCREEN 0: CLS
WIDTH 80, 25
COLOR 15, 4
LOCATE 1, 1
PRINT STRING$(80, " "

LOCATE 1, 1
PRINT " 3D Polygon Engine v2.0 by Sami Ky”stil„ 1997"
COLOR 3, 0
PRINT
RESTORE ObjectData
READ MaxPoints
READ MaxPolygons
DIM SHARED Pnt(1 TO MaxPoints) AS PointType
DIM SHARED Poly(1 TO MaxPolygons) AS Polygontype
DIM SHARED Pointer(1 TO MaxPolygons)
DIM SHARED Txt(-1 TO TSize + 1, -1 TO TSize + 1) AS INTEGER
DIM SHARED ASMMemCopy$
DIM SHARED ASMFillChar$
asm$ = ""
asm$ = asm$ + CHR$(85)
asm$ = asm$ + CHR$(137) + CHR$(229)
asm$ = asm$ + CHR$(30)
asm$ = asm$ + CHR$(139) + CHR$(70) + CHR$(10)
asm$ = asm$ + CHR$(142) + CHR$(192)
asm$ = asm$ + CHR$(139) + CHR$(70) + CHR$(14)
asm$ = asm$ + CHR$(142) + CHR$(216)
asm$ = asm$ + CHR$(139) + CHR$(118) + CHR$(8)
asm$ = asm$ + CHR$(139) + CHR$(126) + CHR$(12)
asm$ = asm$ + CHR$(139) + CHR$(78) + CHR$(6)
asm$ = asm$ + CHR$(243)
asm$ = asm$ + CHR$(164)
asm$ = asm$ + CHR$(31)
asm$ = asm$ + CHR$(93)
asm$ = asm$ + CHR$(203)
ASMMemCopy$ = asm$
asm$ = ""
asm$ = asm$ + CHR$(85)
asm$ = asm$ + CHR$(137) + CHR$(229)
asm$ = asm$ + CHR$(139) + CHR$(78) + CHR$(6)
asm$ = asm$ + CHR$(139) + CHR$(86) + CHR$(8)
asm$ = asm$ + CHR$(139) + CHR$(70) + CHR$(12)
asm$ = asm$ + CHR$(30)
asm$ = asm$ + CHR$(142) + CHR$(216)
asm$ = asm$ + CHR$(139) + CHR$(94) + CHR$(10)
asm$ = asm$ + CHR$(136) + CHR$(23)
asm$ = asm$ + CHR$(67)
asm$ = asm$ + CHR$(226) + CHR$(251)
asm$ = asm$ + CHR$(31)
asm$ = asm$ + CHR$(93)
asm$ = asm$ + CHR$(203)
ASMFillChar$ = asm$
PRINT "Number of points:", , MaxPoints
PRINT "Number of polygons:", , MaxPolygons
PRINT "Starting position (XYZ)", , Xr; Yr; Zr
PRINT "Texture size: ", , TSize; "x"; TSize
PRINT "Initial shading model:", , " "; ShadeName$(ShadingModel)
PRINT "Ambient lighting level:", , Ambient
Separator 1, "Ä"
COLOR 7
PRINT " þ Reading points...";
FOR i = 1 TO MaxPoints
READ Pnt(i).x3
READ Pnt(i).y3
READ Pnt(i).z3
NEXT
PRINT "Done"
PRINT " þ Reading polygons...";
FOR i = 1 TO MaxPolygons
READ Poly(i).P1
READ Poly(i).P2
READ Poly(i).P3
READ Poly(i).Col
Poly(i).Col = Poly(i).Col * 64
NEXT
PRINT "Done"
PRINT " þ Generating texture...";
MakeTexture
PRINT "Done"
PRINT " þ Initializing mouse...";
RESTORE MouseData
DIM SHARED hiiri$
hiiri$ = SPACE$(57)
FOR i% = 1 TO 57
READ a$
h$ = CHR$(VAL("&H" + a$))
MID$(hiiri$, i%, 1) = h$
NEXT i%
napit% = Hiiritarkista%
IF (napit% = 0) THEN
PRINT "Mouse not found!"
MouseNotFound = 1
ELSE
PRINT "Done (Press left MButton to rotate)"
END IF
PRINT
Separator 3, "Ä"
ColPrint " &FF1&7 - Wireframe &FF2&7 - Z-Gouraud &FF3&7 - Z-Flat &FF4&7 - Textured"
PRINT
ColPrint " &FArrows/-/+&7 - Rotate &FA/Z&7 - Zoom In/Out &FJ/K/L/I&7 - Pan &F5&7 - Stop &F0&7 - Reset"
PRINT
ColPrint " &FF5&7/&FF6&7 - Adjust ambient lighting level "
PRINT
ColPrint " &FF7&7 - Point display toggle"
PRINT
ColPrint " &FF8&7 - Frame rate toggle"
PRINT
ColPrint " &FF9&7 - Animated texture 1 - &EFire"
PRINT
ColPrint " &FF10&7 - Animated texture 2 - &EBumpmap"
PRINT
ColPrint " &FF11&7 - Animated texture 3 - &ETexture panning"
PRINT
ColPrint " &FF12&7 - Animated texture 4 - &EPlasma"
MakeLight
DO: LOOP UNTIL INKEY$ <> ""
SCREEN 13: CLS
MakePalette
COLOR 255
DIM Temp(0 TO TSize, 0 TO TSize) AS INTEGER
FOR y& = 0 TO TSize
FOR x& = 0 TO TSize
Temp(x&, y&) = Txt(x&, y&)
NEXT
NEXT
DIM Cosinus(160) AS INTEGER
DIM Rand(255) AS INTEGER
FOR c = 0 TO 160
Cosinus(c) = COS(c * 2 * PI / 80) * 16 + 16
NEXT
FOR c = 0 TO 255
Rand(c) = INT(RND * 4) + 1
NEXT
XAdd& = 1
YAdd& = 1
Anim = False
DO
RotatePoints
FOR i& = 1 TO MaxPolygons
Poly(i&).AvgZ = (Pnt(Poly(i&).P1).Nz + Pnt(Poly(i&).P2).Nz + Pnt(Poly(i&).P3).Nz) \ 3
Pointer(i&) = i&
Poly(i&).Culled = False
NEXT
FOR i& = 1 TO MaxPolygons
coord1 = Poly(i&).P1
coord2 = Poly(i&).P2
coord3 = Poly(i&).P3
z1& = Pnt(coord1).Nz
z2& = Pnt(coord2).Nz
z3& = Pnt(coord3).Nz
x1& = Pnt(coord1).Nx
x2& = Pnt(coord2).Nx
x3& = Pnt(coord3).Nx
y1& = Pnt(coord1).Ny
y2& = Pnt(coord2).Ny
y3& = Pnt(coord3).Ny
IF (x1& - x2&) * (y3& - y2&) - (y1& - y2&) * (x3& - x2&) < 0 THEN Poly(i&).Culled = True
NEXT
FOR i& = 1 TO MaxPolygons
FOR ii& = 1 TO MaxPolygons - 1
IF Poly(Pointer(ii&)).AvgZ > Poly(Pointer(ii& + 1)).AvgZ THEN SWAP Pointer(ii&), Pointer(ii& + 1)
NEXT
NEXT
FOR ii& = 1 TO MaxPolygons
i& = Pointer(ii&)
IF NOT Poly(i&).Culled = True THEN
DrawPoly Pnt(Poly(i&).P1).x + SrX, Pnt(Poly(i&).P1).y + SrY, Pnt(Poly(i&).P2).x + SrX, Pnt(Poly(i&).P2).y + SrY, Pnt(Poly(i&).P3).x + SrX, Pnt(Poly(i&).P3).y + SrY, Pnt(Poly(i&).P1).Shade + Poly(i&).Col, Pnt(Poly(i&).P2).Shade + Poly(i&).Col, _
Pnt(Poly(i&).P3).Shade + Poly(i&).Col, INT(i&)
END IF
NEXT
Memcopy VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), &HA000, 0, &HFA00
Fillchar VARSEG(Buffer(0, 0)), VARPTR(Buffer(0, 0)), 0, &HFA00
'Print Point numbers
IF PDisp = True THEN
FOR i = 1 TO MaxPoints
Ty = (Pnt(i).y + SrY) \ 8 + 1
Tx = (Pnt(i).x + SrX) \ 8 + 1
IF Ty > 23 THEN Ty = 23
IF Ty < 1 THEN Ty = 1
IF Tx < 1 THEN Tx = 1
IF Tx > 40 THEN Tx = 40
LOCATE Ty, Tx
PRINT LTRIM$(RTRIM$(STR$((i))))
NEXT
END IF
HandleKeys
SELECT CASE AnimType
CASE 1
ShadingModel = 4
FOR y = 0 TO TSize - 1
FOR x = 0 TO TSize
Txt(x, y + 1) = (Txt(x - 1, y - 1) + Txt(x, y - 1) + Txt(x + 1, y - 1) + Txt(x + 1, y) + Txt(x + 1, y + 1) + Txt(x, y + 1) + Txt(x - 1, y + 1) + Txt(x - 1, y)) \ 8 - 1
NEXT
NEXT
FOR i = 0 TO TSize \ 4
XPos = RND * TSize
Temp = RND * 63
Txt(XPos, -1) = RND * Temp
Txt(XPos, 0) = RND * Temp
NEXT
CASE 2
ShadingModel = 4
Lx& = Lx& + XAdd&
Ly& = Ly& + YAdd&
FOR y& = 0 TO TSize
FOR x& = 0 TO TSize
Txt(x&, y&) = Temp(x&, y&)
NEXT
NEXT
FOR y& = 0 TO LSize
FOR x& = 0 TO LSize
Txt((x& + Lx&) MOD TSize, (y& + Ly&) MOD TSize) = Txt((x& + Lx&) MOD TSize, (y& + Ly&) MOD TSize) + l(x&, y&)
NEXT
NEXT
Lx& = Lx& + XAdd&
Ly& = Ly& + YAdd&
IF Lx& = TSize THEN XAdd& = -XAdd&
IF Lx& = 0 THEN XAdd& = -XAdd&
IF Ly& = TSize - 2 THEN YAdd& = -YAdd&
IF Ly& = 0 THEN YAdd& = -YAdd&
CASE 3
ShadingModel = 4
FOR y = 1 TO TSize - 1
FOR x = 0 TO TSize
Txt(x, y - 1) = Txt(x, y)
NEXT
NEXT
FOR i = 0 TO TSize
Txt(i, TSize - 1) = Txt(i, 0)
NEXT
CASE 4
ShadingModel = 4
WAVE1 = WAVE1 + WaveSide1
IF WAVE1 >= 80 THEN
WAVE1 = 0
R1 = (R1 + 1) AND 255
WaveSide1 = Rand(R1)
END IF
WAVE2 = WAVE2 + WaveSide2
IF WAVE2 >= 80 THEN
WAVE2 = 0
R2 = (R2 + 2) AND 255
WaveSide2 = Rand(R2)
END IF
WAVE3 = WAVE3 + WaveSide3
IF WAVE3 >= 80 THEN
WAVE3 = 0
R3 = (R3 + 2) AND 255
WaveSide3 = Rand(R3)
END IF
FOR y& = 0 TO TSize
E = Cosinus(y& + WAVE1)
FOR x& = 0 TO TSize
Col = Cosinus(x& + WAVE2) + E + Cosinus(x& + WAVE3) + Cosinus(x& + y&)
IF Col > 127 THEN Col = 127
Txt(x&, y&) = Col
NEXT
NEXT
END SELECT
'----------------------------------------------------------------------------
' Update rotation velocities
'----------------------------------------------------------------------------
Xr = Xr + Vx
Yr = Yr + Vy
Zr = Zr + Vz
IF Xr < 0 THEN Xr = 360 + Xr
IF Yr < 0 THEN Yr = 360 + Yr
IF Zr < 0 THEN Zr = 360 + Zr
Xr = Xr MOD 361
Yr = Yr MOD 361
Zr = Zr MOD 361
IF TIMER >= start& + 2 THEN
FPS& = INT(Frame / 2)
Frame = 0
start& = INT(TIMER)
END IF
Frame = Frame + 1
IF FDisp = True THEN
COLOR 255
LOCATE 1, 1: PRINT FPS&; "fps "
END IF
IF MouseNotFound = 0 THEN
HiiriLue B1, B2, B3, MouseX, MouseY
IF B1 = -1 THEN
Xr = MouseX
Zr = MouseY
END IF
END IF
LOOP
'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
' Object data
'ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
ObjectData:
' Number of points
DATA 5
' Number of polygons
DATA 6
' Point data
'
' X Y Z
DATA -100, 0, 100
DATA -100, 0, -100
DATA 100, 0, -100
DATA 100, 0, 100
DATA 0, -190, 0
' Polygon data
'
' Pnt1 Pnt2 Pnt3 Color (1-4)
DATA 5, 1, 4, 1
DATA 5, 4, 3, 2
DATA 5, 2, 1, 3
DATA 5, 3, 2, 4
DATA 4, 1, 2, 1
DATA 4, 2, 3, 1
MouseData:
DATA 55, 89, E5, 8B, 5E, 0C, 8B, 07, 50, 8B, 5E, 0A, 8B, 07, 50, 8B
DATA 5E, 08, 8B, 0F, 8B, 5E, 06, 8B, 17, 5B, 58, 1E, 07, CD, 33, 53
DATA 8B, 5E, 0C, 89, 07, 58, 8B, 5E, 0A, 89, 07, 8B, 5E, 08, 89, 0F
DATA 8B, 5E, 06, 89, 17, 5D, CA, 08, 00
REM $STATIC
SUB ColPrint (Text$)
'----------------------------------------------------------------------------
' SúYúSúTúEúM
'----------------------------------------------------------------------------
'----------------------------------------------------------------------------
' Prints color-coded text
'----------------------------------------------------------------------------
' Color codes:
'
' & followed by a color value between 0-15 (in hex)
'
' Example:
'
' This text is &Cred
'----------------------------------------------------------------------------
FOR i = 1 TO LEN(Text$)
Done = 0
DO
IF MID$(Text$, i, 1) = "&" AND INSTR("0123456789ABCDEF", MID$(Text$, i + 1, 1)) AND i < LEN(Text$) THEN
COLOR VAL("&H" + MID$(Text$, i + 1, 1))
i = i + 2
ELSE
Done = 1
END IF
LOOP UNTIL Done
PRINT MID$(Text$, i, 1);
NEXT
END SUB
SUB DrawLine (x, y, x2, y2, Col1, Col2, Tx1, Ty1, Tx2, Ty2)
'----------------------------------------------------------------------------
' Calculate the points of a polygon into the buffer
'----------------------------------------------------------------------------
IF y < Upper THEN Upper = y
IF y > Lower THEN Lower = y
IF Upper < 0 THEN Upper = 0
IF Lower > 199 THEN Lower = 199
'Calculate deltas and scale by 1024
Steps = SQR((x2 - x) ^ 2 + ((y2 - y) ^ 2))
IF Steps > 0 THEN
XStep& = ((x2 - x) / Steps) * 1024
YStep& = ((y2 - y) / Steps) * 1024
ColStep& = ((Col2 - Col1) / Steps) * 1024
ELSE
EXIT SUB
END IF
Tempxx& = x
Tempyy& = y
xxx& = Tempxx& * 1024
yyy& = Tempyy& * 1024
Col& = CLNG(Col1) * 1024
IF ShadingModel = 4 THEN
Tx& = CLNG(Tx1) * 1024
Ty& = CLNG(Ty1) * 1024
TxDelta& = ((Tx2 - Tx1) / Steps) * 1024
TyDelta& = ((Ty2 - Ty1) / Steps) * 1024
FOR i& = 1 TO Steps
IF yyy& >= 0 AND yyy& < 204800 THEN
IF xxx& \ 1024 < Fill(yyy& \ 1024).x1 THEN
Fill(yyy& \ 1024).x1 = xxx& \ 1024
Fill(yyy& \ 1024).Tx = Tx& \ 1024
Fill(yyy& \ 1024).Ty = Ty& \ 1024
Fill(yyy& \ 1024).Col1 = Col& \ 1024
END IF
IF xxx& \ 1024 > Fill(yyy& \ 1024).x2 THEN
Fill(yyy& \ 1024).x2 = xxx& \ 1024
Fill(yyy& \ 1024).Tx2 = Tx& \ 1024
Fill(yyy& \ 1024).Ty2 = Ty& \ 1024
Fill(yyy& \ 1024).Col2 = Col& \ 1024
END IF
END IF
xxx& = xxx& + XStep&
yyy& = yyy& + YStep&
Tx& = Tx& + TxDelta&
Ty& = Ty& + TyDelta&
Col& = Col& + ColStep&
NEXT
ELSE
FOR i& = 1 TO Steps
IF yyy& >= 0 AND yyy& < 204800 THEN
IF xxx& \ 1024 < Fill(yyy& \ 1024).x1 THEN
Fill(yyy& \ 1024).x1 = xxx& \ 1024
Fill(yyy& \ 1024).Col1 = Col& \ 1024
END IF
IF xxx& \ 1024 > Fill(yyy& \ 1024).x2 THEN
Fill(yyy& \ 1024).x2 = xxx& \ 1024
Fill(yyy& \ 1024).Col2 = Col& \ 1024
END IF
END IF
xxx& = xxx& + XStep&
yyy& = yyy& + YStep&
Col& = Col& + ColStep&
NEXT
END IF
END SUB
SUB DrawPoly (x, y, x2, y2, x3, y3, P1, P2, P3, Num)
FOR i2 = 1 TO 199
Fill(i2).x1 = 321
Fill(i2).x2 = -1
Fill(i2 - 1).x1 = 321
Fill(i2 - 1).x2 = -1
Fill(i2).Col1 = 0
Fill(i2).Col2 = 0
Fill(i2 - 1).Col1 = 0
Fill(i2 - 1).Col2 = 0
NEXT
DrawLine x, y, x2, y2, P1, P2, TSize \ 2, TSize, TSize, 0
DrawLine x3, y3, x, y, P3, P1, 0, 0, TSize \ 2, TSize
DrawLine x2, y2, x3, y3, P2, P3, TSize, 0, 0, 0
SELECT CASE ShadingModel
CASE 1
OldPos1 = 321
OldPos2 = 321
FOR yy& = Upper TO Lower - 1
XLen = Fill(yy&).x2 - Fill(yy&).x1
IF XLen > 0 AND Fill(yy&).x1 > 0 AND Fill(yy&).x2 < 319 AND Fill(yy&).x1 < 319 AND Fill(yy&).x2 > 0 THEN
IF OldPos1 < 320 AND OldPos1 > 0 THEN
IF OldPos1 > Fill(yy&).x1 THEN
FOR xx& = OldPos1 - 1 TO Fill(yy&).x1 STEP -1
Buffer(xx&, yy&) = CHR$(Fill(yy&).Col1 MOD 255)
NEXT
ELSE
FOR xx& = OldPos1 + 1 TO Fill(yy&).x1
Buffer(xx&, yy&) = CHR$(Fill(yy&).Col1 MOD 255)
NEXT
END IF
ELSE
Buffer(Fill(yy&).x1, yy&) = CHR$(Fill(yy&).Col1 MOD 255)
END IF
IF OldPos2 < 320 AND OldPos2 > 0 THEN
IF OldPos2 > Fill(yy&).x2 THEN
FOR xx& = OldPos2 TO Fill(yy&).x2 STEP -1
Buffer(xx&, yy&) = CHR$(Fill(yy&).Col2 MOD 255)
NEXT
ELSE
FOR xx& = OldPos2 TO Fill(yy&).x2
Buffer(xx&, yy&) = CHR$(Fill(yy&).Col2 MOD 255)
NEXT
END IF
ELSE
Buffer(Fill(yy&).x2, yy&) = CHR$(Fill(yy&).Col2 MOD 255)
END IF
END IF
OldPos1 = Fill(yy&).x1
OldPos2 = Fill(yy&).x2
NEXT
CASE 2
FOR yy& = Upper TO Lower - 1
XLen = Fill(yy&).x2 - Fill(yy&).x1
IF XLen > 0 THEN
ColDelta& = (Fill(yy&).Col2 - Fill(yy&).Col1) / XLen * 1024
Col& = CLNG(Fill(yy&).Col1) * 1024
IF Fill(yy&).x1 + XLen > 319 THEN XLen = 319 - Fill(yy&).x1
IF Fill(yy&).x1 < 0 THEN XLen = XLen + Fill(yy&).x1: Col& = Col& + ColDelta& * -Fill(yy&).x1: Fill(yy&).x1 = 0
FOR xx& = Fill(yy&).x1 TO Fill(yy&).x1 + XLen
Buffer(xx&, yy&) = CHR$(ABS(Col& \ 1024) MOD 255)
Col& = Col& + ColDelta&
NEXT
END IF
NEXT
CASE 3
FOR yy& = Upper TO Lower - 1
XLen = Fill(yy&).x2 - Fill(yy&).x1
IF XLen > 0 THEN
IF Fill(yy&).x1 + XLen > 319 THEN XLen = 319 - Fill(yy&).x1
IF Fill(yy&).x1 < 0 THEN
XLen = XLen + Fill(yy&).x1
Fill(yy&).x1 = 0
END IF
IF Fill(yy&).x1 < 319 AND XLen > 0 THEN Fillchar VARSEG(Buffer(Fill(yy&).x1, yy&)), VARPTR(Buffer(Fill(yy&).x1, yy&)), (Pnt(Poly(Num).P1).Shade + Pnt(Poly(Num).P2).Shade + Pnt(Poly(Num).P3).Shade) \ 3 + Poly(Num).Col, XLen + 1
END IF
NEXT
CASE 4
IF Anim = False THEN
FOR yy& = Upper TO Lower - 1
XLen = Fill(yy&).x2 - Fill(yy&).x1
IF XLen > 0 THEN
TxDelta& = (Fill(yy&).Tx2 - Fill(yy&).Tx) / XLen * 1024
TyDelta& = (Fill(yy&).Ty2 - Fill(yy&).Ty) / XLen * 1024
Tx& = CLNG(Fill(yy&).Tx) * 1024
Ty& = CLNG(Fill(yy&).Ty) * 1024
ColDelta& = (Fill(yy&).Col2 - Fill(yy&).Col1) / XLen * 1024
Col& = CLNG(Fill(yy&).Col1) * 1024
IF Fill(yy&).x2 > 319 THEN Fill(yy&).x2 = 319
IF Fill(yy&).x1 + XLen > 319 THEN XLen = 319 - Fill(yy&).x1
IF Fill(yy&).x1 < 0 THEN
XLen = XLen + Fill(yy&).x1
Col& = Col& + ColDelta& * -Fill(yy&).x1
Tx& = Tx& + TxDelta& * -Fill(yy&).x1
Ty& = Ty& + TyDelta& * -Fill(yy&).x1
Fill(yy&).x1 = 0
END IF
FOR xx& = Fill(yy&).x1 TO Fill(yy&).x1 + XLen
XPos& = Tx& \ 1024
YPos& = Ty& \ 1024
Buffer(xx&, yy&) = CHR$((Txt(XPos&, YPos&) + ((Col& \ 1024))) MOD 255)
Tx& = Tx& + TxDelta&
Ty& = Ty& + TyDelta&
Col& = Col& + ColDelta&
NEXT
END IF
NEXT
ELSE
FOR yy& = Upper TO Lower - 1
XLen = Fill(yy&).x2 - Fill(yy&).x1
IF XLen > 0 THEN
TxDelta& = (Fill(yy&).Tx2 - Fill(yy&).Tx) / XLen * 1024
TyDelta& = (Fill(yy&).Ty2 - Fill(yy&).Ty) / XLen * 1024
Tx& = CLNG(Fill(yy&).Tx) * 1024
Ty& = CLNG(Fill(yy&).Ty) * 1024
IF Fill(yy&).x2 > 319 THEN Fill(yy&).x2 = 319
IF Fill(yy&).x1 + XLen > 319 THEN XLen = 319 - Fill(yy&).x1
IF Fill(yy&).x1 < 0 THEN
XLen = XLen + Fill(yy&).x1
Col& = Col& + ColDelta& * -Fill(yy&).x1
Tx& = Tx& + TxDelta& * -Fill(yy&).x1
Ty& = Ty& + TyDelta& * -Fill(yy&).x1
Fill(yy&).x1 = 0
END IF
FOR xx& = Fill(yy&).x1 TO Fill(yy&).x2
XPos& = Tx& \ 1024
YPos& = Ty& \ 1024
Buffer(xx&, yy&) = CHR$(ABS((Txt(XPos&, YPos&)) + Ambient) MOD 255)
Tx& = Tx& + TxDelta&
Ty& = Ty& + TyDelta&
NEXT
END IF
NEXT
END IF
END SELECT
END SUB
SUB Fillchar (segment%, offset%, value%, bytes%)
DEF SEG = VARSEG(ASMFillChar$)
CALL absolute(BYVAL segment%, BYVAL offset%, BYVAL value%, BYVAL bytes%, SADD(ASMFillChar$))
DEF SEG
END SUB
SUB HandleKeys
DEF SEG = 0: k = INP(&H60)
WHILE LEN(INKEY$): WEND 'Empty keyboard buffer
SELECT CASE k
CASE &H3B 'F1
ShadingModel = 1
CASE &H3C 'F2
ShadingModel = 2
CASE &H3D 'F3
ShadingModel = 3
CASE &H3E 'F4
ShadingModel = 4
CASE &H3F 'F5
Ambient = Ambient - 1
IF Ambient < 0 THEN Ambient = 0
CASE &H40 'F6
Ambient = Ambient + 1
IF Ambient > 63 THEN Ambient = 63
CASE &H41 'F7
Switch PDisp, True, False
CASE &H42 'F8
Switch FDisp, True, False
CASE &H43 'F9
Switch Anim, True, False
IF Anim = True THEN
AnimType = 1
MakeFirePalette 63
FOR x = 0 TO TSize
FOR y = 0 TO TSize
Txt(x, y) = 0
NEXT
NEXT
FOR i = 64 TO 255
OUT &H3C8, i
OUT &H3C9, 63
OUT &H3C9, 63
OUT &H3C9, 63
NEXT
ELSE
MakePalette
MakeTexture
AnimType = 0
END IF
CASE &H44 'F10
Switch Anim, True, False
IF Anim = True THEN
AnimType = 2
FOR i = 1 TO 63
OUT &H3C8, i
OUT &H3C9, 0
OUT &H3C9, 0
OUT &H3C9, i
NEXT
FOR i = 64 TO 128
OUT &H3C8, i
OUT &H3C9, i
OUT &H3C9, i
OUT &H3C9, 63
NEXT
FOR i = 128 TO 255
OUT &H3C8, i
OUT &H3C9, 63
OUT &H3C9, 63
OUT &H3C9, 63
NEXT
FOR y = 0 TO TSize
FOR x = 0 TO TSize
Txt(x, y) = RND * 64
NEXT
NEXT
ELSE
MakePalette
MakeTexture
AnimType = 0
END IF
CASE &H57 'F11
Switch Anim, True, False
IF Anim = True THEN
AnimType = 3
FOR i = 1 TO 63
OUT &H3C8, i
OUT &H3C9, 0
OUT &H3C9, i
OUT &H3C9, 0
NEXT
FOR i = 64 TO 128
OUT &H3C8, i
OUT &H3C9, i
OUT &H3C9, 63
OUT &H3C9, i
NEXT
FOR i = 128 TO 255
OUT &H3C8, i
OUT &H3C9, 63
OUT &H3C9, 63
OUT &H3C9, 63
NEXT
ELSE
MakePalette
MakeTexture
AnimType = 0
END IF
CASE &H58 'F12
Switch Anim, True, False
IF Anim = True THEN
AnimType = 4
WaveSide1 = 1
WaveSide2 = 3
WaveSide3 = 2
R1 = 1
R2 = 10
R3 = 20
FOR i = 1 TO 63
OUT &H3C8, i
OUT &H3C9, i
OUT &H3C9, 0
OUT &H3C9, 0
NEXT
FOR i = 64 TO 128
OUT &H3C8, i
OUT &H3C9, 63
OUT &H3C9, i
OUT &H3C9, i
NEXT
FOR i = 128 TO 255
OUT &H3C8, i
OUT &H3C9, 63
OUT &H3C9, 63
OUT &H3C9, 63
NEXT
ELSE
MakePalette
MakeTexture
AnimType = 0
END IF
CASE &H52 '0
Zoom = 700
Xr = 400
Yr = 315
Zr = 0
Mx = 0
My = 0
CASE &H4C '5
Vx = 0
Vy = 0
Vz = 0
CASE &H1E 'A
Zoom = Zoom - 10
IF Zoom < 0 THEN Zoom = 0
CASE &H50 '2
Vx = Vx + 1
CASE &H48 '8
Vx = Vx - 1
CASE &H4B '4
Vy = Vy + 1
CASE &H4D '6
Vy = Vy - 1
CASE &H4A '+
Vz = Vz + 1
CASE &H4E '-
Vz = Vz - 1
CASE &H2C 'Z
Zoom = Zoom + 10
CASE &H17 'I
My = My + 5
CASE &H25 'K
My = My - 5
CASE &H24 'J
Mx = Mx + 5
CASE &H26 'L
Mx = Mx - 5
CASE 1 'ESC
TheEnd
END SELECT
END SUB
SUB Hiiriajuri (ax%, bx%, cx%, dx%)
DEF SEG = VARSEG(hiiri$) 'Segmentti talteen
hiiri% = SADD(hiiri$) 'Offsetti talteen
CALL absolute(ax%, bx%, cx%, dx%, hiiri%) 'Kutsu
END SUB
SUB HiiriLue (vasen%, oikea%, keski%, x%, y%)
ax% = 3 'Funktio 3
Hiiriajuri ax%, bx%, cx%, dx% 'Kutsutaan hiiriajuria
vasen% = ((bx% AND 1) <> 0) 'Luetaan nappien asennot
oikea% = ((bx% AND 2) <> 0) 'bx:st„
keski% = ((bx% AND 4) <> 0)
x% = cx% 'ja hiiren koordinaatit
y% = dx% 'cx:st„ ja dx:st„
END SUB
FUNCTION Hiiritarkista%
ax% = 0 'Funktio 0
Hiiriajuri ax%, bx%, 0, 0 'Kutsutaan hiiriajuria
IF (ax% = 0) THEN 'Onko ajuri k„yt”ss„?
Hiiritarkista% = 0 'jos ei, palautetaan 0
ELSEIF (bx% = 3) THEN 'Kolminappinen hiiri?
Hiiritarkista% = 3
ELSEIF (bx% = 0) THEN 'Ep„standardi hiiri?
Hiiritarkista% = 1
ELSE
Hiiritarkista% = 2 'Tavallinen kaksinappinen hiiri?
END IF
END FUNCTION
DEFSNG A-Z
SUB InterPolate (x, y, x2, y2)
P1 = POINT(x, y)
P2 = POINT(x2, y)
P3 = POINT(x, y2)
P4 = POINT(x2, y2)
YDelta1& = (P3 - P1) / (y2 - y) * 1024
YDelta2& = (P4 - P2) / (y2 - y) * 1024
Col1& = P1 * 1024
Col2& = P3 * 1024
FOR yy& = y TO y2
PSET (x, yy&), Col1& \ 1024
PSET (x2, yy&), Col2& \ 1024
Col1& = Col1& + YDelta1&
Col2& = Col2& + YDelta2&
NEXT
XLen = x2 - x
FOR yy& = y TO y2
P1 = POINT(x, yy&)
P2 = POINT(x2, yy&)
XDelta& = (P2 - P1) / XLen * 1024
Col& = P1 * 1024
FOR xx& = x TO x2
PSET (xx&, yy&), Col& \ 1024
Col& = Col& + XDelta&
NEXT
NEXT
END SUB
DEFINT A-Z
SUB LoadObject (File$)
OPEN File$ FOR INPUT AS #1
LINE INPUT #1, Temp$
INPUT #1, MaxPoints
INPUT #1, MaxPolygons
LINE INPUT #1, Temp$
LINE INPUT #1, Temp$
FOR i = 1 TO MaxPoints
INPUT #1, Pnt(i).x3, Pnt(i).y3, Pnt(i).z3
NEXT
LINE INPUT #1, Temp$
LINE INPUT #1, Temp$
FOR i = 1 TO MaxPolygons
INPUT #1, Poly(i).P1, Poly(i).P2, Poly(i).P3, Poly(i).Col
NEXT
CLOSE #1
END SUB
SUB MakeFirePalette (MaxColors) 'Asettaa paletin
FOR x% = 1 TO MaxColors
OUT &H3C8, x%
OUT &H3C9, 63
OUT &H3C9, 63
OUT &H3C9, 63
NEXT
FOR x% = 0 TO (MaxColors \ 4) - 1
OUT &H3C8, x%
OUT &H3C9, x% * (63 / (MaxColors \ 4))
OUT &H3C9, 0
OUT &H3C9, 0
OUT &H3C8, x% + (MaxColors \ 4)
OUT &H3C9, 63
OUT &H3C9, x% * (63 / (MaxColors \ 4))
OUT &H3C9, 0
OUT &H3C8, x% + ((MaxColors \ 4) * 2)
OUT &H3C9, 63
OUT &H3C9, 63
OUT &H3C9, x% * (63 / (MaxColors \ 4))
NEXT x%
END SUB
SUB MakeLight
FOR x& = 0 TO LSize
FOR y& = 0 TO LSize
Xd! = (x& - (LSize \ 2)) / (LSize \ 2)
Yd! = (y& - (LSize \ 2)) / (LSize \ 2)
Light! = (1 - SQR(Xd! ^ 2 + Yd! ^ 2))
IF Light! < 0 THEN Light! = 0
l(x&, y&) = CINT(Light! * (LSize * 4))
NEXT
NEXT
END SUB
SUB MakePalette
FOR i = 0 TO 63
OUT &H3C8, i
OUT &H3C9, i
OUT &H3C9, i
OUT &H3C9, 0
NEXT
FOR i = 64 TO 128
OUT &H3C8, i
OUT &H3C9, i
OUT &H3C9, 0
OUT &H3C9, 0
NEXT
FOR i = 129 TO 192
OUT &H3C8, i
OUT &H3C9, 0
OUT &H3C9, i
OUT &H3C9, 0
NEXT
FOR i = 193 TO 255
OUT &H3C8, i
OUT &H3C9, 0
OUT &H3C9, 0
OUT &H3C9, i
NEXT
END SUB
SUB MakeTexture
FOR y = 0 TO TSize
FOR x = 0 TO TSize
Txt(x, y) = RND * 32
NEXT
NEXT
FOR Iter = 0 TO 0
FOR y = 0 TO TSize
FOR x = 0 TO TSize
Txt(x, y) = (Txt(x - 1, y - 1) + Txt(x, y - 1) + Txt(x + 1, y - 1) + Txt(x + 1, y) + Txt(x + 1, y + 1) + Txt(x, y + 1) + Txt(x - 1, y + 1) + Txt(x - 1, y)) \ 8
NEXT
NEXT
NEXT
END SUB
SUB Memcopy (fromseg%, fromoffset%, toseg%, tooffset%, bytes%)
DEF SEG = VARSEG(ASMMemCopy$)
CALL absolute(BYVAL fromseg%, BYVAL fromoffset%, BYVAL toseg%, BYVAL tooffset%, BYVAL bytes%, SADD(ASMMemCopy$))
DEF SEG
END SUB
SUB ReadObject (File$)
IF File$ = "" THEN
END IF
END SUB
SUB RotatePoint (xo, yo, zo, Rx, Ry, Rz, Nx, Ny, Nz)
'----------------------------------------------------------------------------
' Rotate a point in 3D space
'----------------------------------------------------------------------------
s1& = Sine(Rx MOD 360)
s2& = Sine(Ry MOD 360)
s3& = Sine(Rz MOD 360)
c1& = Cosine(Rx MOD 360)
c2& = Cosine(Ry MOD 360)
c3& = Cosine(Rz MOD 360)
x1 = (xo * c1& - zo * s1&) \ 1024
z1 = (xo * s1& + zo * c1&) \ 1024
z3 = (z1 * c3& - yo * s3&) \ 1024 + oz
y2 = (z1 * s3& + yo * c3&) \ 1024
x2 = (x1 * c2& + y2 * s2&) \ 1024 + ox
y3 = (y2 * c2& - x1 * s2&) \ 1024 + oy
Nx = x2
Ny = y3
Nz = z3
END SUB
SUB RotatePoints
FOR i& = 1 TO MaxPoints
RotatePoint Pnt(i&).x3, Pnt(i&).y3, Pnt(i&).z3, Xr, Yr, Zr, x3, y3, z3
t3d2d x3, y3, z3, SX, SY
Pnt(i&).Nx = x3
Pnt(i&).Ny = y3
Pnt(i&).Nz = z3
Pnt(i&).x = SX
Pnt(i&).y = SY
Pnt(i&).Shade = z3 / 6 + Ambient
IF ShadingModel = 4 THEN
IF Pnt(i&).Shade > 32 THEN Pnt(i&).Shade = 32
ELSE
IF Pnt(i&).Shade > 63 THEN Pnt(i&).Shade = 63
END IF
IF Pnt(i&).Shade < 1 THEN Pnt(i&).Shade = 1
NEXT
END SUB
SUB SaveObject (File$)
OPEN File$ FOR OUTPUT AS #1
PRINT #1, "--------[ 3D Engine (C) Sami Ky”stil„ - Object Data file ]--------"
PRINT #1, MaxPoints
PRINT #1, MaxPolygons
PRINT #1, "---------------------------------------------[ Start Point data ]-"
PRINT #1, "X", "Y", "Z"
FOR i = 1 TO MaxPoints
PRINT #1, Pnt(i).x3, Pnt(i).y3, Pnt(i).z3
NEXT
PRINT #1, "-------------------------------------------[ Start Polygon data ]-"
PRINT #1, "Point 1", "Point 2", "Point 3", "Color"
FOR i = 1 TO MaxPolygons
PRINT #1, Poly(i).P1, Poly(i).P2, Poly(i).P3, Poly(i).Col
NEXT
CLOSE #1
END SUB
DEFLNG A-Z
SUB Separator (Col, Char$)
'----------------------------------------------------------------------------
' Prints a separator line
'----------------------------------------------------------------------------
SELECT CASE Col
CASE IS = 1
Col1 = 1
Col2 = 9
Col3 = 3
Col4 = 11
Col5 = 15
CASE IS = 2
Col1 = 2
Col2 = 10
Col3 = 14
Col4 = 15
Col5 = 15
CASE IS = 3
Col1 = 8
Col2 = 7
Col3 = 15
Col4 = 15
Col5 = 15
END SELECT
COLOR Col1
PRINT STRING$(5, Char$);
COLOR Col2
PRINT STRING$(5, Char$);
COLOR Col3
PRINT STRING$(5, Char$);
COLOR Col4
PRINT STRING$(5, Char$);
COLOR Col5
PRINT STRING$(40, Char$);
COLOR Col4
PRINT STRING$(5, Char$);
COLOR Col3
PRINT STRING$(5, Char$);
COLOR Col2
PRINT STRING$(5, Char$);
COLOR Col1
PRINT STRING$(5, Char$)
END SUB
DEFINT A-Z
FUNCTION ShadeName$ (Model)
SELECT CASE Model
CASE 1: ShadeName$ = "Wireframe"
CASE 2: ShadeName$ = "Z-Gouraud"
CASE 3: ShadeName$ = "Z-Flat"
CASE 4: ShadeName$ = "Textured"
END SELECT
END FUNCTION
SUB Switch (Var, Value1, Value2)
'----------------------------------------------------------------------------
' Switches values
'----------------------------------------------------------------------------
'
' Var - Variable to be changed
' Value1 - Value 1
' Value2 - Value 2
'
'----------------------------------------------------------------------------
'
' if Var = Value1 then Value2 will be assigned to Var
'
' if Var = Value2 then Value1 will be assigned to Var
'
' This SUB is used with Checkboxes and Radiobuttons
'
'----------------------------------------------------------------------------
IF Var = Value1 THEN Var = Value2: EXIT SUB
IF Var = Value2 THEN Var = Value1
END SUB
SUB t3d2d (x, y, z, SX, SY)
'----------------------------------------------------------------------------
' Transforms 3D coordinates into 2D screen coordinates
'----------------------------------------------------------------------------
IF z - Zoom <> 0 THEN SY = CLNG(y + My) * 100 \ INT(z - Zoom)
IF z - Zoom <> 0 THEN SX = CLNG(x + Mx) * 100 \ INT(z - Zoom)
END SUB
SUB TheEnd
SCREEN 0: CLS
WIDTH 80, 25
COLOR 15, 4
LOCATE 1, 1
PRINT STRING$(80, " "

LOCATE 1, 1
PRINT " 3D Polygon Engine v2.0 by Sami Ky”stil„ 1997"
COLOR 3, 0
PRINT
PRINT "Average FPS:", , , FPS&; "fps"
PRINT "Ending position (XYZ)", , Xr; Yr; Zr
PRINT "Shading model:", , " "; ShadeName$(ShadingModel)
PRINT "Ambient lighting level:", , Ambient
SYSTEM
END SUB