REM === 3D GRAPHICS ENGINE === REM ====== BY MCPEPIC ====== '===== 2D ===== GLOBAL READBUFF,WRITEBUFF WRITEBUFF=1 DIM GLOBAL GETADR(1,127),POOL(127) CALL INIT_ADR ON VBL CALL I_VBL '===== 3D ===== GLOBAL WIDTH,HEIGHT,DEG2RAD WIDTH=160 HEIGHT=128 DEG2RAD=0.01745329251 'X,Y,Z, X',Y', FOV', NEAR,FAR DIM GLOBAL CAM(7) CALL INIT_CAM 'VERTEX#,AXIS 'TRIANGLE#; 'V0, V1, V2 'PALETTE[0..7], BRIGHTNESS[0..4] 'CENTROID 'NORMAL DIM GLOBAL VERT(7,2),THIS(2,2), TRI(11,3,2) CALL INIT_VERT CALL INIT_TRI '===== MAIN ===== GAMEPAD 2 DO S=TIMER H=LEFT(0)-RIGHT(0) V=DOWN(0)-UP(0) F=BUTTON(0,0)-BUTTON(0,1) RH=LEFT(1)-RIGHT(1) RV=UP(1)-DOWN(1) CALL MOVECAMLOCAL(H*0.1,F*0.1,V*0.1) CALL ROTATECAM(RV,RH) 'FOR T=0 TO UBOUND(TRI) ' CALL TRI3D(T) 'NEXT T CX=CAM(0)\10*10 CY=CAM(1)\10*10 CZ=CAM(2)\10*10 FOR Z=-1 TO 1 FOR Y=-1 TO 1 FOR X=-1 TO 1 XX=10*X+CX YY=10*Y+CY ZZ=10*Z+CZ CALL VERT3D(XX,YY,ZZ,2,0) NEXT X NEXT Y NEXT Z CALL FLIPPAGE CALL DEBUG(S) LOOP SUB DEBUG(S) TRACE "FPS: "+STR$(INT(60/(TIMER-S))) TRACE "" TRACE STR$(INT(CAM(0)))+" "+STR$(INT(CAM(1)))+" "+STR$(INT(CAM(2))) TRACE STR$(CAM(3))+" "+STR$(CAM(4)) TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" TRACE "" END SUB '===== 2D SUB ===== SUB I_RASTER0 COPY GETADR(0,RASTER),40 TO $FE00 END SUB SUB I_RASTER1 COPY GETADR(1,RASTER),40 TO $FE00 END SUB SUB I_VBL IF READBUFF THEN ON RASTER CALL I_RASTER1 ELSE ON RASTER CALL I_RASTER0 END SUB SUB LINE(X,Y,L,PP,B) XX=INT(X) LL=INT(L) I=B\2+B IF (B AND 1) AND ((XX AND 1) XOR (Y AND 1)) THEN INC I R=I\4 C=I MOD 4 CC=4*(16*R+C) RESETLINE: IF POOL(Y)=10 THEN EXIT SUB ADR=GETADR(WRITEBUFF,Y)+ 4*POOL(Y) LDIV=LL \ 32 YY=INT(Y)-MIN(31,LL) POKE ADR ,XX +32 POKE ADR+1,YY +32 POKE ADR+2,CC POKE ADR+3,200+PP INC POOL(Y) IF LDIV THEN ADD XX,32 ADD LL,-32 GOTO RESETLINE END IF END SUB SUB CLIP(X,Y,L,PP,B) IF Y>=0 AND Y<128 THEN X2=INT(X+L) IF X<160 AND X2>=0 THEN LC=-X RC=X2-160 IF LC>0 THEN IF RC>0 THEN CALL LINE(0,Y,L-RC-LC,PP,B) ELSE CALL LINE(0,Y,L-LC,PP,B) END IF ELSE IF RC>0 THEN CALL LINE(X,Y,L-RC,PP,B) ELSE CALL LINE(X,Y,L,PP,B) END IF END IF END IF END IF END SUB SUB TRIANGLE(X1,Y1,X2,Y2,X3,Y3,PP,B) IF Y1=Y2 AND Y1=Y3 THEN EXIT SUB 'SORT POINTS TOP-BOTTOM IF Y2=0 THEN L=MIN(MIN(X1,X2),X3) R=MAX(MAX(X1,X2),X3) IF L<160 AND R>=0 THEN IF Y2=Y3 THEN CALL TOPTRI(X1,Y1,X2,Y2,X3,Y3,PP,B) ELSE IF Y1=Y2 THEN CALL BOTTRI(X1,Y1,X2,Y2,X3,Y3,PP,B) ELSE X4=X1+((Y2-Y1)/(Y3-Y1))*(X3-X1) CALL TOPTRI(X1,Y1,X2,Y2,X4,Y2,PP,B) CALL BOTTRI(X2,Y2,X4,Y2,X3,Y3,PP,B) END IF END IF END IF END SUB 'NOTE: MUST BE SORTED PRIOR TO FILL SUB TOPTRI(X1,Y1,X2,Y2,X3,Y3,PP,B) IF X3=CAM(6) AND D0 THEN CALL CAM2SCREEN(0) CALL CAM2SCREEN(1) CALL CAM2SCREEN(2) X1=THIS(0,0) Y1=THIS(0,1) X2=THIS(1,0) Y2=THIS(1,1) X3=THIS(2,0) Y3=THIS(2,1) CALL TRIANGLE(X1,Y1,X2,Y2,X3,Y3,PP,B) END IF END IF END IF END SUB SUB VERT3D(X,Y,Z,PP,B) CALL WORLD2CAM(X,Y,Z,0) IF THIS(0,2)>1 THEN CALL CAM2SCREEN(0) CALL CLIP(THIS(0,0),THIS(0,1),0,PP,B) END IF END SUB SUB MOVECAM(X,Y,Z) ADD CAM(0),X ADD CAM(1),Y ADD CAM(2),Z END SUB SUB ROTATECAM(X,Y) ADD CAM(3),X ADD CAM(4),Y END SUB SUB MOVECAMLOCAL(X,Y,Z) XX=X YY=Y ZZ=Z CALL ROTX(YY,ZZ) CALL ROTY(XX,ZZ) CALL MOVECAM(XX,YY,ZZ) END SUB SUB ROTX(Y,Z) THETA=CAM(3)*DEG2RAD YY=Y*COS(THETA)+Z*-SIN(THETA) ZZ=Y*SIN(THETA)+Z* COS(THETA) Y=YY Z=ZZ END SUB SUB ROTY(X,Z) THETA=CAM(4)*DEG2RAD XX=X* COS(THETA)+Z*SIN(THETA) ZZ=X*-SIN(THETA)+Z*COS(THETA) X=XX Z=ZZ END SUB 'V: WORLD VERTICE INDEX, OUT: TRIANGLE VERTICE INDEX SUB WORLD2CAM(X,Y,Z, OUT) CAMX=CAM(0) CAMY=CAM(1) CAMZ=CAM(2) 'TRANSFORM XX=X-CAMX YY=Y-CAMY ZZ=Z-CAMZ 'ROTATION SX=SIN(CAM(3)*DEG2RAD) CX=COS(CAM(3)*DEG2RAD) SY=SIN(CAM(4)*DEG2RAD) CY=COS(CAM(4)*DEG2RAD) TEMP=CY*ZZ+SY*XX THIS(OUT,0)=CY*XX-SY*ZZ THIS(OUT,1)=SX*TEMP+CX*YY THIS(OUT,2)=CX*TEMP-SX*YY END SUB SUB CAM2SCREEN(OUT) SX=WIDTH SY=HEIGHT RX=2*CAM(6)*TAN(CAM(5)*DEG2RAD) RY=0.8*RX RZ=CAM(6) DX=THIS(OUT,0) DY=THIS(OUT,1) DZ=THIS(OUT,2) X=(DX*SX)/(DZ*RX)*RZ Y=(DY*SY)/(DZ*RY)*RZ ADD X,80 Y=-Y+64 THIS(OUT,0)=X THIS(OUT,1)=Y THIS(OUT,2)=0 END SUB SUB INIT_CAM CAM(2)=-5 CAM(5)=45 CAM(6)=1 CAM(7)=10 END SUB SUB INIT_VERT RESTORE VDATA FOR V=0 TO UBOUND(VERT) READ X,Y,Z VERT(V,0)=X VERT(V,1)=Y VERT(V,2)=Z NEXT V VDATA: DATA -1,1,1, 1,1,1, -1,-1,1, 1,-1,1 DATA -1,1,-1, 1,1,-1, -1,-1,-1, 1,-1,-1 END SUB SUB INIT_TRI RESTORE TDATA FOR T=0 TO UBOUND(TRI) READ V1,V2,V3, PP,B 'VERTICES TRI(T,0,0)=V1 TRI(T,0,1)=V2 TRI(T,0,2)=V3 'PALETTE & BRIGHTNESS TRI(T,1,0)=PP TRI(T,1,1)=B 'CENTROID TRI(T,2,0)= (VERT(V1,0)+VERT(V2,0)+VERT(V3,0))/3 TRI(T,2,1)= (VERT(V1,1)+VERT(V2,1)+VERT(V3,1))/3 TRI(T,2,2)= (VERT(V1,2)+VERT(V2,2)+VERT(V3,2))/3 'NORMAL AX=VERT(V2,0)-VERT(V1,0) AY=VERT(V2,1)-VERT(V1,1) AZ=VERT(V2,2)-VERT(V1,2) BX=VERT(V3,0)-VERT(V1,0) BY=VERT(V3,1)-VERT(V1,1) BZ=VERT(V3,2)-VERT(V1,2) TRI(T,3,0)=AY*BZ-AZ*BY TRI(T,3,1)=AZ*BX-AX*BZ TRI(T,3,2)=AX*BY-AY*BX NEXT T TDATA: DATA 4,5,6,0,0, 6,5,7,0,0 DATA 1,0,3,0,0, 3,0,2,0,0 DATA 5,1,7,1,0, 7,1,3,1,0 DATA 0,4,2,1,0, 2,4,6,1,0 DATA 0,1,4,3,0, 4,1,5,3,0 DATA 6,7,2,3,0, 2,7,3,3,0 END SUB #1:MAIN PALETTES 001020300004182D0001021700283C3E 003F2A15003F2A15003F2A15003F2A15 #2:MAIN CHARACTERS 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0002020A0A2A2AAA0101050515155555 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 01010505151555550002020A0A2A2AAA 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000103070F1F3F7FFF 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0002020A0A2A2AAA0101050515155555 AAAAAAAAAAAAAAAA5555555555555555 00000000000000000000000000000000 00000000000000000000000000000000 01010505151555550002020A0A2A2AAA 5555555555555555AAAAAAAAAAAAAAAA 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000103070F1F3F7FFF 0000000000000000FFFFFFFFFFFFFFFF 00000000000000000000000000000000 0103070F1F3F7FFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 00000000000000000000000000000000 0002020A0A2A2AAA0101050515155555 AAAAAAAAAAAAAAAA5555555555555555 AAAAAAAAAAAAAAAA5555555555555555 00000000000000000000000000000000 01010505151555550002020A0A2A2AAA 5555555555555555AAAAAAAAAAAAAAAA 5555555555555555AAAAAAAAAAAAAAAA 00000000000000000000000000000000 00000000000000000103070F1F3F7FFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0103070F1F3F7FFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 FFFFFFFFFFFFFFFF0000000000000000 0002020A0A2A2AAA0101050515155555 AAAAAAAAAAAAAAAA5555555555555555 AAAAAAAAAAAAAAAA5555555555555555 AAAAAAAAAAAAAAAA5555555555555555 01010505151555550002020A0A2A2AAA 5555555555555555AAAAAAAAAAAAAAAA 5555555555555555AAAAAAAAAAAAAAAA 5555555555555555AAAAAAAAAAAAAAAA 00000000000000000103070F1F3F7FFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 0000000000000000FFFFFFFFFFFFFFFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 01010505151555550103070F1F3F7FFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0002020A0A2A2AAA0103070F1F3F7FFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0103070F1F3F7FFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 01010505151555550103070F1F3F7FFF 5555555555555555FFFFFFFFFFFFFFFF 00000000000000000000000000000000 00000000000000000000000000000000 0002020A0A2A2AAA0103070F1F3F7FFF AAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFF 00000000000000000000000000000000 00000000000000000000000000000000 0103070F1F3F7FFF0103070F1F3F7FFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 01010505151555550103070F1F3F7FFF 5555555555555555FFFFFFFFFFFFFFFF 5555555555555555FFFFFFFFFFFFFFFF 00000000000000000000000000000000 0002020A0A2A2AAA0103070F1F3F7FFF AAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFF AAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFF 00000000000000000000000000000000 0103070F1F3F7FFF0103070F1F3F7FFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 00000000000000000000000000000000 01010505151555550103070F1F3F7FFF 5555555555555555FFFFFFFFFFFFFFFF 5555555555555555FFFFFFFFFFFFFFFF 5555555555555555FFFFFFFFFFFFFFFF 0002020A0A2A2AAA0103070F1F3F7FFF AAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFF AAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFF AAAAAAAAAAAAAAAAFFFFFFFFFFFFFFFF 0103070F1F3F7FFF0103070F1F3F7FFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF