;       Eye Animation   for ZShell              (by Risto J„rvinen)
;       -------------
;
;   Animates a pair of eyes.  Totally useless...  Hmm...  Wait a minute!
; Actually it has one 'entertaining'-use;  hold a Who-Blinks-First contest!
; IMHO TI isn't very good at this game, so you should just count how many
; TI-blinks can you hold your eyes.  However after a while this will irritate
; your eyes.  NOTE:  I accept no responsibility of any possible damage to your
; eyes.  I.E. If you dry your eyes bash your TI not me...
;
;   Controls:
;       Up/Down         Opens and shuts eye
;       F1              Blinks both eyes
;       F5              Blinks left eye
;       Clear           Shuts eyes
;       2nd             Changes eyes  (long coding night, eh?)
;
;   Routine is (again) hand-coded for this specific set of frames.  There are
; six frames each with have resolution of 56*35 pixels.  Actually the frames
; hold only the left eye, the right eye is mirrored from the left.
;
;   All optimizations are encouraged!  Although it's probably impossible to
; comprehend my code :)  I made this piece in a real hurry.
;
;   And last but not least: It's RibaWare; no copyright, 100% public domain.
; All rights wronged, all wrongs reversed.  Learn'n'Copy!
;
;   I, Risto J„rvinen, don't have my own email address so if you wish to
; contact me please use my friends address:
;
;       Jarno_Uurainen@llauta.fipnet.fi
;
;         +------------------------------+
;   NOTE: | DO NOT SEND ANY BIG FILES!!! |
;         +------------------------------+
;   One idiot sent to my friend a 2meg .WAV!  He receives his email via
; a BBS so sending mega-email causes messagepolling to take forever and
; sysop to go nuts.  If mega-stuff pops up place it on FTP and I'll leech
; it someday...  I don't think that You're an idiot (after all you propably
; have TI's calculator).  This is just a precaution :)
;

;  Include Files
#INCLUDE "TI-85.H"      ; Include Extended ZShell Header

;  Constants
VidStart        = VIDEO_MEM+160

;  Temporary Variables
; Location $80DF-$8187 is reserved by ZShell for temporary variables
NoOfPic         = $80DF ; Byte, Number of frame, 3 is closed
AutoBlink       = $80E0 ; Word, Delay counter between automagic blinks
EyeState        = $80E2 ; Byte, Normal / Blood-shot

.org    0
.db     "Eye Animation  1.0",0

   ROM_CALL(CLEARLCD)

   ld   a,3
   CALL_(DrawNext)

KeyLoop:
   call GET_KEY                 ;Get pressed key
   ld   de,(PROGRAM_ADDR)

   ld   hl,KeyLoop
   add  hl,de
   push hl                      ;Sets return address to stack

   cp   K_Up
   JUMP_Z(Open_Eyes_Step)       ;...then opens eyes one step
   cp   K_Down
   JUMP_Z(Close_Eyes_Step)      ;...then closes eyes one step
   cp   K_F1
   JUMP_Z(BlinkBoth)            ;...then blinks both eyes
   cp   K_F5
   JUMP_Z(BlinkLeft)            ;...then blinks left eye (i.e. winks at you :)
   cp   K_Clear
   JUMP_Z(Close_Eyes)           ;...then closes eyes
   cp   K_Second
   JUMP_Z(Change_Eyes)          ;...then toggles 'blood-shot'ness

   cp   K_EXIT                  ;if EXIT pressed...
   jr   nz,NoExit
   pop  hl
   JUMP_Z(Close_Eyes)           ;...then close eyes and return to ZShell

NoExit:
   ld   hl,(AutoBlink)
   dec  hl
   ld   (AutoBlink),hl
   ld   a,h
   or   l
   JUMP_Z(BlinkBoth)
   ret
  

Open_Eyes_Step:
   ld   a,(EyeState)
   or   a
   jr   nz,OpenBS
   ld   a,(NoOfPic)
   or   a
   ret  z               ;Already open
   dec  a
   jr   DrawNext
OpenBS:
   ld   a,(NoOfPic)
   cp   6
   ret  nc              ;Already open
   inc  a
   jr   DrawNext
Close_Eyes_Step:
   ld   a,(NoOfPic)
   cp   3
   ret  z               ;Already closed
   jr   nc,CloseBS
   inc  a
   inc  a               ; <= Size-efficiency hack(?)
CloseBS:
   dec  a
   jr   DrawNext

AbsInc:
   ld   a,(NoOfPic)
   cp   6
   ret  nc              ; No change
   inc  a
   jr   DrawNext
AbsDec:
   ld   a,(NoOfPic)
   or   a
   ret  z               ; No change
   dec  a
DrawNext:
   ld   (NoOfPic),a
   rlca                 ; A shl 1

   ld   bc,(PROGRAM_ADDR)
   ld   hl,EyeSequence
   add  hl,bc
   add  a,l
   ld   l,a
   jr   nc,DecNoCarry
   inc  h
DecNoCarry:
   ld   e,(hl)
   inc  hl
   ld   d,(hl)
   ex   de,hl
   add  hl,bc
   CALL_(DrawBoth)
   ret


DrawBoth:               ; Input:  (HL) = picture
   push hl
   pop  ix
   ld   bc,VidStart
   ld   hl,15
   add  hl,bc
   ex   de,hl           ; BC = Left eye,  DE = Right eye

   ld   hl,$2307
DBOuter:
   push hl
DBInner:
   ld   a,(ix)
   inc  ix
   ld   (bc),a
   inc  bc
                        ; Reverse bit order to flip the other eye
   rlca \ rr h \ rlca \ rr h \ rlca \ rr h \ rlca \ rr h
   rlca \ rr h \ rlca \ rr h \ rlca \ rr h \ rlca \ rr h
   ld   a,h
   ld   (de),a
   dec  de

   dec  l
   jr   nz,DBInner
   ld   hl,16+7
   add  hl,de
   ex   de,hl
   ld   hl,9
   add  hl,bc
   push hl
   pop  bc

   pop  hl
   dec  h
   jr   nz,DBOuter
   ret


Wait:
   ld   hl,$2000
WaitLoop:
   dec  hl
   ld   a,h
   or   l
   ret  z
   jr   WaitLoop

WaitABit:
   ld   hl,$0800
WaitAbitLoop:
   dec  hl
   ld   a,h
   or   l
   ret  z
   jr   WaitABitLoop


Close_Eyes:
   ld   a,(NoOfPic)
   sub  3
   ret  z               ; Check if already closed
   jr   c,CENorm
CEBS:
   push af
   CALL_(AbsDec)
   CALL_(Wait)
   pop  af
   dec  a
   jr   nz,CEBS
   ret
CENorm:
   push af
   CALL_(AbsInc)
   CALL_(Wait)
   pop  af
   inc  a
   jr   nz,CENorm
   ret


BlinkBoth:
   ld   a,(NoOfPic)
   sub  3
   ret  z               ; Can't blink a closed eye...
   ld   c,-1
   jr   nc,BBNorm
   neg
   ld   c,1
BBNorm:
   ld   b,a
   ld   a,(NoOfPic)
   push bc
BBCloseLoop:
   add  a,c
   push bc
   push af
   CALL_(DrawNext)
   CALL_(WaitABit)
   pop  af
   pop  bc
   djnz BBCloseLoop
   CALL_(Wait)
   pop  bc
   ld   a,c
   neg
   ld   c,a
   ld   a,3
BBOpenLoop:
   add  a,c
   push bc
   push af
   CALL_(DrawNext)
   CALL_(WaitABit)
   pop  af
   pop  bc
   djnz BBOpenLoop
   CALL_(Wait)
   ret


BlinkLeft:
   ld   a,(NoOfPic)
   sub  3
   ret  z               ; Can't blink a closed eye...
   ld   c,-1
   jr   nc,BLNorm
   neg
   ld   c,1
BLNorm:
   ld   b,a
   ld   a,(NoOfPic)
   push bc
BLCloseLoop:
   add  a,c
   push bc
   push af
   CALL_(DrawLeft)
   CALL_(WaitABit)
   pop  af
   pop  bc
   djnz BLCloseLoop
   CALL_(Wait)

   pop  bc
   ld   a,c
   neg
   ld   c,a
   ld   a,3
BLOpenLoop:
   add  a,c
   push bc
   push af
   CALL_(DrawLeft)
   CALL_(WaitABit)
   pop  af
   pop  bc
   djnz BLOpenLoop
   CALL_(Wait)
   ret

DrawLeft:
   ld   (NoOfPic),a
   rlca                 ; A shl 1

   ld   bc,(PROGRAM_ADDR)
   ld   hl,EyeSequence
   add  hl,bc
   add  a,l
   ld   l,a
   jr   nc,DLNoAddCarry
   inc  h
DLNoAddCarry:
   ld   e,(hl)
   inc  hl
   ld   d,(hl)
   ex   de,hl
   add  hl,bc
   ld   de,VidStart
   ld   c,35
DLOuter:
   ld   b,7
DLInner:
   ld   a,(hl)
   inc  hl
   ld   (de),a
   inc  de
   djnz DLInner
   ld   a,9
   add  a,e
   ld   e,a
   jr   nc,DLNoLoopCarry
   inc  d
DLNoLoopCarry:
   dec  c
   jr   nz,DLOuter
   ret


Change_Eyes:
   ld   a,(NoOfPic)
   sub  3
   jr   nz,Ch_Blink     ; If not closed then have to blink
   ld   a,(EyeState)
   or   a
   ld   a,0
   jr   nz,Ch_PutZero
   inc  a
Ch_PutZero:
   ld   (EyeState),a
   ret

Ch_Blink:
   ld   c,-1
   jr   nc,Ch_Norm
   neg
   ld   c,1
Ch_Norm:
   ld   b,a
   push bc
   CALL_(Close_Eyes)
   CALL_(Wait)

   ld   a,(EyeState)
   or   a
   ld   a,0
   jr   nz,Ch_Ok
   inc  a
Ch_Ok:
   ld   (EyeState),a

   ld   a,3
   pop  bc
ChOpenLoop:
   add  a,c
   push bc
   push af
   CALL_(DrawNext)
   CALL_(Wait)
   pop  af
   pop  bc
   djnz ChOpenLoop
   CALL_(Wait)
   ret


EyeSequence:
.dw  Pic00,Pic01,Pic02,Pic03,Pic02,Pic04,Pic05

Pic00:
.db   $00,$00,$1A,$4C,$90,$00,$00,
.db   $00,$00,$0A,$28,$90,$00,$00,
.db   $00,$22,$CA,$29,$92,$00,$00,
.db   $00,$36,$49,$29,$14,$48,$00,
.db   $00,$12,$49,$2D,$2C,$E8,$00,
.db   $01,$12,$4D,$69,$4C,$A8,$00,
.db   $14,$CD,$6D,$EF,$4C,$AD,$00,
.db   $12,$3F,$FF,$FF,$DE,$BA,$00,
.db   $89,$DF,$FF,$FF,$FF,$71,$80,
.db   $56,$FF,$82,$BA,$B1,$E7,$20,
.db   $BF,$F0,$0F,$D7,$58,$3C,$A0,
.db   $9F,$80,$1A,$AA,$A8,$0F,$D4,
.db   $7C,$00,$1F,$7D,$58,$13,$A8,
.db   $58,$00,$3A,$FF,$AC,$01,$F4,
.db   $F0,$00,$3D,$FF,$5C,$08,$F8,
.db   $30,$00,$3B,$FF,$BC,$02,$50,
.db   $28,$00,$35,$FF,$DC,$01,$78,
.db   $10,$00,$3B,$FF,$AC,$00,$78,
.db   $1C,$00,$35,$FF,$DC,$02,$F8,
.db   $08,$00,$3F,$BF,$BC,$00,$78,
.db   $0C,$00,$35,$FF,$5C,$00,$F8,
.db   $06,$00,$1E,$FE,$B8,$02,$70,
.db   $03,$40,$1D,$55,$F8,$00,$F0,
.db   $03,$80,$0F,$EA,$B0,$0A,$E0,
.db   $00,$E0,$07,$5D,$E0,$01,$C0,
.db   $00,$50,$03,$FF,$C0,$27,$00,
.db   $00,$1C,$00,$FF,$00,$0E,$00,
.db   $00,$07,$C0,$00,$00,$F0,$00,
.db   $00,$00,$FE,$00,$0F,$80,$00,
.db   $00,$00,$0F,$FF,$FC,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,

Pic01:
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$0E,$B7,$A0,$00,$00,
.db   $00,$03,$7B,$76,$FA,$00,$00,
.db   $00,$17,$E6,$C9,$75,$C0,$00,
.db   $02,$98,$92,$49,$46,$B0,$00,
.db   $01,$6B,$53,$4D,$44,$EE,$00,
.db   $1A,$BB,$7F,$FF,$FF,$8F,$00,
.db   $0F,$9B,$FF,$FE,$AD,$F5,$C0,
.db   $6F,$FF,$FD,$FF,$DC,$1F,$E0,
.db   $3F,$EC,$BB,$FF,$BC,$03,$D0,
.db   $6E,$D0,$35,$FF,$DC,$01,$F8,
.db   $34,$00,$3B,$FF,$AC,$00,$EC,
.db   $28,$00,$35,$FF,$DC,$02,$F8,
.db   $12,$00,$3F,$BF,$FC,$00,$78,
.db   $18,$00,$35,$FF,$5C,$00,$F8,
.db   $0C,$00,$1E,$FE,$B8,$02,$70,
.db   $06,$40,$1D,$55,$F8,$00,$F0,
.db   $03,$80,$0F,$EA,$B0,$0A,$E0,
.db   $00,$E0,$07,$5D,$E0,$01,$C0,
.db   $00,$50,$03,$FF,$C0,$27,$00,
.db   $00,$1C,$00,$FF,$00,$0E,$00,
.db   $00,$07,$C0,$00,$00,$F0,$00,
.db   $00,$00,$FE,$00,$0F,$80,$00,
.db   $00,$00,$0F,$FF,$FC,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,

Pic02:
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$0E,$B7,$A0,$00,$00,
.db   $00,$01,$7F,$76,$FA,$00,$00,
.db   $00,$03,$E0,$41,$15,$C0,$00,
.db   $00,$0E,$82,$48,$00,$B0,$00,
.db   $00,$7B,$10,$00,$88,$2C,$00,
.db   $01,$B8,$24,$08,$00,$67,$00,
.db   $05,$C4,$00,$00,$02,$01,$C0,
.db   $0F,$80,$00,$00,$00,$02,$E0,
.db   $3D,$48,$80,$00,$00,$08,$50,
.db   $7A,$00,$00,$00,$00,$00,$F8,
.db   $75,$00,$00,$00,$00,$00,$6C,
.db   $AA,$10,$00,$00,$00,$09,$58,
.db   $AE,$C0,$00,$00,$00,$00,$FC,
.db   $2E,$78,$80,$08,$06,$3F,$FC,
.db   $57,$FF,$FF,$FF,$FF,$FF,$78,
.db   $35,$FF,$FF,$5D,$FF,$AB,$F0,
.db   $05,$A2,$6F,$EA,$B2,$AA,$E0,
.db   $0D,$E6,$4F,$5D,$F2,$B3,$C0,
.db   $02,$57,$DB,$FF,$D2,$D7,$00,
.db   $00,$DD,$16,$FF,$19,$0E,$00,
.db   $00,$07,$C0,$2E,$00,$F0,$00,
.db   $00,$00,$FE,$00,$0F,$80,$00,
.db   $00,$00,$0F,$FF,$FC,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,

Pic03:
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$0E,$B7,$A0,$00,$00,
.db   $00,$01,$7F,$76,$FA,$00,$00,
.db   $00,$03,$E0,$41,$15,$C0,$00,
.db   $00,$0E,$82,$48,$00,$B0,$00,
.db   $00,$7B,$10,$00,$88,$2C,$00,
.db   $01,$B8,$24,$08,$00,$67,$00,
.db   $05,$C4,$00,$00,$02,$01,$C0,
.db   $0F,$80,$00,$00,$00,$02,$E0,
.db   $3D,$48,$80,$00,$00,$08,$50,
.db   $7A,$00,$00,$00,$00,$00,$F8,
.db   $5D,$00,$00,$00,$00,$00,$6C,
.db   $AA,$10,$00,$00,$00,$09,$58,
.db   $AE,$00,$00,$00,$00,$00,$FC,
.db   $6D,$80,$80,$00,$00,$01,$FE,
.db   $D7,$90,$00,$00,$00,$23,$7E,
.db   $35,$28,$00,$00,$00,$03,$F5,
.db   $65,$E2,$20,$00,$00,$16,$FE,
.db   $0D,$74,$00,$00,$01,$0B,$CA,
.db   $19,$D2,$A2,$82,$28,$9F,$69,
.db   $03,$5D,$08,$00,$01,$5F,$36,
.db   $0E,$57,$D5,$19,$44,$F5,$98,
.db   $00,$D5,$FE,$AA,$13,$D4,$C0,
.db   $01,$B5,$6F,$FF,$FD,$5C,$60,
.db   $00,$25,$6A,$52,$AD,$4F,$00,
.db   $00,$0D,$AA,$52,$AD,$68,$00,
.db   $00,$03,$22,$56,$AF,$AC,$00,
.db   $00,$00,$26,$DC,$B2,$00,$00,
.db   $00,$00,$04,$88,$D0,$00,$00,

Pic04:
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$0E,$B7,$A0,$00,$00,
.db   $00,$03,$7B,$76,$FA,$00,$00,
.db   $00,$17,$E6,$C9,$75,$C0,$00,
.db   $02,$98,$92,$49,$46,$B0,$00,
.db   $01,$6B,$53,$4D,$44,$EE,$00,
.db   $1A,$BB,$7F,$FF,$FF,$8F,$00,
.db   $0F,$9B,$FF,$FE,$AD,$F5,$C0,
.db   $6F,$FF,$FD,$FF,$DC,$1F,$E0,
.db   $3F,$EC,$BB,$FF,$BC,$53,$F0,
.db   $6E,$D6,$35,$FF,$DC,$61,$F8,
.db   $35,$F3,$3B,$FF,$AD,$1F,$FC,
.db   $3F,$80,$35,$FF,$DC,$C4,$78,
.db   $1B,$4C,$3F,$BF,$FC,$77,$FC,
.db   $1D,$7A,$35,$FF,$5C,$1A,$78,
.db   $0E,$99,$9E,$FE,$B8,$70,$F0,
.db   $07,$47,$1D,$55,$F9,$95,$70,
.db   $03,$86,$0F,$EA,$B1,$1A,$E0,
.db   $00,$E3,$87,$5D,$EF,$11,$C0,
.db   $00,$50,$83,$FF,$D8,$77,$00,
.db   $00,$1C,$C0,$FF,$10,$0E,$00,
.db   $00,$07,$C0,$00,$00,$F8,$00,
.db   $00,$00,$FE,$00,$0F,$80,$00,
.db   $00,$00,$0F,$FF,$FC,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,

Pic05:
.db   $00,$00,$1A,$4C,$90,$00,$00,
.db   $00,$00,$0A,$28,$90,$00,$00,
.db   $00,$22,$CA,$29,$92,$00,$00,
.db   $00,$36,$49,$29,$14,$48,$00,
.db   $00,$12,$49,$2D,$2C,$E8,$00,
.db   $01,$12,$4D,$69,$4C,$A8,$00,
.db   $14,$CD,$6D,$EF,$4C,$AD,$00,
.db   $12,$3F,$FF,$FF,$DE,$BA,$00,
.db   $89,$DF,$FF,$FF,$FF,$71,$80,
.db   $56,$FF,$82,$BA,$B1,$E7,$20,
.db   $BF,$FA,$0F,$D7,$5E,$7C,$A0,
.db   $9F,$8C,$1A,$AA,$A8,$AF,$D4,
.db   $7C,$11,$9F,$7D,$58,$93,$A8,
.db   $58,$96,$3A,$FF,$AC,$8D,$F4,
.db   $FF,$F4,$3D,$FF,$5C,$DA,$F8,
.db   $33,$08,$3B,$FF,$BC,$50,$70,
.db   $2A,$06,$35,$FF,$DC,$61,$78,
.db   $11,$F3,$3B,$FF,$AD,$1F,$78,
.db   $1F,$80,$35,$FF,$DC,$C4,$78,
.db   $09,$4C,$3F,$BF,$BC,$77,$F8,
.db   $0D,$7A,$35,$FF,$5C,$1A,$78,
.db   $06,$99,$9E,$FE,$B8,$70,$F0,
.db   $03,$47,$1D,$55,$F9,$95,$70,
.db   $03,$86,$0F,$EA,$B1,$1A,$E0,
.db   $00,$E3,$87,$5D,$EF,$11,$C0,
.db   $00,$50,$83,$FF,$D8,$77,$00,
.db   $00,$1C,$C0,$FF,$10,$0E,$00,
.db   $00,$07,$C0,$00,$00,$F8,$00,
.db   $00,$00,$FE,$00,$0F,$80,$00,
.db   $00,$00,$0F,$FF,$FC,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,
.db   $00,$00,$00,$00,$00,$00,$00,


.end
