
	opt b+
                  icl 'rmt_music.asm'                                ; adres Playera RMT musi być $xx00 !!!
	opt b-

	rmb

                    org $8000

        icl 'inflate.asm'       ; depacker
	icl 'init\init.asm'	; init bufors, copy fonts etc.( to show a screen)
        icl 'BombData.asm'      ; set constants, variables, tables etc.

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; This procedure serves the move of BOMB JACK
; BOMB JACK spada na dół
;--------------------------------------------------------------------------------------------------------------------------------------------------------
RCI_BOMB_JACK_Joystick_Part2 .proc
                  lda Is_No_Flight_BOMB_JACK
                  jne RCI_JACK1_skipS

                  jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25        ;                 ...
                  jsr Get_Action_from_tab_Action_for_256Chars                ;                 ...
                  lda Is_Collision_with_LEDGE_BOMB_JACK                      ;                 .x.
                  seq
                  rts

                  jsr address1_SBW_1byte                                     ; previous column ...
                  jsr Get_Action_from_tab_Action_for_256Chars                ;                 ...
                  lda Is_Collision_with_LEDGE_BOMB_JACK                      ;                 x..
                  seq
                  rts

                  jsr address1_ADW_1byte                                     ; next column     ...
                  jsr address1_ADW_1byte                                     ; next column     ...
                  jsr Get_Action_from_tab_Action_for_256Chars                ;                 ..x
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  seq
                  rts

                  dec Repeat_PosY_Ground
                  bne skp1

                  mva #$07/SPEED_SPRITE Repeat_PosY_Ground

                  lda Offset_PosY_Ground
                  cmp #$08
                  bcs skp1

                  :SPEED_SPRITE inc Offset_PosY_Ground

skp1              adb Sprite0_PosY Offset_PosY_Ground
                  jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25        ;                 ...
                  jmp Get_Action_from_tab_Action_for_256Chars                ;                 ...
.endp

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; This procedure convert datas of SPRITES from C64 to ATARI format
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Convert_Sprites_C64_to_ATARI_jack
; translate X,Y Coordinate(C64) to X,Y Coordinate(ATARI)
                  lda Sprite0_PosX
                  lsr @
                  sta sprites[0].psx     ; PosX/2

; tutaj wstawiony kawałek kodu, który ma zlikwidować błąd polegający na zaskakującym teleporcie BJ (czasami w trakcie gry)
                  lda Sprite0_PosY
                  sub #CORR_Y
                  sub sprites[0].psy
                  bcs corr_0
                      eor #$ff
                      adc #1
corr_0            cmp #20
                  bcc corr_1
                      lda sprites[0].psy
                      add #CORR_Y
                      sta Sprite0_PosY
corr_1            lda Sprite0_PosY
                  sub #CORR_Y
                  sta sprites[0].psy

; translate SHAPE from C64 to ATARI
                  lda tab_Addr_Sprite0_7_Pattern
                  sub #$60
                  tay
                  ldx tab_conv_sprite_number_C64_to_ATARI,y
                  mva   tab_SHP_C64_to_ATARI,x sprites[0].shp       ; set the number of SHAPE
                  mva tab_FRM_C64_to_ATARI_L,x sprites[0].frm+0     ; set the address of animation frames
                  mva tab_FRM_C64_to_ATARI_H,x sprites[0].frm+1
                  mva tab_PMG_C64_to_ATARI_L,x sprites[0].pmg+0     ; set the address of PMG animation frames
                  mva tab_PMG_C64_to_ATARI_H,x sprites[0].pmg+1
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; This procedure serves the move of BOMB JACK
;--------------------------------------------------------------------------------------------------------------------------------------------------------
BombJack_Joy      mva #$0C tab_choose_col_PMG+0                     ; ustaw kolor dla 'bomb jack-a'

                  lda Is_Dance_BOMB_JACK \ jne RCI_JACK1_Dance
                  lda Is_Dead_BOMB_JACK \ jne Animate_Dead_BOMB_JACK

                  jsr RCI_JACK1
                  jsr RCI_BOMB_JACK_Joystick_Part2
                  jmp Convert_Sprites_C64_to_ATARI_jack

;-----------------------------------------------------------------------
RCI_JACK1         joy1_left  RCI_JACK1_Left
                  joy1_right RCI_JACK1_Right

RCI_JACK1_loop1   joy1_nofire RCI_JACK1_NO_Fire

                  lda Is_FIRE_Still_Pressed
                  beq RCI_JACK1_skip1

                  joy1_nostay jack_skp1
                  mva #$A8 BombJack_SHP_C64                             ; BombJack_HandsUp_CapeDn - 64-bajtowy blok danych - sprite #0 ($A9*$40 = $6A40) - klatka z BOMB JACK'iem z uniesionymi rękami i opuszczoną peleryną

jack_skp1         inc Sprite0_PosY
                  rts

RCI_JACK1_skip1   mva #TRUE Is_FIRE_Still_Pressed
                  mva #sfx_jump_jack sfx_effect
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  jne RCI_JACK1_skipP

RCI_JACK1_skip0   mva #$00 Offset_PosY_Ground
                  sta      Is_No_Flight_BOMB_JACK                       ; =0 BOMB JACK lata!
                  mva #$06/SPEED_SPRITE Repeat_PosY_Ground
                  jmp RCI_JACK1_skip2

; tutaj obsługa BOMB JACK-a jeżeli nie wciśnięto FIRE oraz nie ruszono joystickiem ani w prawo ani w lewo
RCI_JACK1_NO_Fire mva #$00 Is_FIRE_Still_Pressed
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  seq
                  rts

RCI_JACK1_skip2   joy1_left  RCI_JACK1_RTS
                  joy1_right RCI_JACK1_RTS
                  mva #$A8 BombJack_SHP_C64                             ; BombJack_HandsUp_CapeDn - 64-bajtowy blok danych - sprite #0 ($A8*$40 = $6A00) - klatka z BOMB JACK'iem z uniesionymi rękami i spuszczoną peleryną

                  lda Is_No_Flight_BOMB_JACK
                  seq
                  rts

                  mva #$A9 BombJack_SHP_C64                             ; BombJack_HandsUp_CapeUp - 64-bajtowy blok danych - sprite #0 ($A9*$40 = $6A40) - klatka z BOMB JACK'iem z uniesionymi rękami i uniesioną peleryną
RCI_JACK1_RTS     rts

; skok tutaj jeżeli Joystick w lewo
RCI_JACK1_Left    lda Sprite0_PosX
                  cmp #MIN_POSX_SPRITE+4                                ; Czy wsp.X BOMB JACK-a osiągnęła lewy margines? (badamy czy PosX=$1B or PosX=$1C bo przesuwamy o -2 piksele)
                  bcc RCI_JACK1_RTS                                     ; TAK!

                  mva #$01     is_jack_left_or_right
                  jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25 ; oblicz adres(korzystając z wsp. X i Y) w ScreenBuff40x25, na którym aktualnie jest wyświetlany SPRITE
                  sbw address1 #2*32+2                                ; -82
                  mva #$01     is_jack_left_or_right
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Store_Action                                    ; Czy na pozycji BOMB JACK-a jest zielony margines lub kładka?
                  beq RCI_JACK1_skip9

                  dec Store_Action
                  rts

RCI_JACK1_skip9   jsr address1_SBW_40bytes
                  mva #$01 is_jack_left_or_right
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Store_Action                                    ; Czy na pozycji BOMB JACK-a (wiersz wyżej) jest zielony margines lub kładka?
                  beq RCI_JACK1_skipA

                  dec Store_Action
                  rts

RCI_JACK1_skipA   jsr address1_ADW_40bytes
                  jsr address1_ADW_40bytes
                  mva #$01 is_jack_left_or_right
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Store_Action                                    ; Czy na pozycji BOMB JACK-a (wiersz niżej) jest zielony margines lub kładka?
                  beq RCI_JACK1_skipB

                  dec Store_Action
                  rts

RCI_JACK1_skipB   sbb Sprite0_PosX #SPEED_SPRITE*2                    ; przesuń w lewo BOMB JACK-a o -2 piksele
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  bne RCI_JACK1_skipD

                  mva #$AD BombJack_SHP_C64    ; BombJack_Left - 64-bajtowy blok danych - sprite #0 ($AD*$40 = $6B40) - klatka z BOMB JACK'iem zwróconym w lewo
                  lda Is_No_Flight_BOMB_JACK
                  jne RCI_JACK1_loop1

                  mva #$AB BombJack_SHP_C64    ; BombJack_Left_Dn - 64-bajtowy blok danych - sprite #0 ($AB*$40 = $6AC0) - klatka z BOMB JACK'iem spadającym i zwróconym w lewo
                  jmp RCI_JACK1_loop1

RCI_JACK1_skipD   lda Delay_Move_BOMB_JACK_Left_or_Right
                  cmp #$03
                  beq RCI_JACK1_skipE

                  inc Delay_Move_BOMB_JACK_Left_or_Right
                  jmp RCI_JACK1_loop1

RCI_JACK1_skipE   mva #$00 Delay_Move_BOMB_JACK_Left_or_Right
                  ldx index_tab4clips_Move_BOMB_JACK      ; pobierz wskaźnik wsk. na kolejną klatkę przesuwającą w lewo BOMB JACK-a

RCI_JACK1_skipF   lda tab_4clips_Move_BOMB_JACK_Left,x    ; pobierz kolejną klatkę z przesuwających BOMB JACK-a w lewo (są ich 4-ry)
                  beq RCI_JACK1_skipG

                  sta BombJack_SHP_C64                    ; 64-bajtowy blok danych - sprite #0 (rej.A*$40)
          ;        mva tab_sfx_move,x sfx_effect               ;   sta sprites[0].shp
                  inc index_tab4clips_Move_BOMB_JACK      ; +1 wskaźnik
                  jmp RCI_JACK1_loop1

RCI_JACK1_skipG   mvx #$00           index_tab4clips_Move_BOMB_JACK ; =0 ustaw wskaźnik na pierwszą klatkę przesuwającą BOMB JACK-a w lewo!
                  jmp RCI_JACK1_skipF                               ; skocz pobrać tą pierwszą klatkę

; skok tutaj jeżeli Joystick w prawo
dec_Store_Action  dec Store_Action
                  rts

RCI_JACK1_Right   lda Sprite0_PosX
                  cmp #MAX_POSX_SPRITE-WIDTH_SPRITE
                  scc
                  rts

                  mva #$01 is_jack_left_or_right                                  ; x...
                  jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25             ;  ...
                  sbw address1 #2*32-2                                            ;  ...
                  mva #$01     is_jack_left_or_right
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Store_Action
                  jne dec_Store_Action

                  jsr address1_SBW_40bytes
                  mva #$01 is_jack_left_or_right
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Store_Action
                  jne dec_Store_Action

                  jsr address1_ADW_40bytes                                         ;  ...
                  jsr address1_ADW_40bytes                                         ;  ...
                  mva #$01 is_jack_left_or_right                                   ; x...
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Store_Action
                  jne dec_Store_Action

                  adb Sprite0_PosX #SPEED_SPRITE*2
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  bne RCI_JACK1_skipL

                  mva #$AC BombJack_SHP_C64 ; BombJack_Right - 64-bajtowy blok danych - sprite #0 ($AC*$40 = $6B00) - klatka z BOMB JACK'iem odwróconym w prawo i stojącym nieruchomo!
                  lda Is_No_Flight_BOMB_JACK
                  jne RCI_JACK1_loop1

                  mva #$AA BombJack_SHP_C64 ; BombJack_Right_Dn - 64-bajtowy blok danych - sprite #0 ($AA*$40 = $6A80) - klatka z BOMB JACK'iem odwróconym w prawo - lądującym po wykonanym skoku!
                  jmp RCI_JACK1_loop1

RCI_JACK1_skipL   lda Delay_Move_BOMB_JACK_Left_or_Right
                  cmp #$03
                  beq RCI_JACK1_skipM

                  inc Delay_Move_BOMB_JACK_Left_or_Right
                  jmp RCI_JACK1_loop1

RCI_JACK1_skipM   mva #$00 Delay_Move_BOMB_JACK_Left_or_Right
                  ldx index_tab4clips_Move_BOMB_JACK        ; pobierz wskaźnik na kolejną klatkę przesuwającą w prawo BOMB JACK-a

RCI_JACK1_skipN   lda tab_4clips_Move_BOMB_JACK_Right,x     ; pobierz kolejną klatkę z przesuwających BOMB JACK-a w prawo (są ich 4-ry)
                  beq RCI_JACK1_skipO

                  sta BombJack_SHP_C64                      ; 64-bajtowy blok danych - sprite #0 (rej.A*$40)
               ;   mva tab_sfx_move,x sfx_effect             ;    sta sprites[0].shp
                  inc index_tab4clips_Move_BOMB_JACK        ; +1 wskaźnik
                  jmp RCI_JACK1_loop1

RCI_JACK1_skipO   mvx #$00           index_tab4clips_Move_BOMB_JACK   ; =0 ustaw wskaźnik na pierwszą klatkę przesuwającą BOMB JACK-a w prawo!
                  jmp RCI_JACK1_skipN                                 ; skocz pobrać tą pierwszą klatkę

RCI_JACK1_skipP   lda Is_No_Flight_BOMB_JACK                ; Czy BOMB JACK nie lata?
                  jne RCI_JACK1_skip0                       ; TAK!

                  lda #$00
                  ldx #$00
                  ldy #$10                                  ; +100.000 punktów
                  jsr Add_Points_to_SCORE_PLAYER_AXY
                  mva #$01 Is_No_Flight_BOMB_JACK           ; =1 BOMB JACK nie lata!

                  mva #$06*SPEED_SPRITE Add_PosY_BOMB_JACK_Better_Jump
                  mva #$00 Is_Collision_with_LEDGE_BOMB_JACK

                  joy1_noup RCI_JACK1_skipR

                  mva #$07*SPEED_SPRITE Add_PosY_BOMB_JACK_Better_Jump   ; If FIRE+UP pressed than BOMB JACK can do higher jump

RCI_JACK1_skipR   mva #$0A/SPEED_SPRITE Decrease_Value_Add_PosY_during_JUMP_BOMB_JACK
                  rts
;----------------------
RCI_JACK1_skipS   jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25
                  jsr Test_Jack_Up
                  bcs *+3
                  rts

                  dec Decrease_Value_Add_PosY_during_JUMP_BOMB_JACK
                  lda Decrease_Value_Add_PosY_during_JUMP_BOMB_JACK
                  bne RCI_JACK1_skipV

                  mva #$08/SPEED_SPRITE Decrease_Value_Add_PosY_during_JUMP_BOMB_JACK
                  lda Add_PosY_BOMB_JACK_Better_Jump
                  beq RCI_JACK1_skipW

                  .rept SPEED_SPRITE
                    dec Add_PosY_BOMB_JACK_Better_Jump
                  .endr
                  bpl RCI_JACK1_skipV

                  mva #0 Add_PosY_BOMB_JACK_Better_Jump

RCI_JACK1_skipV   lda Add_PosY_BOMB_JACK_Better_Jump
                  cmp #9
                  bcc RCI_JACK1_skipV0

                  jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25
                  sbw address1 #1*32
                  jsr Test_Jack_Up
                  bcs RCI_JACK1_skipV0

                  mva #8 Add_PosY_BOMB_JACK_Better_Jump

RCI_JACK1_skipV0  sbb Sprite0_PosY Add_PosY_BOMB_JACK_Better_Jump

                  lda Sprite0_PosY
                  cmp #MIN_POSY_SPRITE
                  bcs RCI_JACK1_skipV2

                  mva #MIN_POSY_SPRITE Sprite0_PosY
                  jmp RCI_JACK1_skipW

RCI_JACK1_skipV2  rts

RCI_JACK1_skipW   mva #$00            Is_No_Flight_BOMB_JACK
                  sta                 Offset_PosY_Ground
                  mva #$07/SPEED_SPRITE Repeat_PosY_Ground
                  rts

; sprawdzaj czy podczas lotu do góry 'bomb jack-a' nadzieje się on na kładkę?
Test_Jack_Up      sbw address1 #4*32                                      ;
                  jsr Get_Action_from_tab_Action_for_256Chars             ;   x
                  lda Is_Collision_with_LEDGE_BOMB_JACK                   ;  ...
                  beq RCI_JACK1_skipU                                     ;  ...
                                                                          ;  ...
RCI_JACK1_skipT   mva #$07/SPEED_SPRITE Repeat_PosY_Ground
                  mva #$00 Offset_PosY_Ground
                  sta      Is_No_Flight_BOMB_JACK
                  sta      Is_Collision_with_LEDGE_BOMB_JACK
                  clc
                  rts

RCI_JACK1_skipU   jsr address1_SBW_1byte                                  ; poprzednia kolumna
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  bne RCI_JACK1_skipT

                  jsr address1_ADW_1byte                                  ; następna kolumna
                  jsr address1_ADW_1byte                                  ; następna kolumna
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  bne RCI_JACK1_skipT

                  sec
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura pobiera "kod akcji" dla wartości spod (address1) przeszukując tablice - tab_Action_for_256Chars
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Get_Action_from_tab_Action_for_256Chars .proc
                  get_byte_from_address #0
                  jeq_a #$01,Get_Action_skip1

                  lda is_jack_left_or_right
                  beq Get_Action_skip0

                  mva #$00 Store_Action              ; "kod akcji" = $00 (dla wszystkich kodˇw <> $01)
                  sta is_jack_left_or_right
                  rts

Get_Action_skip0  mva #FALSE Is_Collision_with_LEDGE_BOMB_JACK
                  rts

Get_Action_skip1  lda is_jack_left_or_right
                  beq Get_Action_skip2

                  dec is_jack_left_or_right
                  mva #$01 Store_Action              ; "kod akcji" = $01
                  rts

Get_Action_skip2  ldx index_tab_Addr_SPRITE_ScreenBuff40x25
                  mva tab_Addr_SPRITE_ScreenBuff40x25+2,x Sprite0_PosY
                  mva #$00              Offset_PosY_Ground                ; dodaj w pierwszym przejťciu +0 do wsp.Y BOMB JACK-a (w nastŕpnych przejťciach +1,+2,+3 itd.)
                  mva #$07/SPEED_SPRITE Repeat_PosY_Ground                ; wykonaj 7 razy pŕtle
Get_Action_skip3  mva #TRUE             Is_Collision_with_LEDGE_BOMB_JACK ; trafiono na zielon¦ ramkŕ lub podk-adke wiŕc BOMB JACK wraca na ziemie
                  rts
.endp

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura obsługująca tańczenie BOMB JACK-a (po zebraniu wszystkich BOMB)
;--------------------------------------------------------------------------------------------------------------------------------------------------------
RCI_JACK1_Dance   mva #0 sprites[bomb_sprite].sts
                  lda #mus_level_complited
                  cmp number_song
                  beq jack_dance1

                  sta number_song
                  jsr play_music
                  mva #0 index_tab_Dance_BOMB_JACK

jack_dance1       inc Delay_Dance_BOMB_JACK
                  lda Delay_Dance_BOMB_JACK
                  cmp #$0A
                  beq RCI_Dance_skip1

                  rts
;-----------------
RCI_Dance_skip1   ldy index_tab_Dance_BOMB_JACK
                  lda tab_Dance_BOMB_JACK,y         ; pobierz kolejną klatkę z ciągu, który powoduje tańczenie BOMB JACK-a (jak zbierze wszystkie bomby)
                  beq RCI_Dance_skip2               ; =0 koniec tańczenia!

                  sta BombJack_SHP_C64              ; 64-bajtowy blok danych - sprite #0 (rej.A*$40)
                  jsr Convert_Sprites_C64_to_ATARI_jack
                  inc index_tab_Dance_BOMB_JACK
                  mva #$00 Delay_Dance_BOMB_JACK

                  rts
;-----------------
RCI_Dance_skip2   mva #$00 Delay_Dance_BOMB_JACK
                  sta      Is_Dance_BOMB_JACK
                  inc Number_Round_BIN              ; następna plansza (runda)
                  lda Number_Round_BIN
                  jsr Set_Number_of_Round
                  ldx #50
                  jsr wait_time
                  
                  jsr stop_music

                  mva #$00 blink_faces
                  mva @TAB_MEM_BANKS+=Show_Bonus_Screen portb
                  jsr fade_out
                  jsr prepare_screen
                  jsr Show_Bonus_Screen
                  mva save_portb portb

                  lda Number_Round_BIN                           ; Czy przeszliśmy już wszystkie 20-ścia plansz?
                  cmp #20+1
                  jcc change_board

               :2 inc Show_Number_Round.repeat_20levels          ; +2 do licznika zliczającego ile razy gra została zapętlona
                  lda Show_Number_Round.repeat_20levels
                  cmp #8
                  sne
                  mva #$00 Show_Number_Round.repeat_20levels

                  mva #$01 Number_Round_BIN
                  sta      Number_Round_BCD
                  jmp change_board

              /*    mva #$01 choose_buff
                  jsr show_buff
                  mva @TAB_MEM_BANKS+=Show_Get_Nick_Screen portb
                  jsr Show_Get_Nick_Screen
                  jmp start_game
                */
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura animująca martwego BOMB JACK-a
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Animate_Dead_BOMB_JACK
                  lda Counter_Collected_BOMBS
                  cmp #24                                       ; Czy zebrano już wszystkie 24 bomby?
                  sne                                           ; TAK!
                  rts

                  mva #$00      is_fast_move_on                    ; wyłącz szybki przesów przeciwników w pionie (bo ptaszek nad głową martwego BJ w złym miejscu się na chwilę pojawia)
                  mva #C64_None tab_Type_SPRITES_0_7+letter_sprite

                  lda Is_Collision_with_LEDGE_BOMB_JACK         ; jeżeli 'bomb jack' po śmierci zaczął spadać i spadł na kładkę(lub dół planszy)...
                  bne Dead_JACK_skip1                           ; ...to wtedy wykonaj animację ze skrzydełkami nad jego głową

                  mva #$04 Time_Delay_Animate_Dead_BOMB_JACK
                  jmp Dead_JACK_skip3

Dead_JACK_skip1   mva #$0F Time_Delay_Animate_Dead_BOMB_JACK
                  mva #$AE BombJack_SHP_C64                     ; 64-bajtowy blok danych - sprite #0 ($AE*$40 = $6B80) - klatka z BOMB JACK'iem do góry nogami (jeżeli zabity przez przeciwnika to ona się pojawia)
                  jsr Convert_Sprites_C64_to_ATARI_jack

Dead_JACK_skip2   inc Delay_Animate_Dead_BOMB_JACK
                  lda Delay_Animate_Dead_BOMB_JACK
                  cmp Time_Delay_Animate_Dead_BOMB_JACK
                  beq *+3
                  rts

Dead_JACK_skip22  lda Is_Collision_with_LEDGE_BOMB_JACK         ; Czy 'bomb jack' leży na kładce lub na dole planszy?
                  bne Dead_JACK_skip4                           ; TAK!

Dead_JACK_skip3   mva #$00 Delay_Animate_Dead_BOMB_JACK
                  lda index_tab_Dead_BOMB_JACK
                  add #1
                  and #3
                  sta index_tab_Dead_BOMB_JACK
                  tay
                  mva tab_Dead_BOMB_JACK,y BombJack_SHP_C64     ; sprites[0].shp tablica z 2 klatkami animującymi śmierść BOMB JACK-a po dotknięciu przez wroga (raz do góry nogami, a raz normalnie ustawiony BOMB JACK)-$6A40 i $6B80
                  adb Sprite0_PosY #4
                  jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  bne Dead_JACK_skip22
                  adw address1 #1
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  jne Dead_JACK_skip22
                  sbw address1 #2
                  jsr Get_Action_from_tab_Action_for_256Chars
                  lda Is_Collision_with_LEDGE_BOMB_JACK
                  jne Dead_JACK_skip22
                  jmp Convert_Sprites_C64_to_ATARI_jack
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Dead_JACK_skip4   mva #$00             Delay_Animate_Dead_BOMB_JACK
                  mva Sprite0_PosX     Sprite0_PosX+letter_sprite*2
                  sbb Sprite0_PosY #17 Sprite0_PosY+letter_sprite*2

                  ldy index_tab_Bird_Over_BOMB_JACK
                  lda tab_Bird_Over_BOMB_JACK,y                  ; tablica z animacją ptaszka nad BOMB JACKIEM, jeżeli ten zginął ($BA*$40 = $6E80)
                  beq Dead_JACK_skip5                            ; =0 ostatnia klatka z tablicy więc trzeba od początku zacząć brać klatki!

                  sta tab_Addr_Sprite0_7_Pattern+letter_sprite
                  mva #$01             is_anim_dead_bird         ; właśnie animujemy ptaszka śmierci nad głową BJ
                  sta                  sprites[letter_sprite].sts
                  inc index_tab_Bird_Over_BOMB_JACK
                  jsr Convert_Sprites_C64_to_ATARI                     ; pokaż gracza i przeciwników
                  mva #$00             tab_choose_sprite+letter_sprite ; wykorzystanie PMG #0 dla ptaszka śmierci nad głową BJ
              ;    mva #$00             tab_type_SPRITES_0_7+letter_sprite
                  joy1_fire Dead_JACK_skip5
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
Dead_JACK_skip5   mva #$00 tab_Type_SPRITES_1_7
                  sta      index_tab_Bird_Over_BOMB_JACK
                  sta      Is_Dead_BOMB_JACK
                  ldx #$ff                                       ; wyzeruj wskaźnik stosu
                  txs

                  jsr stop_music
                  lda pos_tab_addr_live
                  jeq Game_Over_BombJack

; po śmierci 'bomb jacka' (gdy ma jakieś życia jeszcze) tutaj kod wyświetla ponownie tą samą planszę
                  dec pos_tab_addr_live
                  jsr fade_out
                  jsr zero_multiplex_DLI                         ; wyłącz działanie MULTIPLEXER'a PMG
                  jsr reset_variables_game                       ; procedura ustawia na początkowe wartości różne zmienne występujące w grze
                  jsr refresh_info
                  jsr init_pmg
                  mva #$01 choose_buff
                  jsr show_buff
                  jsr show_buff
                  jmp anim_START

; tutaj wyświetlamy kolejną planszę gry
change_board      mva #$01 choose_buff
                  jsr show_buff
                  mva #$00 size_MM_vbl
                  mva #$ff key
                  jsr Round2Board                                ; ustawia numer planszy #1-5  zależności od aktualnej rundy
                  jsr init_scr                                   ; inicjacja planszy gry
                  jsr refresh_info
                  jsr game_settings
                  jsr init_pmg                                   ; inicjacja PMG

                  mva #$01 choose_buff
                  jsr show_buff
                  wait_vbl
                  jsr init_col
                  ldx <tcol_board
                  ldy >tcol_board
	          jsr save_color
                  jmp anim_START

; procedura wyświetlająca napis 'Game Over' bo koniec żyć 'bomb jacka'
Game_Over_BombJack
                  jsr fade_out
                  jsr init_pmg

                  mvx #C64_GameOver+0 tab_Addr_Sprite1_7_Pattern+0
                  inx
                  stx                 tab_Addr_Sprite1_7_Pattern+1
                  inx
                  stx                 tab_Addr_Sprite1_7_Pattern+2
                  inx
                  stx                 tab_Addr_Sprite1_7_Pattern+3
                  inx
                  stx                 tab_Addr_Sprite1_7_Pattern+4

                  mva #74             Sprite1_PosX
                  mva #74+24          Sprite2_PosX
                  mva #74+24*2        Sprite3_PosX
                  mva #74+24*3        Sprite4_PosX
                  mva #74+24*4        Sprite5_PosX

                  mva #80+29          Sprite1_PosY
                  sta                 Sprite2_PosY
                  sta                 Sprite3_PosY
                  sta                 Sprite4_PosY
                  sta                 Sprite5_PosY

                  mva #1              sprites[1].sts
                  sta                 sprites[2].sts
                  sta                 sprites[3].sts
                  sta                 sprites[4].sts
                  sta                 sprites[5].sts

                  mva #$01 choose_buff
                  jsr show_buff
                  jsr show_buff
                  jsr fade_in
                  mva #mus_game_over number_song
                  jsr play_music

                  wait_trig0

                  jsr stop_music
                  mwa #B2ant AddrDisplayList
                  mva #$00   choose_PMG_on_VBL
                  jsr fade_out

                  mva @TAB_MEM_BANKS+=Show_Get_Nick_Screen portb
                  jsr Show_Get_Nick_Screen
                  jsr game_settings
                  jmp start_game

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura odejmuje 40 bajtów od address1
;--------------------------------------------------------------------------------------------------------------------------------------------------------
address1_SBW_40bytes
                  sbw address1 #$0020     ; -32
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura dodaje 40 bajtów do address1
;--------------------------------------------------------------------------------------------------------------------------------------------------------
address1_ADW_40bytes
                  adw address1 #$0020     ; +32
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; przesuwa kursor w lewo
;--------------------------------------------------------------------------------------------------------------------------------------------------------
address1_SBW_1byte
                  sbw address1 #$01       ; -1
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; przesuwa kursor w prawo
;--------------------------------------------------------------------------------------------------------------------------------------------------------
address1_ADW_1byte
                  adw address1 #$01       ; +1
                  rts

; dodanie wartości (rej. A,X,Y) do SCORE PLAYER
Add_Points_to_SCORE_PLAYER_AXY
                  sed
                  sta Add_Value_to_Score_Player+$00
                  stx Add_Value_to_Score_Player+$01
                  sty Add_Value_to_Score_Player+$02
                  clc
                  lda Score_Player+$02
                  adc Add_Value_to_Score_Player+$02
                  sta Score_Player+$02
                  lda Score_Player+$01
                  adc Add_Value_to_Score_Player+$01
                  sta Score_Player+$01
                  lda Score_Player+$00
                  adc Add_Value_to_Score_Player+$00
                  sta Score_Player+$00
                  cld
                  jmp Show_Score_Player                               ; wyświetl aktualną liczbę punktów bo zebrano bombę

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; This procedure convert datas of 'opponents' from C64 to ATARI format
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Convert_Sprites_C64_to_ATARI
                  jsr Convert_Sprites_C64_to_ATARI_jack

Convert_Sprites_C64_to_ATARI_opponent .proc
                  jsr set_PosX_div4                                   ; modyfikacja wsp.X (tak, żeby była podzielna przez 4-ry)

; translate X,Y Coordinate(C64) to X,Y Coordinate(ATARI)
                  ldx #0
                 .rept 7,#
                   lda Sprite0_PosY+[#+1]*2
                   sub #CORR_Y
                   cmp #(26*8)+CORR_Y-(8*3)+1
                   scc
                   stx sprites[#+1].sts                               ; wyłącz danego sprite'a

                   sta sprites[#+1].psy
                 .endr

; dzięki temu ptaszek nad martwym BJ pojawi się nawet jak będzie on przy górnej krawędzi ekranu
                   lda Sprite0_PosY+[letter_sprite]*2
                   sub #CORR_Y
                   scs
                   lda #0
                   sta sprites[letter_sprite].psy

; translate SHAPE from C64 to ATARI
                .rept 7
                  lda tab_Addr_Sprite0_7_Pattern+#+1
                  sub #$60
                  tay
                  ldx tab_conv_sprite_number_C64_to_ATARI,y
                  mva tab_SHP_C64_to_ATARI,x   sprites[#+1].shp      ; set the number of SHAPE
                  mva tab_FRM_C64_to_ATARI_L,x sprites[#+1].frm+0    ; set the address of animation frames
                  mva tab_FRM_C64_to_ATARI_H,x sprites[#+1].frm+1
                  mva tab_PMG_C64_to_ATARI_L,x sprites[#+1].pmg+0    ; set the address of PMG animation frames
                  mva tab_PMG_C64_to_ATARI_H,x sprites[#+1].pmg+1
                .endr

                  rts
.endp

; skasuj całą tablice dla PMG Multiplexer'a
do_multiplexer .proc
;dupa
          ;       lda is_init_multiplex_VBL                           ; eliminuje błąd PMG multiplexer'a
           ;      seq
            ;     rts

      ; mva random colbak

                 lda #0
                 ldx #27
lop0             sta tab_multiplex_count,x
                 sta tab_multiplex_sprites,x
                 dex
                 bpl lop0

; zaktualizuj tablicę dla PMG Multiplexer'a (stawiamy wartości <>$00 dla wierszy które zajmuje dany przeciwnik)
skp1             lda sprites[1].sts
                 beq skp2
                 lda sprites[1].psy
                 ldx tab_Type_SPRITES_1_7+0
                 ldy #%00000001
                 jsr set_multiplexer_row

skp2             lda sprites[2].sts
                 beq skp3
                 lda sprites[2].psy
                 ldx tab_Type_SPRITES_1_7+1
                 ldy #%00000010
                 jsr set_multiplexer_row

skp3             lda sprites[3].sts
                 beq skp4
                 lda sprites[3].psy
                 ldx tab_Type_SPRITES_1_7+2
                 ldy #%00000100
                 jsr set_multiplexer_row

skp4             lda sprites[4].sts
                 beq skp5
                 lda sprites[4].psy
                 ldx tab_Type_SPRITES_1_7+3
                 ldy #%00001000
                 jsr set_multiplexer_row

skp5             lda sprites[5].sts
                 beq con1
                 lda sprites[5].psy
                 ldx tab_Type_SPRITES_1_7+4
                 ldy #%00010000
                 jsr set_multiplexer_row

; aktualizacja tablicy "tab_choose_sprite"
con1             lda #$ff
              :7 sta      tab_choose_sprite+#+1

                 mvy #0 init_multiplex_VBL.sav2+1                 ; wyzeruj, żeby wiadomo było potem czy wartość ta była modyfikowana czy nie
                 sty    init_multiplex_VBL.sav4+1                 ; to samo co wyżej
                 ldx #0

lop1             lda tab_multiplex_sprites,y
                 beq nxt5

                 and #%00000001
                 beq nxt1

                 mva tab_no_pmg,x+ tab_choose_sprite+1

nxt1             lda tab_multiplex_sprites,y
                 and #%00000010
                 beq nxt2

                 mva tab_no_pmg,x+ tab_choose_sprite+2

nxt2             lda tab_multiplex_sprites,y
                 and #%00000100
                 beq nxt3

                 mva tab_no_pmg,x+ tab_choose_sprite+3

nxt3             lda tab_multiplex_sprites,y
                 and #%00001000
                 beq nxt4

                 mva tab_no_pmg,x+ tab_choose_sprite+4

nxt4             lda tab_multiplex_sprites,y
                 and #%00010000
                 beq nxt5

                 mva tab_no_pmg,x+ tab_choose_sprite+5

nxt5             iny
                 cpx #4
                 bcc nxt7
                 lda init_multiplex_VBL.sav2+1                   ; czy już raz zmieniono wartość? jeżeli tak to więcej jej nie zmieniaj!
                 bne nxt6

                 sty init_multiplex_VBL.sav2+1                   ; zapamiętujemy wiersz, od którego wykorzystamy PMG #7 (tak naprawdę to jest PMG #3 ale rozmnażane na DLI)
                 dec init_multiplex_VBL.sav2+1

nxt6             cpx #5
                 bne nxt7
                 lda init_multiplex_VBL.sav4+1
                 bne nxt7

                 sty init_multiplex_VBL.sav4+1
                 dec init_multiplex_VBL.sav4+1

nxt7             cpy #26
                 bne lop1

                 lda clr_second_time_pmg
                 cmp #2
                 sne
                 rts

                 mva #1 is_init_multiplex_VBL                   ; aktywacja multiplexer'a PMG podczas przerwania VBL
                 rts

; przygotowanie tablic pomocniczych dla multiplexer'a PMG
set_multiplexer_row
                 cpx #C64_Letter_P                              ; jeżeli typ sprite'a to litera lub np. punkty to nie uwzględniaj go
                 bcc set_multiplexer_row1
                 cpx #C64_Bird
                 beq set_multiplexer_row1
                 cpx #C64_New_Opponent
                 beq set_multiplexer_row1
                 rts

set_multiplexer_row1
                 sta sav1+1
                 :3 lsr @                                       ; /8
                 tax
                 tya
                 ora tab_multiplex_sprites,x
                 sta tab_multiplex_sprites,x
                 inc tab_multiplex_count+0,x
                 inc tab_multiplex_count+1,x
                 inc tab_multiplex_count+2,x

sav1             lda #$ff                                       ; jeżeli przesunięcie przeciw. nie jest podzielne przez 8 tzn. ze zajmuje 4 wiersze
                 and #$07
                 seq
                 inc tab_multiplex_count+3,x

                 rts
.endp

; zerowanie DLI multiplexer'a PMG
zero_multiplex_DLI
             ;    lda #{rts}                                   ; wyłącz działanie MULTIPLEXER'a PMG
             ;    .rept 25,#
             ;      sta pmg7_multiplex_row:1
             ;      sta pmg6_multiplex_row:1
             ;    .endr
                 .rept 25,#
                   mwa #ret_pmg7_row:1 ret_pmg7_row:1-2
                   mwa #ret_pmg6_row:1 ret_pmg6_row:1-2
                 .endr
                 rts


; inicjacja przerwań DLI w celu rozmnożenia PMG
; należy wykonać tą procedurę na przerwaniu VBL jeżeli "is_init_multiplex_VBL=1"
init_multiplex_VBL .proc
                 mva #$00  is_init_multiplex_VBL
                 jsr zero_multiplex_DLI                        ; wyłącz działanie MULTIPLEXER'a PMG

sav2             ldy #$00
                 bne *+3
                 rts

                 mva tab7_ret_l-0,y sav3+1                     ; oblicz adres w którym wierszu aktywować PMG #5 (+ ewentualnie PMG #6)
                 mva tab7_ret_h-0,y sav3+2

                 ldx #0
                 lda tab7_multiplex_l-0,y
                 jsr sav3
                 inx
                 lda tab7_multiplex_h-0,y
                 jsr sav3

sav4             ldy #$00
                 bne *+3
                 rts

                 mva tab6_ret_l-0,y sav5+1                     ; oblicz adres w którym wierszu aktywować PMG #5 (+ ewentualnie PMG #6)
                 mva tab6_ret_h-0,y sav5+2

                 ldx #0
                 lda tab6_multiplex_l-0,y
                 jsr sav5
                 inx
                 lda tab6_multiplex_h-0,y

sav5             sta $ffff,x                                   ; aktywuj PMG #6 (PMG #2)
                 rts

sav3             sta $ffff,x                                   ; aktywuj PMG #7 (PMG #3)
                 rts

.endp

; sprawdzamy czy już jest max. liczba sprite'ów w wierszu? (ograniczenie błędów multiplexer'a PMG)
test_max_sprites_in_row .proc
                 lda Number_Round_BIN
                 jeq_a #20,jmp1
                 jeq_a #40,jmp1
                 jeq_a #60,jmp1
                 jeq_a #80,jmp1

                 lda Number_Board
                 cmp #5
                 jeq skp

jmp1             stx reg_x

                 ldx Do_Number_SPRITE_1_7
                 lda test_max_sprites_in_row.allow,x
                 bne skp

; kod likwidujący błąd zawieszania się transformacji nowego przeciwnika
                 lda tab_Type_SPRITES_1_7,x
                 cmp #C64_New_Opponent
                 jeq skp

                 lda Do_Number_SPRITE_1_7                                ; 0-6 (sprite'y #1-#7)
                 asl @                                                   ; *2
                 tax
                 lda Sprite1_PosY,x                                      ; wsp.Y danego sprite'a
                 sub #CORR_Y
                 :3 lsr @                                                ; /8
                 tax

                 lda tab_multiplex_count+0,x
                 cmp #3                                                  ; set "C" flag (C=1 - 3th or more opponents per row)
                 bcs skp2
                 lda tab_multiplex_count+1,x                             ; konieczny test, żeby był odstęp min. 2-ch wierszy (dla uniknięcia śmieci multiplexer'a PMG)
                 cmp #3
                 bcs skp2
                 lda tab_multiplex_count+2,x                             ; konieczny test, żeby był odstęp min. 2-ch wierszy (dla uniknięcia śmieci multiplexer'a PMG)
                 cmp #3
                 bcs skp2
                 lda tab_multiplex_count+3,x                             ; konieczny test, żeby był odstęp min. 2-ch wierszy (dla uniknięcia śmieci multiplexer'a PMG)
                 cmp #3
                 bcs skp2
                 lda tab_multiplex_count+4,x                             ; usuwa błąd syfienia multiplexer'a PMG na 6-stej planszy
                 bne skp2

skp              ldx Do_Number_SPRITE_1_7
                 mva #$01 test_max_sprites_in_row.allow,x
                 ldx reg_x
                 clc
                 rts

skp2             ldx reg_x
                 sec
                 rts                                                              ; "C"=0 - max. 2nd opponents per row

reg_x .db $00
allow .db $00,$00,$00,$00,$00,$00,$00
.endp


; Procedura testująca czy w wierszu wyżej jest już trzech przeciwników (jeżeli tak to nie może tam się znaleźć kolejny przeciwnik!)
; wyjście: znacznik C=1 tzn., że już jest 3-ch przeciwników!
; UWAGA! nie wolno używać rej.Y!
test_max_3_opponents_per_row_up .proc
                 stx reg_x
                 ldx Do_Number_SPRITE_1_7
                 mva #$00 tab_too_many_sprites1_7_in_row,x

                 lda tab_Type_SPRITES_1_7,x
                 cmp #C64_Letter_P
                 beq skp0

                 lda Do_Number_SPRITE_1_7                                ; 0-6 (sprite'y #1-#7)
                 asl @                                                   ; *2
                 tax
                 lda Sprite1_PosY,x                                      ; wsp.Y danego sprite'a
                 sub #CORR_Y
                 :3 lsr @                                                ; /8
                 tax

                 jsr check_astronaut

                 dex
                 bmi skp0

                 lda tab_multiplex_count,x
                 cmp cnt_astro                                           ; set "C" flag (C=1 - 3th or more opponents per row)
                 bcs skp

                 dex
                 bmi skp0

                 lda tab_multiplex_count,x                             ; konieczny test, żeby był odstęp min. 2-ch wierszy (dla uniknięcia śmieci multiplexer'a PMG)
                 cmp cnt_astro
                 bcs skp

                 dex
                 bmi skp0

                 lda tab_multiplex_count,x                             ; konieczny test, żeby był odstęp min. 2-ch wierszy (dla uniknięcia śmieci multiplexer'a PMG)
                 cmp cnt_astro
                 bcs skp

skp0             ldx reg_x
                 clc
                 rts

skp              ldx Do_Number_SPRITE_1_7
                 mva #$01 tab_too_many_sprites1_7_in_row,x
                 ldx reg_x
                 sec
                 rts                                                     ; "C"=0 - max. 2nd opponents per row
reg_x .db $00
.endp

; Procedura testująca czy w wierszu niżej jest już trzech przeciwników (jeżeli tak to nie może tam się znaleźć kolejny przeciwnik!)
; wyjście: znacznik C=1 tzn., że już jest 3-ch przeciwników!
; UWAGA! nie wolno używać rej.Y!
tab_too_many_sprites1_7_in_row .db $00,$00,$00,$00,$00,$00,$00
test_max_3_opponents_per_row_dn .proc
                 stx reg_x
                 ldx Do_Number_SPRITE_1_7                                ; 0-6 (sprite'y #1-#7)
                 mva #$00 tab_too_many_sprites1_7_in_row,x

                 lda tab_Type_SPRITES_1_7,x
                 cmp #C64_Letter_P
                 bne skp1

                 ldx reg_x
                 clc
                 rts

skp1             lda Do_Number_SPRITE_1_7                                ; 0-6 (sprite'y #1-#7)
                 asl @                                                   ; *2
                 tax
                 lda Sprite1_PosY,x                                      ; wsp.Y danego sprite'a
                 add #(31-CORR_Y)                                        ; obl. ostatnią linię zajmowaną przez sprite'a (=0 więc można dać jako komentarz)
                 :3 lsr @                                                ; /8
                 tax
                 jsr check_astronaut
                 lda tab_multiplex_count+0,x
                 cmp cnt_astro                                           ; set "C" flag (C=1 - 3th opponents per row)
                 bcs skp
                 lda tab_multiplex_count+1,x                             ; konieczny test, żeby był odstęp min. 2-ch wierszy (dla uniknięcia śmieci multiplexer'a PMG)
                 cmp cnt_astro
                 bcs skp
                 lda tab_multiplex_count+2,x                             ; konieczny test, żeby był odstęp min. 2-ch wierszy (dla uniknięcia śmieci multiplexer'a PMG)
                 cmp cnt_astro
                 ldx reg_x
                 rts

skp              ldx Do_Number_SPRITE_1_7
                 mva #$02 tab_too_many_sprites1_7_in_row,x
                 ldx reg_x
                 rts
reg_x .db $00
.endp

; procedura sprawdza czy któryś z przeciwników jest astronautą (jeżeli tak tzn., że dozwolona liczba przeciwników w wierszu to tylko 2-ch(a nie trzech)
cnt_astro .db $00
check_astronaut .proc
                 stx reg_x

                 ldx Do_Number_SPRITE_1_7                                ; 0-6 (sprite'y #1-#7)
                 lda tab_Type_SPRITES_1_7,x
                 cmp #C64_Bird                                           ; dla ptaszka ograniczenie liczby przeciwników w wierszu jest mniejsze
                 sne
                 mva #$03 cnt_astro
                 bne skp2

                 ldx #$04

lop              lda tab_Type_SPRITES_1_7,x
                 jeq_a #$01,skp                                          ; Czy to astronauta?
                 dex
                 bpl lop
                 ldx reg_x
                 rts

skp              mva #$02 cnt_astro
skp2             ldx reg_x
                 rts
reg_x .db $00
.endp

;########################################################################################################################################################
; główna procedura obsługująca wszystkie ruchome obiekty na ekranie poza BOMB JACK-iem
;########################################################################################################################################################
Opponents_Mov    lda Is_Dead_BOMB_JACK                      ; Jeżeli trwa właśnie animacja śmierci 'bomb jacka' to nie obsługuj przeciwników
                 seq
                 rts

                 lda Smiling_Time
                 beq Opponents_Mov1
                 lda Time_Get_SmilingFace_Soon_Finish+1
                 bne Opponents_Mov1
                 lda Time_Get_SmilingFace_Soon_Finish
                 sne
                 jsr End_Animation_Smiling_Face_Sprite

Opponents_Mov1   jsr Do_Move_SPRITES_1_7
                 jsr do_multiplexer
                 jmp Convert_Sprites_C64_to_ATARI_opponent

;----------------------------------------------------------------------
Do_Move_SPRITES_1_7
                  ldy #$06                                            ; wykonaj pętle dla siedmiu SPRITE'ów ($06-$00)

Do_Move_loop0     sty Do_Number_SPRITE_1_7                            ; zapametaj rej.Y - aktualny numer SPRITE'a #1-#7
                  lda tab_Type_SPRITES_1_7,y                          ; pobierz typ SPRITE'a
                  bne Do_Move_skip1                                   ; <>0 to ten SPRITE jest aktualnie używany!

; jeżeli procedura tutaj przechodzi to oznacza, że dany SPRITE jest nieużywany aktualnie i należy go schować poza ekranem
Do_Move_loop2     ldy Do_Number_SPRITE_1_7                            ; odtwórz rej.Y - aktualny numer SPRITE'a #1-#7
                  tya
                  asl @
                  tax
                  lda tab_First_PosX_SPRITES_1_7,y                    ; tablica zawiera początkową wsp.X dla SPRITE'ów #1-#7 (wykorzystywana np: zaraz jak rozpoczyna się gra)
                  sta      Sprite1_PosX,x                             ; ustaw pozycje SPRITE #1-#7
                  mva #$00 Sprite1_PosY,x                             ; ustaw wsp.Y=0 SPRITE #1-#7 (czyli poza widzialnym ekranem)
                  ldx tab_sprite8,y
                  sta sprites[1].sts,x                                ; wyłącz danego sprite'a

Do_Move_skip3     ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  ldx tab_Type_SPRITES_1_7,y                          ; ustaw 3-ci kolor (PMG)

                  mva tab_col_opponent_PMG,x tab_choose_col_PMG+1,y

                  dey
                  jpl Do_Move_loop0
                  rts

Do_Move_skip1     sta save_typ_sprite
                  jeq_a #C64_Astronaut,Do_Animation_Astronaut_Sprite                                    ; C64_Astronaut           = $01
                  jeq_a #C64_Drill,Do_Animation_Drill_Sprite                                            ; C64_Drill               = $02
                  jeq_a #C64_Feeler_Ball,Do_Animation_Feeler_Square_DotBall_SmilingFace_LetterP_Sprite  ; C64_Feeler_Ball         = $03
                  jeq_a #C64_Square_Ball,Do_Animation_Feeler_Square_DotBall_SmilingFace_LetterP_Sprite  ; C64_Square_Ball         = $04
                  jeq_a #C64_Dot_Ball,Do_Animation_Feeler_Square_DotBall_SmilingFace_LetterP_Sprite     ; C64_Dot_Ball            = $05
                  jeq_a #C64_UFO,Do_Animation_UFO_Sprite                                                ; C64_UFO                 = $06
                  jeq_a #C64_Smiling_Face,Do_Animation_Feeler_Square_DotBall_SmilingFace_LetterP_Sprite ; C64_Smiling_Face        = $07
                  jeq_a #C64_Letter_P,Do_Animation_Feeler_Square_DotBall_SmilingFace_LetterP_Sprite     ; C64_Letter_P            = $08
                  jeq_a #C64_Letter_E,Do_Animation_Letter_E_B_Sprite                                    ; C64_Letter_E            = $09
                  jeq_a #C64_Letter_B,Do_Animation_Letter_E_B_Sprite                                    ; C64_Letter_B            = $0A (zwiększa liczbę punktów za bomby od 2 do 4 razy)
                  jeq_a #C64_Bird,Do_Animation_Bird_Sprite                                              ; C64_Bird                = $0B
                  jeq_a #C64_New_Opponent,Do_Animation_New_Opponent_Appear_Sprite                       ; C64_New_Opponent        = $0C
                  jeq_a #C64_Points,Do_Animation_Score_Sprite                                           ; C64_Points              = $0F (SPRITE w postaci punktów (100-600) - pokazują się po zebraniu np: LITERY B)
                  jeq_a #C64_Blink_Bomb,Do_Move_skip3                                                   ; C64_Blink_Bomb          = $10
                  jmp Do_Move_loop2

save_typ_sprite .db $00
;                   $00 ast dri fee squ dot ufo smi leP leE leB bir new $0D $0E poi bli
tab_first_clip  .db $60,$91,$71,$78,$60,$66,$A4,$81,$94,$7F,$7C,$86,$99,$60,$60,$60,$60    ; pierwsza klatka wyśw. zaraz po pojawianiu się przeciwnika

;########################################################################################################################################################
; procedura obsługująca pojawiające się punkty(SPRITE) na ekranie (1sek)
;########################################################################################################################################################
Do_Animation_Score_Sprite
                  ldx Do_Number_SPRITE_1_7                                               ; pobierz jaki należy obsłużyć SPRITE #1-#7
                  adb tab_Points_100_600_SPRITES_1_7,x #$C0 tab_Addr_Sprite1_7_Pattern,x

                  inc tab_Delay_Points_100_600_SPRITES_1_7,x                             ; licznik zliczający opóżnienie +1
                  lda tab_Delay_Points_100_600_SPRITES_1_7,x
                  cmp #50                                                                ; czy opóżnienie = 50?
                  jne Do_Move_skip3                                                      ; NIE!

                  mva #$00 tab_Delay_Points_100_600_SPRITES_1_7,x                        ; zeruj licznik zliczający opóźnienie
                  sta      tab_Type_SPRITES_1_7,x                                        ; =0 wyczyść typ SPRITE'a, który zderzył się z BOMB JACK-iem
                  ldy      tab_sprite8,x
                  sta      sprites[1].sts,y                                              ; wyzeruj znacznik widoczności danego sprite'a
                  mva #$ff tab_choose_sprite+1,x                                         ; =$ff oznacza, że nie wolno użyć już tutaj żadnego wypełnienia PMG
                  jmp Do_Move_skip3                                                      ; powrót do głównej pętli skąd wywołano tą procedure

tab_sprite8 :8 .by @sprite*#

;########################################################################################################################################################
; procedura odpowiada za animacje SPRITE'a "ASTRONAUTY"
;########################################################################################################################################################
Do_Animation_Astronaut_Sprite
                  ldy Do_Number_SPRITE_1_7                           ; pobierz numer aktualnego SPRITE'a #1-#7 (0-6)
                  lda tab_Is_Sprite1_7_on_Screen,y                   ; Czy SPRITE już narysowany na ekranie?
                  bne Anim_Astro_skip1                               ; TAK!

; jeszcze nienarysowany więc najpierw musi być animacja jego pojawienia się na ekranie
                  mva #$0C tab_Type_SPRITES_1_7,y                    ; wstaw "12" jako typ SPRITE'a - pojawienie się nowego przeciwnika
                  mva #$97 tab_Addr_Sprite1_7_Pattern,y              ; ustaw kształt pierwszej klatki pojawiającego się nowego przeciwnika
                  mva #$01 tab_Is_Sprite1_7_on_Screen,y
                  sta      tab_Show_Type_Sprite1_7_After_Animation_Appearing,y  ; typ "ASTRONAUTA" - zapamiętaj
                  jmp Do_Move_skip3                                  ; powrót do głównej pętli animującej SPRITE #1-#7

Anim_Astro_skip1  lda Number_Round_BCD                               ; pobierz numer rundy w kodzie BCD???
                  cmp #$0B                                           ; Czy numer rundy>=11? (tak naprawdę to sprawdzamy czy nr_rundy>=$09)
                  bcs Anim_Astro_skip2                               ; TAK! (od rundy 10 "ASTRONAUCI" poruszają się 2x szybciej)

                  lda tab_Every_Second_Frame_Atronaut_Sprite,y       ; Czy to pierwsza ramka?
                  eor #$01                                           ; zamiana 1<->0
                  sta tab_Every_Second_Frame_Atronaut_Sprite,y
                  jne Do_Move_skip3

Anim_Astro_skip2  sty Store_Do_Number_SPRITE_1_7                     ; zapamiętaj numer SPRITE'a #1-#7, który aktualnie obrabiamy
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; obsługa ruchu i badania z czym "ASTRONAUTA" zetknął się na planszy
; uwaga! są tutaj reguły, które powodują, że "ASTRONAUTA" zachowuje się w pewien ściśle określony sposób
Anim_Astro_skip3  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25  ; oblicz adres gdzie znajduje się aktualnie dany SPRITE  ...
                  get_byte_from_address #0                           ;                                                        ...
                  jeq_a #$01,Anim_Astro_skip9                        ;                                                        .x.

                  ldy Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y ; Czy "ASTRONAUTA" stoi w miejscu?
                  jeq Astronaut_Stand                                ; TAK!

                  cmp #$01                                           ; Czy przesuwa się w prawo?
                  bne Anim_Astro_skip6                               ; NIE!

; teraz badamy co znajduje się pod nogami "ASTRONAUTY" z lewej strony (a przesuwa się on w prawo)
                  jsr address1_SBW_1byte                             ; poprzednia kolumna  ...
                  get_byte_from_address #0                           ;                     ...
                  jeq_a #$01,Anim_Astro_skip5                        ;                     x..

; natrafiono na jakieś tło planszy
Anim_Astro_skip4  jsr Astronaut_Reach_Left_or_Right_Edge_FootBridge
                  mva #$02 Opposite_Direction_Move_New_Apper_Astronaut_than_Old_Astronaut ; Nowy "ASTRONAUTA", który się pojawi ma przesuwać się w lewo
                  lda Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                              ; *2
                  tay
                  adb Sprite1_PosX,y #$08 Store_Sprite1_PosX         ; dodaj +8 do wsp.X - z prawej strony pojawi się nowy przeciwnik - "ASTRONAUTA"

; miejsce gdzie inicjujemy pojawienie się nowego przeciwnika - "ASTRONAUTY" (stary "ASTRONAUTA" ma zlecieć w dół)
Anim_Astro_loop1  ldy Do_Number_SPRITE_1_7                           ; numer SPRITE'a
                  mva #$01 tab_jump_down_sprite1_7,y
                  mva #$00 tab_Add_One_if_Astronaut_Reach_Left_or_Right_Edge_FootBridge_Sprites1_7,y
                  sta      tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y
                  jsr Show_New_Astronaut
                  lda Is_New_Astronaut_Appear                        ; Czy nowy przeciwnik "ASTRONAUTA" się pojawił? (bo np: jak już jest max. liczba przeciwników na ekranie to nie pokaże się)
                  jne Anim_Astro_skip9                               ; TAK!

; NIE pojawił się nowy przeciwnik "ASTRONAUTA"
                  jsr Restore_Do_Number_SPRITE_1_7
                  jmp Do_Move_skip3                                  ; powrót do głównej pętli obsł. SPRITE'ów #1-#7

; natrafiono na murek lub kładkę z lewej strony pod nogami "ASTRONAUTY"
Anim_Astro_skip5  jsr Astronaut_Reach_Left_or_Right_Edge_FootBridge  ; "ASTRONAUTA" osiągnął PRAWY brzeg "kładki" (bo z lewej jest "kładka" a pośrodku nie ma kładki)
                  jsr test_astro_jump                                ; Czy droga w dół jest wolna?
                  bcs skip_astro0                                    ; NIE!

                  lda tab_Add_One_if_Astronaut_Reach_Left_or_Right_Edge_FootBridge_Sprites1_7,y
                  cmp #$02                                           ; Czy 4-ry razy lub więcej "ASTRONAUTA" osiągnął lewą lub prawą krawędź "kładki"? (czyli w sumie 2x przeszedł z lewej do prawej strony "kładki")
                  jcs Anim_Astro_skip7                               ; TAK!

skip_astro0       ldy Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$02 tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y ; =2 "ASTRONAUTA" przesuwa się w lewo
                  jmp Anim_Astro_skip9

; teraz badamy co znajduje się pod nogami "ASTRONAUTY" z prawej strony (a przesuwa się on w lewo)      ...
Anim_Astro_skip6  jsr address1_ADW_1byte                             ; następna kolumna                ...
                  get_byte_from_address #0                           ;                                 ..x
                  jeq_a #$01,Anim_Astro_skip8                        ; Czy "kod akcji" = $01? czyli natrafiono na murek lub kładke? z prawej strony pod nogami "ASTRONAUTY"

; test czy przeciwnik ma wolną drogę spadając w dół? (jeżeli nie to musi czekać aż będzie ona wolna tzn. PMG #2 i #3 nie będą występować razem w wierszu)
Anim_Astro_skip7  jsr Astronaut_Reach_Left_or_Right_Edge_FootBridge
                  mva #$01 Opposite_Direction_Move_New_Apper_Astronaut_than_Old_Astronaut ; Nowy "ASTRONAUTA", który się pojawi ma przesuwać się w prawo
                  lda Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  sbb Sprite1_PosX,y #$08 Store_Sprite1_PosX         ; odejmij -8 od wsp.X - w tym miejscu pojawi się nowy przeciwnik!
                  jmp Anim_Astro_loop1                               ; skocz do miejsca gdzie inicjujemy pojawienie się nowego przeciwnika "ASTRONAUTY"

; natrafiono na murek lub kładkę
Anim_Astro_skip8  jsr Astronaut_Reach_Left_or_Right_Edge_FootBridge  ; "ASTRONAUTA" osiągnął LEWY brzeg "kładki" (bo z lewej jest "kładka" a pośrodku nie ma kładki)
                  jsr test_astro_jump                                ; Czy droga w dół jest wolna?
                  bcs skip_astro1                                    ; NIE!

                  lda tab_Add_One_if_Astronaut_Reach_Left_or_Right_Edge_FootBridge_Sprites1_7,y
                  cmp #$02                                           ; Czy 4-ry razy lub więcej "ASTRONAUTA" osiągnął lewą lub prawą krawędź "kładki"? (czyli w sumie 2x przeszedł z lewej do prawej strony "kładki")
                  jcs Anim_Astro_skip4                               ; TAK!

skip_astro1       ldy Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$01 tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y ; =1 "ASTRONAUTA" przesuwa się w prawo
                  jmp Anim_Astro_skip9

; procedurka testująca czy przeciwnik ma wolną drogę spadając w dół? (jeżeli nie to musi czekać aż będzie ona wolna tzn. PMG #2 i #3 nie będą występować razem w wierszu)
; konieczne jest również spełnienie warunku, że aktualnie żaden przeciwnik "ASTRONAUTA" nie spada w dół!
; jeżeli znacznik C=0 tzn., że może astronauta lecieć w dół!
; UWAGA! nie wolno wykorzystywać w tej procedure rej.Y bo zawiera on nr. aktualnego sprite'a * 2
test_astro_jump .proc
                  ldx #4

loop0             lda tab_Type_SPRITES_1_7,x
                  cmp #$01                             ; Czy to ASTRONAUTA?
                  bne skip1                            ; NIE!

                  lda tab_jump_down_sprite1_7,x
                  bne exit2
                  lda tab_Addr_Sprite1_7_Pattern,x
                  cmp #$91                             ; Czy ASTRONAUTA jest odwrócony prosto do nas? (czyli spada na dół?)
                  beq exit2                            ; TAK!

skip1             dex
                  bpl loop0

; testowanie kolejnego warunku
                  tya
                  asl @
                  tax
                  lda Sprite1_PosY,x                   ; pobranie aktualnej współrzędnej obsługiwanego przeciwnika
                  sub #CORR_Y
                  :3 lsr @
                  add #4                               ; uproszczenie (bo czasami mogłoby być tutaj +3)
                  tax

loop1             lda tab_multiplex_count,x
                  cmp #3                               ; max. 2-ch przeciwników może być w wierszu!
                  bcs exit1                            ; niestety droga nie jest wolna!

                  inx
                  cpx #26
                  bne loop1

                  clc                                  ; droga wolna!

exit1             rts

exit2             sec
                  rts
 .endp

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; "ASTRONAUTA" natrafił na murek lub kładkę i tutaj obsługujemy to zdarzenie
Anim_Astro_skip9  ldx index_tab_Addr_SPRITE_ScreenBuff40x25              ; pobierz, w którym wierszu jest aktualnie obrabiany SPRITE #1-#7 - wskaźnik na tablice z adresami+wsp.Y, po 3-bajty dla każdego wiersza
                  lda tab_Addr_SPRITE_ScreenBuff40x25+2,x                ; pobierz wsp.Y dla wiersza o numerze zapisanym w rej.X
                  tax
                  :2 inx                                                 ; +2
                  lda Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                                  ; *2
                  tay
                  txa
                  sta Sprite1_PosY,y                                     ; zapisz do wsp.Y SPRITE'a (powiększoną o +2)
                  ldy Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$00 tab_Anim_Speed_Jump_Down,y                    ; inicjacja wartości jaką będziemy dodawać do wsp.Y "ASTRONAUTY"...
                  mva #$07 tab_7x_Add_Speed_Jump_Down_to_PosY,y          ; ...i inicjacja licznika ile razy dodamy tą wartość
                  mva #$00 tab_jump_down_sprite1_7,y

                  lda tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y     ; Czy "ASTRONAUTA" wykonuje ruch w lewo lub prawo?
                  bne Anim_Astro_skipA                                   ; TAK!

; aktualnie "ASTRONAUTA" się nie rusza tylko stoi w miejscu
                  tya
                  asl @
                  tay
                  lda Sprite1_PosY,y                                     ; pobierz wsp.Y SPRITE'a
                  cmp #MAX_POSY_SPRITE                                   ; >=218 (czyli spr. czy "ASTRONAUTA" dotarł już do samego dołu planszy?)
                  jcs Astronaut_Transform_More_Dangerous_Opponent        ; przekształcenie "ASTRONAUTY" w groźniejszego przeciwnika!

; "ASTRONAUTA" nie dotarł jeszcze do samego dołu planszy
                  ldy Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$01 tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y ; =1 "ASTRONAUTA" przemieszcza się w prawo
                  jsr Restore_Do_Number_SPRITE_1_7
                  jmp Do_Move_skip3                                       ; powrót do pętli głównej

; aktualnie "ASTRONAUTA" przesuwa się albo w lewo albo w prawo
Anim_Astro_skipA  cmp #$01                                               ; Czy "ASTRONAUTA" przesuwa się w prawo?
                  jne Anim_Astro_skipF                                   ; TAK!

; aktualnie "ASTRONAUTA" przesuwa się w prawo
                  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25      ; oblicz w address1, nad którym bajtem w ScreenBuff40x25 znajduje się SPRITE #1-#7
                  jsr address1_SBW_40bytes                               ; wcześniejszy wiersz         ..X
                  jsr address1_SBW_40bytes                               ; wcześniejszy wiersz         ...
                  jsr address1_ADW_1byte                                 ; następna kolumna            ...
                  get_byte_from_address #0
                  cmp #$01                                               ; Czy "kod akcji" = $01? czyli natrafiono na murek lub kładke
                  bne Anim_Astro_skipB                                   ; NIE!

; natrafiono na murek lub kładkę więc nie można wykonać ruchu "ASTRONAUTY"
                  ldy Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$02 tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y ; =2 "ASTRONAUTA" przesuwa się w lewo
                  jsr Restore_Do_Number_SPRITE_1_7                        ; odtworzenie zapamiętanej wcześniej zmiennej "Do_Number_SPRITE_1_7"
                  jmp Do_Move_skip3                                       ; powrót do pętli głównej

; natrafiono na jakieś tło planszy więc można wykonać ruch "ASTRONAUTY" w prawo
Anim_Astro_skipB  lda Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  adb Sprite1_PosX,y #$01*SPEED_SPRITE                   ; dodaj do wsp.X obrabianego SPRITE'a #1-#7 +1 - na przerwaniu VBL zostanie narysowany na nowej pozycji X
                  cmp #MAX_POSX_SPRITE-WIDTH_SPRITE
                  bcc astro_skp1

                  ldx Do_Number_SPRITE_1_7
                  mva #$02 tab_Is_Astronaut_Move_Left_or_Right_or_Stand,x ; =2 "ASTRONAUTA" przesuwa się w lewo
                  mva #MAX_POSX_SPRITE-WIDTH_SPRITE Sprite1_PosX,y
             ;     jsr Astronaut_Reach_Left_or_Right_Edge_FootBridge

astro_skp1        jsr Astronaut_Change_PosX                              ; ust. znacznik, że zmieniła się wsp.X "ASTRONAUTY"
                  ldy Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Every_Fourth_Frame_Astronaut_Sprite,y
                  cmp #$04                                               ; Czy już 4-ta ramka od ost. narysowania "ASTRONAUTY"?
                  beq Anim_Astro_skipC                                   ; TAK!

                  adb tab_Every_Fourth_Frame_Astronaut_Sprite,y #$01     ; +1 do licznika zliczającego ramki do 4-rech
                  jsr Restore_Do_Number_SPRITE_1_7                       ; odtworzenie zmiennej "Do_Number_SPRITE_1_7"
                  jmp Do_Move_skip3                                      ; powrót do pętli głownej

; to jest 4-ta ramka więc należy narysować "ASTRONAUTE" (wypełnić jego wzór nową definicją)
Anim_Astro_skipC  mva #$00 tab_Every_Fourth_Frame_Astronaut_Sprite,y

Anim_Astro_loop2  lda index_tab_4th_clips_Move_Opponent_Astronaut_Left_or_Right,y  ; pobierz wskaźnik na kolejną klatkę
                  tax
                  lda tab_4th_clips_Move_Opponent_Astronaut_Right,x      ; pobierz kolejną z 4-rech klatek animujących ruch "ASTRONAUTY" w prawo
                  beq Anim_Astro_skipE                                   ; =0 oznacza, że wyświetlono już wszystkie klatki z tej tablicy

                  sta tab_Addr_Sprite1_7_Pattern,y                          ; zapisz wskażnik(*64+$4000), który służy do obl. adresu z danymi wzoru SPRITE'a #1-#7

                  adb index_tab_4th_clips_Move_Opponent_Astronaut_Left_or_Right,y #$01 ; +1 aktualizuj wskaźnik wskazujący na kolejną klatkę z tablicy
                  jsr Restore_Do_Number_SPRITE_1_7                       ; odtwórz zapamiętaną zmienną "Do_Number_SPRITE_1_7"
                  jmp Do_Move_skip3                                      ; powrót do pętli głównej

Anim_Astro_skipE  mva #$00 index_tab_4th_clips_Move_Opponent_Astronaut_Left_or_Right,y  ; ustaw wskaźnik na początek tablicy z klatkami animacyjnymi dla "ASTRONAUTY"
                  jmp Anim_Astro_loop2
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; aktualnie "ASTRONAUTA" przesuwa się w lewo
Anim_Astro_skipF  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25      ; oblicz w address1, nad którym bajtem w ScreenBuff40x25 znajduje się SPRITE #1-#7
                  jsr address1_SBW_40bytes                               ; wcześniejszy wiersz  X..
                  jsr address1_SBW_40bytes                               ; wcześniejszy wiersz  ...
                  jsr address1_SBW_1byte                                 ; poprzednia kolumna   ...
                  get_byte_from_address #0
                  cmp #$01
                  bne Anim_Astro_skipG

                  ldy Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$01 tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y ; =1 "ASTRONAUTA" przesuwa się w prawo
                  jsr Restore_Do_Number_SPRITE_1_7                        ; odtworzenie zapamiętanej wcześniej zmiennej "Do_Number_SPRITE_1_7"
                  jmp Do_Move_skip3                                       ; powrót do pętli głównej

; natrafiono na jakieś tło planszy więc można przesunąć "ASTRONAUTE" w lewo
Anim_Astro_skipG  lda Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  sbb Sprite1_PosX,y #$01*SPEED_SPRITE                   ; odejmij od wsp.X obrabianego SPRITE'a #1-#7 -1
                  cmp #MIN_POSX_SPRITE+4
                  bcs astro_skp2

                  ldx Do_Number_SPRITE_1_7
                  mva #$01 tab_Is_Astronaut_Move_Left_or_Right_or_Stand,x ; =1 "ASTRONAUTA" przesuwa się w prawo
                  mva #MIN_POSX_SPRITE+2 Sprite1_PosX,y
 ;                 jsr Astronaut_Reach_Left_or_Right_Edge_FootBridge

astro_skp2        jsr Astronaut_Change_PosX                              ; ust. znacznik, że zmieniła się wsp.X "ASTRONAUTY"
                  ldy Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Every_Fourth_Frame_Astronaut_Sprite,y
                  cmp #$04
                  beq Anim_Astro_skipH

                  adb tab_Every_Fourth_Frame_Astronaut_Sprite,y #$01     ; +1 do licznika zliczającego ramki do 4-rech
                  jsr Restore_Do_Number_SPRITE_1_7                       ; odtworzenie zmiennej "Do_Number_SPRITE_1_7"
                  jmp Do_Move_skip3                                      ; powrót do pętli głownej

Anim_Astro_skipH  mva #$00 tab_Every_Fourth_Frame_Astronaut_Sprite,y

Anim_Astro_skipI  lda index_tab_4th_clips_Move_Opponent_Astronaut_Left_or_Right,y ; pobierz wskaźnik na kolejną klatkę
                  tax
                  lda tab_4th_clips_Move_Opponent_Astronaut_Left,x       ; pobierz kolejną klatkę animacyjną ruchu przeciwnika "ASTRONAUTY" w lewo
                  beq Anim_Astro_skipJ                                   ; =0 - oznacza, że już wyświetlono wszystkie 4-ry klatki

                  sta tab_Addr_Sprite1_7_Pattern,y                          ; zapisz wskażnik(*64+$4000), który służy do obl. adresu z danymi wzoru SPRITE'a #1-#7
                  adb index_tab_4th_clips_Move_Opponent_Astronaut_Left_or_Right,y #$01 ; +1 aktualizuj wskaźnik na kolejną klatkę "ASTRONAUTY" w lewo
                  jsr Restore_Do_Number_SPRITE_1_7                       ; odtwórz zapamiętaną wcześniej zmienną "Do_Number_SPRITE_1_7"
                  jmp Do_Move_skip3                                      ; powrót do głównej pętli

Anim_Astro_skipJ  mva #$00 index_tab_4th_clips_Move_Opponent_Astronaut_Left_or_Right,y ; więc zapisz, że klatki ruchu "ASTRONAUTY" w lewo mają być pobierane od początku
                  jmp Anim_Astro_skipI
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; "ASTRONAUTA" aktualnie stoi w miejscu
Astronaut_Stand   ldy Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$91 tab_Addr_Sprite1_7_Pattern,y                  ; zapisz wskażnik(*64+$4000), który służy do obl. adresu z danymi wzoru SPRITE'a #1-#7 - $91 - to klatka przeciwnika "ASTRONAUTY", który patrzy prosto na nas
                  jsr Anim_Astronaut_Jump_Down                           ; Animuj "ASTRONAUTE" spadającego w dół
                  jsr Restore_Do_Number_SPRITE_1_7                       ; odtwórz zmienną "Do_Number_SPRITE_1_7"
                  jmp Do_Move_skip3                                      ; powrót do głównej pętli
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; "ASTRONAUTA" dotarł do samego dołu i teraz przemienia się w groźniejszego przeciwnika!
;dupa dta $00
Astronaut_Transform_More_Dangerous_Opponent
              ;    lda choose_PMG \ eor #1 \ sta choose_PMG
              ;    jsr clr_pmg_clip                                        ; skasuj kształt PMG w niewidocznym buforze
              ;    lda choose_PMG \ eor #1 \ sta choose_PMG
              ;    jsr clr_pmg_clip                                        ; skasuj kształt PMG w niewidocznym buforze

                  ldy Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
               ;   mva #C64_Clear_PMG tab_Type_SPRITES_1_7,y
                  mva #$97              tab_Addr_Sprite1_7_Pattern,y
                  mva #C64_New_Opponent tab_Type_SPRITES_1_7,y
      ;            mva #$00              tab_jump_down_sprite1_7,y

   ;    inc dupa

             ;     ldx tab_sprite8,y
              ;    mva #$00 sprites[1].sts,x

                  ldy index_tab_More_Dangerous_Opponent_for_Next_Astronauts_Transform
                  lda tab_More_Dangerous_Opponent_for_Next_Astronauts_Transform,y
                  ldy Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  sta tab_Show_Type_Sprite1_7_After_Animation_Appearing,y ; jaki typ SPRITE'a ma się pojawić zaraz po animacji, że za chwilę coś się pojawi
                  jsr Restore_Do_Number_SPRITE_1_7                        ; odtwórz zmienną "Do_Number_SPRITE_1_7"

                  lda index_tab_More_Dangerous_Opponent_for_Next_Astronauts_Transform
                  cmp #MAX_TRANSFORM-1
                  scs
                  inc index_tab_More_Dangerous_Opponent_for_Next_Astronauts_Transform

                  tya
                  asl @
                  tay
                  mva #MAX_POSY_SPRITE Sprite1_PosY,y
                  jmp Do_Move_skip3                                       ; powrót do pętli głównej
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura dodaje +1 do tablicy jeżeli "ASTRONAUTA" osiągnął lewy lub prawy brzeg "kładki" (te po których może skakać BOMB JACK)
Astronaut_Reach_Left_or_Right_Edge_FootBridge
                  ldy Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  adb tab_Add_One_if_Astronaut_Reach_Left_or_Right_Edge_FootBridge_Sprites1_7,y #$01
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura ustawia znacznik w tablicy jeżeli "ASTRONAUTA" zmienił swoją wsp. X o +1 lub -1
Astronaut_Change_PosX
                  ldy Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$01 tab_Is_Astronaut_Change_PosX,y
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura sprawdza czy może się pojawić nowy przeciwnik "ASTRONAUTA" na ekranie? (jeżeli TAK to dodaje go)
Show_New_Astronaut
                  ldy Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Is_Astronaut_Change_PosX,y                     ; =0? Czy "ASTRONAUTA" nie wykonał żadnego ruchu zmieniającego wsp. X?(-1 lub +1)
                  jeq Anim_Astro_skipP                                   ; TAK!

; "ASTRONAUTA" wykonał ruchu zmieniający wsp.X (+1 lub -1)
                  lda Do_Number_SPRITE_1_7                               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                                  ; *2
                  tay
                  mva Sprite1_PosY,y Store_Sprite1_PosY                  ; zapamiętaj wsp.Y SPRITE'a #1-#7

                  ldy #$06                                               ; SPRITES #1-#7 (UWAGA! powinna być wart. #$06 bo pod $07 jest już wsp. Sprite1_X)

Anim_Astro_loop3  lda tab_Type_SPRITES_1_7,y                             ; UWAGA! tutaj tak naprawdę pobieramy Sprite1_PosX (bo rej. Y=7!!!, a ta tablica ma tylko elementy od 0 do 6)
                  cmp #$0E                                               ; Czy typ = 14? Czyli wolne miejsce, w którym może się pojawić kolejny przeciwnik na planszy
                  beq Anim_Astro_skipQ                                   ; TAK!

                  dey                                                    ; rey.Y -1
                  bpl Anim_Astro_loop3

; <>$0E - brak wolnych miejsc na pojawienie się nowego przeciwnika na ekranie!
Anim_Astro_skipP  mva #$00 Is_New_Astronaut_Appear
                  rts

; pojawianie się nowego przeciwnika "ASTRONAUTY" na ekranie
Anim_Astro_skipQ  mva #$00 tab_Add_One_if_Astronaut_Reach_Left_or_Right_Edge_FootBridge_Sprites1_7,y

                  mva #$97 tab_Addr_Sprite1_7_Pattern,y                      ; ustaw kształt pierwszej klatki pojawiającego się nowego przeciwnika
                  mva #$01 Is_New_Astronaut_Appear
                  sty Do_Number_SPRITE_1_7                               ; zapisz numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  sta tab_Type_SPRITES_1_7,y                             ; wstaw "1" jako typ SPRITE'a - "ASTRONAUTA"
                  mva Opposite_Direction_Move_New_Apper_Astronaut_than_Old_Astronaut tab_Is_Astronaut_Move_Left_or_Right_or_Stand,y
                  tya
                  asl @                                                  ; *2
                  tay
                  mva Store_Sprite1_PosX Sprite1_PosX,y                  ; odtwórz zapamiętaną wsp.X SPRITE'a #1-#7
                  mva Store_Sprite1_PosY Sprite1_PosY,y                  ; odtwórz zapamiętaną wsp.Y SPRITE'a #1-#7

                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura odtwarza zapamiętaną wcześniej zmienną Do_Number_SPRITE_1_7
Restore_Do_Number_SPRITE_1_7
                  mva Store_Do_Number_SPRITE_1_7 Do_Number_SPRITE_1_7    ; odtwórz zapamiętany wcześniej numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  rts

;########################################################################################################################################################
; procka obsługująca zachowanie przeciwników "ŚWIDERKA", "KULI Z KROPKAMI", "KULI Z KWADRATOWYMI OKNAMI", "UFO"
;########################################################################################################################################################
Service_Behavior_Drill_DotBall_SquareBall_UFO
                  ldy Do_Number_SPRITE_1_7                           ; pobierz numer aktualnego SPRITE'a #1-#7 (0-6)
                  ldx tab_Is_Sprite1_7_on_Screen,y                   ; Czy SPRITE już narysowany na ekranie?
                  bne Anim_skp1                                      ; TAK!

; jeszcze nienarysowany więc najpierw musi być animacja jego pojawienia się na ekranie
                  mva save_typ_sprite tab_Show_Type_Sprite1_7_After_Animation_Appearing,y  ; typ "ASTRONAUTA" - zapamiętaj
                  mva #$0C tab_Type_SPRITES_1_7,y                    ; wstaw "12" jako typ SPRITE'a - pojawienie się nowego przeciwnika
                  mva #$97 tab_Addr_Sprite1_7_Pattern,y              ; ustaw kształt pierwszej klatki pojawiającego się nowego przeciwnika
                  mva #$01 tab_Is_Sprite1_7_on_Screen,y
                  jmp Do_Move_skip3                                  ; powrót do głównej pętli animującej SPRITE #1-#7

Anim_skp1         ldx Do_Number_SPRITE_1_7                                ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Type_SPRITES_1_7,x
                  cmp #$02                                                ; Czy "ŚWIDEREK"?
                  beq Beh_Drill_skip1                                     ; TAK!

                  cmp #$06                                                ; Czy "UFO"?
                  bne Beh_Drill_skip3                                     ; NIE!
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; obsługa zachowania "ŚWIDERKA" i "UFO"
Beh_Drill_skip1   lda Number_Round_BCD                                    ; Czy numer "RUNDY">=11?
                  cmp #$11
                  bcs Beh_Drill_skip3                                     ; TAK! więc animacja "ŚWIDERKA" i "UFO" co 1 ramkę (czyli 2x szybciej niż normalnie)

; numer "RUNDY"<11
                  lda tab_Every_Second_Frame_Drill_UFO_Sprite,x           ; dzięki temu warunkowi rysujemy co 2-ga ramkę
                  beq Beh_Drill_skip2

                  eor #$01
                  sta tab_Every_Second_Frame_Drill_UFO_Sprite,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO

Beh_Drill_skip2   eor #$01
                  sta tab_Every_Second_Frame_Drill_UFO_Sprite,y
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; obsługa zachowania "ŚWIDERKA", "UFO", "KULI Z KROPKAMI" i "KULI Z KWADRATOWYMI OKNAMI"
Beh_Drill_skip3   lda tab_Move_Left_or_Right_Sprite_1_7,x                 ; czy aktualnie SPRITE przesuwa się w prawo?
                  jne Beh_Drill_skipB                                     ; TAK!

; SPRITE aktualnie przesuwa się w lewo - testuj sposobem #1 (są dwa sposoby bo dzięki temu jak SPRITE napotka przeszkodę z lewej strony to ją omija)
                  lda Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x
                  cmp #$08                                                ; czy testować co jest z lewej strony SPRITE'a?
                  jeq Beh_Drill_skip7                                     ; TAK!

                  lda Is_Sprite1_7_Block_During_Move_Left,x               ; czy podczas ruchu w lewo SPRITE został przyblokowany przez "kładkę" lub "murek"?
                  beq Beh_Drill_skip4                                     ; NIE!

                  dec Is_Sprite1_7_Block_During_Move_Left,x               ; TAK! więc wykonaj ruch w górę lub w dół, żeby ominąć blokadę
                  jmp Beh_Move_Up_or_Down                                 ; skocz do części sprawdzającej dla ruchu SPRITE'a w górę lub w dół

; sprawdź jaki bajt znajduje się przy SPRITE'cie z prawej strony i jeżeli to jest jakieś tło to dodaj do wsp.X SPRITE'a +2
Beh_Drill_skip4   inc Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x
                  mva Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x Is_Sprite1_7_Block_During_Move_Left,x

                  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25
                  ldx Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy     ...X
                  jsr address1_ADW_1byte                             ; następna kolumna                                    ...
                  jsr address1_ADW_1byte                             ; następna kolumna                                    ...
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code         ; pobierz "kod akcji"
                  cmp #$01                                           ; Czy kod akcji to kod "murka" lub "kładki"?
                  bne Beh_Drill_skip6                                ; NIE!

; TAK! natrafiono na "murek" lub "kładkę"
Beh_Drill_skip5   mva #$08 Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x ; dzięki temu wyk. proc. spr. co jest z lewej strony
                  jmp Beh_Move_Up_or_Down                                          ; skocz do części sprawdzającej dla ruchu SPRITE'a w górę lub w dół

; NIE! natrafiono na jakieś tło planszy
Beh_Drill_skip6   ldy #$20                                           ; 32 - wiersz niżej                                   ...
                  jsr Get_Byte_address1_and_Find_Action_Code         ;                                                     ...X
                  cmp #$01                                           ; czy "murek" lub "kładka"?                           ...
                  jeq Beh_Drill_skip5                                ; TAK!

; NIE! natrafiono na jakieś tło planszy - cofamy SPRITE'a w prawo o +2 - dzięki temu omija on przeszkodę ("murek" lub "kładka")
                  jsr CoordinateX_add_One_Sprite1_7                  ; +1 wsp.X SPRITE'a
                  jsr CoordinateX_add_One_Sprite1_7                  ; +1 wsp.X SPRITE'a
                  mva #$08 Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x                                    ; dzięki temu wyk. proc. spr. co jest z lewej strony
                  jmp Beh_Move_Up_or_Down                            ; skocz do części sprawdzającej dla ruchu SPRITE'a w górę lub w dół

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; SPRITE aktualnie przesuwa się w lewo - testuj sposobem #2 (są dwa sposoby bo dzięki temu jak SPRITE napotka przeszkodę z lewej strony to ją omija)
Beh_Drill_skip7   lda Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x
                  beq Beh_Drill_skip8a

                  lda Is_2x_Block_Right_Side_Sprite1_7,x
                  beq Beh_Drill_skip8

                  dec Is_2x_Block_Right_Side_Sprite1_7,x
                  jmp Beh_Move_Up_or_Down                            ; skocz do części sprawdzającej dla ruchu SPRITE'a w górę lub w dół

Beh_Drill_skip8   dec Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x
                  mva Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x Is_2x_Block_Right_Side_Sprite1_7,x

; sprawdź jaki bajt znajduje się przy SPRITE'cie z lewej strony
Beh_Drill_skip8a  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz                                      X...
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz                                       ...
                  jsr address1_SBW_1byte                             ; poprzednia kolumna                                        ...
                  jsr address1_SBW_1byte                             ; poprzednia kolumna
                  ldx Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code
                  cmp #$01                                           ; czy "murek" lub "kładka"?
                  bne Beh_Drill_skipA                                ; NIE!

; TAK! natrafiono na "murek" lub "kładkę"
Beh_Drill_skip9   mva #$00 Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x    ; dzięki temu zostanie wyk. proc. spr. co jest z prawej strony
                  jmp Beh_Move_Up_or_Down                            ; skocz do części sprawdzającej dla ruchu SPRITE'a w górę lub w dół

; NIE! nie natrafiono na "murek" lub "kładkę"
Beh_Drill_skipA   ldy #$28                                           ; 40 -wiersz niżej                                          ...
                  jsr Get_Byte_address1_and_Find_Action_Code         ;                                                          X...
                  cmp #$01                                           ; czy "murek" lub "kładka"?                                 ...
                  jeq Beh_Drill_skip9                                ; TAK!

; przesunięcie SPRITE'a w lewo o -1
                  jsr CoordinateX_sub_One_Sprite1_7                  ; odejmij od wsp.X SPRITE'a -1
                  jmp Beh_Move_Up_or_Down                            ; skocz do części sprawdzającej dla ruchu SPRITE'a w górę lub w dół
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; SPRITE aktualnie przesuwa się w prawo
Beh_Drill_skipB   lda Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x
                  cmp #$08
                  jeq Beh_Drill_skipE

                  lda Is_Sprite1_7_Block_During_Move_Right,x
                  beq Beh_Drill_skipC

                  dec Is_Sprite1_7_Block_During_Move_Right,x
                  jmp Beh_Move_Up_or_Down

; SPRITE aktualnie przesuwa się w prawo - testuj sposobem #1 (są dwa sposoby bo dzięki temu jak SPRITE napotka przeszkodę z prawej strony to ją omija)
Beh_Drill_skipC   inc Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x
                  mva Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x Is_Sprite1_7_Block_During_Move_Right,x

                  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25
                  ldx Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy   X...
                  jsr address1_SBW_1byte                             ; poprzednia kolumna                                 ...
                  jsr address1_SBW_1byte                             ; poprzednia kolumna                                 ...
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code
                  cmp #$01                                           ; Czy kod akcji to kod "murka" lub "kładki"?
                  bne Beh_Drill_skipD                                ; NIE!

; TAK! natrafiono na "murek" lub "kładkę"
Beh_Drill_skipCa  mva #$08 Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x
                  jmp Beh_Move_Up_or_Down

; NIE! nie natrafiono na "murek" lub "kładkę"
Beh_Drill_skipD   ldy #$28                                           ; 40 - wiersz niżej                                 ...
                  jsr Get_Byte_address1_and_Find_Action_Code         ;                                                  X...
                  cmp #$01                                           ; Czy kod akcji to kod "murka" lub "kładki"?        ...
                  jeq Beh_Drill_skipCa                               ; TAK!

                  jsr CoordinateX_sub_One_Sprite1_7                  ; -1 wsp.X SPRITE'a
                  jsr CoordinateX_sub_One_Sprite1_7                  ; -1 wsp.X SPRITE'a
                  mva #$08 Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x
                  jmp Beh_Move_Up_or_Down
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; SPRITE aktualnie przesuwa się w prawo - testuj sposobem #2 (są dwa sposoby bo dzięki temu jak SPRITE napotka przeszkodę z prawej strony to ją omija)
Beh_Drill_skipE   lda Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x
                  jeq Beh_Drill_skipFa

                  lda Is_2x_Block_Left_Side_Sprite1_7,x
                  beq Beh_Drill_skipF

                  dec Is_2x_Block_Left_Side_Sprite1_7,x
                  jmp Beh_Move_Up_or_Down

Beh_Drill_skipF   dec Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x
                  mva Is_Test_Left_or_Right_Side_During_Move_Left_Sprite1_7,x Is_2x_Block_Left_Side_Sprite1_7,x

Beh_Drill_skipFa  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25
                  ldx Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  jsr address1_ADW_1byte                              ; następna kolumna                                   ...X
                  jsr address1_ADW_1byte                              ; następna kolumna                                   ...
                  jsr address1_SBW_40bytes                            ; wcześniejszy wiersz                                ...
                  jsr address1_SBW_40bytes                            ; wcześniejszy wiersz
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code
                  cmp #$01
                  bne Beh_Drill_skipH

Beh_Drill_skipG   mva #$00 Is_Test_Left_or_Right_Side_During_Move_Right_Sprite1_7,x
                  jmp Beh_Move_Up_or_Down

Beh_Drill_skipH   ldy #$28                                            ; 40 - wiersz niżej                                  ...
                  jsr Get_Byte_address1_and_Find_Action_Code          ;                                                    ...X
                  cmp #$01                                            ;                                                    ...
                  jeq Beh_Drill_skipG                                 ;

                  jsr CoordinateX_add_One_Sprite1_7                   ; dodaj do wsp.X SPRITE'a +1
                  jmp Beh_Move_Up_or_Down
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; badanie dla ruchu SPRITE'a do góry lub na dół
Beh_Move_Up_or_Down
                  lda tab_Move_Up_or_Down_Sprite_1_7,x
                  jne Beh_Drill_skipO

; aktualnie SPRITE przesuwa się do góry
                  lda Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x
                  cmp #$08
                  jeq Beh_Drill_skipL

                  lda Is_Sprite1_7_Block_During_Move_Up,x
                  beq Beh_Drill_skipJ

                  dec Is_Sprite1_7_Block_During_Move_Up,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO

Beh_Drill_skipJ   inc Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x
                  mva Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x Is_Sprite1_7_Block_During_Move_Up,x

                  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25    ;                                                       ...
                  jsr address1_SBW_1byte                               ; poprzednia kolumna                                    ...
                  ldx Do_Number_SPRITE_1_7                             ; numer SPRITE'a #1-#7, który aktualnie obrabiamy       X..
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code
                  cmp #$01
                  bne Beh_Drill_skipK

Beh_Drill_skipJa  mva #$08 Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
;-----------------------------------------------------------------------
Beh_Drill_skipK   ldy #$02                                             ;                                                       ...
                  jsr Get_Byte_address1_and_Find_Action_Code           ;                                                       ...
                  cmp #$01                                             ;                                                       ..X
                  jeq Beh_Drill_skipJa

                  jsr test_max_3_opponents_per_row_dn                  ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  bcs drill_skp1                                       ; TAK!

                  jsr CoordinateY_add_One_Sprite1_7                    ; dodaj do wsp.Y SPRITE'a +1
                  jsr CoordinateY_add_One_Sprite1_7                    ; dodaj od wsp.Y SPRITE'a +1

drill_skp1        mva #$08 Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Beh_Drill_skipL   lda Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x
                  beq Beh_Drill_skipMa

                  lda Is_2x_Block_Down_Side_Sprite1_7,x
                  beq Beh_Drill_skipM

                  dec Is_2x_Block_Down_Side_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO

Beh_Drill_skipM   dec Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x
                  mva Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x Is_2x_Block_Down_Side_Sprite1_7,x

Beh_Drill_skipMa  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25  ;                                                       X
                  ldx Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy       ...
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz                                   ...
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz                                   ...
                  jsr address1_SBW_40bytes                           ; wcześniejszy wiersz
                  jsr address1_SBW_1byte                             ; poprzednia kolumna
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code
                  cmp #$01
                  bne Beh_Drill_skipN

Beh_Drill_skipMb  mva #$00 Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
                                                                     ;                                                         X
Beh_Drill_skipN   ldy #$02                                           ;                                                       ...
                  jsr Get_Byte_address1_and_Find_Action_Code         ;                                                       ...
                  cmp #$01                                           ;                                                       ...
                  jeq Beh_Drill_skipMb

                  jsr test_max_3_opponents_per_row_up                ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  scs                                                ; TAK!
                  jsr CoordinateY_sub_One_Sprite1_7                  ; odejmij od wsp.Y SPRITE'a -1

                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; aktualnie SPRITE przesuwa się w dół
Beh_Drill_skipO   lda Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x
                  cmp #$08
                  jeq Beh_Drill_skipR

                  lda Is_Sprite1_7_Block_During_Move_Down,x
                  beq Beh_Drill_skipP

                  dec Is_Sprite1_7_Block_During_Move_Down,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO

Beh_Drill_skipP   inc Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x
                  mva Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x Is_Sprite1_7_Block_During_Move_Down,x
                  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25   ;                                                     X
                  ldx Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy     ...
                  jsr address1_SBW_40bytes                            ; wcześniejszy wiersz                                 ...
                  jsr address1_SBW_40bytes                            ; wcześniejszy wiersz                                 ...
                  jsr address1_SBW_40bytes                            ; wcześniejszy wiersz
                  jsr address1_SBW_1byte                              ; poprzednia kolumna
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code
                  cmp #$01
                  bne Beh_Drill_skipQ

Beh_Drill_skipPa  mva #$08 Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
                                                                      ;                                                       X
Beh_Drill_skipQ   ldy #$02                                            ;                                                     ...
                  jsr Get_Byte_address1_and_Find_Action_Code          ;                                                     ...
                  cmp #$01                                            ;                                                     ...
                  jeq Beh_Drill_skipPa

                  jsr test_max_3_opponents_per_row_up                 ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  bcs drill_skp2                                      ; TAK!

                  jsr CoordinateY_sub_One_Sprite1_7                   ; odejmij od wsp.Y SPRITE'a -1
                  jsr CoordinateY_sub_One_Sprite1_7                   ; odejmij od wsp.Y SPRITE'a -1

drill_skp2        mva #$08 Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Beh_Drill_skipR   lda Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x
                  beq Beh_Drill_skipSa

                  lda Is_2x_Block_Up_Side_Sprite1_7,x
                  beq Beh_Drill_skipS

                  dec Is_2x_Block_Up_Side_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO

Beh_Drill_skipS   dec Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x
                  mva Is_Test_Up_or_Down_Side_During_Move_Up_Sprite1_7,x Is_2x_Block_Up_Side_Sprite1_7,x

Beh_Drill_skipSa  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25   ;                                                         ...
                  jsr address1_SBW_1byte                              ; poprzednia kolumna                                      ...
                  ldx Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy         X..
                  ldy #$00
                  jsr Get_Byte_address1_and_Find_Action_Code          ; pobierz "kod akcji"
                  cmp #$01                                            ; czy natrafiono na "murek" lub "kładkę"?
                  bne Beh_Drill_skipW  ;slow                          ; NIE!

; pod nogami SPRITE'a z lewej lub z prawej strony natrafiono na "murek" lub "kładkę"
Beh_Drill_skipT   mva #$00 Is_Test_Up_or_Down_Side_During_Move_Down_Sprite1_7,x
                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO

Beh_Drill_skipW   ldy #$02                                            ;                                                         ...
                  jsr Get_Byte_address1_and_Find_Action_Code          ; pobierz "kod akcji"                                     ...
                  cmp #$01                                            ; czy natrafiono na "murek" lub "kładkę"?                 ..X
                  jeq Beh_Drill_skipT                                 ; TAK!

; pod nogami SPRITE'a zarówno z lewej jak i prawej strony nie ma "murka" lub "kładki"
                  jsr test_max_3_opponents_per_row_dn                 ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  scs                                                 ; TAK!
                  jsr CoordinateY_add_One_Sprite1_7                   ; dodaj do wsp.Y SPRITE'a +1

                  jmp Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; pobranie bajtu z pozycji (address1) i odszukanie na jego podstawie "kodu akcji"
Get_Byte_address1_and_Find_Action_Code .proc
                  lda (address1),y
                  tay
                  lda tab_Action_for_256Chars,y
                  rts
.endp

get_byte_from_address .proc (.byte Y) .reg
                  lda (address1),y
                  tax
                  lda tab_Action_for_256Chars,x
                  rts
.endp

get_byte_from_address_left .proc (.byte Y) .reg
                  lda Sprite0_7_PosX_div_8
                  cmp #2
                  bcs get_byte_from_address

                  lda #1                                        ; przekroczenie dozwolonego zakresu dla wsp.X - więc ustaw, że natrafiono na murek
                  rts
.endp

get_byte_from_address_right .proc (.byte Y) .reg
                  lda Sprite0_7_PosX_div_8
                  cmp #2+32-2
                  bcc get_byte_from_address

                  mva random colbak
                  lda #1                                        ; przekroczenie dozwolonego zakresu dla wsp.X - więc ustaw, że natrafiono na murek
                  rts
.endp
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; wyznacznie kierunku ruchu SPRITE'a
Determine_Move_Direction_Drill_DotBall_SquareBall_UFO
                  ldx Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Every_100th_Move_Follow_BOMB_JACK,x      ; czy licznik osiągnął już 0?
                  beq Beh_Drill_skipZ                              ; TAK!

                  dec tab_Every_100th_Move_Follow_BOMB_JACK,x      ; -1 licznik
                  jmp Beh_Drill_skipA3                             ; skok do biernego ruchu SPRITE'a (bez zważania na to gdzie aktualnie znajduje się BOMB JACK)

; próba zmiany ruchu SPRITE'a tak, żeby mógł dopaść BOMB JACK-a
Beh_Drill_skipZ   lda Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                            ; *2
                  tax
                  ldy Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda Sprite0_PosX
                  cmp Sprite1_PosX,x                               ; czy wsp.X BOMB JACKA < wsp.X PRZECIWNIKA?
                  bcc Beh_Drill_skipA1                             ; TAK!

                  mva #$01 tab_Move_Left_or_Right_Sprite_1_7,y     ; NIE! więc PRZECIWNIK ma się przesuwać w prawo! (żeby zbliżyć się do BOMB JACK-a)
                  jmp Beh_Drill_skipA1a

Beh_Drill_skipA1  mva #$00 tab_Move_Left_or_Right_Sprite_1_7,y     ; TAK! więc PRZECIWNIK ma się przesuwać w lewo! (żeby zbliżyć się do BOMB JACK-a)

Beh_Drill_skipA1a mva #$00 tab_Move_Up_or_Down_Sprite_1_7,y        ; PRZECIWNIK ma się przesuwać w górę (żeby zbliżyć się do BOMB JACK-a)
                  lda Sprite0_PosY
                  cmp Sprite1_PosY,x                               ; czy wsp.Y BOMB JACKA < wsp.Y PRZECIWNIKA?
                  bcc Beh_Drill_skipA2                             ; TAK!

                  mva #$01 tab_Move_Up_or_Down_Sprite_1_7,y        ; TAK! więc PRZECIWNIK ma się przesuwać w dół (żeby zbliżyć się do BOMB JACK-a)

Beh_Drill_skipA2  mva #$3B/SPEED_SPRITE tab_Every_100th_Move_Follow_BOMB_JACK,y ; 100x animuj zgodnie z zachowaniem "LITER", czyli nie zważając na to gdzie jest BOMB JACK (a raz na 100 razy tak modyfikuj ruch, żeby zbliżać się do BOMB JACK-a)
                  jsr Random_Value_Value_x2                        ; losowanie przypadkowej wartości
                  jsr Random_Change_Direction_Move_Sprites1_7      ; zmień kierunek ruchu SPRITE'a (lewo<->prawo lub góra<->dół)

; skok do ruchu biernego SPRITE'a czyli nie zważamy na to gdzie jest BOMB JACK aktualnie
Beh_Drill_skipA3  jmp Next_Clip_for_LetterP_FeelerBall_UFO         ; skocz do procki animującej zachowanie "LITER"

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; zmiana kierunku ruchu lewo<->prawo lub góra<->dół w zależności od wylosowanej wartości
Random_Change_Direction_Move_Sprites1_7
                  lda random ;                                     ; wylosuj przypadkową wartość w rej.A (0-255)
                  cmp #$96                                         ; czy losowa wartość < 150?
                  bcc Change_Move_skip1                            ; TAK!

                  cmp #$DC                                         ; czy losowa watość < 220?
                  bcc Change_Move_skip0                            ; TAK!

; zmiana ruchu na przeciwny góra<->dół
                  ldx Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Move_Up_or_Down_Sprite_1_7,x             ; zmiana ruchu SPRITE'a (góra<->dół)
                  eor #$01                                         ; 0<->1
                  sta tab_Move_Up_or_Down_Sprite_1_7,x

Change_Move_skip0 rts

Change_Move_skip1 cmp #$14                                         ; czy losowa wartość >= 20?
                  bcs Change_Move_skip0                            ; TAK!

; zmiana ruchu na przeciwny lewo<->prawo
                  ldx Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Move_Left_or_Right_Sprite_1_7,x          ; zmiana ruchu SPRITE'a (lewo<->prawo)
                  eor #$01                                         ; 0<->1
                  sta tab_Move_Left_or_Right_Sprite_1_7,x
                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; Y=X, A=A*2, X=A
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Calculate_X_mul_2 txa
                  tay
                  asl @
                  tax
                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
CoordinateX_add_One_Sprite1_7
                  jsr Calculate_X_mul_2

                  lda Sprite1_PosX,x
                  cmp #MAX_POSX_SPRITE-WIDTH_SPRITE
                  bcc CoordinateX_add1

                  mva #MAX_POSX_SPRITE-WIDTH_SPRITE Sprite1_PosX,x
                  mva #$00                          tab_Move_Left_or_Right_Sprite_1_7,x     ; ruch w lewo
                  tya                                                                       ; odtwórz zapamiętany rej.X
                  tax
                  rts

CoordinateX_add1  .rept SPEED_SPRITE
                    inc Sprite1_PosX,x                                                      ; +1 wsp.X (SPRITES #1-#7)
                  .endr
                  tya                                                                       ; odtwórz zapamiętany rej.X
                  tax
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
CoordinateX_sub_One_Sprite1_7
                  jsr Calculate_X_mul_2

                  lda Sprite1_PosX,x
                  cmp #MIN_POSX_SPRITE+4
                  bcs CoordinateX_sub1

                  mva #MIN_POSX_SPRITE+2 Sprite1_PosX,x
                  mva #$01                          tab_Move_Left_or_Right_Sprite_1_7,x     ; ruch w prawo
                  tya                                                                       ; odtwórz zapamiętany rej.X
                  tax
                  rts

CoordinateX_sub1  .rept SPEED_SPRITE
                    dec Sprite1_PosX,x                                                      ; -1 wsp.X (SPRITES #1-#7)
                  .endr
                  tya                                                                       ; odtwórz zapamiętany rej.X
                  tax
                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
CoordinateY_sub_One_Sprite1_7 .proc
                  jsr test_max_3_opponents_per_row_up                ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  bcs CoordinateY_sub_One_Sprite1_7.CoordinateY_sub0 ;skp

                  lda tab_too_many_sprites1_7_in_row,x                                      ; likwidujemy w ten sposób błędy multiplexer'a PMG
                  cmp #1
                  beq CoordinateY_add_One_Sprite1_7.skp

skp               jsr Calculate_X_mul_2
                  .rept SPEED_SPRITE
                    dec Sprite1_PosY,x                                                      ; -1 wsp.Y (SPRITES #1-#7)
                  .endr
                  lda Sprite1_PosY,x
                  cmp #MIN_POSY_SPRITE+1
                  bcs CoordinateY_sub0

                  mva #MIN_POSY_SPRITE Sprite1_PosY,x

CoordinateY_sub0  tya                                                                       ; odtwórz zapamiętany rej.X
                  tax
                  rts
.endp
;--------------------------------------------------------------------------------------------------------------------------------------------------------
CoordinateY_add_One_Sprite1_7 .proc
                  jsr test_max_3_opponents_per_row_dn                ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  bcs CoordinateY_add_One_Sprite1_7.CoordinateY_add0 ;skp

                  lda tab_too_many_sprites1_7_in_row,x                                      ; likwidujemy w ten sposób błędy multiplexer'a PMG
                  cmp #2
                  beq CoordinateY_sub_One_Sprite1_7.skp

skp               jsr Calculate_X_mul_2
                  .rept SPEED_SPRITE
                    inc Sprite1_PosY,x                                                      ; +1 wsp.Y (SPRITES #1-#7)
                  .endr
                  lda Sprite1_PosY,x
                  cmp #MAX_POSY_SPRITE
                  bcc CoordinateY_add0

                  mva #MAX_POSY_SPRITE Sprite1_PosY,x

CoordinateY_add0  tya                                                                       ; odtwórz zapamiętany rej.X
                  tax
                  rts
.endp

;########################################################################################################################################################
; procedura odpowiada za animacje SPRITE'a "ŚWIDERKA"
;########################################################################################################################################################
Do_Animation_Drill_Sprite
                  ldy Do_Number_SPRITE_1_7                          ; pobierz numer aktualnego SPRITE'a
                ;  mva #$0C D028,y                                   ; ustaw kolor dla SPRITE'a #1-#7 na średnioszary
                  mwa #tab_4th_clips_Move_Opponent_Drill_Left Next_Clip_change+1

                  lda tab_Move_Left_or_Right_Sprite_1_7,y           ; w którą stronę przesuwa się SPRITE #1-#7 (0 - w lewo, 1 - w prawo)
                  beq Anim_Drill_skip1

                  mwa #tab_8th_clips_Move_Opponent_Drill_Right Next_Clip_change+1

Anim_Drill_skip1  jmp Service_Behavior_Drill_DotBall_SquareBall_UFO

;########################################################################################################################################################
; procedura odpowiada za animacje SPRITE'ów "KULI Z CZÓŁKAMI", "KULI Z KWADRATOWYMI OKNAMI", "KULI Z KROPKAMI", "UŚMIECHNIĘTEJ BUZI", "LITERY P"
;########################################################################################################################################################
Do_Animation_Feeler_Square_DotBall_SmilingFace_LetterP_Sprite
                  ldy Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Type_SPRITES_1_7,y
                  jeq_a #$04,Do_Animation_Square_Ball_Sprite
                  jeq_a #$08,Do_Animation_Letter_P_Sprite
                  jeq_a #$07,Do_Animation_Smiling_Face_Sprite
                  jeq_a #$03,Do_Animation_Feeler_Ball_Sprite
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; animacja "KULI Z KROPKAMI" - $05
                  mwa #tab_3th_clips_Move_Opponent_Dot_Ball Next_Clip_change+1
                  jmp Service_Behavior_Drill_DotBall_SquareBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; animacja "LITERY P"
Do_Animation_Letter_P_Sprite
                  jsr Can_Show_LetterP_on_Board
                  mva #$01 sprites[letter_sprite].sts
                  ldy Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mwa #tab_6th_clips_Move_Letter_P Next_Clip_change+1
                  mva #$01*SPEED_SPRITE Add_to_CoordinateX_Sprite_1_7
                  mva #$02*SPEED_SPRITE Add_to_CoordinateY_Sprite_1_7
                  jmp Service_Behavior_LetterP_FeelerBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; animacja "UŚMIECHNIĘTEJ BUZI"
Do_Animation_Smiling_Face_Sprite
                  ldy Do_Number_SPRITE_1_7                             ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda Time_Get_SmilingFace_Soon_Finish+1
                  jne Anim_Face_skip2
                  lda Time_Get_SmilingFace_Soon_Finish
                  cmp #$19*2                                           ; 25
                  jcs Anim_Face_skip2
                  cmp #0
                  jne Anim_Face_skip0

; koniec czasu na zebranie 'uśmiechniętych buziek'!
End_Animation_Smiling_Face_Sprite
                  ldx Number_Board
                  mva tab_mus-1,x number_song                          ; set number of music
                  jsr play_music
                  mva #$00 Smiling_Time                                ; wyzeruj znacznik, że aktualnie trwa czas buziek
                  sta      blink_faces                                 ; wyłącz miganie buziek
                  :5 mva save_tab_Addr_Sprite1_7_Pattern+# tab_Addr_Sprite1_7_Pattern+#
                  jmp Set_Sprites_Parameters_after_Get_Smiling_Faces

; czasu na zebranie jest już poniżej 25 jednostek (1 jednostka = 1/50s)
Anim_Face_skip0   lda number_song
                  cmp #mus_bonus2
                  jeq Anim_Face_skip2

                  mva #TIME_BLINK_FACES blink_faces                    ; włącz miganie buziek
                  mva #mus_bonus2 number_song                          ; set number of music
                  jsr play_music

; czasu na zebranie jest równo lub więcej niż 25 jednostek (1 jednostka = 1/50s)
Anim_Face_skip2   mwa #tab_5th_clips_Move_Opponent_Smiling_Face Next_Clip_change+1
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO

tab_blink_smi    .db col_smifac,col_smifac-8
blink_faces      .db $00
TIME_BLINK_FACES = 2
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; animacja "KULI Z CZUŁKAMI"
Do_Animation_Feeler_Ball_Sprite
                  ldy Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Every_Second_Frame_Feeler_Ball_Sprite,y  ; 0-rysuj "KULĘ Z CZUŁKAMI", 1-nie rysuj "KULI Z CZUŁKAMI" (dzięki temu KULA jest rys. co 2 ramki)
                  beq Anim_Feeler_skip1

; nie rysuj "KULI Z CZUŁKAMI"
                  eor #$01                                         ; zmiana 0<->1
                  sta tab_Every_Second_Frame_Feeler_Ball_Sprite,y
                  jmp Do_Move_skip3                                ; powrót do głównej pętli

; rysuj "KULĘ Z CZUŁKAMI"
Anim_Feeler_skip1 eor #$01                                                         ; zmiana 0<->1
                  sta tab_Every_Second_Frame_Feeler_Ball_Sprite,y                  ; 0-rysuj "KULĘ Z CZUŁKAMI", 1-nie rysuj "KULI Z CZUŁKAMI" (dzięki temu KULA jest rys. co 2 ramki)
                  mwa #tab_8th_clips_Move_Opponent_Feeler_Ball Next_Clip_change+1
                  mva #$01*SPEED_SPRITE Add_to_CoordinateX_Sprite_1_7
                  mva #$01*SPEED_SPRITE Add_to_CoordinateY_Sprite_1_7              ; $02*SPEED_SPRITE kiedyś było
                  jmp Service_Behavior_LetterP_FeelerBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; animacja "KULI Z KWADRATOWYMI OKNAMI"
Do_Animation_Square_Ball_Sprite
                  mwa #tab_6th_clips_Move_Opponent_Square_Ball Next_Clip_change+1
                  jmp Service_Behavior_Drill_DotBall_SquareBall_UFO

;########################################################################################################################################################
; procedura obsługuje zachowanie "LITERY P", "KULI Z CZUŁKAMI" i "UFO"
;########################################################################################################################################################
Service_Behavior_LetterP_FeelerBall_UFO
                  lda bits0_1_Right_Down,y
                  and #$01                                            ; zostaw tylko bit0
                  beq Beh_Letter_skip0                                ; SPRITE przesuwa się w lewo
                  jmp Beh_Letter_skip4                                ; SPRITE przesuwa się w prawo

Beh_Letter_loop0  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda bits0_1_Right_Down,y
                  and #$02                                            ; zostaw tylko bit1
                  jne Beh_Letter_skipB                                ; SPRITE przesuwa się w dół
                  jmp Beh_Letter_skip6                                ; SPRITE przesuwa się w górę
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; ruch SPRITE'a w lewo
Beh_Letter_skip0  lda Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  lda Sprite1_PosX,y                                  ; pobierz wsp.X SPRITE'a #1-#7
                  cmp #MIN_POSX_SPRITE+4                              ; Czy wsp.X jest równa 25?
                  bcs Beh_Letter_skip2                                ; NIE!

; natrafiono na "murek" lub "kładkę"
Beh_Letter_loop1  jsr Beh_Letter_skip1                                ; TAK!
                  jmp Beh_Letter_skip5

; natrafiono na "murek" lub "kładkę"
Beh_Letter_loop2  jsr Beh_Letter_skip1
                  jmp Beh_Letter_skip3
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; zmiana kierunku ruchu przeciwnika lewo <-> prawo (wsp.X)
change_movement_X
Beh_Letter_skip1  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda bits0_1_Right_Down,y
                  eor #$01
                  sta bits0_1_Right_Down,y
                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Beh_Letter_skip2  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25 ; x..
                  sbw address1 #@sw*2+1                             ; ...
                  get_byte_from_address #0                          ; ...
                  jeq_a #$01,Beh_Letter_loop1                       ;     ...
                  get_byte_from_address #@sw                        ;     x..
                  jeq_a #$01,Beh_Letter_loop1                       ;     ...

; nie natrafiono na "murek" lub "kładkę"
Beh_Letter_skip3  lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  sbb Sprite1_PosX,y Add_to_CoordinateX_Sprite_1_7  ; odejmij od wsp.X SPRITE'a - czyli ruch w lewo
                  jmp Beh_Letter_loop0
;---------------------------------------------------------------------
; ruch SPRITE'a w prawo
Beh_Letter_skip4  lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  lda Sprite1_PosX,y                                ; pobierz wsp.X SPRITE'a #1-#7
                  cmp #MAX_POSX_SPRITE-WIDTH_SPRITE                 ; Czy wsp.X jest równa 240?
                  bcs Beh_Letter_loop2                              ; TAK!

; nie natrafiono na "murek" lub "kładkę"
                  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25 ; ..x
                  sbw address1 #@sw*2-1                             ; ...
                  get_byte_from_address #0                          ; ...
                  jeq_a #$01,Beh_Letter_loop2                       ;     ...
                  get_byte_from_address #@sw                        ;     ..x
                  jeq_a #$01,Beh_Letter_loop2                       ;     ... ...

; nie natrafiono na "murek" lub "kładkę"
Beh_Letter_skip5  lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  adb Sprite1_PosX,y Add_to_CoordinateX_Sprite_1_7  ; dodaj do wsp.X SPRITE'a czyli ruch w prawo
                  jmp Beh_Letter_loop0
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; ruch SPRITE'a w górę
Beh_Letter_skip6  lda Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  lda Sprite1_PosY,y                             ; pobierz wsp.Y SPRITE'a #1-#7
                  cmp #MIN_POSY_SPRITE+1                         ; Czy wsp.Y jest równa lub większa niż 50?
                  bcs Beh_Letter_skip9                           ; TAK!

                  mva #MIN_POSY_SPRITE+1 Sprite1_PosY,y

; natrafiono na "murek" lub "kładkę"
Beh_Letter_skip7  jsr Beh_Letter_proc1
                  jmp Beh_Letter_skipC

; natrafiono na "murek" lub "kładkę"
Beh_Letter_skip8  jsr Beh_Letter_proc1
                  jmp Beh_Letter_skipA
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Beh_Letter_proc1  ldy Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda bits0_1_Right_Down,y
                  eor #$02
                  sta bits0_1_Right_Down,y
                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; nie natrafiono na "murek" lub "kładkę"                            ;  x
Beh_Letter_skip9  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25 ; ...
                  sbw address1 #@sw*3                               ; ...
                  get_byte_from_address #0                          ; ...
                  jeq_a #$01,Beh_Letter_skip7

; nie natrafiono na "murek" lub "kładkę"
Beh_Letter_skipA  ldy Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  tya
                  asl @
                  tay

                  jsr test_max_3_opponents_per_row_up               ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  scs                                               ; TAK!
                  sbb Sprite1_PosY,y Add_to_CoordinateY_Sprite_1_7  ; odejmij od wsp.Y czyli ruch SPRITE'a w górę

                  jmp Next_Clip_for_LetterP_FeelerBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; ruch SPRITE'a w dół
Beh_Letter_skipB  lda Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  lda Sprite1_PosY,y
                  cmp #MAX_POSY_SPRITE
                  bcc Beh_Letter_skipBb

; natrafiono na "murek" lub "kładkę"
                  mva #MAX_POSY_SPRITE Sprite1_PosY,y
                  jmp Beh_Letter_skip8

; pobierz bajt spod (address1)
Beh_Letter_skipBb jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25  ; ...
                  get_byte_from_address #0                           ; ...
                  jeq_a #$01,Beh_Letter_skip8                        ; .x.

; nie natrafiono na "murek" lub "kładkę"
Beh_Letter_skipC  lda Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay

                  jsr test_max_3_opponents_per_row_dn               ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  scs                                               ; TAK!
                  adb Sprite1_PosY,y Add_to_CoordinateY_Sprite_1_7  ; dodaj do wsp.Y SPRITE'a czyli ruch w dół

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; tutaj wyświetlamy kolejną klatkę animacyjną
Next_Clip_for_LetterP_FeelerBall_UFO
                  ldy Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Every_Third_Frame_Move_Sprite,y
                  cmp #$03
                  beq Next_Clip_skip1

                  adb tab_Every_Third_Frame_Move_Sprite,y #$01
                  jmp Do_Move_skip3                              ; powrót do głównej pętli

Next_Clip_skip1   mva #$00 tab_Every_Third_Frame_Move_Sprite,y

Next_Clip_loop1   lda index_tab_clips_Move_Opponent,y            ; pobierz wskaźnik (SPRITE zgodnie z rej.Y)
                  tax

Next_Clip_change  lda tab_6th_clips_Move_Opponent_Square_Ball,x  ; UWAGA! tutaj jest modyfikacja kodu gry czasami! więc może być odwołanie do innej tablicy
                  beq Next_Clip_skip2                            ; =0? jeżeli tak tzn., że wyświetlono już wszystkie klatki animacji

                  sta tab_Addr_Sprite1_7_Pattern,y               ; ustaw wygląd SPRITE'a #1-#7
                  adb index_tab_clips_Move_Opponent,y #$01       ; +1 wskażniki - aby wskazywał na kolejną klatkę
                  jmp Do_Move_skip3                              ; powrót do pętli głównej

Next_Clip_skip2   mva #$00 index_tab_clips_Move_Opponent,y       ; ustaw wskaźnik na pierwszą klatkę (SPRITE zgodnie z rej.Y)
                  jmp Next_Clip_loop1

;########################################################################################################################################################
; procedura sprawdza czy można wyświetlić "LITERE P"? Jeżeli tak to losuje wsp.X i Y (lewy-górny róg lub prawy-dolny róg)
;########################################################################################################################################################
Can_Show_LetterP_on_Board
                  ldy Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Can_Show_LetterP_on_Board,y            ; Czy można wyświetlić "LITERE P"?
                  jeq Can_LetterP_skip1                          ; TAK!

                  rts

Can_LetterP_skip1 mva #$01 tab_Can_Show_LetterP_on_Board,y
                  lda random
                  cmp #$7D                                       ; 125
                  bcc Can_LetterP_skip2

                  lda Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                          ; *2
                  tay
                  mva #$3C Sprite1_PosX,y                        ; wsp.X=60 - lewy,górny róg - na tej pozycji pojawia się "LITERA P"
                  sta      Sprite1_PosY,y                        ; wsp.Y=60
                  rts

Can_LetterP_skip2 lda Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                          ; *2
                  tay
                  mva #$C8 Sprite1_PosX,y                        ; wsp.X=200 - prawy,dolny róg - na tej pozycji pojawia się "LITERA P"
                  sta      Sprite1_PosY,y                        ; wsp.Y=200
                  rts

;########################################################################################################################################################
; procedura animuje SPRITE'a w kształcie "UFO"
;########################################################################################################################################################
Do_Animation_UFO_Sprite
                  mwa #tab_6th_clips_Move_Opponent_UFO Next_Clip_change+1
                  ldx Do_Number_SPRITE_1_7                                  ; numer SPRITE'a #1-#7, który aktualnie obrabiamy

Anim_UFO_loop1    lda tab_Every_Second_Frame_UFO_Sprite,x
                  beq Anim_UFO_skip1

                  lda tab_After_255_Clips_Change_Behavior_UFO,x             ; =0?
                  beq Anim_UFO_skip2                                        ; TAK!

                  dec tab_After_255_Clips_Change_Behavior_UFO,x
                  jmp Service_Behavior_Drill_DotBall_SquareBall_UFO

Anim_UFO_skip1    lda tab_After_255_Clips_Change_Behavior_UFO,x             ; =0?
                  beq Anim_UFO_skip2                                        ; TAK!

                  dec tab_After_255_Clips_Change_Behavior_UFO,x             ; -1
                  mva #$01*SPEED_SPRITE Add_to_CoordinateX_Sprite_1_7
                  mva #$02*SPEED_SPRITE Add_to_CoordinateY_Sprite_1_7
                  jmp Service_Behavior_LetterP_FeelerBall_UFO

Anim_UFO_skip2    lda tab_Every_Second_Frame_UFO_Sprite,x
                  eor #$01
                  sta tab_Every_Second_Frame_UFO_Sprite,x
                  mva #$7F/SPEED_SPRITE tab_After_255_Clips_Change_Behavior_UFO,x        ; co 255 klatek zmiana sposobu zachowania "UFO"
                  jmp Anim_UFO_loop1

;########################################################################################################################################################
; procedura odpowiada za animacje SPRITE'a "PTASZKA"
;########################################################################################################################################################
Do_Animation_Bird_Sprite
                  ldy Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Is_Sprite1_7_on_Screen,y                  ; Czy SPRITE już narysowany na ekranie?
                  bne Bird_skp1                                     ; TAK!

; jeszcze nienarysowany więc najpierw musi być animacja jego pojawienia się na ekranie
                  mva #$0C tab_Type_SPRITES_1_7,y                   ; wstaw "12" jako typ SPRITE'a - pojawienie się nowego przeciwnika
                  mva #$97 tab_Addr_Sprite1_7_Pattern,y             ; ustaw kształt pierwszej klatki pojawiającego się nowego przeciwnika
                  mva #$01 tab_Is_Sprite1_7_on_Screen,y
                  mva #$0B tab_Show_Type_Sprite1_7_After_Animation_Appearing,y  ; typ "ASTRONAUTA" - zapamiętaj
                  jmp Do_Move_skip3                                 ; powrót do głównej pętli animującej SPRITE #1-#7

Bird_skp1         lda Number_Round_BCD                              ; pobierz numer rundy w BCD
                  cmp #$06                                          ; czy "RUNDA">=6
                  bcs Anim_Bird_skip1                               ; TAK!
; "RUNDA"<6
                  inc Service_Bird_Every_2th_Frame
                  lda Service_Bird_Every_2th_Frame
                  and #$02                                          ; czy bit0=1?
                  jne Do_Move_skip3                                 ; TAK! powrót do głównej pętli - dzięki jeżeli "RUNDA"<6 to "PTASZEK" jest obsł. co 2 ramke
; "RUNDA">=6
Anim_Bird_skip1   lda tab_Is_Change_PosX_or_PosY_Bird,y             ; czy zmieniać wsp.X "PTASZKA"?
                  jne Anim_Bird_skipB                               ; TAK!

; NIE! zmienić wsp.Y "PTASZKA"
                  jsr Next_Clip_Bird_Move_Up_or_Down                ; wyświetl kolejną klatkę "PTASZKA"

                  lda Choose_Move_Up_Down_Bird                      ; Jaki ruch należy wykonać "PTASZKIEM"? w górę czy w dół?
                  beq Anim_Bird_skip2                               ; =0 - skok do części dla ruchu SPRITE'a w dół lub w górę (zależy od wsp.Y)
                  cmp #$01
                  beq Anim_Bird_skip3                               ; =1 - skok do części dla ruchu SPRITE'a w dół
                  jmp Anim_Bird_skip7                               ; =2 - skok do części dla ruchu SPRITE'a w górę
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; testowanie wsp.Y - ruch SPRITE'a w dół
Anim_Bird_skip2   tya
                  asl @                                             ; *2
                  tay
                  ldx Sprite1_PosY,y                                ; Czy wsp.Y SPRITE'a #1-#7...
                  cpx Sprite0_PosY                                  ; ...jest równa wsp.Y BOMB JACK-a?
                  jeq Anim_Bird_End2                                ; TAK!
                  inx
                  cpx Sprite0_PosY                                  ; taki test eliminuje drgawki ptaszka (błąd, który czasem się ujawniał)
                  jeq Anim_Bird_End2
               :2 dex
                  cpx Sprite0_PosY
                  jeq Anim_Bird_End2
                  bcs Anim_Bird_skip7                               ; NIE! jest większa czyli skok do części dla ruchu SPRITE'a w górę

; NIE! wsp.Y SPRITE'a < wsp.Y BOMB JACK-a więc ruch SPRITE'a w dół                        ...
Anim_Bird_skip3   jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25 ;                     ...
                  get_byte_from_address #0                          ;                     .x.
                  cmp #$01                                          ; czy "murek" lub "kładka"?
                  bne Anim_Bird_skip6                               ; NIE!
                  jmp Anim_Bird_skip4a                              ; TAK!
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Anim_Bird_skip4   lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                             ; *2
                  tay
                  lda Sprite1_PosX,y                                ; Czy wsp.X SPRITE'a #1-#7...
                  cmp Sprite0_PosX                                  ; ...jest równa wsp.X BOMB JACK-a?
                  jne Anim_Bird_End2                                ; NIE!

; TAK! współrzędne X są równe
Anim_Bird_skip4a  ldy Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Is_Change_PosX_or_PosY_Bird,y
                  eor #$01
                  sta tab_Is_Change_PosX_or_PosY_Bird,y
                  lda random
                  cmp #$8C                                          ; 140
                  bcc Anim_Bird_skip5

                  mva #$01 Choose_Move_Left_Right_Bird              ; trzeba ominąć przeszkodę - więc ustaw ruch "PTASZKA" w prawo
                  mva #$3B/SPEED_SPRITE Counter_Move_Left_Right_Up_Down_Bird     ; 75
                  jmp Anim_Bird_End

Anim_Bird_skip5   mva #$02 Choose_Move_Left_Right_Bird              ; trzeba ominąć przeszkodę - więc ustaw ruch "PTASZKA" w lewo
                  mva #$3B/SPEED_SPRITE Counter_Move_Left_Right_Up_Down_Bird     ; 75
                  jmp Do_Move_skip3                                 ; powrót do pętli głównej
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Anim_Bird_skip6   clc
                  lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                             ; *2
                  tay

                  jsr test_max_3_opponents_per_row_dn               ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  jcs Anim_Bird_End                                 ; TAK!
                  lda Sprite1_PosY,y                                ; pobierz wsp.Y SPRITE'a #1-#7
                  add #$01*SPEED_SPRITE
                  cmp #MAX_POSY_SPRITE                              ; Czy wsp.Y jest większa od MAX_POSY_SPRITE?
                  bcs Anim_Bird_skip4                               ; TAK!
;dupa bird
                  sta Sprite1_PosY,y
                  jmp Anim_Bird_End
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; testowanie wsp.Y - ruch SPRITE'a w górę
Anim_Bird_skip7   jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25 ;   x
                  sbw address1 #@sw*3                               ;  ...
                  get_byte_from_address #0                          ;  ...
                  jeq_a #$01,Anim_Bird_skip4a                       ;  ...

                  lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
;dupa bird
                  jsr test_max_3_opponents_per_row_up               ; Czy w wierszu niżej znajduje się już 3-ch przeciwników?
                  bcs Anim_Bird_End                                 ; TAK!
                  lda Sprite1_PosY,y                                ; pobierz wsp.Y SPRITE'a #1-#7
                  sub #$01*SPEED_SPRITE
                  cmp #MIN_POSY_SPRITE+1                            ; Czy wsp.Y jest mniejsza od MIN_POSY_SPRITE+1?
                  jcc Anim_Bird_skip4

                  sta Sprite1_PosY,y

Anim_Bird_End     dec Counter_Move_Left_Right_Up_Down_Bird          ; -1
                  lda Counter_Move_Left_Right_Up_Down_Bird          ; czy nadal przesuwać "PTASZKA" zgodnie z ustalonym wcześńiej kierunkiem?
                  jpl Do_Move_skip3                                 ; TAK! powrót do głównej pętli

; NIE! "zresetowanie" zmiennych, żeby możliwe było ponowne wyznaczenie kierunku ruchu "PTASZKA"
Anim_Bird_End2    mva #$3B/SPEED_SPRITE Counter_Move_Left_Right_Up_Down_Bird     ; 100
                  mva #$00 Choose_Move_Up_Down_Bird                 ; zapisz wartość neutralną
                  sta      Choose_Move_Left_Right_Bird              ; zapisz wartość neutralną
                  ldy Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Is_Change_PosX_or_PosY_Bird,y
                  eor #$01
                  sta tab_Is_Change_PosX_or_PosY_Bird,y
                  jmp Do_Move_skip3                                 ; powrót do głównej pętli
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; testowanie wsp.X - ruch SPRITE'a w prawo
Anim_Bird_skipB   lda Choose_Move_Left_Right_Bird                   ; Jaki ruch należy wykonać "PTASZKIEM"? w lewo czy w prawo?
                  beq Anim_Bird_skipC                               ; =0 - skok do części dla ruchu SPRITE'a w lewo lub w prawo (zależy od wsp.X)
                  cmp #$01
                  jeq Anim_Bird_skipD                               ; =1 - skok do części dla ruchu SPRITE'a w prawo
                  jmp Anim_Bird_skipI                               ; =2 - skok do części dla ruchu SPRITE'a w lewo
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Anim_Bird_skipC   tya
                  asl @                                             ; *2
                  tay
                  lda Sprite1_PosX,y                                ; Czy wsp.X SPRITE'a #1-#7...
                  cmp Sprite0_PosX                                  ; ...jest równa wsp.X BOMB JACK-a?
                  jeq Anim_Bird_End2                                ; TAK!
                  jcs Anim_Bird_skipI                               ; NIE! jest większa

; NIE! jest mniejsza czyli ruch w prawo
Anim_Bird_skipD   jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25
                  ldy #$00                                         ;                                ...
                  jsr address1_SBW_40bytes                         ; wcześniejszy wiersz            ..X
                  jsr address1_ADW_1byte                           ; następna kolumna               ...

                  get_byte_from_address #0
                  cmp #$01                                         ; czy "murek" lub "kładka"?
                  bne Anim_Bird_skipH                              ; NIE!
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; natrafiono na "murek" lub "kładkę"
During_Move_Left_or_Right_Bird_Detect_Blocade
                  lda Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  ldx Sprite1_PosY,y                               ; Czy wsp.Y SPRITE'a #1-#7...
                  cpx Sprite0_PosY                                 ; ...jest równa wsp.Y BOMB JACK-a?
                  beq block_skp1
                  inx
                  cpx Sprite0_PosY                                  ; taki test eliminuje drgawki ptaszka (błąd, który czasem się ujawniał)
                  beq block_skp1
               :2 dex
                  cpx Sprite0_PosY
                  bne Anim_Bird_SkipG

; TAK! współrzędne Y są równe
block_skp1        ldy Do_Number_SPRITE_1_7                         ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Is_Change_PosX_or_PosY_Bird,y
                  eor #$01
                  sta tab_Is_Change_PosX_or_PosY_Bird,y
                  lda random
                  cmp #$8C                                         ; czy losowa wartość < 140
                  bcc Anim_Bird_skipF                              ; TAK!

                  mva #$01 Choose_Move_Up_Down_Bird                ; trzeba ominąć przeszkodę - więc ustaw ruch "PTASZKA" w dół
                  mva #$3B/SPEED_SPRITE Counter_Move_Left_Right_Up_Down_Bird    ; 75
                  jmp Anim_Bird_End

Anim_Bird_skipF   mva #$02 Choose_Move_Up_Down_Bird                ; trzeba ominąć przeszkodę - więc ustaw ruch "PTASZKA" w górę
                  mva #$3B/SPEED_SPRITE Counter_Move_Left_Right_Up_Down_Bird    ; 100
                  jmp Anim_Bird_End

Anim_Bird_skipG   jmp Anim_Bird_End2
;---------------------------------------------------------------------------------------------------------------------------------------------------------
; nie natrafiono na "murek" lub "kładkę"
Anim_Bird_skipH   jsr address1_SBW_40bytes                          ; wcześniejszy wiersz          ..X
                  get_byte_from_address #0                          ;                              ...
                  cmp #$01                                          ; czy "murek" lub "kładka"?    ...
                  jeq During_Move_Left_or_Right_Bird_Detect_Blocade ; TAK!

                  lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  lda Sprite1_PosX,y                                ; pobierz wsp.X SPRITE'a #1-#7
                  cmp #MAX_POSX_SPRITE-WIDTH_SPRITE                 ; Czy wsp.X jest równa 250?
                  jeq During_Move_Left_or_Right_Bird_Detect_Blocade ; TAK! - "murek"

                  adb Sprite1_PosX,y  #$01*SPEED_SPRITE             ; dodaj do wsp.X SPRITE'a +1
                  lda Sprite1_PosX,y
                  cmp #MAX_POSX_SPRITE-WIDTH_SPRITE
                  bcc Anim_BirdH1

                  mva #MAX_POSX_SPRITE-WIDTH_SPRITE Sprite1_PosX,y
                  mva #$02 Choose_Move_Left_Right_Bird              ; ruch w lewo

Anim_BirdH1       jsr Next_Clip_Bird_Move_Right                     ; wyświetl kolejną klatkę SPRITE'a
                  jmp Anim_Bird_End
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; testowanie wsp.X - ruch SPRITE'a w lewo
Anim_Bird_skipI   jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25
                  ldy #$00                                          ;                                   ...
                  jsr address1_SBW_40bytes                          ; wcześniejszy wiersz               X..
                  jsr address1_SBW_1byte                            ; poprzednia kolumna                ...
                  get_byte_from_address #0
                  cmp #$01                                          ; czy "murek" lub "kładka"?
                  jeq During_Move_Left_or_Right_Bird_Detect_Blocade ; TAK!
                                                                    ;                                   X..
                  jsr address1_SBW_40bytes                          ; wcześniejszy wiersz               ...
                  get_byte_from_address #0                          ;                                   ...
                  cmp #$01                                          ; czy "murek" lub "kładka"?
                  jeq During_Move_Left_or_Right_Bird_Detect_Blocade ; TAK!

                  lda Do_Number_SPRITE_1_7                          ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                             ; *2
                  tay
                  lda Sprite1_PosX,y                                ; pobierz wsp.X SPRITE'a #1-#7

                  sbb Sprite1_PosX,y #$01*SPEED_SPRITE              ; odejmij od wsp.X SPRITE'a -1

                  lda Sprite1_PosX,y
                  cmp #MIN_POSX_SPRITE+4 ;1
                  bcs Anim_BirdI1

                  mva #MIN_POSX_SPRITE+2 Sprite1_PosX,y
                  mva #$01 Choose_Move_Left_Right_Bird              ; ruch w prawo

Anim_BirdI1       jsr Next_Clip_Bird_Move_Left                      ; wyświetl kolejną klatkę SPRITE'a
                  jmp Anim_Bird_End
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; wyświetlenie kolejnej klatki, jeżeli "PTASZEK" przesuwa się górę lub w dół
Next_Clip_Bird_Move_Up_or_Down
                  mva #<tab_6th_clips_Move_Opponent_Bird_Up_Down Next_Bird_Change+1
                  mva #>tab_6th_clips_Move_Opponent_Bird_Up_Down Next_Bird_Change+2
                  jsr Next_Clip_for_Bird
                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; wyświetlamy kolejną klatkę "PTASZKA"
Next_Clip_for_Bird
                  ldy Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Every_Third_Frame_Move_Bird_Sprite,y
                  cmp #$03
                  beq Next_Bird_skip1

                  adb tab_Every_Third_Frame_Move_Bird_Sprite,y #$01  ; +1 licznik - co 3 ramkę ma być zmiana def. SPRITE'a
                  rts

Next_Bird_skip1   mva #$00 tab_Every_Third_Frame_Move_Bird_Sprite,y

Next_Bird_loop1   lda index_tab_clips_Move_Bird,y
                  tax
Next_Bird_Change  lda tab_6th_clips_Move_Opponent_Bird_Up_Down,x     ; UWAGA! modyfikacja kodu! wcale nie musi tutaj być ta akurat tablica!
                  beq Next_Bird_skip2

                  sta tab_Addr_Sprite1_7_Pattern,y                      ; ustaw adres klatki dla SPRITE'a  ($4000+(wskaźnik)*$40)

                  adb index_tab_clips_Move_Bird,y #$01*SPEED_SPRITE  ; +1 - licznik wskazujący na kolejną klatkę
                  rts

Next_Bird_skip2   mva #$00   index_tab_clips_Move_Bird,y
                  jmp Next_Bird_loop1
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; wyświetlenie kolejnej klatki, jeżeli "PTASZEK" przesuwa się w prawo
Next_Clip_Bird_Move_Right
                  mva #<tab_6th_clips_Move_Opponent_Bird_Right Next_Bird_Change+1
                  mva #>tab_6th_clips_Move_Opponent_Bird_Right Next_Bird_Change+2
                  jsr Next_Clip_for_Bird
                  rts
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; wyświetlenie kolejnej klatki, jeżeli "PTASZEK" przesuwa się w lewo
Next_Clip_Bird_Move_Left
                  mva #<tab_6th_clips_Move_Opponent_Bird_Left Next_Bird_Change+1
                  mva #>tab_6th_clips_Move_Opponent_Bird_Left Next_Bird_Change+2
                  jsr Next_Clip_for_Bird
                  rts

;########################################################################################################################################################
; animacja pokazywana przed pojawieniem się nowego przeciwnika
;########################################################################################################################################################
Do_Animation_New_Opponent_Appear_Sprite
                  jsr test_max_sprites_in_row            ; sprawdzamy czy już jest max. liczba sprite'ów w wierszu? (ograniczenie błędów multiplexer'a PMG)
                  jcs Do_Move_skip3                      ; nie może pojawić się nowy sprite na razie! (bo multiplexer PMG nie mógłby obsłużyć go)

                  ldy Do_Number_SPRITE_1_7               ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  ldx tab_sprite8,y                      ; włącz danego sprite'a
                  mva #$01 sprites[1].sts,x

                  lda tab_Every_Second_Frame_New_Appear_Sprite,y
                  cmp #$02
                  beq Anim_New_skip1

                  adb tab_Every_Second_Frame_New_Appear_Sprite,y #$01
                  jmp Do_Move_skip3

; wyświetlamy pojawianie się SPRITE'a (np: najpierw pojawia się "dymek"($99), potem "trafienie"($98), potem "kółko"($97) i dopiero nowy przeciwnik)
Anim_New_skip1    mva #$00 tab_Every_Second_Frame_New_Appear_Sprite,y
                  lda index_tab_7th_clips_New_Opponent_Appear,y         ; pobierz wskaźnik dla SPRITE'a #1-#7
                  tax
                  lda tab_7th_clips_New_Opponent_Appear,x               ; pobierz kolejną klatkę zgodnie z wskaźnikiem
                  beq Anim_New_skip2                                    ; Czy wskaźnik = 0? jeżeli tak tzn., że już wyświetlono wszystkie klatki

                  sta        tab_Addr_Sprite1_7_Pattern,y               ; ustaw wygląd SPRITE'a
                  adb index_tab_7th_clips_New_Opponent_Appear,y #$01    ; +1 aby wskaźnik wskazywał kolejną klatkę
                  jmp Do_Move_skip3                                     ; powrót do głównej pętli

; wyświetlono już wszystkie klatki animacji pojawiania się przeciwnika - teraz ma pokazać się postać przeciwnika
Anim_New_skip2    mva #$00   index_tab_clips_Move_Opponent,y
                  sta        test_max_sprites_in_row.allow,y            ; wyzeruj wsk. pozwolenia na pojawienie się sprite'a
                  sta        tab_Every_Third_Frame_Move_Sprite,y
                  sta        index_tab_7th_clips_New_Opponent_Appear,y  ; wskazanie na pierwszą klatkę
                  mva tab_Show_Type_Sprite1_7_After_Animation_Appearing,y tab_Type_SPRITES_1_7,y
                  tax
                  mva tab_first_clip,x                                    tab_Addr_Sprite1_7_Pattern,y
                  jmp Do_Move_skip3                                     ; powrót do pętli głównej

;########################################################################################################################################################
; procedura obsługuje spadające litery B i E, które może zebrać BOMB JACK
;########################################################################################################################################################
Anim_LetEB_End    mva #$0C tab_Type_SPRITES_0_7+letter_sprite                  ; ustaw na animację pojawiania się nowego przeciwnika
                  mva #$00 tab_Move_Left_or_Right_or_Down_LetterEB+letter_sprite-1
                  sta      tab_Show_Type_Sprite1_7_After_Animation_Appearing+letter_sprite-1 ; =0 SPRITE nie używany
                  jmp Do_Move_skip3                                                          ; powrót do pętli głównej

Do_Animation_Letter_E_B_Sprite
                  lda Can_Show_LetterEB_on_Board                     ; Czy można wyświetlić "LITERE E lub B"?
                  beq Anim_LetEB_End                                 ; =0 NIE!

                  mva #$01 sprites[letter_sprite].sts
                  dec Can_Show_LetterEB_on_Board
                  mwa #tab_8th_clips_Letter_E Next_Clip_change+1     ; animacja "LITERY E"

                  ldy Do_Number_SPRITE_1_7                           ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  lda tab_Type_SPRITES_1_7,y
                  cmp #$0A                                           ; Czy "LITERA B"?
                  sne
                  mwa #tab_8th_clips_Letter_B Next_Clip_change+1     ; animacja "LITERY B"

                  lda tab_Move_Left_or_Right_or_Down_LetterEB,y
                  jeq Anim_LetEB_skip3                               ; =0 - wylosuj miejsce, gdzie pokaże się "LITERA" na planszy
                  jeq_a #1,Anim_LetEB_skip9                          ; =1 - ruch w lewo "LITERY"
                  jeq_a #2,Anim_LetEB_loop1                          ; =2 - ruch w prawo "LITERY"

; =3 - ruch w dół "LITERY"
                  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25  ; obl. adres miejsca, nad którym jest SPRITE      ...
                  get_byte_from_address #0                           ; pobierz "kod akcji" dla tego znaku              ...
                  jeq_a #1,Anim_LetEB_skip1                          ; czy to jakaś "kładka" lub "zielony margines"?   .X.

; NIE! więc można wykonać ruch "LITERY" w dół
                  jsr Anim_Astronaut_Jump_Down
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO

; TAK! wykryto na dole "murek" lub "kładkę"
Anim_LetEB_skip1  ldx index_tab_Addr_SPRITE_ScreenBuff40x25
                  lda tab_Addr_SPRITE_ScreenBuff40x25+2,x             ; pobierz wsp.Y
                  tax
                  :2 inx                                              ; +2

                  lda Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  txa
                  sta Sprite1_PosY,y

                  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$00 tab_Anim_Speed_Jump_Down,y
                  mva #$07 tab_7x_Add_Speed_Jump_Down_to_PosY,y
                  mva #$01 tab_Move_Left_or_Right_or_Down_LetterEB,y  ; ruch w lewo
                  lda random
                  cmp #$82
                  jcc Next_Clip_for_LetterP_FeelerBall_UFO

                  mva #$02 tab_Move_Left_or_Right_or_Down_LetterEB,y  ; ruch w prawo
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO

;--------------------------------------------------------------------------------------------------------------------------------------------------------
Anim_LetEB_skip3  ldx #128-[WIDTH_SPRITE/2]                           ; pokaż na środku litere

Anim_LetEB_skip4  lda Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @                                               ; *2
                  tay
                  txa
                  sta                      Sprite1_PosX,y             ; ustaw. wylosowaną wcześniej wsp.X dla "LITERY"
                  mva #MIN_POSY_SPRITE+8-4 Sprite1_PosY,y             ; ustaw wsp.Y = 80
                  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$03 tab_Move_Left_or_Right_or_Down_LetterEB,y
                  sta      tab_Every_Third_Frame_Move_Sprite,y
                  mva #$00 index_tab_clips_Move_Opponent,y            ; wyzeruj wskaźnik wskazujący na kolejną klatkę litery E lub B
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO

Anim_LetEB_skip5  adc #$2A                                            ; +42
                  tax
                  jmp Anim_LetEB_skip4
;-----------------
Anim_LetEB_loop1  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25   ;  ...x
                  sbw address1 #2*32-2                                ;  ...
                  get_byte_from_address #0                            ;  ...
                  jne_a #$01,Anim_LetEB_skip6

; TAK! wykryto z prawej strony "murek" lub "kładkę"
                  mva #$01 tab_Move_Left_or_Right_or_Down_LetterEB+letter_sprite-1                                 ; ruch w lewo
                  jmp Anim_LetEB_skip9

; NIE! nie wykryto z prawej strony "murka" lub "kładki"
Anim_LetEB_skip6  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25   ;
                  dew address1                                        ;                                      ...
                  get_byte_from_address #0                            ;                                      ...
                  cmp #$01                                            ; czy "murek" lub "kładka"?            x..
                  beq Anim_LetEB_skip8                                ; TAK!

; NIE! nie wykryto na dole "murka" lub "kładki"
                  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$03 tab_Move_Left_or_Right_or_Down_LetterEB,y                                     ; ruch w dół
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Anim_LetEB_skip7  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$01 tab_Move_Left_or_Right_or_Down_LetterEB,y                                     ; ruch w lewo
                  jmp Anim_LetEB_skipC
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; spr. czy prawy margines osięgnięto?
Anim_LetEB_skip8  lda Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  lda Sprite1_PosX,y
                  cmp #MAX_POSX_SPRITE-WIDTH_SPRITE                   ; czy wsp.X "LITERY" = 247?
                  bcs Anim_LetEB_skip7                                ; TAK!

; NIE! więc można przesunąć "LITERE" w prawo
                  add #$01*SPEED_SPRITE
                  sta Sprite1_PosX,y
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
; obsługa ruchu "LITERY" w lewo lub w dół - dzięki temu ruch "LITERY" zawsze w dół, chyba, że "kładka" przyblokuje to ruch w lewo
Anim_LetEB_skip9  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25  ;  x...
                  sbw address1 #2*32+2                               ;   ...
                  get_byte_from_address_left #0                      ;   ...
                  cmp #$01                                           ; czy "murek" lub "kładka"?
                  bne Anim_LetEB_skipA                               ; NIE!

; TAK! "murek" lub "kładka" - czyli ruch w lewo przyblokowany
                  mva #$02 tab_Move_Left_or_Right_or_Down_LetterEB+letter_sprite-1                             ; ruch w prawo
                  jmp Anim_LetEB_loop1

; NIE! ruch w lewo możliwy
Anim_LetEB_skipA  jsr Calculate_address1_SPRITE_1_7_ScreenBuff40x25   ;                              ...
                  get_byte_from_address #1                            ;                              ...
                  cmp #$01                                            ; czy "murek" lub "kładka"?    ..x
                  beq Anim_LetEB_skipC                                ; TAK! więc ruch w lewo

; NIE! ruch w dół możliwy (ma on wyższy piorytet niż w lewo więc wykonaj)
                  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$03 tab_Move_Left_or_Right_or_Down_LetterEB,y                                     ; ruch w dół
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Anim_LetEB_skipB  ldy Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  mva #$02 tab_Move_Left_or_Right_or_Down_LetterEB,y                                     ; ruch w prawo
                  jmp Anim_LetEB_skip8

; spr. czy lewy margines osięgnięto?
Anim_LetEB_skipC  lda Do_Number_SPRITE_1_7                            ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  asl @
                  tay
                  lda Sprite1_PosX,y
                  cmp #MIN_POSX_SPRITE+8+1                            ; czy wsp.X "LITERY" = 35?
                  bcc Anim_LetEB_skipB                                ; TAK! czyli osiągnięto lewy margines

; NIE! więc można przesunąć "LITERE" w lewo
                  sub #$01*SPEED_SPRITE                               ; -1
                  sta Sprite1_PosX,y
                  jmp Next_Clip_for_LetterP_FeelerBall_UFO

;########################################################################################################################################################
; procedura oblicza w (address1) adres bajtu w ScreenBuff40x25 nad, którym znajduje się dany SPRITE
; SPRITE pokrywa 3x3 znaki na ekranie więc wyliczamy adres znaku "X": (patrz niżej)
;     ...
;     ...
;     .X.
;########################################################################################################################################################
Calculate_address1_BOMB_JACK_in_ScreenBuff40x25
                  ldy #0
                  beq calc_addr1

Calculate_address1_SPRITE_1_7_ScreenBuff40x25
                  lda Do_Number_SPRITE_1_7                       ; numer aktualnego SPRITE'a #1-#7
                  add #1
                  asl @                                          ; *2
                  tay

calc_addr1        lda Sprite0_PosX,y                             ; pobierz wsp.X
                  :3 lsr @                                       ; /8 - obl. wsp.X  w bajtach...
                  add #1
                  sta Sprite0_7_PosX_div_8                       ; ...i zapamiętaj

                  lda Sprite0_PosY,y                             ; pobierz wsp.Y
                  :3 lsr @                                       ; /8 - obl. wsp.Y w bajtach...
                  sta Sprite0_7_PosY_div_8                       ; ...i zapamiętaj

                  asl @                                          ; *2
                  add Sprite0_7_PosY_div_8                       ; powyższe instrukcje to nic innego jak oblicznie: rej.A = wsp.Y*3
                  tay
                  mwa tab_Addr_SPRITE_ScreenBuff40x25,y address1 ; pobierz adres SPRITE'a na pozycji w ScreenBuff40x25
                  adb address1 Sprite0_7_PosX_div_8              ; dodaj wsp.X/8 do (address1) - dla aktualnego SPRITE'a
                  scc
                  inc address1+1

                  tya
                  tax
                  stx index_tab_Addr_SPRITE_ScreenBuff40x25      ; zapisz wiersz
                  rts

;########################################################################################################################################################
; animacja spadającego przeciwnika "ASTRONAUTY" w dół (np: kiedy zeskakuje z kładki)
; procka wykorzystywana także przez spadające "LITERY E i B"
;########################################################################################################################################################
Anim_Astronaut_Jump_Down
                  lda Do_Number_SPRITE_1_7                       ; numer SPRITE'a #1-#7, który aktualnie obrabiamy
                  tay
                  asl @                                          ; *2
                  tax
                  sbb tab_7x_Add_Speed_Jump_Down_to_PosY,y #$01  ; -1 licznik ile razy należy dodać wart. z "tab_Anim_Speed_Jump_Down" do wsp.Y "ASTRONAUTY"
                  bne Anim_Down_skip1

                  mva #$07 tab_7x_Add_Speed_Jump_Down_to_PosY,y  ; ustaw licznik od początku
                  lda      tab_Anim_Speed_Jump_Down,y
                  cmp #$08
                  beq Anim_Down_skip1

                  adb tab_Anim_Speed_Jump_Down,y #$01            ; +1

Anim_Down_skip1   adb Sprite1_PosY,x tab_Anim_Speed_Jump_Down,y  ; dodanie do wsp.Y wartości z jaką szybkością ma spadać "ASTRONAUTA" (1-8)
                  rts

;########################################################################################################################################################
; procedura losuje jedną wartość, zapamiętuje ją, następnie mnoży ją x2 i również zapamiętuje
;########################################################################################################################################################
Random_Value_Value_x2       ;??? $D012 - zamiast random na C64
                  mva random Random_Value                           ; VicRaster
                  asl @                                           ; *2
                  sta      Random_Value_x2
                  beq Random_Value_Value_x2                       ; =0? jeżeli tak to losuj jeszcze raz!

                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura kasuje wskazany obszar pamięci wartością $00
;--------------------------------------------------------------------------------------------------------------------------------------------------------
clr_mem .macro ','
         mva @TAB_MEM_BANKS+=clr_mem_bank portb
         mwa :1   address1
         mwa :2   address2
         jsr clr_mem_bank
.endm

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura wypełnia wskazany obszar pamięci wartością 'byt'
;--------------------------------------------------------------------------------------------------------------------------------------------------------
fil_mem .macro ','
         mva @TAB_MEM_BANKS+=fil_mem_bank portb
         mwa :1   address1
         mwa :2   address2
         mva :3   :fil_mem_bank.byt
         jsr fil_mem_bank
.endm

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; proc. kopiuje obszar pamięci o zadanej długości w nowe miejsce
;--------------------------------------------------------------------------------------------------------------------------------------------------------
cop_mem .macro ','
         mva @TAB_MEM_BANKS+=cop_mem_bank portb
         mwa :1   address1
         mwa :2   address2
         mwa :3   address3
         jsr cop_mem_bank
.endm

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; Wait until key is pressed
;--------------------------------------------------------------------------------------------------------------------------------------------------------
wait_key .proc
         lda #$ff
         cmp key
         beq *-3

         sta key
         rts
.endp

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; Set number of Round from reg.A
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Set_Number_of_Round .proc
         mvx @TAB_MEM_BANKS+=Set_Number_of_Round_Bank portb
         jmp Set_Number_of_Round_Bank
.endp

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura sprawdza czy BOMB JACK trafił na BOMB-ę, jeżeli tak to zbiera on ją (zamazujemy BOMB-ę poprzez narysowanie na niej tła spod spodu(znaki+atrybuty)
; i dodajemy punkty za zebraną BOMB-ę
;--------------------------------------------------------------------------------------------------------------------------------------------------------
BombJack_Get_Bomb jsr Get_Bomb
                  jsr Delete_Collected_Bomb

                  lda Counter_Collected_BOMBS
                  cmp #24                                             ; Czy zebrano już wszystkie 24 bomby?
                  seq                                                 ; TAK!
                  rts

                  mva #TRUE Is_Dance_BOMB_JACK
                  jsr stop_music
                  mva #BombJack_Dance BombJack_SHP_C64
                  jsr Convert_Sprites_C64_to_ATARI_jack
                  mva #mus_level_complited number_song                ; set number of music
                  jmp play_music

;---------------------------------------------------------------------
Get_Bomb          jsr Calculate_address1_BOMB_JACK_in_ScreenBuff40x25 ; oblicz jaki adres pamięci ekranu przykrywa sprajt BOMB JACK-a
                  jsr address1_SBW_40bytes                            ; poprzedni wiersz
                  jsr address1_SBW_40bytes                            ; poprzedni wiersz

                  get_byte_from_address #0
                  jeq_a #$02,Get_BOMB_skip1                           ; Czy BOMB JACK trafił na lewy górny róg BOMB-y do zebrania?
                  jeq_a #$03,Get_BOMB_mov1                            ; Czy BOMB JACK trafił na prawy górny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!
                  jeq_a #$04,Get_BOMB_mov2                            ; Czy BOMB JACK trafił na lewy dolny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!
                  jeq_a #$05,Get_BOMB_mov3                            ; Czy BOMB JACK trafił na prawy dolny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!

                  adw address1 #1
                  get_byte_from_address #0
                  jeq_a #$02,Get_BOMB_skip1                           ; Czy BOMB JACK trafił na lewy górny róg BOMB-y do zebrania?
                  jeq_a #$03,Get_BOMB_mov1                            ; Czy BOMB JACK trafił na prawy górny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!
                  jeq_a #$04,Get_BOMB_mov2                            ; Czy BOMB JACK trafił na lewy dolny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!
                  jeq_a #$05,Get_BOMB_mov3                            ; Czy BOMB JACK trafił na prawy dolny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!

                  sbw address1 #2
                  get_byte_from_address #0
                  jeq_a #$02,Get_BOMB_skip1                           ; Czy BOMB JACK trafił na lewy górny róg BOMB-y do zebrania?
                  jeq_a #$03,Get_BOMB_mov1                            ; Czy BOMB JACK trafił na prawy górny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!
                  jeq_a #$04,Get_BOMB_mov2                            ; Czy BOMB JACK trafił na lewy dolny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!
                  jeq_a #$05,Get_BOMB_mov3                            ; Czy BOMB JACK trafił na prawy dolny róg BOMB-y do zebrania? TAK! ale przesuń (address1) tak, żeby wskazywał na prawy górny róg BOMB-y!
                  rts                                                 ; NIE! BOMB JACK nie trafił na żaden z 4-rech znaków BOMBY!

Get_BOMB_skip1    lda Is_Dead_BOMB_JACK                               ; Czy BOMB JACK jest martwy?
                  beq Get_BOMB_skip3                                  ; NIE!

Get_BOMB_skip2    rts                                                 ; TAK! wyjście z procedury

;--------------------------------------------------------------------------------------------------------------------------------------------------------
Get_BOMB_skip3    sbw address1 #B1Scr Offset_Bomb_to_Clear            ; wyciągnij offset z B1SCR i zapamiętaj do wykorzystania na przerwaniu VBL
                  inc Is_Draw_Back_On_Collected_Bomb                  ; <>0 rysuj na przerwaniu VBL tło w miejscu zebranej bomby
                  inc Counter_Collected_BOMBS                         ; dodaj +1 do licznika zebranych bomb
                  jsr set_pattern_panel                               ; poszerz migający pasek na górnym panelu bo zebrano kolejną bombę
                  mva #sfx_get_bomb sfx_effect                        ; odtwórz SFX zebrania bomby

                  adw Offset_Bomb_to_Clear #tab_Screen_BOMB address1

                  lda Is_Blink_BOMB                                   ; Czy należy migać bombą?
                  jne Get_BOMB_skipB                                  ; TAK!

                  lda Counter_Collected_BOMBS                         ; Czy zebrano aktualnie tylko jedną bombę?
                  cmp #$01
                  beq Get_BOMB_skip4                                  ; TAK!

                  inc Is_Blink_BOMB                                   ; +1 należy migać BOMB-ą
                  jmp Get_BOMB_skipB

; pobierz wskaźnik na następną bombę, która ma migać po zebraniu bieżącej
Get_BOMB_skip4    mvy #$01         Is_Blink_BOMB                      ; pobierz wartość z odpowiedniej pozycji tablicy 'tab_Screen_BOMB'
                  mva (address1),y index_Address_BOMBS                ; wskaźnik*2+ScreenText40x25 - wskazuje na adres lewego górnego rogu następnej migającej BOMB-y

                  ldy #$00
                  tya
                  sta (address1),y                                    ; kasuj bieżącą bombę bo już jest ona zebrana z tego miejsca!

; pobierz dane następnej bomby, która ma migać
                  lda index_Address_BOMBS                             ; wskaźnik*2+ScreenText40x25 - wskazuje na adres lewego górnego rogu migającej BOMB-y
                  asl @
                  tax
                  mwa Buffor_Offset_in_tab_Screen_BOMB,x address1
                  ldy #$00
                  mva #$02             (address1),y                   ; wpisz kod "$02"- migaj następną bombą, tab_Screen_BOMB (w miejscu gdzie kiedyś było "$01" dla oznaczenia lewego górnego rogu BOMB-y)
                  jmp Get_BOMB_skip6

;--------------------------------------------------------------------------------------------------------------------------------------------------------
Get_BOMB_skip5    lda #$00
                  tay
                  sta (address1),y                                    ; wykasuj bombę z bufora

Get_BOMB_skip6    lda index_Address_BOMBS                             ; wskaźnik*2+ScreenText40x25 - wskazuje na adres lewego górnego rogu migającej BOMB-y
                  asl @
                  tax
                  mwa Buffor_Offset_in_tab_Screen_BOMB,x Offset_Bomb_to_Blink
                  sbw Offset_Bomb_to_Blink #tab_Screen_BOMB

                  lda tab_Type_SPRITES_0_7+letter_sprite              ; Czy aktualnie wyświetlamy coś na sprite'cie programowym #7?
                  beq Get_BOMB_skip7                                  ; NIE!

                  rts
;-----------------
Get_BOMB_skip7    inc Counter_5th_BOMBS_to_Show_LETTER_B
                  lda Counter_5th_BOMBS_to_Show_LETTER_B
                  cmp #$05+1
                  bne Get_BOMB_skip9

                  mva #$09   tab_Type_SPRITES_0_7+letter_sprite       ; $09 - LETTER E
                  mva #170   Can_Show_LetterEB_on_Board               ; You can show LETTER E
                  mva #$00   Counter_5th_BOMBS_to_Show_LETTER_B       ; ustaw zmienne, żeby pokazała się "LITERA E" na ekranie

                  lda Number_Board                                    ; Sprawdzamy czy to nie jest plansza nr.#3?
                  cmp #3
                  bne not_letter_E

                  lda counter_show_Letter_E                           ; sprawdzamy czy jest dozwolone pokazanie się litery E?
                  bne not_letter_E

                  lda random                                          ; wylosuj czy litera "E" ma się pojawić?
                  cmp #128                                            ; 50% prawdopodobieństwa jest na to
                  bcc not_letter_E

                  inc counter_show_Letter_E                           ; zwiększ licznik wyświetlenia litery "E"
                  rts

not_letter_E      inc tab_Type_SPRITES_0_7+letter_sprite              ; $0A - LETTER B
                  rts

Get_BOMB_skip9    lda Counter_9th_BOMBS_to_Show_LETTER_P
                  cmp #$09
                  bne Get_BOMB_skipA

                  mva #$00 Counter_9th_BOMBS_to_Show_LETTER_P         ; ustaw zmienne, żeby pokazała się "LITERA P" na ekranie
                  sta      tab_Can_Show_LetterP_on_Board+letter_sprite-1
                  sta      index_tab_clips_Move_Opponent+letter_sprite-1
                  sta      tab_Every_Third_Frame_Move_Sprite+letter_sprite-1
                  mva #$08 tab_Type_SPRITES_0_7+letter_sprite         ; $08 - LETTER P
                  rts

Get_BOMB_skipA    inc Counter_9th_BOMBS_to_Show_LETTER_P
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
Get_BOMB_skipB    ldy #$00
                  lda (address1),y
                  cmp #$02                                  ; Czy to jest BOMBA, która aktualnie miga na ekranie?
                  jeq Get_BOMB_skipC                        ; TAK!

; wartość <>$02 - więc BOMB JACK zebrał zwykłą BOMB-ę (dostanie za to standardową liczbę punktów)
                  ldx Counter_Collected_Letter_B            ; pobierz liczbę umiejscowioną w migającym prostokącie na ekranie "x1" (tam gdzie "1" może być dowolna liczba)
                  inx
                  lda #$00
                  tay
                  jsr Add_Points_to_SCORE_PLAYER_AXY        ; dodaj punkty zawarte w rej. A,X,Y do punktów gracza
                  jmp Get_BOMB_skip5

; wartość $02 - więc BOMB JACK zebrał migającą BOMB-ę (czyli dostanie za to więcej punktów)
Get_BOMB_skipC    lda Counter_Collected_Letter_B             ; pobierz liczbę umiejscowioną w migającym prostokącie na ekranie "x1" (tam gdzie "1" może być dowolna liczba)
                  add #1
                  asl @                                      ; *2
                  tax
                  lda #$00
                  tay
                  jsr Add_Points_to_SCORE_PLAYER_AXY         ; dodaj punkty zawarte w rej. A,X,Y do punktów gracza

                  inc Counter_Blink_BOMBS                    ; liczba zebranych migających BOMB +1

                  ldy #$01
                  mva (address1),y index_Address_BOMBS2      ; pobierz wskaźnik na następną bombę, która ma migać
                  dey
                  mva #$00         (address1),y              ; zmaż bombę z tego miejsca (w buforze bo na ekranie już dawno zmazana)
                  sta              Loop_All_BOMBS

; pętla sprawdza po kolei czy dana bomba jest już zebrana przez 'bomb jacka'
Get_BOMB_loop1    inc Loop_All_BOMBS                         ; kolejna bomba

                  lda Loop_All_BOMBS
                  cmp #$19                                   ; Czy zebrano już wszystkie 24 BOMBY ?
                  beq Get_BOMB_skipE                         ; TAK!

                  lda index_Address_BOMBS2
                  asl @                                      ; *2
                  tay
                  mwa Buffor_Offset_in_tab_Screen_BOMB,y address1 ; pobierz adres bomby zgodnie ze wskazaniem 'index_Address_BOMBS2'
                  ldy #$00
                  lda (address1),y                                ; czy pod tym adresem jest jeszcze bomba do zebrania?
                  bne Get_BOMB_skipD                              ; TAK!

                  ldy #$01
                  mva (address1),y index_Address_BOMBS2           ; ustaw wskaźnik na kolejną bombę, która ma migać
                  jmp Get_BOMB_loop1

Get_BOMB_skipD    ldy #$00
                  mva #$02 (address1),y                          ; ustaw, że ta bomba ma teraz migać
                  mva index_Address_BOMBS2 index_Address_BOMBS   ; wskaźnik*2+ScreenText40x25 - wskazuje na adres lewego górnego rogu migającej BOMB-y
                  jmp Get_BOMB_skip6

; zebrano wszystkie bomby!
Get_BOMB_skipE    mva #$01 Is_Dance_BOMB_JACK                    ; =1 BOMB JACK tańczy
                  mva #$00 Is_Blink_BOMB                         ; =0 żadna bomba już nie miga
                  jmp Get_BOMB_skip6

;--------------------------------------------------------------------------------------------------------------------------------------------------------
Get_BOMB_mov2     jsr address1_SBW_40bytes         ; -40 - wiersz wcześniej
                  jmp Get_BOMB_skip1

;--------------------------------------------------------------------------------------------------------------------------------------------------------
Get_BOMB_mov3     jsr address1_SBW_40bytes         ; -40 - wiersz wcześniej...
Get_BOMB_mov1     jsr address1_SBW_1byte           ; ...i kolumna wcześniej
                  jmp Get_BOMB_skip1

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; procedura odtwarza tło w miejscu zebrania bomby przez BOMB JACK-a (4-ry znaki)
; (address2) - adres tła(30x25) dla planszy nr. x  (począwszy od adresu $E000 co 1KB są zapamiętane kolejne plansze gry 30x25 znaków)
; (address1) - adres na ekranie(ScreenBuff40x25) gdzie narysujemy tło na zebranej bombie (powodując tym samym zniknięcie bomby)
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Draw_Background_on_BOMB
                  ldy #$00
                  mva (address2),y (address1),y+
                  mva (address2),y (address1),y
                  ldy #@sw
                  mva (address2),y (address1),y+
                  mva (address2),y (address1),y
                  rts

;--------------------------------------------------------------------------------------------------------------------------------------------------------
; Delete the collected bomb
;--------------------------------------------------------------------------------------------------------------------------------------------------------
Delete_Collected_Bomb
                  lda Is_Draw_Back_On_Collected_Bomb
                  beq Del_Col

                  mva #0 Is_Draw_Back_On_Collected_Bomb
                  adw Offset_Bomb_to_Clear #tab_Back32x26 address2
                  adw Offset_Bomb_to_Clear #B1SCR         address1
                  jsr Draw_Background_on_BOMB                         ; procedura odtwarza tło(znaki) w miejscu zebrania bomby przez BOMB JACK-a (4-ry znaki)

                  adw Offset_Bomb_to_Clear #B2SCR address1
                  jsr Draw_Background_on_BOMB                         ; procedura odtwarza tło(znaki) w miejscu zebrania bomby przez BOMB JACK-a (4-ry znaki)

                  adw Offset_Bomb_to_Clear #B3SCR address1
                  jsr Draw_Background_on_BOMB                         ; procedura odtwarza tło(znaki) w miejscu zebrania bomby przez BOMB JACK-a (4-ry znaki)

Del_Col           rts


        	ert *>$Bfff
