;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