Login

Subversion Repositories NedoOS

Rev

Rev 971 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

        ;MAIN "VERA",8

DV32    LD A,(MENLP-1) ;кол-во пунктов
        SUB B          ;не больше ли?
        LD A,C
        RET NC
        JR SETCUR
DIV3
        JR C,SETCUR
        LD C,A
        LD B,1
DV31    SUB 3
        JR Z,DV32
        INC B
        JR NC,DV31

;установить текущий пункт меню
SETCUR
SETCURp1=$+1
        LD A,1      ;текущ. пункт
        LD B,A
        ADD A,A     ;A*3
        ADD A,B
        SCF
        RET

;Готовы ли к скроллу? (мигает курсор)
;флаг C - да
SCRLMAP
        LD A,(CCURS+1)
        LD B,A
        SUB 2
        CP 2
        LD A,B
        RET

;Проверка на анимацию предметов
;by axor, 27.04.2004
;Изменен формат анимированных спрайтов
;11.05.2004
;И снова сменен формат. Уже давно, но работаю только сейчас
;4.07.05, 7.09.05
;OUT: флаг C=1 значит спрайт анимированный и его нужно печатать
;          C=0 не анимация
ANIM
        srl a ;RRA    ;Это анимация?
        RET NC ;Нет!
        ;jr $
        PUSH DE
        LD C,A        ;A=номеру группы
        LD B,0
        ADD A,A       ;A=A*2
        LD E,A
        LD D,B
        LD A,H        ;Номер спрайта в группе*2
        EX AF,AF' ;'
        LD HL,AdrGrps
        ADD HL,DE
        LD E,(HL)
        INC HL
        LD D,(HL)     ;Высчитали адрес заголовка группы

        LD HL,AnimGrps
        ADD HL,BC
        LD A,(HL)
        AND A
        JR Z,ANM_FRS  ;была ли группа на экране?

;Группа уже на экране, значит просто берем
;текущую фазу спрайта
        EX DE,HL
        INC HL
        JR AN_CUR

;Группа печатается впервые
ANM_FRS INC (HL)      ;Установим флаг появления групп на экране
        EX DE,HL      ;HL-адрес заголовка группы

        LD E,(HL)     ;Восстан. для счетчика
        INC HL
        DEC (HL)
        JR NZ,AN_CUR  ;уменьшаем счетчик (скорость)

;Если значение счетчика нулевое, то меняем фазу анимации
        LD (HL),E     ;восстановили счетчик
        INC HL
        LD C,(HL)     ;Тип анимации

        INC HL
        LD A,(HL)     ;кол-во фаз в группе
        AND A
        JR Z,AN_CUR+2 ;Если кол-во фаз=0, то это заморож. анимац
        INC HL
        INC (HL)      ;Меняем фазу
        LD E,(HL)
        CP E
        JR NC,AN_NXT

        DEC E
        LD (HL),E
        DEC C
        JR Z,NO_FADE  ;Зацикл. аним.
        DEC C
        JR NZ,NO_FADE ;Реверсивная

;FADE
;Затух. аним.
;Меняет значение спрайтов на карте
;Это дает возможность перейти к другой аним. группе
;или оставить спрайт навсегда на карте
        INC HL
        EX AF,AF' ;'
        LD C,A
        ADD HL,BC
        LD C,(HL)
        INC HL
        LD H,(HL)
        LD L,C
        LD D,B  ;B=0
        SLA E
        ADD HL,DE     ;HL=ссылке на фазу спрайта с учетом смещ.
        LD A,(HL)
        INC HL
        LD C,(HL)
MLB2    LD HL,0       ;Ставим на карту последний спрайт группы,
        LD (HL),A     ;тем самым убирая анимацию вообще или
        INC HL        ;переходя на новую анимацию
        LD (HL),C
        LD L,A
        LD H,C
        POP DE
        SCF
        RET

NO_FADE LD E,C
        LD (HL),E
        JR AN_NXT

AN_CUR  INC HL
        INC HL
        INC HL
        LD E,(HL)     ;смещение от начала фазы
AN_NXT  INC HL
        EX AF,AF' ;'
        LD C,A
        ADD HL,BC
        LD C,(HL)
        INC HL
        LD H,(HL)
        LD L,C
        SLA E
        LD D,B  ;B=0
        ADD HL,DE     ;HL=ссылке на фазу спрайта с учетом смещ.
        LD A,(HL)     ;берем номер спрайта
        INC HL
        LD H,(HL)
        LD L,A
        POP DE
        SCF
        RET

;Печать видимой части карты
PRMAP
        LD HL,A_TILE
        LD (ADRTL+1),HL
        XOR A
        LD (TILED+1),A

        LD DE,0
        LD BC,(DispMapX) ;B-Y, C-X ;смещение карты
        LD HL,(HEROCRD)  ;H-Y, L-X ;коорд. героя на карте
        LD A,H
        SUB B
        JR NC,PM0
        NEG
        CP 2
        JR NC,PM2
PM0     CP SCRHG
        JR NC,PM2
        ADD A,A
        ADD A,SHADSCR/256
        LD H,A
        LD A,L
        SUB C
        JR NC,PM1
        NEG
        CP 2
        JR NC,PM2
PM1     CP SCRWD
        JR NC,PM2
        ADD A,A
        LD L,A
        EX DE,HL
PM2     EX DE,HL
        LD (WHERE+1),HL

        CALL CalcMap  ;Высчитываем смещение в карте
HMAP    LD C,SCRHG/2  ;Высота
        LD DE,SHADSCR ;D-Y, E-X

       if !EGA
;Искусственно делаем значение SP, которое будет на выходе
        PUSH HL,HL,HL   ;,HL-если будет CALL BLOCK22
        LD (BL22SP+1),SP
        POP HL,HL,HL    ;,HL
       endif

PRMLP0  LD B,SCRWD/2 ;Ширина
PRMLP1  PUSH DE
        PUSH BC

        LD A,PG_MAP
        ;LD (NUMPAGE),A
        ;OR 16+8
        ;LD BC,#7FFD
        ;OUT (C),A
        call PAGE

        LD A,(HL)
        LD (MLB2+1),HL
        INC L
        PUSH HL
        LD H,(HL)
        LD L,A
        CALL ANIM    ;Проверка на анимацию (A bit0) и т.п.

;Флаг полного обновления экрана, если=0, 1-не обновлять
MAPFLAG LD A,0
       if PRFULLMAP
        xor a
       endif
       if EGA
        dec a
        jr nz,PRBLKm3 ;точно печатаем тайл
       else
        DEC A
        JR NZ,PRBLKm3 ;точно печатаем тайл
       endif
        JR C,ADRTL   ;[спрайт]тайл нужно напечатать, т.к. это анимация

;Проверка попадает ли текущий [спрайт]тайл под героя
WHERE   LD BC,0 ;коорд. героя на экране
        LD A,C   ;X
        SUB E
        JR NC,W1
        NEG
W1      CP 3
;       JR NC,PRBLK+3
        JP NC,NOPRBLK
        LD A,B   ;Y
        SUB D
        JR NC,W2
        NEG
        INC A
W2      CP 5
;       JR NC,PRBLK+3
        JP NC,NOPRBLK

ADRTL   LD BC,A_TILE
        LD A,E
        LD (BC),A
        INC BC
        LD A,D
        LD (BC),A
        INC BC
        LD (ADRTL+1),BC
        LD A,1
PRBLKm3
        LD (TILED+1),A
       
       if EGA
        call prtileega
       else
;PRBLK
        ;CALL BLOCK22 ;Печать блока
;Основная идея (формат спрайта) Д.Быстрова (Alone Coder)
;Реализация (axor)
;Печать идет через стек, но без запрета прерываний
;Печать спрайта 2*2 знакоместа в теневом экране
;DE-адрес в теневом экране
;HL-адрес спрайта
;BLOCK22
;       LD A,PG_SPR ;=0
        XOR A
        ;LD (NUMPAGE),A
        ;OR 16+8
        ;LD BC,#7FFD
        ;OUT (C),A
        call PAGE

        LD C,(HL)    ;Делаем именно так, чтобы прерывание
                     ;не испортило спрайт
        INC L        ;поэтому в BC у нас
                     ;уже есть первые 2 байта спрайта
        LD B,(HL)
        INC L
        LD SP,HL     ;Теперь стек указывает на начало спрайта

        EX DE,HL     ;HL-адрес в теневом экране
        LD DE,#FF20
;Непосредственно сам вывод спрайта
        LD (HL),C
        INC L
        LD (HL),B
        INC H
        POP BC
        LD (HL),B
        DEC L
        LD (HL),C
        ADD HL,DE

        DUP 6
        POP BC
        LD (HL),C
        INC L
        LD (HL),B
        INC H
        POP BC
        LD (HL),B
        DEC L
        LD (HL),C
        ADD HL,DE
        EDUP

        POP BC
        LD (HL),C
        INC L
        LD (HL),B
        INC H
        POP BC
        LD (HL),B
        DEC L
        LD (HL),C
BL22SP  LD SP,0
;       RET
       endif

NOPRBLK POP HL
        POP BC
        POP DE
        INC HL
        INC E        ;X=X+2
        INC E
        DEC B
        JP NZ,PRMLP1
        LD E,B       ;X=0
        INC D        ;Y=Y+2
        INC D
        LD A,C
        LD C,128-(SCRWD)
        ADD HL,BC
        DEC A
        LD C,A
        JP NZ,PRMLP0
       if EGA
        ld a,(MAPFLAG+1)
        dec a
        jr z,$+5
        LD (MAPFLAG+1),A
       else
        INC A
        LD (MAPFLAG+1),A
       endif
        LD HL,(ADRTL+1)
        LD (HL),255

;После печати карты обнуляем видимость анимационных групп,
;т.к. они в любой момент могут "уйти"
;за счет скроллирования игрового поля игроком
        LD B,QGRPS
        LD HL,AnimGrps
ANG     LD (HL),C   ;C=0
        INC HL
        DJNZ ANG
;       CALL STONE ;отображает непрох. клетки
        RET

       if !EGA
;Печать блока 3*3 знакоместа на основном экране (реально 0xc000+)
;HL-адрес спрайта
;DE-адрес в экране (а не координаты в обычных знакоместах D-X, E-Y)
;1223 такта
BLOCK33
        ;CALL SCR_ADR ;эта процедура занимает
                     ;67 тактов включая RET
        LD (BL33SP+1),SP ;20
        LD C,(HL)        ;7
        INC HL           ;6
        LD B,(HL)        ;7
        INC HL           ;6
        LD SP,HL         ;6
        EX DE,HL         ;4
        LD DE,#2008      ;10 =66
         DUP 4
        LD (HL),C ;1     ;7
        INC L            ;4
        LD (HL),B ;2     ;7
        INC L            ;4
        POP BC           ;10
        LD (HL),C ;3     ;7
        INC H            ;4
        LD (HL),B ;4     ;7
        DEC L            ;4
        POP BC           ;10
        LD (HL),C ;5     ;7
        DEC L            ;4
        LD (HL),B ;6     ;7
        INC H            ;4
        POP BC           ;10
         EDUP

        ORG $-1

        LD A,L           ;4
        ADD A,D          ;4
        LD L,A           ;4
        JR C,$+5         ;12
        LD A,H           ;4
        SUB E            ;4
        LD H,A           ;4

         DUP 4
        POP BC
        LD (HL),C ;1
        INC L
        LD (HL),B ;2
        INC L
        POP BC
        LD (HL),C ;3
        INC H
        LD (HL),B ;4
        DEC L
        POP BC
        LD (HL),C ;5
        DEC L
        LD (HL),B ;6
        INC H
         EDUP

        LD A,L
        ADD A,D
        LD L,A
        JR C,$+5
        LD A,H
        SUB E
        LD H,A

         DUP 4
        POP BC
        LD (HL),C ;1
        INC L
        LD (HL),B ;2
        INC L
        POP BC
        LD (HL),C ;3
        INC H
        LD (HL),B ;4
        DEC L
        POP BC
        LD (HL),C ;5
        DEC L
        LD (HL),B ;6
        INC H
         EDUP
        ORG $-1
BL33SP  LD SP,0
        RET
       endif

;Герой вышел за пределы экрана
NOPRNT  POP DE,HL
        RET

;Мигание героя
HERO2
HERO2p1=$+1
        LD A,0
        DEC A
        LD (HERO2p1),A
        JR NZ,H2
        LD HL,HERO
        LD (CLR_MAPm2),HL
H2      BIT 1,A
        RET Z
       
;Печать героя на теневом экране
;Процедура очень похожа на печать
;курсора на теневом экране
;IN:  HL-адрес спрайта
;     DE-координаты в пикселях на экране
;     D-Y,E-X
;[OUT: HL-адрес следующего спрайта???]
HERO
        PUSH HL,DE
        LD HL,(DispMapX) ;H-Y, L-X ;смещение карты
        LD DE,(HEROCRD)  ;D-Y, E-X ;коорд. героя на карте
        LD A,D
        INC A
        SUB H
        JR C,NOPRNT  ;Ушел вверх
        CP SCRHG/2+3
        JR NC,NOPRNT ;Ушел вниз
        LD A,E
        INC A
        SUB L
        JR C,NOPRNT  ;Ушел влево
        CP SCRWD/2+2
        JR NC,NOPRNT ;Ушел вправо

        POP DE,HL

       if EGA
        ld a,55 ;"scf"
        ld (wasdrawimg),a
       ;di ;не помогает
;IN:  HL-адрес спрайта (N*128)
;     DE-координаты в пикселях на экране
;     D-Y,E-X
        add hl,hl
        add hl,hl ;N*512
;hl=адрес спрайта
        ld a,h
        sub 24*2 ;24 спрайта в странице
        ld c,PGSPRITES0
        jr c,HERO_pg0
        ld h,a ;pg1
        inc c ;ld c,PGSPRITES1
HERO_pg0
       ld a,(NEV1)
       or a
       jr nz,$+4
       inc c
       inc c ;PGSPRTRAN0/1
        ld a,c
        call setpg
       ;push ix
       ;push iy
        ld a,h
        ;add a,a ;N*4
        ;add a,4
        ;ld ly,a
        ;ld a,h
        ;add a,0xc0
        ;ld hy,a
        ld ($+5),a
        ld iy,(0xc000)
        call setpgsscr40008000_current ;shadow

       ld a,(HMOVEp1) ;высота видимой части карты/8
       add a,a
       add a,a
       add a,a
       ld (prspr_curscrhgt),a
       inc a
       ld (prspr_curscrhgtplus1),a
       add a,sprmaxhgt-2
       ld (hero_curmaxy),a

        ld a,e
       add a,16 ;если спрайт за левой границей
        srl a
        add a,sprmaxwid-1 -8
        cp 96-8+1+sprmaxwid-1 ;scrwid-1+sprmaxwid ;чтобы не давать выходить за правую границу активной зоны (TODO менять окно клипирования)
        jr nc,hero_drawspr_skip
        ld e,a
        ld a,d
        add a,sprmaxhgt-1
hero_curmaxy=$+1
        cp scrhgt-1+sprmaxhgt
        jr nc,hero_drawspr_skip
        sub sprmaxhgt-1
        ld c,a

;в 4000,8000 уже включен экран (setpgsscr40008000)
;iy=sprite data+2 = spraddr+4
;e=x = -(sprmaxwid-1)..159 (кодируется как x+(sprmaxwid-1))
;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
;(iy-3)=sprhgt
;(iy-4)=sprwid
        call prspr
hero_drawspr_skip
       ld a,192
       ld (prspr_curscrhgt),a
       inc a
       ld (prspr_curscrhgtplus1),a
       ;pop iy
       ;pop ix
        jp setpgsmain40008000
       ;ei
       else

        LD A,32      ;высота героя в пикс.
        LD B,A
        LD (hero1-1),A
        LD A,D
        CP 223
        JR C,hero0
        NEG
        LD C,A
        LD A,B
        SUB C
        RET Z   ;Герой вышел за пределы экрана
        LD (hero1-1),A  ;Уменьшаем высоту спрайта, т.к. голова
                        ;вышла за пределы
        LD A,C
        ADD A,A
        ADD A,A
        LD B,0
        LD C,A
        ADD HL,BC       ;Делаем смещение от начала спрайта
        LD D,B    ;Y=0

hero0   LD A,PG_HERO
        CALL PAGE
        LD A,E
        AND 7

        DUP 3
        SRL D
        RR E
        EDUP

        PUSH HL

        LD HL,SHADSCR
        ADD HL,DE

        INC A
        LD B,A
        LD A,-1
        ADD A,A
        DJNZ $-1

        LD (hero2-1),A

        EX DE,HL ;DE-адрес на экране для печати
        POP HL   ;HL-адрес спрайта

;Проверка на выход за нижнюю границу теневого экрана
        LD A,D
        CP SCRHG+(SHADSCR/256)
        RET NC

        LD B,32  ;Высота спрайта героя в пикселях
hero1   PUSH BC
        LD C,(HL)
        INC HL
        LD B,(HL)
        INC HL
        LD A,(HL)
        INC HL
        PUSH HL
        LD H,(HL)
        LD L,A
        PUSH DE
        LD A,(DE)
        LD E,A
        SCF
        SBC A,A
        LD D,0
hero2   RL C
        RL B
        RLA
        ADD HL,HL
        RL D
        JR C,hero2
        AND E
NEV1    XOR D   ;для видимости/"невидимости" героя
        POP DE

        EX AF,AF' ;'
        LD A,E
        AND 31
        CP SCRWD
        JR NC,hero3

        EX AF,AF' ;'
        LD (DE),A

hero3   INC DE
        LD A,E
        AND 31
        CP SCRWD
        JR NC,hero4

        LD A,(DE)
        AND B
NEV2    XOR H
        LD (DE),A

;Проверка на выход за правую границу теневого экрана
hero4   INC DE
        LD A,E
        AND 31
        CP SCRWD
        JR NC,hero5

        LD A,(DE)
        AND C
NEV3    XOR L
        LD (DE),A
hero5   DEC DE
        DEC DE
        LD HL,32
        ADD HL,DE
        EX DE,HL
        POP HL
        POP BC
        INC HL

;Проверка на выход за нижнюю границу теневого экрана
        LD A,D
        CP SCRHG+(SHADSCR/256)
        RET NC
        DJNZ hero1
        RET
       endif

       if EGA
;Печать строки (конец печати - 0, перевод строки - 13)
;HL-координаты
;H-X (0-63), L-Y (0-23)
;DE-адрес текста
PR64
        ld a,(egaon)
        or a
        jp z,PR64_6912
        push de
        push hl
        call PAGE_PG_VIEW
        call setpgsscr40008000_current
        call PR64_onescreen
        pop hl
        pop de
        call setpgsscr40008000
PR64_onescreen
        PUSH HL
        ld a,h ;x
        ld h,0
        ld b,h
        ld c,l
        add hl,hl
        add hl,hl
        add hl,bc ;*5
        add hl,hl
        add hl,hl
        add hl,hl ;*40
        add hl,hl
        add hl,hl
        add hl,hl ;*40*8
        ld b,0x40
        rra
        ;jr nc,$+4
        ;ld b,0x60
        ld c,a
        rla
        dup scrbase&0xff
        inc c
        edup
        add hl,bc
        ld b,a ;x

PR64LP  LD A,(DE)
        AND A  ;Конец текста?
        jr z,PR64q
        CP #0D ;13
        JR NZ,PR64LP2
        POP HL
        INC L
        INC DE
        JR PR64
PR64q
        POP HL
        jp setpgsmain40008000
PR64LP2
        PUSH HL
        PUSH DE
        LD E,A
        LD D,FNT/256
;Расчет половинки байта
;Все зависит от четной или
;нечетной текущей координаты X
        inc b
        LD A,B
        EX AF,AF' ;'

        push hl
        ;push ix
        push iy
       
        bit 0,b
        jr nz,$+4
        set 5,h
       
        ld hy,8
        ;ld ix,0x3fc9
;lx=background color %33210210
;hx=color %33210210
;de=font char
;hl=screen
prchar48ega_hxoncolor0
        ld b,hx
        ld a,(de)
        ld c,a
        ld a,lx
        rl c
        jr nc,$+2+4
         xor b
         and 0xb8;%10111000
         xor b
        rl c
        jr nc,$+2+4
         xor b
         and 0x47;%01000111
         xor b
        ld (hl),a
        ld a,h
        add a,0x40
        ld h,a
        ld a,lx
        rl c
        jr nc,$+2+4
         xor b
         and 0xb8;%10111000
         xor b
        rl c
        jr nc,$+2+4
         xor b
         and 0x47;%01000111
         xor b
        ld (hl),a
        inc d
        ld bc,+(40-0x4000)
        add hl,bc
        dec hy
        jp nz,prchar48ega_hxoncolor0
        pop iy
        ;pop ix
        pop hl

        POP DE
        POP HL
        INC DE

        EX AF,AF' ;'
        LD B,A
        rra
        JP C,PR64LP
        INC L
        JP PR64LP
        ret
       endif
;6912
;Печать строки (конец печати - 0, перевод строки - 13)
;HL-координаты
;H-X (0-63), L-Y (0-23)
;DE-адрес текста
PR64_6912
        PUSH HL
        LD A,L ;расчет адреса в экране
        LD B,H

        AND 7
        RRCA
        RRCA
        RRCA

        SRL H
        ADD A,H
        LD H,A

        LD A,L
        AND #18
        ;OR SCR/256 ;#C0
       or 0x40
        LD L,H
        LD H,A

PR64LP_  LD A,(DE)
        AND A  ;Конец текста?
        JR NZ,$+4
        POP HL
        RET
        CP #0D ;13
        JR NZ,PR64LP2_
        POP HL
        INC L
        INC DE
        JR PR64_6912

PR64LP2_ PUSH HL
        PUSH DE
        LD E,A
        LD D,FNT/256

;Расчет из какой половинки байта брать
;спрайт буквы. Все зависит от четной или
;нечетной текущей координаты X
        LD A,B
        INC B
        RRA
        SBC A,A
        XOR %11110000
        LD C,A

        LD A,B

        EX AF,AF' ;'

        LD B,8
PR64LOP_ LD A,(DE)
        XOR (HL)
        AND C
        XOR (HL)
        LD (HL),A
        INC H
        INC D
        DJNZ PR64LOP_

        POP DE
        POP HL
        INC DE

        EX AF,AF' ;'
        LD B,A
        JP M,PR64LP_
        INC L
        JP PR64LP_

;MATH
HL72
        DUP 3
        ADD HL,HL
        EDUP
        LD B,H
        LD C,L
        DUP 3
        ADD HL,HL
        EDUP
        ADD HL,BC    ;HL=HL*72
       if EGA
        add hl,hl
        add hl,hl
        ld bc,0xc000
        add hl,bc
       else
        LD BC,SPR33
        ADD HL,BC
       endif
        RET

;b=A/24
DIV24   LD BC,#0018
DIV24_0
        SUB C
        RET C
        INC B
        JR DIV24_0

;На выходе в А ПСЧ
RND     LD A,0
        LD B,A
        ADD A,A
        ADD A,A
        ADD A,B
        INC A
        LD (RND+1),A
        RET

;На выходе в А ПСЧ
RND2    PUSH HL
RND1    LD HL,0
        INC HL
        LD A,H
        AND #3F
        LD H,A
        LD (RND1+1),HL
        LD A,R
        XOR (HL)
        POP HL
        RET

;Из координат адрес в атрибутах
;H-X, L-Y
ATRADR LD A,H
        ADD HL,HL
        ADD HL,HL
        ADD HL,HL
        LD H,#36 ;если экран с #C000
                 ;#16, если с #4000
        ADD HL,HL
        ADD HL,HL
        ADD A,L
        LD L,A
        RET

;IN:   A-номер вещи
;OUT: BC-адрес свойств вещи
SVOYST
        LD HL,VSVOY
        ADD A,A
        LD C,A
        LD B,0
        ADD HL,BC
        LD C,(HL)
        INC HL
        LD B,(HL)
        RET

;Расчет по смещению от начала карты
;(лев. верх. угол) адреса элементов из которых состоит карта
;Карта - двумерный массив 64*64 двубайтных элементов
;IN:  None
;OUT: HL-адрес элемента в массиве карты
CalcMap
         LD HL,#3400 ;H-Y, L-X
DispMapX EQU CalcMap+1 ;Смещ. от начала карты по X
DispMapY EQU CalcMap+2 ;Смещ. от начала карты по Y
         LD E,L
         LD D,0
         LD L,H
         LD H,D

;Уместный в данном контексте метод
         XOR A  ;4
         SRL L  ;8
         LD H,L ;4
         RRA    ;4
         LD L,A ;4 24 такта

         ADD HL,DE
         ADD HL,DE
         LD DE,MAP ;Начало карты
         ADD HL,DE
         RET

CALC0
        XOR A
        LD H,A
        LD L,A
        LD (PERSON),HL
        LD (DISTV),HL
        LD (UNDER+1),A  ;Код вещи под курсором
        INC A
        LD (ONHERO),A
CL0     LD A,(F3+1)
        AND A
        JP Z,VNE2       ;стир. назв. вещи
        RET

;Расчет по положен. курсора разных параметров
CALC
        CALL SCRLMAP
        RET C       ;скролим карту

        CALL DIV16
CALC1   LD A,(VUS+1)     ;Герой что-то ложит
        AND A
        RET NZ

        LD A,H
        CP (SCRWD/2)
        JR NC,CALC0

        LD E,H
        LD D,L
        LD HL,(DispMapX) ;берем смещение от начала карты
                         ;складываем его с коорд. курсора
        ADD HL,DE        ;HL=коорд. курсора на игровом поле

        LD (CURSCRD+1),HL
        LD A,PG_MAP
        CALL PAGE
        PUSH HL
        PUSH HL

        RLC L,L
        SRL H
        RR L
        SRL H
        RR L
        LD A,MASSIVE/256
        ADD A,H
        LD H,A

        LD A,(HL)    ;элемент под курсором
        AND A
        EX AF,AF' ;'
        LD (ADRELM),HL
        POP HL
        CALL CalcMap+3
        LD (ADRSPRT),HL
        LD A,(HL)
        INC HL
        LD H,(HL)
        LD L,A
        LD (SPRCURS+1),HL

        AND A
        LD DE,SPR+(151*32)
        SBC HL,DE
        JR C,CLC01
        LD DE,38*32
        EX DE,HL
        SBC HL,DE
        JR C,CLC01

        EX DE,HL
        ADD HL,HL         ;A=HL/32
        ADD HL,HL         ;by Sam Style
        ADD HL,HL
        LD A,H

        INC A
        CP 39
        JR C,CLC01+1
CLC01   XOR A
        LD (UNDER+1),A  ;Код вещи под курсором

        LD HL,(HEROCRD) ;H-Y,L-X героя
        POP DE          ;D-Y,E-X курсора
        PUSH HL

        XOR A
        SBC HL,DE
        JR Z,CLC10
        LD A,H
        DEC A
        OR L
CLC10   LD (ONHERO),A   ;Если=0, то курсор на герое
        POP HL
        LD BC,#0100
        LD A,H
        SUB D
        LD H,DSTV+2
        JR NC,CLC1
        NEG
        DEC H
CLC1    CP H;на сколько близко должен наход. курсор к герою
        JR NC,CLC2
        INC C
        CP DSTV+1
        JR C,CLC2
        LD D,A
        LD A,H
        CP DSTV+2
        JR NZ,CLC2-1
        LD C,64 ;можно прим. взять, но не положить
        LD A,D
CLC2    CP DSTP+1;персонаж
        JR C,CLC2_
        DEC B
CLC2_   LD A,L
        SUB E
        JR NC,CLC3
        NEG
CLC3    CP DSTV+1;вещь
        JR C,CLC4
        LD C,0
CLC4    CP DSTP+1
        JR C,CLC4_
        LD B,0

;Под курсором вещь?
CLC4_   LD HL,UNDER+1
        LD A,(HL)
        AND A
        JR Z,SPRCURS-1
        DEC C
        INC C
        JR Z,SPRCURS-1
        SET 7,(HL)
        XOR A

SPRCURS LD HL,0  ;код спр. под курсором
        PUSH HL
        LD A,L
        RRA           ;Анимация?
        JR NC,CLC40   ;Нет
        AND A
        JR Z,CLC400   ;это провидец!
        CP 9
        JR NC,CLC41   ;эти ан. группы не участв.
        LD H,A
        LD L,0
        JR CLC42_

CLC40
;CY=0!!!
        LD DE,SPR+(215*32)
        SBC HL,DE
        JR C,CLC41

        LD A,L          ;A=HL/64
        RLCA
        RLCA
        AND 3
        SLA H
        SLA H
        OR H

        INC A
CLC400  INC A
        CP PERS+1       ;кол-во перс.
        JR C,CLC41+1
CLC41   XOR A
        LD L,A
        LD H,0

CLC42_  POP DE
        EX DE,HL
        LD A,D
        OR E
        JR NZ,CLC42     ;предм. уже обнаружен

        PUSH BC
        LD BC,SPR+(454*32)
        SBC HL,BC
        POP BC
        JR C,CLC42

        ADD HL,HL         ;A=HL/32
        ADD HL,HL
        ADD HL,HL
        LD A,H

;D=0
        CP 44
        JR NC,CLC42
        INC D
        CP 36
        JR NC,CLC41_ ;хмель
        INC D
        CP 24
        JR NC,CLC41_ ;пшеница
        INC D
        CP 18
        JR NC,CLC41_ ;улей
        INC D
        CP 16
        JR NC,CLC41_ ;колодец
        INC D
        CP 3
        JR NC,CLC41_ ;Храм
        INC D
        CP 2
        JR NC,CLC41_ ;Козленок
        INC D        ;Колодец с живой водой

CLC41_  LD A,8
        ADD A,D
        LD D,A

CLC42   LD A,(KARM)
        LD H,A
        AND A
        JR Z,CLC45      ;в кармане пусто

        LD A,(ONHERO)
        AND A
        LD A,C
        JR Z,CLC45+1    ;курсор на герое
        AND A
        JR Z,CLC45+1    ;Далеко от героя
        LD A,E
        OR D
        JR NZ,CLC45+1   ;можно выложить/отдать
        EX AF,AF' ;'       ;элемент 0/1
        SET 7,C
        JR Z,CLC45+1    ;только выложить рядом
        XOR A
CLC45   LD C,A
        AND A
        LD L,B
        LD B,0
        JR NZ,CLC48     ;работаем только с вещью
        LD A,E
        AND A
        JR Z,CLC48      ;под курсором не персонаж
        DEC H           ;в кармане есть
        INC H
        JR NZ,CLC48
        INC B           ;B=1
                        ;допустимое рассотяние для разговора
        DEC L           ;L=1?
        JR Z,CLC48
        INC B           ;B=2 с этим персонажем можно говорить

;C=0 если нет вещи или вещь применять нельзя
;C=1 можно выложить/примен./отдать вещь (мигает курсор)
;B=0 герой не говорит с персонажем
;B=1 герой может говорить с перс.
;B=2 факт разговора (персонаж далеко от героя)

;E=0 под курсором не персонаж
;E=1-PERS+1 код персонажа
;D=0 неучаствующий в игр. процессе предмет
;D>1 код предмета участвующего в игр. процессе

CLC48   LD (PERSON),DE
        LD (DISTV),BC
CLC48_  NOP
        LD HL,0
        LD A,D
        AND A
        JR Z,CLC49
        LD H,PERS
CLC49   OR E
        JR Z,UNDER
        LD L,38     ;смещ. от начала названий вещей
UNDER   LD A,0      ;код вещи под курсором
        AND %01111111
        ADD A,E
        ADD A,D
        JP Z,CL0    ;стир. назв. вещи
        ADD A,L
        ADD A,H
        LD B,A
        JP PRVESH   ;печ. назв. вещи/персонажа

;Проверка на манипуляции с вещами/разговорами
;OUT:B=0 ничего не делаем
;      1 применяем на героя
;      2 отдаем персонажу
;      3 разговариваем
;      4 применяем на объект
;      5 выкладываем рядом с героем
;      6 берем вещь
MANAGE
        LD HL,(DISTV);H-персон. L-предметы
        LD A,H
        CP 2
        LD B,0
        RET Z

        INC B   ;1 на героя
        LD E,-1
        LD A,(KARM)
        LD C,A
        LD A,(ONHERO)
        ADD A,E
        SBC A,A
        INC A
        ADD A,E
        SBC A,A
        AND C
        JR Z,MAN1

        LD DE,(PERSON)
        LD A,(UNDER+1)
        OR D
        OR E
        LD E,-1
        RET Z

MAN1    INC B   ;2 отдаем
        LD A,(PERSON)
        ADD A,E
        SBC A,A
        AND L
        RET NZ

        INC B   ;3 говорим
        LD A,H
        AND A
        RET NZ

        INC B   ;4 примен.
        LD A,(ITEM)
        ADD A,E
        SBC A,A
        AND L
        RET NZ

        INC B   ;5 выклад.
        LD A,L
        AND %00111111
        ADD A,E
        SBC A,A
        AND C
        RET NZ

        LD B,A
        LD A,(UNDER+1)
        RLA ;7-й бит значит, что вещь рядом с героем
        RET NC
        DEC C
        INC C
        RET NZ
        LD B,6  ;6 берем
        RET

;Установка цвета фона игрового экрана
FONE
       if EGA
;FNLP
        ;jr $
       ex af,af' ;'
       push af
        ld a,(COLOUR)
        ld b,a
        ld de,verapalevening ;if 0
        djnz $+5
        ld de,verapalnight ;if 1
        djnz $+5
        ld de,verapaldawn ;if 2
        djnz $+5
        ld de,verapalday ;if 3
        OS_SETPAL
       pop af
       ex af,af' ;'
        ret
FNLPm1=$+1
        LD E,SCRHG ;высота
FNLPp1=$+1
        LD C,8
FNLPp3=$+1
        LD B,SCRWD ;ширина
       else
        LD A,(COLOUR)
        LD HL,#5800+#8000
FNLPm1=$+1
        LD E,SCRHG ;высота
FNLP
FNLPp1=$+1
        LD C,8
FNLPp2
FNLPp3=$+1
        LD B,SCRWD ;ширина
        LD (HL),A
        INC L
        DJNZ $-2
        ADD HL,BC
        DEC E
        JR NZ,FNLPp2
        RET
       endif
       
;4.12.2004
;Скроллирование спрайта дня и ночи
N_WGHT  EQU 19 ;ширина спрайта

DAY_NGT
        RET ;patch
        LD A,201
        LD (DAY_NGT),A
       if EGA
        call prsprhud
       else
;      LD A,PG_VIEW
        CALL PAGE_PG_VIEW
        LD HL,NG+N_WGHT-1
        LD DE,N_WGHT
        LD C,32       ;высота в пикселях
NG_SCR2 LD B,N_WGHT
        AND A
        PUSH HL
NG_SCRL LD A,(HL)
        ADC A,A
        LD (HL),A
        DEC HL
        DJNZ NG_SCRL
        POP HL
        LD A,B
        ADC A,A
        OR (HL)
        LD (HL),A
        ADD HL,DE
        DEC C
        JR NZ,NG_SCR2

;Накладывание маски на спрайт дня и ночи
        LD IX,REZULT  ;где создать результат
        LD DE,NG      ;спрайт дня
        LD HL,NG_MASK ;маска

        LD C,N_WGHT-6
        LD A,32
NGHT_LP EX AF,AF' ;'
        LD B,6
NGLP    LD A,(DE)
        AND (HL)
        INC HL
        OR (HL)
        INC HL,DE
        LD (IX),A
        INC IX
        DJNZ NGLP
        EX DE,HL
        ADD HL,BC
        EX DE,HL
        EX AF,AF' ;'
        DEC A
        JR NZ,NGHT_LP
       endif

;B-атрибут
        LD A,(SUTKI)
        INC A
       if EGA
        ld b,0
       else
        LD B,5*8 ;  вечер, цвет фона
       endif
        CP 38    ;четверть суток
        JR Z,SUT1
       if EGA
        inc b
       else
        LD B,8+64   ;ночь
       endif
        CP 38*2
        JR Z,SUT1
       if EGA
        inc b
       else
        LD B,6*8    ;утро
       endif
        CP 38*3
        JR Z,SUT1
       if EGA
        inc b
       else
        LD B,7*8+64 ;день
       endif
        CP 38*4
        JR NZ,SUT2
        XOR A
        LD (MUSNUM),A
SUT1    EX AF,AF' ;'
        CALL MUSNXT2
        LD A,B
        LD (COLOUR),A
        CALL FONE
        EX AF,AF' ;'
SUT2    LD (SUTKI),A
        XOR A
        JP setDAYS_a;D_SP+5

       if EGA
prsprhud
;TODO печатать всегда теневой экран! и вызывать независимо (т.е. будет два вызова на соседних кадрах)
       ;halt
       display "prsprhud=",prsprhud
       ;di
       ld a,55
       ld (im_arroff),a
       call ARROFF
        ld a,(daynightphase)
        inc a
        cp 152
        jr nz,$+3
        xor a
        ld (daynightphase),a
        call setpgsscr40008000 ;visible
        call prsprhud_onescreen
       call ARRON
       ld a,55+128 ;"or a"
       ld (im_arroff),a
       ;ei
        call setpgsscr40008000_current ;shadow
        ld a,55 ;"scf"
        ld (wasdrawimg),a
        call prsprhud_onescreen
        jp setpgsmain40008000
prsprhud_onescreen
        ld a,PGDAYNIGHT
        call setpg
        ld hl,(daynightphase)
        srl l
        ld de,0xc000
        jr c,$+5
        ld de,0xc000+(200*32/2)
        ld h,0
        add hl,hl
        add hl,hl
        add hl,hl
        add hl,hl
        add hl,hl ;*32
        add hl,de
        ex de,hl
        ld hl,scrbase+(40*136)+(200/8)
        ld bc,0x2018
;b=hgt,c=wid (/2)
;de=gfx
;hl=scr
        call primgega0
        ld a,PGHUD
        call setpg
        ld iy,hudspr
        ld e,200/2+sprmaxwid-1
        ld c,136
;в 4000,8000 уже включен экран (setpgsscr40008000)
;iy=sprite data+2 = spraddr+4
;e=x = -(sprmaxwid-1)..159 (кодируется как x+(sprmaxwid-1))
;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
;(iy-3)=sprhgt
;(iy-4)=sprwid
        jp prspr
       endif

;Восстанавливаем карту после заливки
CLMAP
        LD (CLR_MAPp1),A
        LD A,PG_MAP
        CALL PAGE
        LD HL,MASSIVE ;должен быть ровным адресом
        LD BC,#1000 ;длина карты
wav_1   LD A,(HL)
        DEC A
        JR Z,wav_2
        LD (HL),C
wav_2   INC L
        JR NZ,wav_1
        INC H
        DJNZ wav_1
        RET

NEW_CRD DW 0

;Перекидываем теневой экран на основной
;Теневым у нас является стандарный экран #4000
;Основным - второй экран в 7-й стр.
;Формат теневого экрана линейный, но не совсем
;Его размер определяется по формуле:
;SCRHG*32*8, не смотря на то,
;что активная часть задается переменной SCRWD (ширина)
;Это сделано для более простых расчетов
MOVE

       if EGA
;TODO swapscr
        ret
       endif


;       LD A,PG_VIEW
        CALL PAGE_PG_VIEW

OLD_CRD LD DE,0   ;Предыдущие координаты курсора.
                  ;Запоминаются во вторых прерываниях
        CALL ARRONS+4
        LD HL,BUSY+1
        PUSH HL
        INC (HL)
        LD HL,SHADSCR ;теневой экран
        LD DE,SCR     ;основной экран

;0-обновлять весь экран или 1-только отдельные тайлы
TILED   LD A,0
        DEC A
        JP Z,MOVE2
        INC A
        JR Z,MVEND

HMOVEp1=$+1
        LD C,SCRHG    ;высота видимой части карты/8
PRSHAD0 LD B,4
PRSHAD1 PUSH BC

        DUP SCRWD-1   ;ширина видимой части карты
        LDI
        EDUP

        LD A,(HL)
        LD (DE),A
        INC D
        SET 5,L

        DUP SCRWD-1
        LDD
        EDUP

        LD A,(HL)
        LD (DE),A
        INC D

        LD BC,32
        ADD HL,BC
        POP BC
        DJNZ PRSHAD1

        LD A,E
        ADD A,32
        LD E,A
        JR C,$+6
        LD A,D
        SUB 8
        LD D,A
        DEC C
        JR NZ,PRSHAD0
MVEND   POP HL
        LD (HL),0
        JP ARROFFS

;Вывод только тех тайлов,
;которые изменились на теневом экране
MOVE2
       if EGA
        ret ;TODO swapscr
       endif
        LD HL,A_TILE ;список изм. тайлов (адреса)
        LD BC,#FF21

MV2     LD E,(HL)
        INC E
        JR Z,MVEND

        DEC E
        INC HL
        LD D,(HL)
        INC HL
        PUSH HL

        LD H,E
        LD A,D
        SUB #40
        LD L,A

;Коорд. в знак. преобразуем в адрес экрана
;H-X L-Y
        LD A,L
        AND 7
        RRCA
        RRCA
        RRCA
        ADD A,H
        LD H,L
        LD L,A
        LD A,H
        AND #18
        OR SCR/256
        LD H,A

        EX DE,HL

       DUP 8
        LDI
        LD A,(HL)
        LD (DE),A
        INC H
        LD A,E
        ADD A,C
        LD E,A
        LDD
        INC C
        LD A,(HL)
        LD (DE),A
        ADD HL,BC
        LD A,E
        SUB C
        LD E,A
        INC D
        INC C
       EDUP

        POP HL
        JP MV2

;IN  A-направление
;OUT BC-приращение координат в завис. от направления
NAPR    LD HL,DIR_TAB
        ADD A,A
        ADD A,L
        LD L,A
        ADC A,H
        SUB L
        LD H,A
        LD C,(HL)
        INC HL
        LD B,(HL)
        RET

;Таблица направлений героя
DIR_TAB DW #FFFF ; 0 вправо-вниз
        DW #00FF ; 1 вправо
        DW #01FF ; 2 вправо-вверх
        DW #FF00 ; 3 вниз
        DW #0100 ; 4 вверх
        DW #FF01 ; 5 влево-вниз
        DW #0001 ; 6 влево
        DW #0101 ; 7 влево-вверх

;Вывод кнопки ">" окна диалога
WKEYS
        LD HL,FMCNT
        DEC (HL)
        RET NZ
        LD (HL),FRM/2
       if EGA
        push af
;рисуем на двух экранах, как PR64
curhudarrnext=$+1
        ld de,hudarrnext0
        ld hl,0xffff&(hudarrnext0+hudarrnext1)
        or a
        sbc hl,de
        ld (curhudarrnext),hl
        ex de,hl
        ld hl,scrbase+(136*40)+22
        ld a,PGHUD
        call setpg
        ld bc,0x0804
;b=hgt,c=wid (/2)
;de=gfx
;hl=scr
        ;ld a,55 ;"scf"
        ;ld (wasdrawimg),a ;не надо, т.к. мы в прерывании
        call primgega
        pop af
        ret
       else
        EXA
        LD HL,WIN_SPR+480
        LD A,8
        XOR 8
        LD ($-1),A
        ADD A,L
        LD L,A
        LD DE,#5036+#8000
        DUP 7
        LD A,(HL)
        LD (DE),A
        INC HL
        INC D
        EDUP
        LD A,(HL)
        LD (DE),A
        EXA
        RET
       endif        

;Спрайты героя
;48 спрайтов по 128 б
Vr1     EQU hero;#C000
Vr2     EQU Vr1+#0080
Vr3     EQU Vr1+#0100
Vl1     EQU Vr1+#0180
Vl2     EQU Vr1+#0200
Vl3     EQU Vr1+#0280
Vu1     EQU Vr1+#0300
Vu2     EQU Vr1+#0380
Vu3     EQU Vr1+#0400
Vd1     EQU Vr1+#0480
Vd2     EQU Vr1+#0500
Vd3     EQU Vr1+#0580
Vru1    EQU Vr1+#0600
Vru2    EQU Vr1+#0680
Vru3    EQU Vr1+#0700
Vrd1    EQU Vr1+#0780
Vrd2    EQU Vr1+#0800
Vrd3    EQU Vr1+#0880
Vlu1    EQU Vr1+#0900
Vlu2    EQU Vr1+#0980
Vlu3    EQU Vr1+#0A00
Vld1    EQU Vr1+#0A80
Vld2    EQU Vr1+#0B00
Vld3    EQU Vr1+#0B80
VTr1    EQU Vr1+#0C00
VTr2    EQU Vr1+#0C80
VTr3    EQU Vr1+#0D00
VTl1    EQU Vr1+#0D80
VTl2    EQU Vr1+#0E00
VTl3    EQU Vr1+#0E80
VTu1    EQU Vr1+#0F00
VTu2    EQU Vr1+#0F80
VTu3    EQU Vr1+#1000
VTd1    EQU Vr1+#1080
VTd2    EQU Vr1+#1100
VTd3    EQU Vr1+#1180
VTru1   EQU Vr1+#1200
VTru2   EQU Vr1+#1280
VTru3   EQU Vr1+#1300
VTrd1   EQU Vr1+#1380
VTrd2   EQU Vr1+#1400
VTrd3   EQU Vr1+#1480
VTlu1   EQU Vr1+#1500
VTlu2   EQU Vr1+#1580
VTlu3   EQU Vr1+#1600
VTld1   EQU Vr1+#1680
VTld2   EQU Vr1+#1700
VTld3   EQU Vr1+#1780

;Ссылки на спрайты
;Очередность спрайтов зависит от направления
;героя и процедуры расчета группы спрайтов по этому направлению

;Перемещение героя (очередность спрайтов)
VeraTab
R_down  DB 3
        DW Vrd1,Vrd2,Vrd1,Vrd3
Right   DB 2
        DW Vr1,Vr2,Vr1,Vr3
R_up    DB 1
        DW Vru3,Vru1,Vru2,Vru1
Down    DB 4
        DW Vd2,Vd1,Vd3,Vd1
Up      DB 0
        DW Vu2,Vu1,Vu3,Vu1
L_down  DB 5
        DW Vld1,Vld2,Vld1,Vld3
Left    DB 6
        DW Vl1,Vl2,Vl1,Vl3
L_up    DB 7
        DW Vlu1,Vlu2,Vlu1,Vlu3

;Взятие предмета
VeraTab2
TUp     DW VTu1,VTu2,VTu3,VTu2,VTu1,Vu1
TR_up   DW VTru1,VTru2,VTru3,VTru2,VTru1,Vru1
TRight  DW VTr1,VTr2,VTr3,VTr2,VTr1,Vr1
TR_down DW VTrd1,VTrd2,VTrd3,VTrd2,VTrd1,Vrd1
TDown   DW VTd1,VTd2,VTd3,VTd2,VTd1,Vd1
TL_down DW VTld1,VTld2,VTld3,VTld2,VTld1,Vld1
TLeft   DW VTl1,VTl2,VTl3,VTl2,VTl1,Vl1
TL_up   DW VTlu1,VTlu2,VTlu3,VTlu2,VTlu1,Vlu1

RotTabl DW Vu1,Vru1,Vr1,Vrd1,Vd1,Vld1,Vl1,Vlu1