device zxspectrum1024
include "settings.ast"
MEM128=ATM;1 ;TODO автоопределение 48/128?
if ATM
include "../../_sdk/sys_h.asm"
endif
STICKMOUSEXTOGRID=!ATM;1
FASTMAPPER=0 ;выброшено
CEILING=0 ;с потолком 8K лишних, только при FASTMAPPER=0
Nobjects=16+4 ;16 worms + 4 mines
if ATM
STACK=0x4000
UVSCROLL_USETILES=0
UVSCROLL_USEBMP=0
else
STACK=0x6000
endif
FD EQU 0x7ffd
COLOUR EQU 7
TITLCOL EQU 71
PGMASK_ EQU #17
if MEM128
MASK=0xf000 ;(MAPWID/2)*((256-8)/2+1[временно для mkmap]) = 46*125 = 5750
else
MASK=0xb000 ;(MAPWID/2)*(TERRAINHGT/2+1[временно для mkmap]) = 46*79 = 3634 ;TODO в 128K тут будет потолок карты (80*93=7440)
endif
if !ATM
PGMAP=0x10
endif
PGHICODE=0x14
PGLMN=0x16
;LMNS EQU #C000 ;for mkmap
NLMN=15 ;число всех элементов фона в LMNS
NLMNONMAP=5 ;число элементов, которые ставим на карту
;USELMNBUF=0
; if USELMNBUF
;LMNBUF=0x4000 ;во время построения карты
;LMNSZ=0x0800
; else
if !ATM
LMNGFX=0x4000 ;здесь будут лежать только те элементы, которые точно хотим ставить (тогда можем перестроить карту и в 48K)
LMNGFXSZ=0x0800 ;не более стольких байт, иначе число элементов будет урезано (а по умолчанию MLMNONMAP штук)
endif
; endif
MAPWID EQU 93 ;нечётная! т.к. маска без 4 пикс слева и 4 пикс справа - там червей нельзя ставить ;TODO а если червь влетит в стену на левой границе карты? надо полную маску или при любой порче ландшафта крайний левый пикс маски формировать из 5 левых пикс, справа аналогично?
MASKWID EQU MAPWID/2 ;округление вниз (x в маске считается для центра червя, x=0 соответствует x=4 в карте)
XWID=MAPWID*2 ;максимальное значение координаты xhigh
XWIDCHRBITS=1
XWIDCHR=1<<XWIDCHRBITS;2 ;одно знакоместо смещает xhigh вот на столько
INVISIBLEX=220 ;xhigh между 186 и 255, чтобы даже бомба не задела стоящих там трупов
MAPHGT EQU 22*8 ;высота карты в пикселях
TERRAINHGT = MAPHGT-20 ;высота генерируемой карты в пикселях ;чтобы уместить червей и надписи сверху ;защита от вставания на идеально высокого червя - отсутствие маски для строк выше
MASKHGT EQU MAPHGT/2 ;высота маски в пикселях
BIGMAPHGT EQU 256 ;с небом
SKYHGT=BIGMAPHGT-MAPHGT ;высота неба
SKYMASKHGT=SKYHGT/2
if ATM
RAMKAX=5
else
RAMKAX=1
endif
RAMKAHGT=16
RAMKAWID=14
SCRTOP=#4061 ;левый верхний угол активной зоны экрана
SCRHGT=17*8 ;высота активной зоны экрана в пикселях
if ATM
SCRWID=40 ;ширина активной зоны экрана в знакоместах
TITLEY=200-32-8
else
SCRWID=30 ;ширина активной зоны экрана в знакоместах
TITLEY=128
endif
;SHADWD=SCRWID+2
;SHADHGT=SCRHGT;+14?
WATERHGT=32 ;высота воды в пикселях дополнительно к высоте карты с небом (BIGMAPHGT)
;для мыши:
waterYwin=BIGMAPHGT-SCRHGT ;waterYwin - это где высота воды 0
maxYwin=waterYwin+WATERHGT ;waterYwin+WATERHGT - это где высота воды WATERHGT
maxXwin=(MAPWID-SCRWID)*8
;DOPRSZ EQU 56
;UPPRSZ EQU SCRHGT-DOPRSZ
;DOPRSCR EQU -(DOPRSZ*4)+#4981
MAP=0xc000 ;там лежит карта в PGMAP
MAPDO EQU -(MAPWID*SKYHGT)+MAP ;виртуальный адрес начала карты, включая небо
MASKDO EQU -(MASKWID*(SKYMASKHGT-4))+MASK ;виртуальный адрес начала маски, включая небо ;маска - под ногами червя (высота червя=8, в маске =4)
MASKSZ EQU MAPHGT/2*MASKWID
if ATM
INTSTACK=0x3f80
else
INTSTACK=0x5c00
endif
;SPOILSTACK=INTSTACK+2 ;2 bytes for drawmap
if ATM
uvscroll_scrbase=0x4000+(24*40)
uvscroll_pushbase=0x8000
uvscroll_callbase=0xc000
UVSCROLL_WID=1024
UVSCROLL_HGT=256;512;256
SKIPPGS=0;16 ;0 for UVSCROLL_HGT=256
UVSCROLL_SCRWID=SCRWID*8;320 ;8*(TILEMAPWID-2)
UVSCROLL_SCRHGT=136;200;192-16 ;(делится на 16!!!) ;8*(TILEMAPHGT-2) ;чтобы выводить всегда 12 метатайлов (3 блока по 8) по высоте
UVSCROLL_NPUSHES=UVSCROLL_WID/2/4/2
UVSCROLL_SCRNPUSHES=UVSCROLL_SCRWID/2/4/2
UVSCROLL_SCRSTART=uvscroll_scrbase+((UVSCROLL_SCRHGT-1)*40)
UVSCROLL_LINESTEP=-40
UVSCROLL_NCALLPGS=4
macro SETPGPUSHBASE
SETPG8000
endm
macro RECODEBYTE
ld a,(de)
ld ($+4),a
ld a,(trecodebyteright)
ld c,a
dec de
ld a,(de)
dec de
ld ($+4),a
ld a,(trecodebyteleft)
or c
endm
endif
macro SCRADDR x,y ;x in chr, y in pix
if ATM
_=0x4000+((y)*40)+(x)
else
_=0x4000+(((y)&7)<<8)+(((y)&0x38)<<2)+(((y)&0xc0)<<5)+(x)
endif
endm
page 0
if ATM
org PROGSTART
else
ORG 0x6000
endif
begin
if ATM
ld sp,STACK
OS_HIDEFROMPARENT
ld e,0+128 ;+128=keep
OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
ld e,0
OS_SETSCREEN
ld e,0 ;color byte
OS_CLS
ld e,1
OS_SETSCREEN
ld e,0 ;color byte
OS_CLS
OS_NEWPAGE
ld a,e
ld (pg1),a
OS_NEWPAGE
ld a,e
ld (pg2),a
OS_GETMAINPAGES
;dehl=номера страниц в 0000,4000,8000,c000
ld a,e
LD (pgmain4000),A
ld a,h
LD (pgmain8000),A
ld a,l
ld (pgmask),a
ld de,res_path
OS_CHDIR
call SetPgTexture8000
ld de,fnpg1
call loadfile8000
call SetPgLmn8000
ld de,fnpg2
call loadfile8000
call setpgsmain40008000
;call cls
call swapimer
call uvscroll_prepare
jp GO
loadfile8000
call openstream_file
ld de,0x8000
ld hl,0x4000
call readstream_file
jp closestream_file
;bgxyfilename
; db "bg8-16d.bmp",0
swapimer
di
ld de,0x0038
ld hl,oldimer
ld bc,3
swapimer0
ld a,(de)
ldi ;[oldimer] -> [0x0038]
dec hl
ld (hl),a ;[0x0038] -> [oldimer]
inc hl
jp pe,swapimer0
ei
ret
oldimer
jp on_int ;заменится на код из 0x0038
jp 0x0038+3
on_int
;restore stack with de
EX DE,HL
EX (SP),HL ;de="hl", в стеке "de"
LD (on_int_jp),HL
LD (on_int_sp),SP
LD SP,INTSTACK
push af
push bc
push de ;"hl"
exx
ex af,af' ;'
push af
push bc
push de
push hl
push ix
push iy
curscrnum_int=$+1
ld e,0
OS_SETSCREEN
call oldimer ;ei ;а что если выйдем поздно (по yield)? надо в конце обработчика убрать ei, но и это не поможет, т.к. yield сейчас с включенными прерываниями!!!
;GET_KEY
;ld a,c ;кнопка без учёта языка
;or a
;jr z,$+5
;ld (curkey),a
;OS_GETKEYMATRIX
LD hl,curwater
ld a,(hl)
SUB -16
LD (hl),A
CALL MOUSE
call TIME
ld hl,timer
inc (hl)
pop iy
pop ix
pop hl
pop de
pop bc
pop af
ex af,af' ;'
exx
pop hl
pop bc
pop af
on_int_sp=$+1
ld sp,0
pop de
ei
on_int_jp=$+1
jp 0
align 256
endif
_tables=$
macro TABLE sz
org _tables
_tables=_tables+sz
endm
macro ENDTABLE
endm
TABLE 0x200
FONT
INCBIN "w64fnt.bin" ;todo PG ;todo 256 байт (по 2 символа в байте)
ENDTABLE
TABLE 0x200
FONT88
INCBIN "w88_fnt.bin" ;(пока адрес делится на 512) можно уменьшить (за счёт ненужных символов и высоты), но не сильно
ENDTABLE
TABLE 0x100
WATER
INCBIN "water.bin" ;todo PG
ENDTABLE
TABLE 0x100
DTNTAB ;32 байта по круглому адресу во время построения контура карты
MKMASKBUF EQU DTNTAB ;(MASKWID) ;во время построения карты
TPLACES EQU DTNTAB ;table of y's (per column) usable for worms ;во время построения карты
TXY EQU TPLACES+256-(2*Nobjects) ;x,y всех червей (генерируется в mkmap) временно, потом используем WORMXY
;TABSIN EQU DTNTAB ;пока топорный квадратичный (для перемещения курсора вокруг червя) во время хода игрока (но не логики)
;MAXWXY EQU 98
;SPRITE,COORDS,SPEED
WORMXY EQU DTNTAB ;во время игры
;TEAM,WORM,ENERGY,WEAPON,AIM,0
CUWORMS EQU DTNTAB+0x80
;TODO ещё буфер координат партиклов - или их сюда же? тогда не более 22 партиклов при 512 байт на два этих списка
ENDTABLE
TABLE 0x100
TITBUF ;todo очередь в PG
ENDTABLE
TABLE 0x400
Tshift ;,#400 ;во время игры (скролл 3,5)
grassbuf=Tshift ;for mkmap
grassbufsz=0x400 ;0x200 часто выдаёт "nowhere to worm"
LMNused=grassbuf ;(NLMN) ;for mkmap ;там помечается, какие номера элементов уже использовались
LMNlist=LMNused+256-NLMNONMAP ;список используемых
ENDTABLE
TABLE 0x100
TABROLL ;для логики (быстрая работа с маской)
ENDTABLE
TABLE 0x200
TMASKLN ;512 ;адреса строк маски = MASK+l*MASKWID ;почему-то не используется при построении карты
ENDTABLE
if !ATM
TABLE 0x200
TMAPLN ;512 ;адреса строк карты = MAP+l*MAPWID ;во время построения карты и для drawinmap (и для FASTMAPPER)
ENDTABLE
TABLE 0x200
skysprlist=$+256-(42*6)+(4*6) ;80 строк по 6 байт (480 байт) с запасом сверху на 4 (не хватило на высоту червя) (внутри каждых 6 байт адресация inc l!)
ENDTABLE
endif
endtables=_tables
ds endtables-$
GO
ld sp,STACK
if !ATM
xor a
out (0xfe),a
ld hl,0x6000
ld (hl),a
inc l
ld (hl),a
inc l
ld (hl),a ;was jp GO
endif
LD A,R
ld l,a
;ld hl,0xcdc5;0x4dd5;0xf1b3
ld (rndseed1),hl
ld hl,(0x5c78)
;ld hl,0x765e;0x2734;0x6c1b
ld (rndseed2),hl
if !ATM
ld a,PGLMN
call OUTME
ld a,(LMNS)
ld (LMNSfirstbyte),a
endif
if ATM
;шрифт должен содержать по 2 копии каждой буквы
ld hl,FONT
ld bc,512 +255 ;+255 для цикла dec bc:inc b:djnz
mkdoublefont0
ld a,(hl)
rlca
rlca
rlca
rlca
or (hl)
ld (hl),a
inc hl
dec bc
inc b
djnz mkdoublefont0
endif
LD HL,TITBUF
LD (HL),0
;NACHALO
if !ATM
LD DE,MAPDO
LD BC,MAPWID
LD L,B;0
MKTBROW0 LD H,TMAPLN/256
LD (HL),E
INC H
LD (HL),D
;BIT 6,D
;JR NZ,$+6
;LD (HL),#C0
;DEC H
;LD (HL),B
EX DE,HL
ADD HL,BC
EX DE,HL
INC L
JR NZ,MKTBROW0
endif
LD L,0
LD DE,MASKDO
LD C,MASKWID
MKTBMSK LD H,TMASKLN/256
LD (HL),E
INC H
LD (HL),D
LD A,L ;l=y не в маске, а в карте, причём для головы, а не для ног!
add a,8 ;координата для ног
cp SKYHGT
jr nc,MKTBMSKnoblank
; CP -8
; JR NC,$+6
;BIT 5,D
;JR NZ,$+7
LD (HL),BLANK/256
DEC H
LD (HL),BLANK&0xff
MKTBMSKnoblank
RRA
JR NC,$+5
EX DE,HL
ADD HL,BC ;двигаемся каждый второй раз (1 строка маски = 2 строки карты)
EX DE,HL
INC L
JR NZ,MKTBMSK
CALL INIMOUS ;портит ba00
if ATM
call SetPgMuzC000
call muz
ld hl,muz+5
ld a,(pg1)
OS_SETMUSIC
else
ld a,PGMAP
call OUTME
xor a
ld (muz),a
ld a,PGLMN
call OUTME
ld a,(muz)
sub 0x21
ld (muzpatch),a
call z,muz
CALL MAKINT
endif
NACHALO
LD HL,TLAND
jr newmapgo
nowhere ;return here if "nowhere to worm"
LD HL,MESWHE ;"nowhere to worm"
newmapgo
ld sp,STACK
CALL MTITLE
call cls
if ATM
;ld de,bgxyfilename
;call uvscroll_preparebmp;uvscroll_prepare
ld de,pal;SUMMERPAL
OS_SETPAL
YIELD
ld hl,panel16
call DrawPanel
else
ld hl,panel
call DrawPanel
endif
LD HL,(curdrawingtitle)
CALL DrawTitle ;печать игрового сообщения
CALL MKMAP
if !ATM
ld hl,Tshift
ld de,0x0705
call fixshift
ld h,Tshift/256+2
ld de,0x1f03
call fixshift
endif
;TODO сделать нормальный синус
;он тут кладётся, т.к. TABSIN затёрта во время генерации карты
;LD HL,TABSIN
;XOR A
;LD B,22
;LD (HL),A
;INC HL
;ADD A,B
;DJNZ $-3
LD HL,MESHOM
CALL MTITLE
CALL DrawAttrField
CALL ResetTime
CALL DrawEnergyPanel ;печать панельки для энергии и ветра
LD HL,TABROLL
LD C,1
MKTRL LD A,L
AND 31
JR NZ,$+4
RRC C
LD (HL),C
INC L
JR NZ,MKTRL
call ForcedDrawWormsInMap
gamemove
call DrawWormsDataInMap
ld a,STATE_MOVE
ld (gamestate),a
genwind0
call RND
and 127
cp 46+1+46
jr nc,genwind0
sub 46
ld (wind),a
if 1 ;TODO remove
genpowr0
call RND
and 127
cp 119
jr nc,genwind0
ld (powr),a
endif
CALL DrawEnergy ;печать полосок энергии и ветра
gameloop
LD HL,(MOUSEx)
LD (MOUSEX),HL
LD A,(MOUSEy)
LD (MOUSEY),A
;HALT
;CALL MAPPER ;печать верха карты при one frame выводилке
if !ATM
LD A,PGMAP;16
CALL OUTME
endif
call DrawWormsInMap ;TODO рисовать только сместившихся ;даже если напечатали ниже 0xc000, то всё равно сотрём сразу после отрисовки
ld a,(gamestate)
cp STATE_MOVE
call z,DrawCrossInMap
CALL DrawMap ;TODO не перерисовывать, если не сменился XY и не сместились объекты (прорисовать только строки под стрелкой для air strike)
CALL DrawTime
if !ATM
LD A,PGMAP;16
CALL OUTME
endif
ld a,(gamestate)
cp STATE_MOVE
call z,UnDrawCrossInMap
call UnDrawWormsInMap ;TODO стирать только сместившихся
call AnimMines
;LD A,-64
;LD HY,'TY4TOP
;CALL WORMS
;CALL CURSOR
oldtitletimer=$+1
ld e,0
ld a,(timer)
ld (oldtitletimer),a
sub e
ld e,a
STCNTa=$+1
LD A,1
sub e;DEC A
JR nc,STNOTIT
xor a
curdrawingtitle=$+1
LD HL,TITBUF
CP (HL)
CALL NZ,DrawTitle ;печать игрового сообщения
JR $+5
STNOTIT LD (STCNTa),A
;DOPR CALL 0 ;печать низа карты при one frame выводилке
;DOPRA LD HL,0
; LD (HL),#FD
; INC HL
; INC HL
; LD (HL),#E1
; CALL DrawWater
; LD BC,999
; LD D,B
;NOLDIR LDIR ;wait for turbo mode (недостаточно при 14 МГц)
;XOR A
;LD HY,'TY4LOW
;CALL CURSOR ;TODO для AIRSTRIKE (надо печатать на карте с запоминанием - прямо перед выводом карты, а потом восстанавливать)
if ATM
call changescrpg ;с этого момента (точнее, с прерывания) можем видеть, что нарисовали
halt
;ld a,(curscrnum_int)
;ld e,a
;OS_SETSCREEN
endif
;logic:
;delta timing
oldtimer=$+1
ld e,0
waithalt
ld a,(timer)
ld (oldtimer),a
sub e
cp 1;2
if ATM
jp c,waithalt ;это не гарантия переключения экрана!!!
else
jp c,timeraction0q;waithalt ;чтобы линия обновления экрана была в рандомном месте
endif
logicframesremained=$+1
add a,0 ;0..LOGICSPEED-1
timeraction0
ld (logicframesremained),a
sub 1;2
jr c,timeraction0q
push af
CALL WRMOVE
ld a,(gamestate)
cp STATE_MOVE
call z,ControlCurWorm
call WormsVsMines
call StayingWormsVsMovingWorms ;столкновение летящего со стоящим
pop af
jr timeraction0
timeraction0q
ld a,(gamestate)
cp STATE_FLYCURWORM
jr nz,noflycurworm ;не режим прыжка
call CheckFlyingWorms
jr nz,noflycurworm ;есть летящие
call DrawCurWormData
ld a,STATE_MOVE
ld (gamestate),a
noflycurworm
ld a,(gamestate)
cp STATE_FLY
jr nz,flyingok ;не режим взрыва
call CheckFlyingWorms
jr nz,flyingok ;есть летящие
;летящих червей больше нет, печатаем названия всех живых червей и переходим в режим смертей (а из него потом или в режим взрыва, или в режим перехода хода)
ld a,STATE_DIE
ld (gamestate),a
;TODO...
;TODO асинхронно от цикла графики
jp gamemove
flyingok
;
;CALL CLRTOP
;CALL UPPRU
;CALL 8020
;RET NC
LD A,-3
IN A,(-2)
BIT 1,A
CALL Z,unsetwms;SETWMS ;"S" - заново расставить червей
LD A,#FB
IN A,(-2)
BIT 3,A
JP Z,NACHALO ;"R" - заново сгенерировать карту
JP gameloop
timer
db 0 ;for logic
wind
db 0 ;-46..46
powr
db 0 ;0..118
gamestate
db 0 ;STATE_MOVE=управление червём (в т.ч. ИИ), STATE_SHOT=анимация выстрела, STATE_BULLET=полёт снаряда, STATE_FLY=взрыв, STATE_DIE=смерти, STATE_NEXTMOVE=переход хода
STATE_MOVE=0
STATE_SHOT=1
STATE_BULLET=2
STATE_FLY=3 ;сняты надписи со всех червей
STATE_DIE=4
STATE_NEXTMOVE=5
STATE_FLYCURWORM=6 ;прыжок/падение во время хода, снята надпись только с текущего червя
if !ATM
fixshift
fixshift0
ld b,e
ld a,l
RRCA
DJNZ $-1
ld (hl),a
and d
inc h
ld (hl),a
dec h
xor (hl)
ld (hl),a
inc l
jr nz,fixshift0
ret
endif
if !ATM
MAKINT
LD A,IMTAB/256
LD I,A
IM 2
EI
RET
endif
if !ATM
;PRGA LD A,0
curpg
db 0x10
OUTME
;LD (PRGA+1),A
ld (curpg),a
;OUTNO
PUSH BC
LD BC,FD
OUT (C),A
POP BC
RET
endif
SetPgMask
if ATM
pgmask=$+1
ld a,0
push bc
SETPGC000
pop bc
ret
else
LD A,PGMASK_
jp OUTME
endif
if ATM
SetPgMask8000
ld a,(pgmask)
push bc
SETPG8000
pop bc
ret
SetPgTexture8000
pg1=$+1
ld a,0
push bc
SETPG8000
pop bc
ret
SetPgTextureC000
ld a,(pg1)
push bc
SETPGC000
pop bc
ret
SetPgLmn8000
pg2=$+1
ld a,0
push bc
SETPG8000
pop bc
ret
SetPgMuzC000
ld a,(pg2) ;TODO отдельная страница
push bc
SETPGC000
pop bc
ret
endif
RND
PUSH de
PUSH HL
;Patrik Rak
rndseed1=$+1
ld hl,0xA280 ; xz -> yw
rndseed2=$+1
ld de,0xC0DE ; yw -> zt
ld (rndseed1),de ; x = y, z = w
ld a,e ; w = w ^ ( w << 3 )
add a,a
add a,a
add a,a
xor e
ld e,a
ld a,h ; t = x ^ (x << 1)
add a,a
xor h
ld d,a
rra ; t = t ^ (t >> 1) ^ w
xor d
xor e
ld h,l ; y = z
ld l,a ; w = t
ld (rndseed2),hl
POP HL
POP de
RET
RNDA
PUSH BC
LD C,A
CALL RND
SUB C
JR NC,$-1
ADD A,C
POP BC
RET
unsetwms
ld a,(gamestate)
cp STATE_FLY
ret z
call ForcedUnDrawWormsInMap
call UnDrawWormsDataInMap
ld a,STATE_FLY
ld (gamestate),a
ld a,80
call RND
add a,80
ld e,a ;y0
call RND
ld c,a ;x0low
xor a
sla c
rla
sla c
rla
ld b,a ;bc=x0
ld a,40
call RNDA
add a,10
ld d,a ;d=R
;ld bc,200
;ld e,100
call UnDrawCircleInMap
LD HL,WORMXY
unsetwms0
;POP BC ;SPRITE (lsb=xlow*32)
;POP HL ;COORDS
;POP DE ;SPEED
ld c,(hl)
inc l
ld b,(hl) ;spritehsb
inc l
dec b
ret z
inc b
ld a,(hl) ;x
inc l
inc l
inc l
cp XWID
jr nc,unsetwms_skip
call RND
and 7
sub 4
ld c,a
call RND
and 7
sub 7;4
ld b,a ;dy
dec l
ld (hl),c
inc l
ld (hl),b
unsetwms_skip
inc l
jr unsetwms0
SETWMS
;чтобы считывать XY в случайном порядке, будем переставлять случайно несколько раз с первым
ld b,100
SETWMS_SHUFFLE0
ld hl,TXY
xor a
sub l
srl a ;число объектов
call RNDA
add a,a
cpl
ld e,a
dec e
ld d,h
ld c,(hl)
ld a,(de)
ld (hl),a
ld a,c
ld (de),a
inc l
inc e
ld c,(hl)
ld a,(de)
ld (hl),a
ld a,c
ld (de),a
djnz SETWMS_SHUFFLE0
LD HL,WORMXY
LD DE,TXY
LD B,0
SWMS0 LD A,(DE) ;x from TXY (до 186?)
;ld a,l
INC E
LD C,A
;SWMSAp1=$+1
LD A,#80
;SRL C
;RRA
LD (HL),A ;xlow*64;32 (was for sprite)
INC HL
LD (HL),sprworm_0/256;BOMBWMS/256+1 ;sprite
ld a,e
cp -2*4 ;4 mines (last in the list)
jr c,$+4
LD (HL),sprmine_0/256;BOMBWMS/256+1 ;sprite
INC HL
LD (HL),C ;xhigh
INC HL
LD A,(DE) ;y from TXY
;ld a,l
LD (HL),A ;y
INC HL
LD (HL),B;0 ;dx
INC HL
LD (HL),SPRLIST_STAYING ;dy
INC HL
INC E
JR NZ,SWMS0
INC HL
LD (HL),1 ;end of list (impossible xlow)
inc hl
inc hl
inc hl
inc hl
ld (hl),SPRLIST_END ;end of list (impossible dy)
;LD HL,SWMSAp1
;LD A,(HL)
;SUB -2
;OR #80
;LD (HL),A ;"рандомная" младшая часть x
LD HL,CUWORMS
MKCUW0 XOR A
MKCUW1 LD (HL),B ;team 0..3
INC HL
LD (HL),A ;worm 0..3 in team
INC HL
LD (HL),150 ;health
INC HL
LD (HL),0 ;???
INC HL
LD (HL),10 ;???
INC HL
INC HL
INC A ;next worm in team
CP 4
JR C,MKCUW1
INC B
ld a,b
cp 4 ;костыль ;FIXME for 2 or 3 teams
;CP B ;4 teams ;FIXME for 2 or 3 teams
JR NZ,MKCUW0
RET
;offint:
MOUSEX DW 0
MOUSEY DB 0
NUMFONTCHARSZ=16;8
ResetTime
LD HL,6*NUMFONTCHARSZ*256+(0*NUMFONTCHARSZ) ;"60"
LD (curtime),HL
LD A,50
LD (curtimeframe),A
jp Hud_ResetTime
TIME
curtime=$+1
LD BC,6*NUMFONTCHARSZ*256+(0*NUMFONTCHARSZ) ;"60"
LD A,C
INC A
ret z ;JR Z,PTIMOUT
curtimeframe=$+1
LD A,50
DEC A
JR NZ,$+4
LD A,50
LD (curtimeframe),A
ret nz ;JR NZ,TIMPR
LD A,C
SUB NUMFONTCHARSZ;8
LD C,A
JR NC,TIMEok
LD C,9*NUMFONTCHARSZ;8
LD A,B
SUB NUMFONTCHARSZ;8
LD B,A
JR NC,TIMEok
LD HL,MESTIM
CALL MTITLE
LD A,-1
LD (curtime),A
jp Hud_UnDrawTime
TIMEok LD (curtime),BC
ret
if FASTMAPPER
MAKELDI
PUSH BC
LD (HL),225
INC HL
LD B,15
MLDI1 LD (HL),225
INC HL
LD (HL),34
INC HL
LD (HL),E
INC HL
LD (HL),D
INC HL
INC E
INC E
DJNZ MLDI1
CALL DDE
POP BC
DJNZ MAKELDI
DEC HL
DEC HL
CALL READER
LD SP,IX
RET
NOP
RET
endif
if FASTMAPPER
READER
;генерация в HL куска кода, заданного после CALL (0 = конец куска)
EX DE,HL
EX (SP),HL
DEC DE
READ0 INC DE
LD A,(HL)
LD (DE),A
INC HL
OR A
JR NZ,READ0
EX (SP),HL
EX DE,HL
RET
endif
cursorkeys
db 0 ;11LRDUef cursor
TLAND DB 18,"CREATING LANDSCAPE"
MESHOM DB 17,"2X HOMING MISSILE"
MESWHE DB 16,"NOWHERE TO WORM!"
MESTIM DB 11,"TIME IS OUT"
db 0
MESDIE DB "123456789012 IS AN EX-WORM"
MESTEAM
DB "1234567890123456 TEAM IS NO MORE"
TEAMLEN=16
CUTEAMS ;каждая надпись по TEAMLEN символов
DB "ALONE CODER "
DB "DAVE "
DB "WORMS "
DB "THE FARM "
NAMES DB "ALCO "
DB "ALCO2 "
DB "ALCO3 "
DB "ALCO4 "
DB "DAVE "
DB "D2 "
DB "D3 "
DB "D4 "
DB "FLAT "
DB "EARTH "
DB "TAPE "
DB "WOOD "
DB "MOO "
DB "HORSE "
DB "PIGGY "
DB "CHICKEN "
;db "BOMBA "
;db "BOMBA "
;db "BOMBA "
;db "BOMBA "
numfont
include "numfont.ast"
if !ATM
include "panel.ast" ;в 48K версии можно несъёмную панель (без панелей оружия)
endif
include "input.asm"
include "mkmap.asm"
if ATM
include "mkmapatm.asm"
else
include "mkmap6912.asm"
endif
include "hud.asm"
if ATM
include "hudatm.asm"
else
include "hud6912.asm"
endif
display "fast procedures: ",$,">=0x8000"
include "logic.asm"
include "drawmap.asm"
if ATM
include "drawmapatm.asm"
include "bgpushxy.asm"
include "../../_sdk/file.asm"
;include "../../_sdk/bmp.asm"
;bmpwid
;dw 0
include "mem.asm"
else
include "drawmap6912.asm"
endif
include "drawinmap.asm"
if ATM
include "drawinmapatm.asm"
else
include "drawinmap6912.asm"
endif
if ATM
BLANK DS MASKWID ;BLANK - пустая строка маски (небо) шириной MASKWID
else
align 256
IMTAB DS 257,$/256+1
BLANK DS $/256-1 ;BLANK - пустая строка маски (небо) шириной MASKWID
IMER
;restore stack from de
;if sp=screen, fill with 0
;if critical section, unwind de/bc and restore from de/bc
ld (imerhl),hl
pop hl
ld (imerjp),hl
ld (imersp),sp
ld sp,INTSTACK
push BC
push DE
push HL
PUSH AF
if !ATM
ld a,l
sub x6line_startcritical&0xff
ld a,h
sbc a,x6line_startcritical/256
jr c,IMERnocritical
ld a,l
sub x6line_endcritical&0xff
ld a,h
sbc a,x6line_endcritical/256
jr nc,IMERnocritical
ld a,(x6line_restorede_startcritical+x6line_startcritical)&0xff
sub l
ld l,a
ld a,((x6line_restorede_startcritical+x6line_startcritical)/256)&0xff
sbc a,h
ld h,a
pop af
push af
ld (IMERcriticaljp),hl
ld hl,IMERcritical_restorede ;jp (hl)=restore de, ret=restore bc
IMERcriticaljp=$+1
call 0 ;unwind de ;addr=x6line_restorede_startcritical-(imerjp-x6line_startcritical)
ld hl,(imersp)
dec hl
ld (hl),b
dec hl
ld (hl),c
jp IMERcriticalq
IMERcritical_restorede
;after jp (hl)
pop af ;skip return addr
IMERnocritical
endif
ld hl,(imersp)
dec hl
dec hl
bit 7,h
jr nz,IMERnozerostack
ld de,0
if !ATM
ld a,l
inc a
jr nz,IMERnozerostack
ld a,h
sub 0x50
cp 7
jr nc,IMERnozerostack
;при запарывании 0x50ff..0x56ff (ATM=0)
;50ff - берём из 51ff
;51ff - берём из 50ff
;52ff - берём из 51ff
;53ff - берём 0f
;прочие - берём ff
;call ReDrawEnergy ;при запарывании 0x50ff..0x56ff
cp 3
ld e,0x0f
jr z,IMERnozerostack
ld e,0xff
jr nc,IMERnozerostack
cpl
and 1
add a,0x50
ld b,a
ld c,l
ld a,(bc)
ld e,a
endif
IMERnozerostack
ld (hl),e
inc hl
ld (hl),d
IMERcriticalq
LD hl,curwater
ld a,(hl)
SUB -16
LD (hl),A
ex af,af' ;'
PUSH AF
CALL MOUSE
call TIME
ld hl,timer
inc (hl)
ld a,(curpg)
push af
push ix
push iy
ld a,PGLMN
call OUTME
muzpatch=$+1
ld a,0
or a
call z,muz+5
pop iy
pop ix
pop af
call OUTME
pop AF
ex af,af' ;'
pop AF
POP HL
pop DE
pop BC
imersp=$+1
ld sp,0
imerhl=$+1
ld hl,0
EI
imerjp=$+1
jp 0
endif
if ATM
genpush_newpage
;заказывает страницу, заносит в tpushpgs, a=pg
push bc
push de
push hl
push ix
OS_NEWPAGE
pop ix
ld a,e
ld (ix),a
ld de,4
add ix,de
pop hl
pop de
pop bc
ret
RestoreMemMap3
;ld a,CC_PAGE3;0
;jp setpgc000;SETPG32KHIGH
ret
include "grass16.ast"
;pal
;DDp palette: %grbG11RB(low),%grbG11RB(high), инверсные
;STANDARDPAL
include "pal.ast"
res_path
;в этом относительном пути будут лежать все загружаемые данные игры
db "worms"
db 0
fnpg1
db "hicode.c",0
fnpg2
db "hicode2.c",0
align 256 ;for setpixel
tpushpgs
ds 128 ;первая страница 0 слоя, первая страница 1 слоя, первая страница 2 слоя, первая страница 3 слоя, вторая страница 0 слоя...
align 256
trecodebyteleft
dup 256
;%00003210 => %.3...210
_3=$&8
_210=$&7
db (_3*0x08) + (_210*0x01)
edup
trecodebyteright
dup 256
;%00003210 => %3.210...
_3=$&8
_210=$&7
db (_3*0x10) + (_210*0x08)
edup
bgpush_bmpbuf ds 1024;320 ;заголовок bmp или одна строка
endif
display "endcode=",$
align 256
tsin
incbin "sin"
if !ATM
align 256
include "texture.ast" ;только при генерации карты (0x800 байт) (можно урезать (как на Амиге) или сжать?)
endif
align 256
include "sprites.ast"
sprpie
INCBIN "gug.bin" ;только при генерации карты (на 48K можно убрать)
display "endgfx=",$
endall
if !ATM
ORG 0x6000
jp GO
endif
page PGHICODE
ORG 0xc000
hicode_begin
if !ATM
nop ;TODO в этой странице тоже что-нибудь
else
include "texforrest.ast"
include "panel16.ast"
endif
hicode_end
page PGLMN
ORG 0xc000
hicode2_begin
LMNS
INCBIN "lmn.bin" ;>7K! в формате SCUT
muz
include "../../_sdk/ptsplay.asm"
MDLADDR
incbin "music/WORMS8.pt3"
;GUG
; INCBIN "gug.bin" ;только при генерации карты (на 48K можно убрать)
hicode2_end
if !ATM
page 0
savebin "code.c",begin,endall-begin
page PGHICODE;6
savebin "hicode.c",hicode_begin,hicode_end-hicode_begin
page PGLMN;4
savebin "hicode2.c",hicode2_begin,hicode2_end-hicode2_begin
else
page 0
savebin "worms.com",begin,endall-begin
page PGHICODE;6
savebin "worms/hicode.c",hicode_begin,hicode_end-hicode_begin
page PGLMN;4
savebin "worms/hicode2.c",hicode2_begin,hicode2_end-hicode2_begin
endif
LABELSLIST "../../../us/user.l",1