'---- 3D DODECAHEDRON INSIDE A FAKE 3D TUNNEL DEMO ----


'-- INITIALIZE 3D DODECAHEDRON DEMO --

SUB INIT_DEMO_3D_DODECAHEDRON

 LOCAL T

 LOADPLY("DODECAHEDRON.PLY",0,0,0,0)
 PLY_ADJUST_COLOR(0,5)
 PLY_RGB(0,20,3,3)

 LOADPLY("DODECAHEDRON.PLY",1,0,0,0)
 PLY_ADJUST_COLOR(1,5)
 PLY_RGB(1,0,0,0)

 CSEC=20.5

 MAXBALL=10
 
 'DEFINE COORDINATES AND SPEED OF BALLS
 FOR T=1 TO MAXBALL
  RESET_TUNNEL_BALL(T,1)
 NEXT T
 FOR T=6 TO MAXBALL
  RESET_TUNNEL_BALL(T,0)
 NEXT T

 'SET BUFFER PAGE
 PAGE WRITE 1

 'LOAD AND PLAY MUSIC ONLY IF RUNNING A DEMO SECTION
 'IF DEMOSEC=1 THEN PLAY STOP: PLAY MODFILE "./ASSETS/excellate_pt3.mod",22050

END SUB


'-- RUN 3D DODECAHEDRON DEMO --

SUB RUN_DEMO_3D_DODECAHEDRON

 LOCAL T,I,X,Y,XX,YY,SEC,C,CO,INTRO,FSPD,AA,BB,CC,DD,FIRST

 'RESET COORDINATES
 X=0: Y=0: FSPD=12: C=0: CO=0
 XX=MAXX+50:YY=MAXY-50

 INTRO=10: FIRST=1

 'RESET TIMERS
 TIMENOW=0: PAUSETIMER=0: Timer=0

 'RUN UNTIL ... SECONDS
 DO WHILE INTRO<=10

  'HORIZONTAL LINES AND COLORS INSIDE TUNNEL
  'ONLY FOR FIRST FRAME TO GRAB IT
  'AND AFTER THE DODECAHEDRON GOES OUT
  IF FIRST=1 OR FSPD>12 THEN
 
   'SET PAGE 2 TO WRITE BACKGROUND FOR DODECAHEDRON
   IF FIRST=1 THEN PAGE WRITE 2: CLS
   
   'CONTROL HORIZONTAL TUNNEL SPEED
   IF SEC<=CSEC THEN 
    C=C+1+(FSPD-12)/20: IF C>0 THEN C=C-40
    AA=-20+C: BB=163+C: CC=20: DD=-40
   ELSE
    C=C-1-(FSPD-12)/20: IF C<0 THEN C=C+40
    AA=163+C: BB=-40+C: CC=-20: DD=60
   ENDIF

   I=0
   FOR T=AA TO BB STEP CC
    YANT=I
    'CONTROL HORIZONTAL LINES
    I=COS(RAD(T+40))*(MAXY/1.8)+MAXY/1.8+DD
    'CONTROL TUNNEL COLOR
    III=(COS(RAD((T+40)*2.5))*127)+127

    IF SEC<=CSEC THEN
     'BLUE POLYGON
     XP%(0)=   0: YP%(0)=  I-80
     XP%(1)=MAXX: YP%(1)= (I-80)*1.25-MAXY/6
     XP%(2)=MAXX: YP%(2)= (I)*1.25-MAXY/6
     XP%(3)=   0: YP%(3)=  I
     POLYGON 4,XP%(),YP%(),RGB(255,255,255),RGB(0,0,III)
    ELSE
     'RED POLYGON
     XP%(0)=   0: YP%(0)= (I-80)*1.25-MAXY/6
     XP%(1)=MAXX: YP%(1)=  I-80
     XP%(2)=MAXX: YP%(2)=  I
     XP%(3)=   0: YP%(3)= (I)*1.25-MAXY/6
     III=((COS(RAD((T+160)*2.5))*127)+127)/2+COS(RAD((CO)*2))*40+40
     IF III>255 THEN III=255
     POLYGON 4,XP%(),YP%(),RGB(255,255,255),RGB(III,0,0)
    ENDIF
   NEXT T

   'CONTROL VERTICAL TUNNEL SPEED
   IF SEC<=CSEC THEN
    II=II+0.010+(FSPD-12)/1000: IF II>1 THEN II=0
   ELSE
    'MAXBALL=10
    II=II-0.010-(FSPD-12)/1000: IF II<0 THEN II=1
   ENDIF

   'FAKE 3D TUNNEL - VERTICAL LINES
   FOR T=-2+II TO 2+II STEP 0.25
    CIRCLE MAXX/2-(T-0.5)*MAXX,MAXY/2,MAXY,1,T-0.5,RGB(255,255,255)
   NEXT T

   'RUN TUNNEL BALLS 
   IF FSPD>CSEC THEN
    'BALLS
    FOR T=1 TO MAXBALL
     RUN_TUNNEL_BALL(T,CO)
    NEXT T
   ENDIF

  ENDIF 'FIRST=1 OR FSPD>12?

  'CONTROL FPS BEFORE AND AFTER DODECAHEDRON
  IF SEC>7 THEN FSPD=FSPD+0.25: IF FSPD>25 THEN FSPD=25
  IF SEC>CSEC THEN FSPD=40

  'MOVE DODECAHEDRON
  IF FIRST=0 THEN

   IF SEC<=CSEC THEN CO=CO+9 ELSE CO=CO-9

   IF FSPD<=12 THEN
    'INSERT BACKGROUND FOR DODECAHEDRON
    BLIT 0,0,0,0,MAXX,MAXY,2,0

   'RENDER AND ROTATE DODECAHEDRON AFTER FIRST SCREEN BACKGROUND GRAB
    X=COS(RAD(CO/2))*20:Y=SIN(RAD(CO/2))*24
    XX=XX-X/2:YY=YY-Y/2
    'SHADOW
    'PLY_MOVE(1,MAXX/2+(XX-MAXX/2)/1.2,MAXY/2+(YY-MAXY/2)/1.2,COS(RAD(100+YY/2.4))*6+9)
    'PLY_SHADOW(1,X/1.5+8,Y/1.5,RGB(0,0,ABS((YY-MAXY/2)/18)*3))
    'PLY_SHADOW(1,X/1.5+8,Y/1.5,0)
    'DODECAHEDRON
    PLY_MOVE(0,XX,YY,COS(RAD(100+YY/2.4))*6+10)
    PLY_ROT_OPT(0,X/1.5+8,Y/1.5,0)
    XX=XX-6    
   ENDIF

  ENDIF

  'WRITE ON PAGE 3 TO GET FOREGROUND FOR DODECAHEDRON
  IF FIRST=1 THEN PAGE WRITE 3: CLS

  'CLEAR INTERNAL CIRCLES AND INSERT EXTERNAL WIREFRAMES AFTER DODECAHEDRON
  FOR T=-0.75+II TO 0.75+II STEP 0.25
   FOR I=0 TO MAXY-20 STEP 20
   TT=COS(RAD(I/1.2+30))*((T-0.5)*30)-(T-0.5)*10
   TC=COS(RAD(I+180))*100+154
   IF SEC<=CSEC THEN
    BOX MAXX/2-(T-0.5)*MAXX*1.579-4+TT,I, 10,20,0,,RGB(TC,TC,255)
   ELSE
    BOX MAXX/2-(T-0.5)*MAXX*1.579-4+TT,I, 10,20,0,,RGB(255,TC,TC)
   ENDIF
  NEXT I,T

  'AFTER WRITE BACKGROUND AND FOREGROUND, USE PAGE 1 AGAIN
  IF FIRST=1 THEN PAGE WRITE 1: CLS: FIRST=0

  'INSERT FOREGROUND FOR DODECAHEDRON FROM THE PAGE 3
  IF FSPD<=12 THEN
   BLIT 40,0,30,MAXY,3,4
   BLIT 300,0,20,MAXY,3,4
   BLIT 550,0,30,MAXY,3,4
  ENDIF

  'FPS(FSPD)
  FPS(30)
 
  SEC=Timer/1000

  'FIX SCREEN BORDER
  BOX 0,0,MAXX,MAXY,1,RGB(0,0,0)

  IF SEC>30 THEN INTRO=INTRO+2

  'BLACK BARS INTRO IN AND OUT EFFECT 
  IF INTRO>0 AND FIRST=0 THEN
   INTRO=INTRO-1
   FOR T=0 TO MAXX STEP 10
    BOX T,0,INTRO,MAXY,0,,RGB(0,0,0)
   NEXT T
  ENDIF

  'COPY TO MAIN PAGE
  PAGE COPY 1 TO 0,I

 LOOP

END SUB


' -- RUN TUNNEL BALL "N" --

SUB RUN_TUNNEL_BALL(N,CO)

 LOCAL I,T,TS,BC,SEC

 SEC=Timer/1000

 'RUN THE BALL
 XD(N)=XD(N)+SP(N)
 YD(N)=YD(N)+SZ(N)

 'CHANGE BALL SPEED ON UPPER AND BELOW SCREEN
 SELECT CASE YD(N)
  CASE < MAXY/2-40: SZ(N)=SZ(N)+1: IF YD(N)<30 THEN SZ(N)=SZ(N)/2
  CASE > MAXY/2+40: SZ(N)=SZ(N)-1: IF YD(N)>MAXY-30 THEN SZ(N)=SZ(N)/2
 END SELECT

 'IS OFFSCREEN?
 SELECT CASE XD(N)
  CASE <=-CSEC: IF SEC<=CSEC THEN RESET_TUNNEL_BALL(N,1)
  CASE >MAXX+2: IF SEC>CSEC THEN RESET_TUNNEL_BALL(N,0)
 END SELECT

 ENDIF

 'CONTROL THE SIZE OF THE BALL
 I=10+ABS((YD(N)-MAXY/2)/15)
 IF I<4 THEN I=4
 IF I>25 THEN I=25

 'DRAW CIRCLE, KEEP JUMPING AND RUNNING WITH TUNNEL
 IF SEC<=CSEC THEN
  SP(N)=SP(N)-0.3
  CIRCLE XD(N),YD(N),I,0,1,,RGB(0,100+(I-10)*10,0) 'BALL
 ELSE
  T=COS(RAD((CO)*2))*70+70 'APPLY RED LIGHT
  SP(N)=SP(N)+0.7
  CIRCLE XD(N),YD(N),I,0,1,,RGB(40+T,100+(I-10)*10,0) 'BALL
 ENDIF

 'VERIFY COLLISION WITH OTHER BALLS
 I=I/1.5

 FOR T=1 TO MAXBALL
  IF T<>N THEN
   TS=(10+ABS((YD(T)-MAXY/2)/18))/1.5
   IF XD(N)+I>XD(T)-TS AND XD(N)-I<XD(T)+TS AND YD(N)+I>YD(T)-TS AND YD(N)-I<YD(T)+TS THEN

    IF XD(N)>XD(T) THEN 
     SP(N)=ABS(SP(N))/2: SP(T)=-ABS(SP(T))
    ELSE
     SP(N)=-ABS(SP(N)):  SP(T)= ABS(SP(T))/2
    ENDIF

    IF YD(N)>YD(T) THEN 
     SZ(N)= ABS(SZ(N)): SZ(T)=-ABS(SZ(T))
    ELSE
     SZ(N)=-ABS(SZ(N)): SZ(T)= ABS(SZ(T))
    ENDIF

   ENDIF

  ENDIF

 NEXT T

END SUB


' -- RESET TUNNEL BALL "N" --

SUB RESET_TUNNEL_BALL(N,R)

  IF R=1 THEN XD(N)=RND(6)*50+MAXX+10 ELSE XD(N)=-RND(6)*50-10

  YD(N)=RND(1)*(MAXY/2.5)+MAXY/2

  IF R=1 THEN SP(N)=-ABS(RND(1)*10)-4 ELSE SP(N)=ABS(RND(1)*10)+4

  DO WHILE SZ(N)>=-4-(1-R)*2 AND SZ(N)<=4+(1-R)*2
   SZ(N)=RND(1)*16-8
  LOOP

END SUB


