;
; IsoRender.bb by Simon Armstrong
;

NEWTYPE .balltype ;alle Felder sind .q (schnelle 32-Bit Festkommazahl)
  depth.q ;wird benoetigt um Liste rueckwaerts zu sortieren
  col     ;Farbe der Kugel (s Tabelle)
  x:y:z   ;3D Position der Kugel
  sx:sy   ;Position der Kugel nach Iso-Projection
End NEWTYPE

Dim List ball.balltype(50)

LoadShapes 4,"balls.shapes" ;muss im Iso-Verzeichnis sein (CD)
LoadPalette 0,"balls.iff"   ;Palette aus IFF-Datei laden

Screen 0,27,"ISOMETRIC SHAPE GENERATOR" ;Hires Lace Screen oeffnen
Use Palette 0
ScreensBitMap 0,0

Box 15,15,15+33,15+41,1 ;Shape muss in diesen Rahmen passen
GetaShape 0,16,15,32,1  ;um Hoehe zu begrenzen

For r=0 To 15
  Restore myshape:f=16+r:Gosub makeframe:Blit f,r*40+16,104
  Restore mozzy:f=32+r:Gosub makeframe:Blit f,r*40+16,144
  Restore blade:f=48+r:Gosub makeframe:Blit f,r*40+16,184
Next

SaveShapes 16,f,"isoshapes" ;alle erzeugten Shapes speichern
MouseWait
End

; Die folgende Routine liest die Daten fuer die Kugeln ein,
; speichert sie in der Liste, dreht sie um die Z-Achse,
; sortiert, projiziert, zeichnet sie und beschneidet 
; die Umrandung.

.makeframe:
  Read n            ;Anzahl der Kugeln?
  rsin=Sin(r*Pi/8)  ;noetig fuer folgende 2D-Rotation
  rcos=Cos(r*Pi/8)
  ClearList ball()  ;Liste ausleeren
  USEPATH ball()    ;spart Tipparbeit (50 mal ball())!

  For b=0 To n-1
    AddItem ball()      ;Kugel in Liste einlesen
    Read \col,tx,ty,\z
    \x=tx*rsin+ty*rcos  ;mit 2D-Matrix rotieren
    \y=tx*rcos-ty*rsin
    \depth=\x+\y        ;Tiefe berechnen fuer Sortierung
  Next

  Boxf 16,16,16+31,16+39,0  ;Rahmen freimachen zum Zeichnen
  SortList ball()           ;Rueckwaerts sortieren
  ResetList ball()          ;Mit der letzten Kugel anfangen
  While NextItem(ball())
    \sx=32+(\x-\y) ASL 4    ;Bildschirmposition berechnen
    \sy=48+(\x+\y-\z) ASL 3
    Blit \col,x+\sx,y+\sy   ;und zeichnen
  Wend

  ; Der folgende Abschnitt beschneidet die Umrandung, 
  ; sodass die kleinstmoegliche Flaeche fuer die Shape 
  ; verwendet wird.

  y0=16:While BlitColl(0,16,y0)=0:Blit 0,16,y0:y0+1:Wend
  y1=16+39:While BlitColl(0,16,y1)=0:Blit 0,16,y1:y1-1:Wend
  GetaShape f,16,y0,32,y1-y0+1
  Handle f,16,36+16-y0
  Return

; Es folgen die Daten fuer die Shapes, freigegeben fuer
; Veraenderungen. Es sollten keine Werte groesser als 2 
; fuer die xyz-Koordinaten verwendet werden.
; Format:
; AnzahlKugeln
;   ShapeNummer,x,y,z
;   ShapeNummer,x,y,z etc.


.myshape:
  Data 14
  Data 8,-.2,-.3,0    ;Fuesse
  Data 8,-.2,0.3,0
  Data 8,0.2,-.3,0
  Data 8,0.2,0.3,0
  Data 6,0,0,1        ;Koerper
  Data 5,0,0,2.5      ;Kopf
  Data 7,.4,-.2,2.5   ;Augen
  Data 7,.4,0.2,2.5
  Data 9,0,-.4,1      ;Arme
  Data 9,0,0.4,1
  Data 9,.2,-.4,1
  Data 9,.2,0.4,1
  Data 9,.4,-.4,1
  Data 9,.4,0.4,1

.mozzy
  Data 5
  Data 4,0,0,1        ;Koerper
  Data 7,-.4,0,1
  Data 7,-.6,0,1
  Data 8,.4,.2,1
  Data 8,.4,-.2,1

.blade
  Data 5
  Data 9,0,-.6,1.8
  Data 8,0,-.3,1.8
  Data 7,0,0,1.8
  Data 8,0,.3,1.8
  Data 9,0,.6,1.8
