;------------------------------------------------------------------
; bmBUFF  EQU BUFF  ; буфер крайней маски
mBUFF   EQU BUFF
sprBUFF EQU BUFF+34

; Процедура вывода спрайта с маской с точностью до пикселя.
; Разработана на основе: 'SETSPR' (c) 1997, Феськов Кузьма  ( zx forum #04 )
; С обрезкой знакомест слева/сверху

SetSPRITE       ;  IN: A  - high bytes X (sign flag)
                     ; A' - high bytes Y (sign flag)
                     ; DE - E = X ,D = Y
                     ; HL - L - scroll pixels for left X , H - cut up lines
                     ; IX - addres of sprite , HL' - address of mask
                     ; BC - B = size Y-1 , C = size X in bytes


                inc b
                push bc
                ld b,a
                ld a,e
                sub l
                ld e,a
               jr nc,1F
                dec b
1               and 7       ; номер бита смещения в байте для счетчика
                ld (.cRoll_),a
                ld (.cRll_),a
                ld a,b
                or a
               jr z,2F
                ; отрицательная координата
                xor a
                sub e   ; neg e
                rrca : rrca : rrca
                and #1F
                ld b,a       ; количество пропускаемых байтов
.cRll_ EQU $+1 : ld a,0
                or a
               jr z,1F
                inc b
1               ld e,0
2               ld a,b
                add a,low mBUFF
                ld (.dcX),a      ; для адреса буфера с пропуском
                ld a,c
                ld (.szx1),a
                inc a
                ld (.szx3),a
                ld (.szx4),a
                sub b     ; количество пропускаемых байтов по x
                pop bc
               ret c
                ld (.szx5),a
                ex af,af'
                or a
               jr z,1F
                ld a,b
                add a,d ; b - neg X
                ld b,a
                ld a,h
                sub d   ; h + neg X
                ld d,0
                ld h,a
1               ld l,c     ; size X
                ld c,b     ; size Y lines
                ld b,h
                ld h,0

                inc b
                dec b
               jr z,2F
                ex de,hl
1               add ix,de  ; сместили адрес на пропуск линий
                push de
                exx
                pop de
                add hl,de  ; сместили маску на пропуск линий
                exx
               djnz 1B
                ex de,hl
2               call PixHL  ; hl - адрес в экране
1               push bc,hl
                call .sprbuf  ; Переносим текущую линию спрайта в буфер
.cRoll_ EQU $+1 : ld a,0       ; счетчик сдвигов
                  or a         ; Проверяем бит смещения на 0, если ноль, то двигать буфер  не надо
                call nz,.rolBF  ; Сдвигаем буфер
                call .prnBF  ; Печатаем буфер
                pop hl,bc
                dec c
               ret z
                inc h
                ld a,h
                and 7
               jp nz,1B
                ld a,l
                sub #E0
                ld l,a
                sbc a,a
                and #F8
                add a,h
                ld h,a
                cp #58
               ret nc
               jp 1B


.sprbuf         exx
.sprbuf_hl      ld hl,BmBUFF    ; exchange ['ld hl,BmBUFF' (for NoM)] to ['ld de,BmBUFF' (for other)]
                ld de,mBUFF
                exx
                ld de,sprBUFF
.szx1 EQU $+1 : ld b,0        ; sx
1               ld a,(ix+0)    ; Копируем данные в буфер
                ld (de),a
                inc ix
                inc de
                exx
                ld a,(hl)    ; Копируем данные маски в буфер
                ld (de),a
                inc hl
                inc de
                exx
               djnz 1B
                xor a
                ld (de),a      ; обнуляем следующий байт
                exx
                cpl
                ld (de),a      ; следующий байт маски
                exx
               ret


.rolBF          push af
                ex de,hl      ; A - counter for bits
1               ld hl,sprBUFF
.szx3 EQU $+1 : ld b,1      ; sx+1
                or a           ; res flag c
2               rr (hl)
                inc hl
               djnz 2B
                dec a
               jr nz,1B
                pop af      ; A - counter for bits

1               ld hl,mBUFF
.szx4 EQU $+1 : ld b,1      ; sx+1
                scf           ; set flag c
2               rr (hl)
                inc hl
               djnz 2B
                dec a
               jr nz,1B

3               ex de,hl       ; восстанавливаем hl
               ret


.prnBF           push ix
.dcX   EQU $+2 : ld ix,mBUFF   ; (ix+0) - mask , (ix+34) - sprite
.szx5  EQU $+1 : ld b,1      ; sx+1-[пропуск байтов]

.tpOPER         ; процедура вывода байта линии
                DUP 7 : NOP : EDUP    ; 7 NOP exchanged for output code   SetSPRITE.tpOPER

                ld (hl),a
                inc ix
                inc l
                ld a,l
                and #1F
               jr z,2F
               djnz .tpOPER
2               pop ix
               ret

.setOutput      push af
                cp 4
                ld a,#21    ; [ ld hl,**** ] for NoM mode   - режим NoM
               jr z,1F
                ld a,#11    ; [ ld de,**** ] for other modes
1               ld (.sprbuf_hl),a
                pop af
                add a,a
                add a,a
                ld l,a
                ld h,0
                ld bc,.ETAB
                add hl,bc
                ld c,(hl)
                inc hl
                ld b,(hl)
                inc hl
                ld e,(hl)
                inc hl
                ld d,(hl)
                ld hl,.tpOPER
                push hl,bc
                ld b,7
1               ld (hl),0     ; nop dup 7
                inc hl
               djnz 1B
                pop bc,hl
                ex de,hl
                ldir
               ret

;--------------------------------------------------------------
; (ix+0) - mask , (ix+34) - sprite

.ETAB    DW .lPUT , .sPUT
         DW .lOR  , .sOR
         DW .lXOR , .sXOR
         DW .lAND , .sAND
         DW .lPUT , .sPUT    ; NoM  -  Not MASK
         DW .lOnM , .sOnM    ; OnM  -  Only MASK
         DW WinClipping.lCUTPUT, WinClipping.sCUTPUT  ; для обрезки N6

; установка режима PUT
; установка режима NoM аналогична PUT (разница в коде буфера) ; Без маски / No Mask
.sPUT           ld a,(ix+0) ; маска
                and (hl)
                or (ix+34)  ; данные спрайта
.lPUT  EQU $-.sPUT

; установка режима OnM   ; Только маска / Only Mask
.sOnM           ld a,(ix+0) ; маска
                and (hl)
.lOnM  EQU $-.sOnM

; установка режима OR
.sOR            ld a,(ix+34)
                or (hl)
.lOR  EQU $-.sOR

; установка режима XOR
.sXOR           ld a,(ix+34)
                xor (hl)
.lXOR  EQU $-.sXOR

; установка режима AND
.sAND           ld a,(ix+34)
                cpl
                and (hl)
.lAND  EQU $-.sAND





SetASPRITE_     ;  IN = in for SetASPRITE  (mask_attr = sprite_attr+6912)
                ;  attributes mask : #FF for screen and #00 for sprite
                push af
                exx
                ld bc,6912
                ld hl,SetASPRITE.amsk_c
                ld (SetASPRITE.Adr_amsk_c),hl
                exx
                pop af
                call SetASPRITE
                push af
                exx
                ld hl,SetASPRITE.ret
                ld (SetASPRITE.Adr_amsk_c),hl
                exx
                pop af
               ret

SetASPRITE      ;  IN: A  - high bytes X (sign flag)
                     ; A' - high bytes Y (sign flag)
                     ; DE - E = X ,D = Y
                     ; HL - L - scroll pixels for left X , H - cut up lines
                     ; IX - addres of attributes sprite
                     ; BC - B = size Y-1 , C = size X in bytes
                   push de
                   or #F8
                   ld d,a
                   ld a,e
                   or 7
                   and d
                   pop de
                   rrca : rrca : rrca

                    ld e,a
1                  ex af,af'
                   push de
                   or #F8
                   ld e,a
                   ld a,d
                   or 7
                   and e
                   pop de
                   rrca : rrca : rrca

                    ld d,a
1                  ld hl,#0000
                   bit 7,e
                  jr z,1F
                   xor a
                   sub e
                   ld l,a
                   ld e,0
1                  bit 7,d
                  jr z,1F
                   xor a
                   sub d
                   ld h,a
                   ld d,0
1                  ld a,b
                   rrca : rrca : rrca
                   and #1F
                   inc a
                   sub h
                   ld b,a
                  ret z      ; если все атрибуты ушли вверх
                   push de,bc
                   ld d,0
                   ld e,c
                   ld b,h
                   inc b
                   dec b
                  jr z,2F
1                  add ix,de  ; попуск линий
                  djnz 1B
2                  ld e,l
                   add ix,de  ; пропуск начальных байтов
                   ld a,c
                   ld (.szX_),a
                   sub l
                   ld (.szoX_),a
                   pop bc,de
                   or a
                  ret z       ; если все атрибуты ушли влево
                   call RASCHA
                   ld c,b
1                  push ix,hl
.szoX_ EQU $+1 :   ld b,1
2                  xor a
                   call .ret    ; пропуск маски атрибутов
.Adr_amsk_c   EQU $-2
                   or a
                  jr nz,3F
                   ld a,(ix+0)
                   ld (hl),a
3                  inc ix
                   inc l
                   ld a,l
                   and #1F
                  jr z,4F
                  djnz 2B
4                  pop hl,ix
                   ld de,32
                   add hl,de
.szX_  EQU $+1 :   ld e,1
                   add ix,de   ; новая строка
                   ld a,h
                   cp #5B
                  ret nc
                   dec c
                  jr nz,1B
                  ret

.amsk_c            exx
                   push ix
                   pop hl
                   add hl,bc
                   ld a,(hl) ; пропуск атрибутов 0
                   exx
.ret              ret




;******** WIN x8/x1 interface **********
; входы для процедур внешних модулей изменения окна
; вызов:     CALL WinFunc : DB Function_Number  ; вызывает функцию по номеру
;
WinFunc
             ld (.A_),a
             ld (.BC_),bc
             ld (.DE_),de
             ld (.HL_),hl
             ex (sp),hl
             ld a,(hl)
             add a,a
             inc hl
             ex (sp),hl
             ld de,.WinFN_
             ld l,a
             ld h,0
             ld bc,PgnPage1*256+4
             ld a,SuxPage
             call CALLSWPhlA ; вход DE - адрес подпрограммы, HL - параметр, B - страница, C - номер модуля, A - work page
             ld bc,0
.bc_   EQU  $-2
             ld de,0
.de_   EQU  $-2
             ld hl,0
.hl_   EQU  $-2
             ld a,0
.a_    EQU $-1
             or a
            ret
; вызываемые процедуры
.WinFN_      ld bc,.end_wn_
             push bc       ; выход
             ld bc,.TABw
             add hl,bc
             ld e,(hl)
             inc hl
             ld d,(hl)
             push de       ; процедура
             ld bc,0
.BC_   EQU  $-2
             ld de,0
.DE_   EQU  $-2
             ld hl,0
.HL_   EQU  $-2
             ld a,0
.A_    EQU $-1
             ret         ; переход на процедуру
.end_wn_     ld (.a_),a
             ld (.bc_),bc
             ld (.de_),de
             ld (.hl_),hl
            ret          ; выход

.TABw     ; процедуры

           DW WinClipping.outWinBoof_   ; 0 - прорисовка окна с обработкой рамки и маски цвета
           DW WinMenu.EraseAllw         ; 1 - стираем все окна
           DW EXcnknum_                 ; 2 - меняем чанк обрамления по кругу
                                        ; in: A=0 - уменьшение плотности , A!=0 - увеличение
           DW WinMenu.outWinBoof        ; 3 -
           DW NormilizeWin              ; 4
           DW CleanMask                 ; 5
           DW wmbooframka               ; 6
           DW WinInvers                 ; 7 -
           DW WinMenu        ; 8 -
           DW WinMenu        ; 9 -
           DW WinMenu        ; 10 -
           DW WinMenu        ; 11 -
           DW WinMenu        ; 12 -
           DW WinMenu        ; 13 -
           DW WinMenu        ; 14 -
           DW Ret            ; 15 -












