;вместо dy могут стоять значения:
 
SPRLIST_STAYING=99 ;мёртвый (xhigh=INVISIBLEX) или уже впечатанный в карту, не обрабатывается логикой
 
SPRLIST_END=100 ;в конце списка ещё spritehsb=1!
 
SPRLIST_PRINTED=101
 
SPRLIST_IMPOSSIBLE=102
 
 
 
;в каких регистрах хранить данные при обработке:
 
;lc=x16 ;XXXXXXXX XXx????? (могут быть проблемы с точностью X при скольжении)
 
;e=dx8 ;sXXXXXXx (не более +-4)
 
;h=y8
 
;d=dy8
 
;c=phase5 (в физике используются только первые несколько фаз)
 
 
 
NEWREGS=0 ;TODO de=x16 (00XXXXXX XXXXxxxx), l=y8, h=dy8, b=dx8 (sXXXxxxx); c=phase (>600*2 фаз не влезет! придётся использовать поле dx8 (или ст. биты h и мл. биты l?) у стоячих червей)
 
 
 
;фазы (черви и мины отличаются регистром B - а у зафиксированных червей больше допустимых комбинаций BC):
 
;0 - стоим (TODO 8 в другую сторону)
 
;TODO 1 - скользим (TODO 9 в другую сторону)
 
;TODO 2..7 - втыкаемся и вылезаем (TODO 10..15 в другую сторону)
 
;16..23 - крутимся (TODO 24..31 в другую сторону) - или стоим/крутимся/сторона - это разные B? тогда всего 3 бита на фазу и 3 на xxx?
 
 
 
 
 
;CHECKMASK не должна портить эти регистры!
 
;ADDCOORDS не должна портить dx,dy!
 
 
 
        macro GETCOORDS
 
       if 1
 
        ld c,(hl)
 
        inc l
 
        ld b,(hl)
 
        inc l
 
       push hl
 
        ld e,(hl)
 
        inc l
 
        ld d,(hl)
 
        inc l
 
        ld a,(hl)
 
        inc l
 
        ld h,(hl)
 
        ld l,a
 
        ex de,hl
 
       else
 
        POP BC ;SPRITE
 
        POP HL ;COORDS
 
        POP DE ;SPEED
 
       endif
 
        endm
 
 
 
        macro REGETCOORDS
 
       if 1 ;TODO NEWREGS
 
       pop hl
 
       push hl
 
        ld a,(hl)
 
        inc l
 
        ld h,(hl)
 
        ld l,a
 
       else
 
        DUP 4
 
        DEC SP
 
        EDUP 
 
        POP HL ;OLD COORDS
 
        pop af ;POP DE ;OLD SPEED
 
       endif
 
        endm
 
 
 
        macro PUTCOORDS
 
       if 1
 
       ex (sp),hl
 
        dec l
 
        dec l
 
        ld (hl),c
 
        inc l
 
        ld (hl),b
 
        inc l
 
       pop bc
 
        ld (hl),c
 
        inc l
 
        ld (hl),b
 
        inc l
 
        ld (hl),e
 
        inc l
 
        ld (hl),d
 
        inc l
 
       else
 
        PUSH de
 
        PUSH hl
 
        PUSH BC
 
        DUP 3
 
        POP BC
 
        EDUP 
 
       endif
 
        endm
 
 
 
        macro ADDCOORDS
 
       if NEWREGS
 
        ld a,l ;dx
 
        or a
 
        jp p,$+4 ;a>=0
 
;a<0,C: значит e>|a|, т.е. фактически нет переноса
 
        dec d ;a<0,NC: d-- (иначе будет компенсирующий инкремент) ;+20
 
        add a,e
 
        jr nc,$+3
 
        inc d ;a>=0,C: d++ (или a<0,C: компенсирующий инкремент) ;+15.5
 
        ld e,a
 
        ld a,h ;dy
 
        add a,l ;y
 
        ld l,a ;y                                                ;+16 = 51.5t (можно x=de, так проще CHECKMASK)
 
       else
 
         ld lx,e
 
        XOR A
 
        SRA E
 
        RRA 
 
        SRA E
 
        RRA 
 
         sra e
 
         rra
 
        ADD A,C ;xlow, phase
 
        ADC HL,DE ;y,xhigh
 
         ld c,a ;xlow, phase
 
         ld e,lx
 
       endif
 
        endm
 
 
 
        macro NEGDX
 
        XOR A
 
       if NEWREGS
 
        sub b ;dx
 
        ld b,a
 
       else
 
        SUB E
 
        LD E,A
 
       endif
 
        endm
 
 
 
        macro NEGDY
 
        XOR A
 
       if NEWREGS
 
        sub h ;dy
 
        ld h,a
 
       else
 
        SUB D
 
        LD D,A
 
       endif
 
        endm
 
 
 
        macro CHECKMASK
 
       if NEWREGS
 
;l=y, de=x (00XXXXXX XXXXxxxx) (ст. биты X использовать только для разных фаз стоячих червей)
 
        push hl
 
         ld a,d ;xhigh>>2
 
         ld h,TMASKLN/256
 
         add a,(hl)
 
         inc h
 
         ld h,(hl)
 
         ld l,a
 
        jr nc,$+3
 
        inc h
 
         ld a,(hl) ;mask byte
 
         ld l,e ;xlow>>2
 
         ld h,TABROLL/256
 
         and (hl) ;bit(x)
 
        pop hl
 
       else
 
;l=xhigh, c=xlow (XXXXXXXX XXx?????), h=y
 
        push hl
 
         ld a,c ;xlow
 
         srl l
 
         rra
 
         srl l
 
         rra
 
         ex af,af' ;' ;xlow>>2
 
        ld a,l ;xhigh>>2
 
        LD L,h ;y
 
        LD H,TMASKLN/256
 
        ADD A,(HL)
 
        INC H
 
        LD H,(HL)
 
        LD L,A
 
       JR NC,$+3
 
       INC H
 
         ex af,af' ;' ;xlow>>2
 
         LD h,(HL) ;mask byte
 
         ld l,a ;xlow>>2
 
         ld a,h ;mask byte
 
         LD H,TABROLL/256
 
         AND (HL) ;bit(x)
 
        pop hl
 
       endif
 
        endm
 
        
 
        macro CHECKX deadaddr
 
       if NEWREGS
 
        ld a,d ;x HSB
 
       else
 
        LD A,L ;x HSB
 
       endif
 
        CP XWID-2;диапазон x на 1 знакоместо меньше, чем карта
 
        JP NC,deadaddr;WMDEAD
 
        endm
 
 
 
WRMOVEQ
 
       pop hl
 
        RET 
 
WRMOVE
 
        ld hl,WORMXY
 
       call SetPgMask
 
DOGRAVa=$+1
 
        LD A,0
 
        ADD A,64
 
        LD (DOGRAVa),A
 
        SBC A,A
 
        and 20 ;"inc d"
 
        LD (WMGRAV_patch),A
 
WM0
 
        GETCOORDS
 
       ld a,d ;dy
 
       cp SPRLIST_PRINTED
 
       jp z,NEWSPD_nogravity;WM0 ;стоячий червь (уже напечатанный) или пустышка
 
       cp SPRLIST_END
 
       jr z,WRMOVEQ ;конец списка
 
       cp SPRLIST_STAYING
 
       jp z,NEWSPD_nogravity;WM0 ;стоячий червь или пустышка
 
        ADDCOORDS
 
        BIT 7,D
 
        jp NZ,WMGOUP
 
        JP C,WMDEAD
 
;движение вниз
 
        CHECKX WMDEAD
 
        CHECKMASK
 
        JP Z,NEWSPD ;проходимо, выходим с новыми координатами
 
        REGETCOORDS
 
        NEGDX ;непроходимо, делаем dx=-dx
 
        ADDCOORDS
 
        JP C,WMDEAD
 
        CHECKX WMDEAD
 
        CHECKMASK
 
        JP Z,NEWSPD_rotate ;проходимо, выходим с новыми координатами
 
;с dx=-dx тоже непроходимо
 
         REGETCOORDS
 
        DEC d ;делаем dy=1 или останавливаем, если уже dy=1
 
        LD de,256
 
        jp nz,NEWSPD_nogravity
 
        ld a,c
 
        and 7
 
        jp nz,NEWSPD_nogravity;nostoprot
 
        ld a,c
 
        and 0xe8 ;8=right
 
        ;or 0;16
 
        ld c,a
 
;nostoprot
 
        LD de,SPRLIST_STAYING*256 ;когда напечатается, будет e!=0
 
       jp NEWSPD_nogravity
 
WMGOUP
 
;движение вверх
 
        jp NC,WMDEAD
 
        CHECKX WMDEAD
 
        CHECKMASK
 
        JP Z,NEWSPD ;проходимо, выходим с новыми координатами
 
        REGETCOORDS
 
        NEGDX ;непроходимо, делаем dx=-dx
 
        ADDCOORDS
 
        jp NC,WMDEAD
 
        CHECKX WMDEAD
 
        CHECKMASK
 
        JP Z,NEWSPD ;проходимо, выходим с новыми координатами
 
        REGETCOORDS
 
         NEGDX ;dx как было
 
        ld d,0;NEGDY ;непроходимо, делаем dy=-dy (отскочили от потолка)
 
        ADDCOORDS
 
        ;JR  C,WMDEAD
 
        CHECKX WMDEAD
 
        CHECKMASK
 
        JR Z,NEWSPD_rotate ;проходимо, выходим с новыми координатами
 
        REGETCOORDS
 
        LD de,0 ;с dy=-dy тоже непроходимо, делаем dx=0, dy=0
 
        ;JR NEWSPDgode
 
NEWSPD
 
WMGRAV_patch=$
 
        INC d ;/nop ;dy
 
NEWSPD_nogravity
 
       bit 4,c
 
       jr z,NEWSPD_skiprot
 
        ld a,c
 
        inc a
 
        xor c
 
        and 7
 
        xor c
 
        ld c,a
 
NEWSPD_skiprot
 
        PUTCOORDS
 
        JP WM0
 
 
 
NEWSPD_rotate
 
        ld a,c
 
        and 0xe8 ;8=right
 
        or 16
 
        ld c,a
 
       ;set 4,c
 
        jp NEWSPD
 
 
 
WMDEAD
 
      if 1
 
      pop hl
 
      push hl
 
       ld a,l
 
       add a,4
 
       ld l,a
 
      else
 
        ld hl,0
 
        add hl,sp
 
        LD (WMsp),HL
 
       ld d,SPRLIST_STAYING ;don't move
 
       push de
 
       ld e,INVISIBLEX ;invisible x
 
       push de 
 
       ;ld a,-1
 
       ;push af ;пустышка
 
      endif
 
       ld a,b
 
       cp sprmine_0/256
 
       jp z,WMDEAD_noworm
 
        ld h,0
 
        add hl,hl
 
        LD DE,NAMES
 
        ADD HL,DE ;name+12
 
      if 1
 
      else
 
        LD SP,iy
 
      endif
 
        CALL MTIDEAD
 
WMDEAD_noworm
 
      if 1
 
       ld d,SPRLIST_STAYING ;don't move
 
       ld l,INVISIBLEX ;invisible x
 
       jp NEWSPD_nogravity
 
      else
 
WMsp=$+1
 
        LD SP,0
 
       JP WM0
 
      endif
 
 
 
ControlCurWorm ;в это время logic вызывать не надо
 
        ld a,(cursorkeys) ;11LRDUef cursor
 
        ld b,a
 
        ld hl,crossalpha ;-64..+64 вправо (-64 самый нижний)
 
        bit 2,b
 
        jr nz,ControlCurWorm_noup
 
        ld a,(hl)
 
        add a,64
 
        jp m,ControlCurWorm_noup
 
        inc (hl)
 
ControlCurWorm_noup
 
        bit 3,b
 
        jr nz,ControlCurWorm_nodown
 
        ld a,(hl)
 
        add a,64-1
 
        jp m,ControlCurWorm_nodown
 
        dec (hl)
 
ControlCurWorm_nodown
 
        ld hl,(curwormxy)
 
        bit 5,b
 
        jr nz,ControlCurWorm_noleft
 
        call UnDrawCurWorm_ifprinted ;nz=not printed
 
        ret nz
 
        res 3,(hl)
 
        ret
 
ControlCurWorm_noleft
 
        bit 4,b
 
        jr nz,ControlCurWorm_noright
 
        call UnDrawCurWorm_ifprinted ;nz=not printed
 
        ret nz
 
        set 3,(hl)
 
        ret
 
ControlCurWorm_noright
 
 
 
        bit 1,b
 
        ret nz ;no jump
 
 
 
        call UnDrawCurWorm_ifprinted ;nz=not printed
 
        ret nz
 
 
 
        GETCOORDS
 
        ld d,-5 ;dy
 
        ld e,1 ;dx
 
        bit 3,c
 
        jr nz,$+5
 
         dec d ;NEWREGS=0
 
         ld e,-1 ;dx
 
        PUTCOORDS
 
        call DrawCurWormData
 
       ld a,STATE_FLYCURWORM
 
       ld (gamestate),a
 
        ret
 
 
 
WormsVsMines
 
        ret
 
 
 
StayingWormsVsMovingWorms ;столкновение летящего со стоящим
 
        ret
 
       
 
CheckFlyingWorms
 
;проверить, есть ли живые не стоящие (логика не дожна зависеть от разницы STAYING/PRINTED!)
 
;z=нету
 
        ld hl,WORMXY
 
CheckFlyingWorms0
 
        ;POP BC ;SPRITE (lsb=xlow*64;32)
 
        ;POP HL ;COORDS
 
        ;POP DE ;SPEED
 
        inc l
 
        inc l
 
        ld a,(hl) ;xhigh
 
        inc l
 
        inc l
 
        inc l
 
       cp XWID
 
       jr nc,CheckFlyingWorms_skip
 
        ld a,(hl) ;dy
 
        cp SPRLIST_END
 
        ret z
 
        cp SPRLIST_PRINTED
 
        jr z,CheckFlyingWorms_skip
 
        cp SPRLIST_STAYING
 
        ret nz
 
CheckFlyingWorms_skip
 
        inc l
 
        jr CheckFlyingWorms0