; [Overlay] Plug-in module for BGE / Сменный модуль для BGE

; Внимание ! Данный модуль является частью редактора BGE и не будет функционировать в иной сборке /DA

; Spray for BGE

           ORG PgnAdr      ; адрес старта модуля

SprayOvb   LD (.RETAD+1),HL
           CALL BSpray
           XOR A
.RETAD    JP 0




SprayPixTB  EQU #C000-#400    ; таблица вывода пикселей в #4000
RNDbuff     EQU SprayPixTB-22 ; буфер для случайных чисел из 22 байт
                              ; Адрес последнего байта буфера должен быть #**FF

;SprayPgn
          ;   DISP PgnAdr

BSpray       ld (.spp),sp
             call SV_UNDO
             call .eraseallw
             call LOADSCR
             call .svSundo
             ld hl,SprayPixTB
             ld de,#4000
             call install_plot
             call RNDF

.l0          call .eraseallw
             call LOADSCR
             call ReWin.i
             call .inPmode
             ld a,#C9   ; ret
             ld (.outplotC),a
             ld a,#FF
             ld (.curX0),a
             ld (.curY0),a
             ld a,%1111
.l1          ld ix,WSpray
             ld (ix+6),a
             ld sp,0
.spp    EQU $-2
             ld a,(REALRGB)
             ld (WSpray.dt_col),a
             call Win_
             cp #FF
            jr z, .exit
.opex        ld bc,WSpray.TAB
            jp TAB_JP

.next        ld a,%1101
            jr .l1

.exit        jp CLOSE


.sel_rgb    call PRGB2
            jr .next


.Sundo      call .eraseallw
            call LOADSCR
            call .exSundo_
           jr .l0

.outPxor
             xor a
            jr 1F
.outPor
             ld a,1
            jr 1F
.outPand
             ld a,2
            jr 1F
.outPnop
             ld a,3
1
             call .outPmode
            jr .next

.view       call LOADSCR
            call NOKEY_
            call WAITKEY_
            jr .l0

.qview      call LOADSCR
            call NOKEY_
            jr .l0

.inPmode     ld a,(.outmode)
.outPmode    ld (.outmode),a
             ld hl,WSpray.setBcol
             ld b,4
            jp SetBCol

.outPnorgb   call .Dnorgb
             jr .next

.Dnorgb      ld a,(WSpray.setNoRGB)
             xor 2
             ld (WSpray.setNoRGB),a
             ret

.Drgb        ld a,ARW_DEFAULT
             call GUI
             jp PRGB2

.eraseallw   ld hl,#C000+6912
             jp ERASE_ALLW.hl

.svSundo                      ; используем страницу окон под miniUNDO
             call OSP         ; ставим страницу окон
             ld hl,#4000
             ld de,#C000
             jp LOADSCR.ldir_

.exSundo      ld a,0
.fstdraw  EQU $-1           ; флаг того что отмена не использовалась
             or a
            jr nz,.exSundo_
             inc a
             ld (.fstdraw),a
             call .svSundo
            jp LOADSCR
.exSundo_    call OSP
             call SWAP_SCR.T
            jp SAVESCR


.run                            ; запуск вывода на экран
             call LOADSCR
             xor a
             ld (.fstdraw),a

.run0        ld hl, #0100       ; смещение для курсора
             ld (ARW_XDISP),hl
             ld hl,SPRAYCUR
             ld (ARW_ADR),hl    ; установка курсора спрея

             ld hl,#00AE
             ld a,(.outmode)
             or a
            jr z,1F
             ld l,#B6
             dec a
            jr z,1F
             ld h,#AE
             dec a
            jr z,1F
             ld hl,00
1            ld (.outplotM),hl
             ld (.outplotcurM),hl
             ld c,#C9  ;ret
             ld a,(WSpray.setNoRGB)
             cp 5
            jr z,1F
             ld c,#78  ; ld a,b
1            ld a,c
             ld (.outplotC),a
             call .eraseallw
            ld ix,DSpray
             ld a,%1000
             ld (ix+6),a
             call Win_
             cp #FF
            jr z,.runquit
             cp 4
            jr nc,1F
             call .outPmode    ; xor/or/and/nop
            jr .run0
1            sub 4
             ld bc,DSpray.TAB
            call TAB_JP
             jr .run0

.runquit
             ld a,ARW_DEFAULT
             call GUI
             call SAVESCR
             jp .l0

.Cr        ; прорисовка при создании окна
            ld hl,#00B6    ; or (hl):nop    ; or
            ld (.outplotM),hl
            ld (.outplotcurM),hl

            ld de,GSpray.size             ; спрайты пояснительных иконок
            ld hl,#0206
            call .spr2
            ld hl,#0209
            call .spr2

.setup                                   ; селект-бары параметров спрея
            ld de,#0506
            ld a,(.size)
            ld b,9
            call .csbar
            ld b,5
            ld de,#0509
            ld a,(.inte)
            call .csbar
            ld de,#090C          ; строим рамку
            call RealWin
            ld l,d
            ld h,e
            dec l
            dec h
              ex de,hl     ; очистка области
              call RASCH_
              ld c, 6*8+5   ; c - число линий
1              ld b,7      ; b - длина линий
               push hl
2               ld (hl),0
                inc l
              djnz 2B
               pop hl
               call INC_Y
               dec c
              jr nz, 1B

             ld de,#0B0E        ; вывод границ распылителя
             call RealWin
             ld l,d
             ld h,e
             add hl,hl
             add hl,hl
             add hl,hl
             ld de,#0404
             add hl,de
             ex de,hl           ; de - центр распылителя

              ld a,(.size)        ; получаем размер пятна
              add a,a           ; *2
              add a,4
              ld (.RAD),a
              inc a
              ld (.rad),a

              xor a          ; вывод границы пятна
1             push af
              call .rXY
              call nc,.outplot
              pop af
              add a,1
.tcircl  EQU $-1
             jr nc, 1B

                              ; предпросмотр спрея
              ld b,12
.l2           push bc

              ld a,(.RAD)
              ld (.rad_),a
              sub 4
             jr nc,1F   ; страховка возможно лишняя
              xor a
1       ;      and #1E  ; страховка лишняя
              ld c,a
              ld b,0
              ld hl,.rdTBadr
              add hl,bc
              ld a,(hl)
              inc hl
              ld h,(hl)
              ld l,a
              ld (.rdtbADR),hl
              ld a,(.size)
              ld c,a
              ld a,(.inte)
              ld b,a
              add a,a
              add a,a
              add a,b
              add a,12
              sub c
             ld (.spray_pls),a
             ld b,a
1             push bc
              call .rndXY
              pop bc
             djnz 1B
              pop bc
             djnz .l2
            ret

.csbar         ; вывод селект-бара  b элементов, a - номер выборки, DE - d-x,e-y
               ld c,a
               ld a,b
               push bc
               sub c
               ld c,a
               call RealWin
               ld h,e
               ld l,d
               ld (.spr1_ix),hl
1              ld a,c
               ld de,GSpray.csbar0
               cp b
              jr nz,2F
               ld de,GSpray.csbar1
2              push bc
                call .spr1
               pop bc
              djnz 1B
               pop bc
               ret


.spr1       ; вход de - адрес спрайта , выход след позиция
              push ix
               ld ix,.spr1_ix
               call LoadWS
               ld a,(.spr1_ix)
               inc a
               ld (.spr1_ix),a
              pop ix
              ret


.spr2       ; вход de - адрес спрайта,  h=x , l=y size 16x16
              ex de,hl
              call RealWin
              push ix
              ld ix,.spr2_ix
              ld (ix+0),d
              ld (ix+1),e
              ex de,hl
              call LoadWS
              pop ix
              ret

.DrawInt      ld a,(DIRECT)   ; прерывания при выводе пульверизатором
              bit 4,a
              ret z
              xor a
              ld (.fstdraw),a  ;  обнуление отмены

              call PutArw   ; процедура из GUI - вывод курсора. Используем для устранения исчезания курсора.
              ld hl,(ARW_X)
              ld (.DIntArwX),hl
              ld de,(ARW_XDISP)
              ld a,l
              sub e
             jr nc,1F
              xor a
1             and #F8
              ld (.curX0),a
              ld a,h
              sub d
             jr nc,1F
              xor a
1             ld (.curY0),a

              ld b,8
.spray_pls EQU $-1   ; количество точек
1
              ld de,0
.DIntArwX  EQU $-2

2             push bc
              call .rndXY
              pop bc
             djnz 2B
4             call GetArw   ; процедура из GUI - убираем курсор для перерисовки
              ret


.WinInt          ; обработка прерываний в окне выбора
              ld a,(DIRECT)
              bit 4,a
              ret z
              ld hl,(ARW_XC)
              ld bc,(WSpray)
              ld a,h
              sub b
              ld d,a     ; y поз.
              ret c
              ld a,l
              sub c
              ld e,a     ; x поз.
              ret c
                          ;  проверяем позиции в области селектбаров
              ld a,e
              sub 5
              ld e,a      ; номер позиции
             ret c
              cp 9
             ret nc
              ld hl,.size
              ld a,d
              cp 6
             jr z, 1F
              inc hl
              cp 9
             ret nz
              ld a,e
              cp 5
             ret nc
1             ld (hl),e
             jp .setup




.spr1_ix    DB 0,0,1,1
.spr2_ix    DB 0,0,2,2

.size       DB 4
.inte       DB 2
.outmode    DB 1          ; xor/or/and/nop







.rndXY                    ; in de: d=y e=x out draw rnd plot
             ld b,20      ; радиус области попадания
.rad_   EQU $-1
1            call RND   ; X
             sra a
             sra a
    ;         sra a      ; уменьшаем максимальный разброс до +/- 32
             ld c,a
             bit 7,a
            jr z, 2F
             neg        ; отриц
2            cp 20
            jr nc,1B
             cp b
            ret nc

             ld hl,.rdtb20
.rdtbADR  EQU $-2              ; адрес таблицы величин для радиуса
             add a,l
             ld l,a
            jr nc, 4F
             inc h
4                          ; hl - адрес максимального Y
5            call RND
             sra a
             sra a
 ;            sra a
             ld b,a
             bit 7,a
            jr z,6F
             neg
6            cp 20
            jr nc,5B
             cp (hl)
            ret nc

7
             ld a,d   ;y
             add a,b
             bit 7,b
            jr z, 1F   ;+
             ccf
1            ret c          ; если вылезли за экран
             cp 192
             ret nc
             ld h,a
             ld a,e   ;x
             add a,c
             bit 7,c
            jr z,1F
             ccf
1            ret c
             ld l,a         ; x
             and #F8        ;позиция с начала знакоместа
             sub 0          ; проверка на попадание в курсор
.curX0   EQU $-1           ; начальная позиция X - знакоместа курсора
            jr c,.outplot
             cp 16          ; ширина буфера в пикселях
            jr nc,.outplot
             ex af,af'
             ld a,h         ; y
             sub 0
.curY0   EQU $-1           ; Начальная позиция Y - буфера курсора
            jr c,.outplot
             cp ARW_YR      ; высота стрелки
            jr nc, .outplot
             add a,a
             ex af,af'
             bit 3,a
            jr z,1F
             ex af,af'
             inc a          ; смещение в буфере относительно текущей точки
             ex af,af'
1
          ; вывод пикселя в области курсора  / in h -y, l-x
              push de,bc
              ex de,hl
              call .pixadr    ; нужно для вывода цвета
              ld de,PLACE
              ex af,af'
              add a,e
              ld e,a
             jr nc,1F
              inc d
1             ld a,(de)  ; de адрес точки в буфере
.outplotcurM  or (hl)         ; меняется от режима
              nop
              ld (de),a
              call .outplotC
              pop bc,de
              ret

.outplot                 ; in h -y, l-x
              push de,bc
              ex de,hl
              call .pixadr
              ld a,(bc)
.outplotM     or (hl)         ; меняется от режима
              nop
              ld (bc),a
              call .outplotC
              pop bc,de
              ret
.outplotC     ld a,b             ; ld a,b / ret
              rrca
              rrca
              rrca
              and 3
              or #58           ; bc -адрес атрибутов
              ld b,a
              ld a,(bc)
              call MIXCOL
              ld (bc),a
              ret

.pixadr
             ld h,high SprayPixTB
             ld l,d
             ld a,(hl)   ; поз в трети
             inc h
             ld b,(hl)   ;треть и поз в знакоместе
             inc h
             ld l,e
             or (hl)     ; + x  знакоместа
             ld c,a      ; адрес собран
             inc h       ; (hl) - маска
             ret



.rXY                       ; вход a - угол в Pi/128  [0-255]
             push de
             push af
             and #3F
             ld c,a        ; bc - расстояние от центра до точки
             ld b,0
             ld hl,.sin64_128
             add hl,bc
             call .rXYml
             ex af,af'
             ld hl,.sin64_128+64
             or a
             sbc hl,bc
             call .rXYml
             ld c,a      ;x
             ex af,af'
             ld b,a      ;y
             pop af
             pop de
             rla
             ld h,a
             ld a,c
            jr nc,1F
             neg         ; -X
             add a,e
             ccf
            jr 2F
1            add a,e
2            ret c
             ld l,a
             ld a,h
             rla
             ld a,b
            jr nc,1F
             neg        ; -y
             add a,d
             ccf
            jr 2F
1            add a,d
2            ret c
             cp 192
             ccf
             ret c
             ld h,a
             or a
             ret

.rXYml     ld h,(hl)
             ld a,4
.rad       EQU $-1       ; временный радиус (расстояние от центра до точки)
             call MULS
             add hl,hl
             ld a,h
             ret

.RAD      DB  4      ; radius

.sin64_128    ; таблица синусов 65 элемента с шагом PI/128 умноженных на 128 ; может потом заменю на встроенную функцию
           DB 0,3,6,9,13,16,19,22,25,28,31,34,37,40,43,46
           DB 49,52,54,58,60,63,66,68,71,74,76,79,81,84,86,88
           DB 91,93,95,97,99,101,103,105,106,108,110,111,113,114,116,117
           DB 118,119,121,122,122,123,124,125,126,126,127,127,127,128,128,128,128



         ; таблицы соответствий x и y  x= 0 ... 20
.rdTBadr    DW .rdtb4,.rdtb6,.rdtb8,.rdtb10,.rdtb12,.rdtb14,.rdtb16,.rdtb18,.rdtb20
              ;
.rdtb4      DB 4,4,3,2
.rdtb6      DB 6,6,6,5,4,3
.rdtb8      DB 8,8,8,7,7,6,5,4
.rdtb10     DB 10,10,10,10,9,9,8,7,6,4
.rdtb12     DB 12,12,12,12,11,11,10,10,9,8,7,5
.rdtb14     DB 14,14,14,14,13,13,13,12,11,11,10,9,7,5
.rdtb16     DB 16,16,16,16,15,15,15,14,14,13,12,12,11,9,8,6
.rdtb18     DB 18,18,18,18,18,17,17,17,16,16,15,14,13,12,11,10,8,6
.rdtb20     DB 20,20,20,20,20,19,19,19,18,18,17,17,16,15,14,13,12,11,9,6

SPRAYCUR   DB 225,0,192,156,224,10,224,12
           DB 192,18,192,18,192,22,192,22
           DB 225,12,243,0

DSpray     DB 0,0,32,24,0,0,%1000
           DB 0
           DW Nil              ; объект-текст
           DW Nil              ; объект-подсветка (выборка)
           DW .HDraw           ; горячие клавиши
           DW Nil              ; объект-кнопки (выборка)
           DW Nil              ; объект-флажки
           DW Nil              ; объект-радио кнопки
           DW Nil              ; ползунок
           DW Nil              ; вызов при создании
           DW BSpray.DrawInt   ; вызов на "прерываниях"
           DW #FFFF

.TAB        DW BSpray.exSundo        ; 4 - SUndo
            DW BSpray.Dnorgb         ; 5 - no rgb
            DW BSpray.Drgb           ; 6 - rgb
            DW Col                   ; 7 - mini rgb
.HDraw
        DB "1",0
         DW 0                 ; xor
        DB "2",0
         DW 1                 ; or
        DB "3",0
         DW 2                 ; and
        DB "4",0
         DW 3                 ; nop
        DB "U",0
         DW 4                 ; Spray undo
        DB "N",0
         DW 5                 ; No RGB
        DB "C",0
         DW 6                 ; rgb
        DB "K",0
         DW 7                 ; mini RGB
        DB #FF


WSpray     DB 14,2,16,18,5*8,5,%00001111
           DB 0
           DW .Text              ; объект-текст
           DW .SWspr             ; объект-подсветка (выборка)
           DW .HWkeys            ; горячие клавиши в окне
           DW .Butts             ; объект-кнопки (выборка)
           DW Nil                ; объект-флажки
           DW Nil                ; объект-радио кнопки
           DW Nil                ; ползунок
           DW BSpray.Cr          ; вызов при создании
           DW BSpray.WinInt      ; вызов на "прерываниях"
           DW #FFFF

.Text      DB "Spray",13,0

.SWspr     DB 9,12,5,5,%11
           DB #FF

.Butts
           DB 4,3,2,2,7,%11  ; 1 - xor
.setBcol EQU $-2
           DW XORS
           DB 6,3,2,2,5,%11  ; 2 - or
           DW ORS
           DB 8,3,2,2,7,%11  ; 3 - and
           DW ANDS
           DB 10,3,2,2,7,%11  ; 4 - nop
           DW NOPS
           DB 13,3,2,2,7,%11 ; 5 - NO RGB
.setNoRGB EQU $-2
           DW NORGBS
           DB 1,15,2,2,7,%11 ; 6 - RGB
           DW RGBS
           DB 3,15,2,2,7,%00 ; 7 - DTRS
.dt_col  EQU $-2                   ; цвет текущих атрибутов
           DW DTRS
           DB 1,3,2,2,6,%11  ; 8 - Spray run
           DW SPRAYS

           DB #FF

.TAB       DW BSpray.run            ; 0 - Run
           DW BSpray.outPxor        ; 1 - xor
           DW BSpray.outPor         ; 2 - or
           DW BSpray.outPand        ; 3 - and
           DW BSpray.outPnop        ; 4 - nop
           DW BSpray.outPnorgb      ; 5 - no RGB
           DW BSpray.sel_rgb        ; 6 - RGB
           DW BSpray.sel_rgb        ; 7 - DTRS
           DW BSpray.run            ; 8 - Run
           DW BSpray.Sundo          ; 9 - Spray Undo
           DW BSpray.view           ; 10 - view
           DW BSpray.qview          ; 11 - q view

.HWkeys
        DB "1",0
         DW 1                 ; xor
        DB "2",0
         DW 2                 ; or
        DB "3",0
         DW 3                 ; and
        DB "4",0
         DW 4                 ; nop
        DB "N",0
         DW 5                 ; no rgb
        DB "C",0
         DW 6                 ; rgb
        DB "U",0
         DW 9                 ; S.undo
        DB "V",0
         DW 10                ; View
        DB #0D,0
         DW 11                ; q view

        DB #FF

;ESpray  DB 0,0,32,24,0,0,%1000
;        DB 0
;        DW Nil          ; объект-текст
;        DW Nil          ; объект-подсветка (выборка)
;        DW Nil ;BSpray.Hkeys ; горячие клавиши при рисовании
;        DW Nil          ; объект-кнопки (выборка)
;        DW Nil          ; объект-флажки
;        DW Nil          ; объект-радио кнопки
;        DW Nil          ; ползунок
;        DW Nil          ; вызов при создании
;        DW Nil ;BSpray.Int   ; вызов на "прерываниях"
;        DW #FFFF


RNDF           ld hl,RNDbuff  ; начальное заполнение буфера для RND
1              ld a,r
               and #07
               ld b,a
               ld a,#35
.seed   EQU $-1
2              bit 0,a
              jr z,3F
               xor %01110000
3              rrca
              djnz 2B
               ld (.seed),a
               ld (hl),a
               inc l
              jr nz,1B
               ret


;RND           ; метод Фибоначчи с запаздываниями , использую буфер на 256 байт вместо 98 для удобства. /DA
;             push hl,de,bc
;             ld de,RNDbuff+256-97   ; 97 a
;.ia      EQU $-2
;             ld hl,RNDbuff+256-33   ; 33 b
;.ib      EQU $-2
;             ld bc,RNDbuff          ; 0 i
;.ii      EQU $-2
;             ld a,(de)
;             sub (hl)
;             ld (bc),a           ; X[i]= X[i-a]-X[i-b]
;             inc l
;             inc c
;             inc e
;             ld (.ia),de
;             ld (.ib),hl
;             ld (.ii),bc
;             pop bc,de,hl
;             ret

RND      push hl        ; code based of http://zx-pk.ru/threads/9031-etyudy.html?p=930124&viewfull=1#post930124   at blackmirror
         ld hl,RNDbuff  ; используется буфер в 22 байта
.bfadr EQU $-2
         ld a,(hl)
         inc l
        jr z,.rnd_2
.rnd_1   sub (hl)
         ld (hl),a
         ld (.bfadr),hl
         pop hl
       ret
.rnd_2   ld l,-22
        jp .rnd_1


GSpray                             ; спрайты опций
.size   DB 0,4,0,8,0,16,0,36       ; размер области
        DB 0,78,0,149,57,4,42,4
        DB 69,4,84,149,84,78,84,36
        DB 68,16,68,8,124,4,0,0
.inte   DB 0,4,0,8,0,16,0,36       ; интенсивность
        DB 0,64,0,142,57,0,42,31
        DB 69,0,84,142,84,64,84,36
        DB 68,16,68,8,124,4,0,0

.csbar0 DB 0,0,0,126,66,126,0,0       ; спрайт выборки - пустая позиция
.csbar1 DB 0,24,60,110,126,126,60,24  ; спрайт выборки - выбранныя позиция


LSpray       EQU $-SprayOvb
        ASSERT  $ < RNDbuff   ; SprayPixTB
     ;   ENT

      DISPLAY "Spray len :",/a, LSpray

