' ****************************************************************************
' MRB_SampleEyes.txt
'
' Make-it-with-Micromite (Part 19)
'
' PE Magazine (August 2020)
'

' This code will allow you to explore how by altering the variables discussed
' in MIWM Pt 19, you can change the way that the eyes look on the two
' LED matrix modules.

' You can alter any value in a line marked with: *** TRY CHANGING ***


' NOTE: Remove jumper JP8 to keep the MRB powered up while in the EDITor

' ****************************************************************************

' ----------------------------------------------------------------------------

' SET-UP
' ======

Option AUTORUN ON              ' set program to automically RUN on power-up
CPU 48          ' set PIC to run at 48MHz (set to 40 if issues)

CS=21               ' define I/O pin connected to the LED MATRIX module CS-pin
Pin(CS)=1                  ' default to high (any SPI data is ignored for now)
SetPin(CS),dout            ' set up the I/O pin as defined in above 2 lines

Dim Leye(8)                 ' an array that holds the 8x8 solid-eyeball pattern
Dim Reye(8)

Dim LeyeTemp(8) As INTEGER ' array used during calculation of LEFT eye data
Dim ReyeTemp(8) As INTEGER ' likewise for RIGHT eye

Dim Lpupil(2)     ' an array that holds the 2x2 pupil pattern
Dim Rpupil(2)

LED_Init                   ' call SUB to configure both LED matrix modules

' ----------------------------------------------------------------------------

' MAIN PROGRAM
' ============

' -----------------------------------------------------------------------------

' define 8x8 eyeball pixel-pattern for LEFT eye
' (this example draws an 8x7 rugby-ball shaped eye)

Leye(1)=&b00111100  ' *** TRY CHANGING ***
Leye(2)=&b01111110  ' *** TRY CHANGING ***
Leye(3)=&b11111111  ' *** TRY CHANGING ***
Leye(4)=&b11111111  ' *** TRY CHANGING ***
Leye(5)=&b11111111  ' *** TRY CHANGING ***
Leye(6)=&b01111110  ' *** TRY CHANGING ***
Leye(7)=&b00111100  ' *** TRY CHANGING ***
Leye(8)=&b00000000  ' *** TRY CHANGING ***

' define 8x8 eyeball pixel-pattern for RIGHT eye

Reye(1)=&b00111100  ' *** TRY CHANGING ***
Reye(2)=&b01111110  ' *** TRY CHANGING ***
Reye(3)=&b11111111  ' *** TRY CHANGING ***
Reye(4)=&b11111111  ' *** TRY CHANGING ***
Reye(5)=&b11111111  ' *** TRY CHANGING ***
Reye(6)=&b01111110  ' *** TRY CHANGING ***
Reye(7)=&b00111100  ' *** TRY CHANGING ***
Reye(8)=&b00000000  ' *** TRY CHANGING ***

' -----------------------------------------------------------------------------

' define 2x2 pupil pixel-pattern for LEFT eye

Lpupil(1)=&b10   ' *** TRY CHANGING ***
Lpupil(2)=&b11   ' *** TRY CHANGING ***

' define 2x2 pupil pixel-pattern for RIGHT eye

Rpupil(1)=&b01   ' *** TRY CHANGING ***
Rpupil(2)=&b11   ' *** TRY CHANGING ***

' -----------------------------------------------------------------------------

' define pupil position for LEFT eye

Lx=3    ' *** TRY CHANGING ***
Ly=4    ' *** TRY CHANGING ***

' define pupil position for RIGHT eye

Rx=5    ' *** TRY CHANGING ***
Ry=4    ' *** TRY CHANGING ***

' -----------------------------------------------------------------------------

' define which pixel-rows are turned off for LEFT eye

LBlink=&b00000000  ' *** TRY CHANGING ***

' define which pixel-rows are turned off for RIGHT eye

RBlink=&b00000000  ' *** TRY CHANGING ***

' -----------------------------------------------------------------------------

' define where to draw LEFT eye 8x8 pixel-image on the LEFT LED matrix

LShiftX=0   ' *** TRY CHANGING ***
LShiftY=0   ' *** TRY CHANGING ***

' define where to draw RIGHT eye 8x8 pixel-image on the RIGHT LED matrix

RShiftX=0   ' *** TRY CHANGING ***
RShiftY=0   ' *** TRY CHANGING ***

' -----------------------------------------------------------------------------

' finally, to 'see' the eyes, call SUB to send data to the LED matrix modules
DrawEye

' -----------------------------------------------------------------------------

' display all the current values on the Terminal Screen
Print Chr$(27)+"[2J"        ' VT Escape Code to clear screen
Print Chr$(27)+"[H";        ' VT Escape Code to postion cursor in top-left corner
Print "*******************************"
'Print "***                         ***"
Print "***  MICROMITE ROBOT BUGGY  ***"
Print "***  =====================  ***"
Print "***                         ***"
Print "***  (MRB_SampleEyes.txt)   ***"
Print "***                         ***"
Print "*******************************"
Print
Print "Current values:"
Print "--------------"
Print
For i = 1 To 8
  Print "  Leye("+Str$(i)+") = &b"+Bin$(Leye(i),8)+"      Reye("+Str$(i)+") = &b"+Bin$(Reye(i),8)
Next i
Print
Print "Lpupil(1) = &b"+Bin$((3 And Lpupil(1)),2)+"          Rpupil(1) = &b"+Bin$((3 And Rpupil(1)),2)
Print "Lpupil(2) = &b"+Bin$((3 And Lpupil(2)),2)+"          Rpupil(2) = &b"+Bin$((3 And Rpupil(2)),2)
Print
Print "     Lx,y = "+Str$(Lx)+","+Str$(Ly)+"                Rx,y = "+Str$(Rx)+","+Str$(Ry)
Print
Print "   LBlink = &b"+Bin$(255 And LBlink,8)+"       RBlink = &b"+Bin$(255 And RBlink,8)
Print
Print "LShiftX,Y = "+Str$(LShiftX)+","+Str$(LShiftY)+"           RShiftX,Y = "+Str$(RShiftX)+","+Str$(RshiftY)
Print
Print
Print "*****************************************************"
Print
Print "Now TRY CHANGING the values of the above variables in"
Print
Print "the program! (The lines are highlighted in the code) "
Print
Print "*****************************************************"

' -----------------------------------------------------------------------------

End    ' ends program and returns to Command Prompt

' -----------------------------------------------------------------------------



' SUBROUTINES
' ===========


Sub DrawEye                        ' DO NOT PANIC IF YOU DON'T FOLLOW THIS SUB!

  'draw both pupils in correct place
  Lpupil(1)=Lpupil(1) And 3 'ensure only two bits long
  Lpupil(2)=Lpupil(2) And 3 'ensure only two bits long
  Rpupil(1)=Rpupil(1) And 3 'ensure only two bits long
  Rpupil(2)=Rpupil(2) And 3 'ensure only two bits long
  For i=1 To 8
    LeyeTemp(i)=Leye(i)
    ReyeTemp(i)=Reye(i)
    If i=Ly Then
      If (Lpupil(1) And 2) Then LeyeTemp(i)=LeyeTemp(i) And (255-2^(8-Lx)) 'switch off relevant pixels
      If (Lpupil(1) And 1) Then LeyeTemp(i)=LeyeTemp(i) And (255-2^(7-Lx)) 'switch of relevant pixels
    End If
    If i=Ly+1 Then
      If (Lpupil(2) And 2) Then LeyeTemp(i)=LeyeTemp(i) And (255-2^(8-Lx)) 'switch off relevant pixels
      If (Lpupil(2) And 1) Then LeyeTemp(i)=LeyeTemp(i) And (255-2^(7-Lx)) 'switch of relevant pixels
    End If

    If i=Ry Then
      If (Rpupil(1) And 2) Then ReyeTemp(i)=ReyeTemp(i) And (255-2^(8-Rx)) 'switch off relevant pixels
      If (Rpupil(1) And 1) Then ReyeTemp(i)=ReyeTemp(i) And (255-2^(7-Rx)) 'switch of relevant pixels
    End If
    If i=Ry+1 Then
      If (Rpupil(2) And 2) Then ReyeTemp(i)=ReyeTemp(i) And (255-2^(8-Rx)) 'switch off relevant pixels
      If (Rpupil(2) And 1) Then ReyeTemp(i)=ReyeTemp(i) And (255-2^(7-Rx)) 'switch of relevant pixels
    End If

  Next i

  'blank out relevant horizontal row(s) of pixels in 8x8 pixel-image
  For i = 1 To 8
    If (LBlink And (2^(8-i))) Then LeyeTemp(i)=&H0
    If (RBlink And (2^(8-i))) Then ReyeTemp(i)=&H0
  Next i

  'shift eye images into correct HORIZONTAL position
  For i = 1 To 8
    Select Case LShiftX
      Case <0
        LeyeTemp(i)=(255 And (LeyeTemp(i)<<Abs(LShiftX)))
      Case >0
        LeyeTemp(i)=(255 And LeyeTemp(i)>>LShiftX)
    End Select
    Select Case RShiftX
      Case <0
        ReyeTemp(i)=(255 And (ReyeTemp(i)<<Abs(RShiftX)))
      Case >0
        ReyeTemp(i)=(255 And ReyeTemp(i)>>RShiftX)
    End Select
  Next i

  'shift eye images into correct VERTICAL position
  Select Case LShiftY
    Case <0
      If LShiftY<-8 Then LShiftY=-8 ' ensure value not less than -8
      For i = 1 To 8
        If Abs(LShiftY)<(9-i) Then
          LeyeTemp(i)=LeyeTemp(i+Abs(LShiftY))
        Else
          LeyeTemp(i)=0
        End If
      Next i
    Case >0
      If LShiftY>8 Then LShiftY=8 ' ensure value not more than 8
      For i = 8 To 1 Step -1
        If LShiftY<i Then
          LeyeTemp(i)=LeyeTemp(i-LShiftY)
        Else
          LeyeTemp(i)=0
        End If
      Next i
    End Select
    Select Case RShiftY
      Case<0
        If RShiftY<-8 Then RShiftY=-8 ' ensure value not less than -8
        For i = 1 To 8
          If Abs(RShiftY)<=(8-i) Then
            ReyeTemp(i)=ReyeTemp(i+Abs(RShiftY))
          Else
            ReyeTemp(i)=0
          End If
        Next i
      Case >0
        If RShiftY>8 Then RShiftY=8 ' ensure value not more than 8
        For i = 8 To 1 Step -1
          If RShiftY<i Then
            ReyeTemp(i)=ReyeTemp(i-RShiftY)
          Else
            ReyeTemp(i)=0
          End If
        Next i
    End Select

    ' send data to draw the eyes
  SPI OPEN 10000000,0,32           ' configure SPI port for communication to 8x8's
    For i = 1 To 8
      Pin(cs)=0
      aa=SPI( (((i*256)+ReyeTemp(i))*(2^16)) Or ((i*256) Or LeyeTemp(i)))
      Pin(cs)=1
    Next i
  SPI CLOSE
End Sub

' -----------------------------------------------------------------------------


Sub LED_Init                      ' initialise the MAX7219 display modules
  SPI OPEN 3000000,0,32           ' configure SPI port for communication
  Pin(cs)=0:AA=SPI(&H0C000C00):Pin(cs)=1
  Pin(cs)=0:AA=SPI(&H09000900):Pin(cs)=1
  Pin(cs)=0:AA=SPI(&H0A050A05):Pin(cs)=1
  Pin(cs)=0:AA=SPI(&H0B070B07):Pin(cs)=1
  Pin(cs)=0:AA=SPI(&H0F000F00):Pin(cs)=1
  Pin(cs)=0:AA=SPI(&H0C010C01):Pin(cs)=1
  SPI CLOSE
End Sub