' %%%%%%% Sweepit Demo by Marc Gale (Xalthorn) %%%%%%%%%%%
' %%   Written for the 300 line demo competition set    %%
' %%   by Shockwave and held on the Yabasic Bulletin    %%
' %%   Boards (pub51.ezboard.com/byabasicprogramming)   %%
' %%                                                    %%
' %%        Download from www.ps2-yabasic.co.uk         %%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%% INITIALISATION %%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
open window 640,512 : window origin "cc"
setrgb 0,100,100,150
for a=0 to 1    : REM ----------------- Setup both buffers
 setdrawbuf a   : clear window
 setrgb 1,0,0,0 : rect -205,-205,205,205

 for b=1 to 2   : REM ---------------- Draw the 'XAL' logo
  if b=2 then setrgb 1,200,150,0 else setrgb 1,100,50,0 fi
  if b=1 then f=20 else f=0 fi
  fill triangle -310,-160+f to -290,-180+f to -230,-60
  fill triangle -240,-180+f to -220,-160+f to -300,-60
  fill triangle -310,40+f/2 to -290,60 to -265,-50+f
  fill triangle -240,60 to -220,40+f/2 to -265,-50+f
  fill rect -290,f/2,-240,20+f/2
  fill triangle -265,80+f to -300,160+f/2 to -280,190
  fill triangle -300,160+f/2 to -280,190 to -230,160+f/2
 next b
next a

' ========================================================
' ============ Set up the Sine and Cosine Arrays =========
' ========================================================
dim co(361),si(361)
for a=0 to 361
 co(a)=cos(a*(pi/180)) : si(a)=sin(a*(pi/180))
next a

' ========================================================
' ================= Set up the scrolltext ================
' ========================================================
for a=1 to 65
m$=m$+" " : next a
m$=m$+"Welcome to my second attempt at the 300 line demo "
m$=m$+"competition. This time I thought I'd have a go at "
m$=m$+"something pre-calculated, so I had some fun with a"
m$=m$+" sweep object."
mx=-300 : mlen=len(m$)

' ========================================================
' ============= Grab the object outline edge =============
' ========================================================
read points
dim bx(points),by(points)
for a=1 to points
 read bx(a),by(a)
next a

' ========================================================
' ========= Determine detail and prepare arrays ==========
' ========================================================
read sweep
mp=points*sweep : nf=points*sweep
a=170*nf : angstep=360/sweep
dim px(mp),py(mp),pz(mp),sx(mp),sy(mp),sz(mp),f1(nf)
dim f2(nf),f3(nf),f4(nf),fv(nf),fl(nf),fz(nf),p1x(a)
dim p2x(a),p3x(a),p4x(a),p1y(a),p2y(a),p3y(a),p4y(a)
dim p1b(a),p2b(a),p3b(a),p4b(a),fra(360)

setdrawbuf cb : REM ---------- Display message about delay
setrgb 1,200,200,255 : text 0,250,"Processing Object","cc"

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%% Sweep the points %%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for p=1 to points : REM -- Sweep the points to make object
 for a=0 to sweep-1
  ang=a*angstep
  x=bx(p) : y=by(p)
  px(p+(a*points))=si(ang)*x*40
  py(p+(a*points))=-y*40
  pz(p+(a*points))=co(ang)*x*40
 next a 
next p

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%% Make the faces %%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for f=1 to points-1 : REM -- Join the points to make faces
 for a=0 to sweep-1
  if a<sweep-1 then : REM ------------ Not the final sweep
   amul=(a*(points))
   f1(f+amul)=f+amul          : f2(f+amul)=f+amul+points
   f3(f+amul)=f+amul+1+points : f4(f+amul)=f+amul+1
  else
   amul=(a*(points))
   f1(f+amul)=f+amul          : f2(f+amul)=f
   f3(f+amul)=f+1             : f4(f+amul)=f+amul+1
  fi
 next a
next f

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%% Create Animation %%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
for angle=1 to 360 : REM ---- Process and record animation

 yr=mod(yr+2,360)  : xr=mod(xr+3,360)

' ========================================================
' ============= Rotate the points into position ==========
' ========================================================
 for p=1 to mp
  xx=px(p)           : REM ----- Get the points and rotate
  y=py(p)            : z=pz(p)
  yy=y*co(xr)+z*si(xr)  : zz=z*co(xr)-y*si(xr)
  x=xx*co(yr)-zz*si(yr) : z=xx*si(yr)+zz*co(yr)
  x=x/((z/2000)+1)      : yy=yy/((z/2000)+1)

  sx(p)=x            : REM -------------- Store the points
  sy(p)=yy           : sz(p)=z
 next p

' ========================================================
' =========== Check faces for visibility =================
' ============= and store visible ones ===================
' ========================================================
 fp=0                : REM ---- Reset the frame face count
 for f=1 to nf       : REM ------------ Loop through faces
  gosub gf           : REM --- Get the face and check vis.
  v1x=x1-x2          : v1y=y1-y2
  v2x=x3-x2          : v2y=y3-y2
  vi=v1x*v2y-v2x*v1y : fv(f)=vi

  if vi>0 then       : REM --- If the face is visible then
   fp=fp+1           : REM     add one to the count
   fl(fp)=f          : fz(f)=(z1+z2+z3+z4)/4
  fi
 next f
 fra(angle)=fp       : REM ---- Store the frame face count

' ========================================================
' =========== Bubble sort the stored faces ===============
' ========================================================
 for f=1 to fp-1     : REM ---- Bubble sort face list by Z
  for a=f+1 to fp
   if fz(fl(f))<fz(fl(a)) then
    t=fl(f)          : REM ------------- Bubble swap faces
    fl(f)=fl(a)      : fl(a)=t
   fi
  next a
 next f

' ========================================================
' ============ Go through sorted faces ===================
' ============= and store them fully =====================
' ========================================================
 for o=1 to fp              : REM - Store the face details
  f=fl(o)                   : REM   For drawing later
   gosub gf                 : REM --- Get the face details
   b=-((z1+z2+z3+z4)/4)+100 : REM ----- Set the brightness

   fct=fct+1                : REM -- Add one to face count

   REM ------ Store the face polygon and vertex brightness
   p1x(fct)=x1         : p1y(fct)=y1
   p2x(fct)=x2         : p2y(fct)=y2
   p3x(fct)=x3         : p3y(fct)=y3
   p4x(fct)=x4         : p4y(fct)=y4
   p1b(fct)=-z1        : p2b(fct)=-z2
   p3b(fct)=-z3        : p4b(fct)=-z4

 next o

' ========================================================
' ========= Processing takes time, draw a ================
' ======= ball to show we're doing something =============
' ========================================================
 setrgb 1,200,150,0 : REM - Draw a circle to keep interest
 setrgb 2,100,50,0  : setrgb 3,100,50,0
 x1=si(angle)*200   : y1=-co(angle)*200
 x2=si(angle+1)*200 : y2=-co(angle+1)*200
 gtriangle 0,0 to x1,y1 to x2,y2

next angle

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%% Get ready to replay the animation %%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
fct=1  : REM ------------------------- Reset face position
a=1    : REM --------------------------------- Reset angle

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%% The main routine, time to play %%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
label main : REM ---------------- The main routine at last
 setdispbuf cb 
 cb=1-cb : setdrawbuf cb

 setrgb 1,0,50,80 : REM --- Clear object window and redraw
 fill rect -200,-200,200,200 : gosub drawobj

 clear fill rect -320,235,320,256 : REM  Clear scroll area
 setrgb 1,200,200,255 : REM ------------ Draw the scroller
 mx=mx-2              : if mx>-330 goto write
 mx=mx+10             : mpos=mod(mpos+1,mlen)
 label write          : text mx,250,mid$(m$,mpos,65)
goto main  : REM ------------- Go back and do it all again

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%% Draw a frame of the animation %%%%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
label drawobj
  for c=1 to fra(a)   : REM ---- Loop through the polygons

   REM -------- Get the face polygon and vertex brightness
   x1=p1x(fct) : y1=p1y(fct)
   x2=p2x(fct) : y2=p2y(fct)
   x3=p3x(fct) : y3=p3y(fct)
   x4=p4x(fct) : y4=p4y(fct)
   b1=p1b(fct) : b2=p2b(fct)
   b3=p3b(fct) : b4=p4b(fct)

   fct=fct+1   : REM --------------- Move to the next face

   setrgb 1,b1+100,b1+50,0 : REM ----------- Draw the face
   setrgb 2,b3+100,b3+50,0 : setrgb 3,b2+100,b2+50,0
   gtriangle x1,y1 to x3,y3 to x2,y2
   setrgb 3,b4+100,b4+50,0
   gtriangle x1,y1 to x3,y3 to x4,y4

  next c

  a=a+1 : REM --------------------------------- Next angle
  if a=361 then : REM -------------------- All done? Reset
   fct=1 : a=1
  fi
return

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%%%%% Get the face structural details %%%%%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
label gf : REM ------------------ Get face details routine
 p1=f1(f)  : p2=f2(f)
 p3=f3(f)  : p4=f4(f)
 x1=sx(p1) : y1=sy(p1)
 z1=sz(p1) : x2=sx(p2)
 y2=sy(p2) : z2=sz(p2)
 x3=sx(p3) : y3=sy(p3)
 z3=sz(p3) : x4=sx(p4)
 y4=sy(p4) : z4=sz(p4)
return

' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%%%%%%% The object definition, small isn't it %%%%%%%%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
' %%% To make your own objects, define an X and Y edge %%%
' %%% like this:                                       %%%
' %%%                                                  %%%
' %%% o                                                %%%
' %%%  o                                               %%%
' %%%    o                                             %%%
' %%%       o                                          %%%
' %%%          o                                       %%%
' %%%        o                                         %%%
' %%%      o                                           %%%
' %%%        o      <----- Y Centre                    %%%
' %%%          o                                       %%%
' %%%           o                                      %%%
' %%%           o                                      %%%
' %%%          o                                       %%%
' %%%       o                                          %%%
' %%%    o                                             %%%
' %%% o                                                %%%
' %%%                                                  %%%
' %%% Just store the points as X and Y values from a   %%%
' %%% centre position (X is 0 on the left hand side    %%%
' %%% and Y is 0 in the middle)                        %%%
' %%%                                                  %%%
' %%% Once you've done that, decide how many sweeps    %%%
' %%% are to be done, and run the demo.                %%%
' %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
data 15           : REM ---- How many points make the edge
data 0.001,2      : REM ----- Always Start very close to 0
data 1,2.3
data 1.5,2.6
data 1.8,4
data 1.9,2.6
data 1.7,2.4
data 1.5,2
data 0.5,1.8
data 0.8,1.5
data 0.5,1.1
data 0.7,-2
data 1,-2.3
data 2,-2.8
data 2,-3
data 0.001,-3     : REM ------- Always End very close to 0

data 10           : REM ------------------ How many sweeps


