DEVICE ZXSPECTRUM1024
TCP=1
LOGGING=0
ifdef CLIENT
VIRTUALKEYS=1
else
VIRTUALKEYS=0
endif
JOYMASK_SELECT=0b00100000
JOYMASK_START =0b00010000
JOYMASK_FIRE =0b10000000
JOYMASK_FIRE2 =0b01000000
JOYMASK_UP =0b00001000
JOYMASK_DOWN =0b00000100
JOYMASK_LEFT =0b00000010
JOYMASK_RIGHT =0b00000001
;7 - A (A)
;6 - B (S)
;5 - Select (Space)
;4 - Start (Enter)
;3 - Up (7)
;2 - Down (6)
;1 - Left (5)
;0 - Right (8)
MANYLIVES=0;1 ;убрать при релизе!!!
TILES87=0
TILEHGT=8-TILES87
DRAWFOREST=1
KEMPSTON=1
DEFINE ProjName ZXBattleCity
DEFINE ProjVer 1_6
include "../../_sdk/sys_h.asm"
;************************* Возможные номера ошибок (errno)*************************
SHUT_RDWR EQU 2
ERR_EAGAIN EQU 35 ;/* Try again */
ERR_EWOULDBLOCK EQU ERR_EAGAIN ;/* Operation would block */
ERR_INTR EQU 4
ERR_NFILE EQU 23
ERR_ALREADY EQU 37
ERR_NOTSOCK EQU 38
ERR_EMSGSIZE EQU 40 ;/* Message too long */
ERR_PROTOTYPE EQU 41
ERR_AFNOSUPPORT EQU 47
ERR_HOSTUNREACH EQU 65
ERR_ECONNABORTED EQU 53 /* Software caused connection abort */
ERR_CONNRESET EQU 54
ERR_NOTCONN EQU 57
;************************* Протоколы соединений *************************
SOCK_STREAM EQU 0x01 ;tcp/ip
SOCK_ICMP EQU 0x02 ;icmp
SOCK_DGRAM EQU 0x03 ;udp/ip
AF_INET EQU 2
TOPYLOAD=32;0
TOPY=0;32
TOPYVISIBLE=TOPY+8
if TILES87
MAXY=(30-2)*8;224
else
MAXY=(26-2)*8
endif
scrbase=0x4000
sprmaxwid=32
sprmaxhgt=32
scrwid=160 ;double pixels
scrhgt=200
pushbase=0x8000
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
STACK=0x3ff0
tempsp=0x3f06 ;6 bytes for prspr
INTSTACK=0x3f00
;TILEFLAGBIT=2
TILEFLAG0=0x18
TILEFLAG1=0x1c
WATERANIMTILE=102
NWATERANIMTILES=2
SPSIZ16=2
SPACT=32
SPSIZ8=0
SPRDROP=256+34
SPRBULLETUP=52
SPRBULLETRIGHT=54
SPRCLOUD0=256+44
SPRCLOUD1=256+46
;сейчас спрайты лежат так (реально есть только чётные номера):
;0..31,64..95,... (my tank level 0,1, enemy1) в spr0 (+256 - mirror hrz, +512 - mirror vert)
;32..63,96..127,... в spr1 (+256 - mirror hrz, +512 - mirror vert)
;TODO:
;256+ (my tank level 2 (+16),3 (+128+16), enemy2 (+0)) в spr2
;512+ (enemy 3 (+0),4 (+64),5 (+128)) в spr3
SPRMYTANKLEVEL0=0
SPRMYTANKLEVEL1=16
SPRMYTANKLEVEL2=256+16
SPRMYTANKLEVEL3=256+128+16
;my tank level 0,1,2,3 - sprite 0,16,256+16,256+128+16
;enemy tank sprites (add 8 for red version):
;SPRENEMY1=0+8;256+128
;SPRENEMY2=0+16;256+128+128
;SPRENEMY3=0+24;256+128+128+128
;SPRENEMY4=64+0;256+128+256+128
;SPRENEMY5=64+8;256+128+256+256
SPRENEMY1=0+64;256+128
SPRENEMY2=256;256+128+128
SPRENEMY3=512;256+128+128+128
SPRENEMY4=512+64;256+128+256+128
SPRENEMY5=512+128;256+128+256+256
SPRMEGASHIP=32;256+36
SPRBONUS0=96;80;256+128+16
SPRBONUS1=98;82;256+128+18
SPRBONUS2=100;84;256+128+20
SPRBONUS3=102;86;256+128+22
SPRBONUS4=104;88;256+128+24
SPRBONUS5=106;90;256+128+26
SPRBONUS6=108;92;256+128+28
SPRBONUS7=110;94;256+128+30
SPRBONUS8=112;192+32;256+128+32
SPRSTAR0=120;256+48
SPRSTAR1=122;256+50
SPRSTAR2=124;256+52
SPRSTAR3=126;256+54
SPRENE0=128+64+46;256+128+46
SPRENE1=128+64+48;256+128+48
SPRENE2=128+64+50;256+128+50
SPRENE3=128+64+52;256+128+52
SPRENE4=128+64+54;256+128+54
SPRBOOM0=56
SPRBOOM1=58
SPRBOOM2=60
SPRBOOM0_=48;256+56 ;big boom
SPRBOOM2_=50;256+60
SPRGAMEOVER0=256+40
SPRGAMEOVER1=256+42
BYTESPERTILE=1;2
BYTESPERTILELINE=(BYTESPERTILE*64);256
macro PRCHAR_TILEMAP_HL
ld (hl),a
set 3,h
ld (hl),TILEFLAG1 ;при печати тайла ставим биты изменения обоих экранов (а при печати спрайта надо только на текущем экране)
res 3,h
set 4,h
ld (hl),TILEFLAG1 ;при печати тайла ставим биты изменения обоих экранов (а при печати спрайта надо только на текущем экране)
res 4,h
endm
macro TILEMAPLINEUP
;LD BC,-256
LD BC,-BYTESPERTILELINE;-256
ADD HL,BC
endm
macro TILEMAPLINEDOWN
;LD BC,256
LD BC,BYTESPERTILELINE;256
ADD HL,BC
endm
macro TILEMAPLEFTLINEDOWN
;LD BC,256-2
LD BC,BYTESPERTILELINE-BYTESPERTILE;256-2
ADD HL,BC
endm
macro TILEMAPLEFT
dup BYTESPERTILE
dec hl
edup
;dec hl
endm
macro TILEMAPRIGHT
dup BYTESPERTILE
inc hl
edup
;inc hl
endm
org PROGSTART
begin
jp MAINGO ;patched by prspr
MAINGO
ld sp,STACK
;OS_HIDEFROMPARENT
ld e,0 + 0x80 ;EGA + 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) +8=noturbo, +0x80=keep gfx pages
ld de,path
OS_CHDIR
call clstwo
OS_GETMAINPAGES
;dehl=номера страниц в 0000,4000,8000,c000
ld a,e
LD (pgmain4000),A
ld a,h
LD (pgmain8000),A
ld a,l
LD (pgmainc000),A
call newpage
ld (pgmuzmain),a
call newpage
ld (pgmuzend),a
call newpage
ld (pgspr0),a
call newpage
ld (pgspr1),a
call newpage
ld (pgspr2),a
call newpage
ld (pgspr3),a
call newpage
ld (pgtiles),a
call newpage
ld (pglvl0),a
call newpage
ld (pglvl1),a
call newpage
ld (pglvl2),a
call newpage
ld (pgarea),a
call newpage
ld (pgfake),a ;эту страницу можно будет запарывать при отрисовке спрайтов с клипированием
ld (pgfake2),a
CALL INSREADY ;Loading Hi-Score table, music, palette, sound FX and palette initialisation
LD HL,48000 ;Sound FX initialisation
CALL AFXINIT
ld hl,prsprqwid
ld (0x0101),hl ;спрайты в файле подготовлены так, что выходят в 0x0100
ifdef CLIENT
if TCP
if CLIENT
call getipfromcmd
;create socket:
CONNECTIONERROR
ld de,SOCK_STREAM+(AF_INET<<8)
OS_NETSOCKET
ld a,l
or a
jp m,CONNECTIONERROR;?C_EXIT
ld (datasoc),a
LD DE,web_ia
OS_NETCONNECT
ld a,l ;DimkaM 12.03.2019
or a
jp p,connect_ok
createsoc_err
ld a,(datasoc)
ld e,0
OS_NETSHUTDOWN
jp CONNECTIONERROR
;CONNECTIONERROR
connect_ok
else ;SERVER
;SOCKET OS_NETSOCKET(unsigned int);
;#define socket(domain, type, protocol) OS_NETSOCKET((domain<<8)+type)
;ld bc,1 ;domain???
LD DE,513 ;type???
OS_NETSOCKET ;Подключить TCP/IP сокет к хосту.???
ld a,l
or a
jp m,CONNECTIONERROR;?C_EXIT
LD (soc),A
;a=socket
LD DE,web_ia
;signed char OS_BIND(const struct sockaddr_in * addr, SOCKET socket);
;#define bind(socket, addr, address_len) OS_BIND(addr,socket)
OS_BIND ;Присвоение сокету конкретного номера исходящего порта.
LD a,(soc) ;socket
;LD DE,0 ;backlog???
;signed char OS_LISTEN(int, SOCKET socket);
;#define listen(socket, backlog) OS_LISTEN(backlog,socket)
OS_LISTEN ;Включить режим прослушивания исходящего порта(режим сервера) TCP/IP сокета.
WAIT_CLIENTS0
LD a,(soc) ;socket
;LD DE,0 ;addr???
;SOCKET OS_ACCEPT(const struct sockaddr_in * addr, SOCKET socket);
;#define accept(socket, addr, address_len) OS_ACCEPT(addr,socket)
OS_ACCEPT ;ждём, когда подсоединятся
BIT 7,L
JR Z,ESTABLISHED
CP ERR_EAGAIN
JP NZ,ERR_EXIT ;обработка ошибки
OS_YIELD ;не обязательно. Если время реагирования на подключение не критично,
;то отдадим квант времени системе.
JR WAIT_CLIENTS0 ;никто не подключился, ждём
ESTABLISHED
LD A,L ;удачно
LD (datasoc),A ;сохраняем дескриптор сокета.
; Возвращаемые значения в регистрах:
; L - SOCKET при положительном значении, при отрицательном значении - функция завершилась с ошибкой.
; А - errno при ошибке.
; Возможные ошибки:
; ERR_NOTSOCK - не действительный дескриптор сокета
; ERR_ECONNABORTED - общая ошибка сокета
; ERR_EAGAIN - входящих подключений пока нет
CONNECTIONERROR
ERR_EXIT
endif
else ;UDP
ld de,0x0203
OS_NETSOCKET
ld a,l
ld (soc),a
or a
jp m,inet_exiterr_nosoc
inet_exiterr_nosoc ;TODO
if CLIENT==0
ld a,(soc)
LD DE,port_ia
OS_BIND
ld a,l
or a
jp m,inet_exiterr
inet_exiterr ;TODO
endif
endif ;UDP
endif
JP PRESTART;S
newpage
OS_NEWPAGE
ld a,e
ret
clstwo
ld e,1
call clsone
ld e,0
clsone
OS_SETSCREEN
ld e,0
OS_CLS
ret
;display $
ds 0x200-$
sprlist
ds 85*6
sprlistsz=$-sprlist
;+0: y
;+1: 2(ysize:SPSIZ16) +0x20(SPACT) +0x40(deact) +0x80(mirrorvert) +1(SPSIZBS)
;+2: x
;+3: 2(xsize:SPSIZ16) +1(SPSIZBS) +0x80(mirrorhor)
;+4,5: pattern number
macro DWBIGENDIAN data
db data/256
db data&0xff
endm
ifdef CLIENT
soc
db 0
datasoc
db 0
;TCP:
curport=$+1
web_ia:
defb 0
DWBIGENDIAN 20001 ;db 0,80
web_ia_ip
db 192,168,1,177;127,0,0,1 ;ip (big endian) ;connect to 192.168.1.177
ds 8 ;reserved
getipfromcmd
ld hl,COMMANDLINE
call skipword
ld a,(hl)
or a
ret z
call skipspaces
ld de,web_ia_ip
ping_nextdig
call strtobyte_hltode
or a
ret nz ;error
ld a,(hl)
cp '.'
inc hl
jr z,ping_nextdig
ret
skipword
;hl=string
;out: hl=terminator/space addr
skipword0
ld a,(hl)
or a
ret z ;jr z,skipwordq
sub ' '
ret z ;jr z,skipwordq
inc hl ;ldi
jr skipword0
skipspaces
;hl=string
;out: hl=after last space
ld a,(hl)
cp ' '
ret nz
inc hl
jr skipspaces
strtodigit_a ;a=FF - err
sub 0x30
jr c,str_digit_a_err
sub 10
jr nc,str_digit_a_err
add 10
ret
str_digit_a_err
ld a,0xFF
ret
strtobyte_hltode ; a=0 ok a=FF error
ld a,(hl)
call strtodigit_a
inc a
or a
jr z,strtobyte_err
dec a
ld c,a
inc hl
ld a,(hl)
call strtodigit_a
inc a
or a
jr nz,strtobyte_2digit
ld a,c
ld (de),a
xor a
inc de
ret
strtobyte_2digit
inc hl
dec a;в а вторая цифра
ex af,af' ;'
ld a,c
ld b,9
strtobyte_2digit0
add c
djnz strtobyte_2digit0
ld c,a
ex af,af' ;'
add c
ld c,a
ld a,(hl)
call strtodigit_a
inc a
or a
jr nz,strtobyte_3digit
ld a,c
ld (de),a
xor a
inc de
ret
strtobyte_3digit
inc hl
dec a; в a третья цифра
ex af,af' ;'
ld a,c
ld b,9
strtobyte_3digit0
add c
jr c,strtobyte_err
djnz strtobyte_3digit0
ld c,a
ex af,af' ;'
add c
jr c,strtobyte_err
ld (de),a
xor a
inc de
ret
strtobyte_err
ld a,0xFF
ret
endif ;ifdef CLIENT
PRESTART;S
;LD A,(ENN) ;resources loaded?
;CP 1
;JP Z,ZZZZ2 ;skip load
call loadresources
;LD HL,(#5CF4) ;Save position of Levels on disk
;LD (DiskAddrLevels),HL
;vertical scroll
call setpgsscr40008000
ld de,bgfilename
call bgpush_prepare
call setpgsmain40008000
call swapimer
ifdef CLIENT
if LOGGING
ld de,fn_log
OS_CREATEHANDLE
ld a,b
ld (loghandle),a
endif
;OS_HIDEFROMPARENT
endif
STARTS
;сюда можем попасть из игры
ld sp,STACK
LD A,1
LD (NEWLEVEL),A ;иначе рычит в меню
ld a,5
ld (SOUNDGO),a ;иначе остаток от рычания после гамовера?
call afxinit
LD HL,BONUS2
LD DE,BONUS
LD BC,96
LDIR
;LD BC,PAGE3
;LD A,#C3
;OUT (C),A
call setpgc3
CALL #C000 ;init muzmain
CALL #CBB8 ;init muzboss
LD A,200+24
LD (SOUNDW),A ;time until music stops
CALL POINTHI ;формирует в TEXT4 строку со счётом
XOR A
LD (NEWTAN1),A
LD (NEWTAN2),A
LD A,(MAP)
CP 255
JR Z,FGF2
XOR A ;first level
;ld a,31 ;18"19" и 23"24" трудные
LD (MAP),A
FGF2
ZZZZ2
;ld ix,UNITS
;ld (ix+UNIT_YESORNOT),0
;xor a
;ld (sprlist+1),a ;disable sprite #0
call clearsprlist
call clstiles
;LD BC,VCONFIG; CHANGE VIDEO RESOLUCION 1
;LD A,VID321X+1
;OUT (C),A
;LD BC,VPAGE; VRAM CHANGE
;LD A,#10
;OUT (C),A
;LD BC,BORDER
;LD A,1
;OUT (C),A
call border1
CALL CLSSTART ;???
LD A,2
LD (FIGH),A ;какой-то признак deact спрайтов??? (потом не обнуляется!)
ld hl,108
ld (callpush_curscroll),hl
;Main menu cycle!
;K inject here! TODO
call doscreen
call doscreen
;ld b,24
;halt
;djnz $-1
ld a,(timer)
ld (KERNSoldtimer),a
ld (scrolloldtimer),a
;цикл показа и обработки меню
KERNS
ifdef CLIENT
if CLIENT
call sendjoyTMP
ld hl,menucheckkeys
call readfrominet_tojoy1joy2 ;читать ровно одно сообщение, выполнить логику. и так пока есть сообщения
else
call readfrominet_tojoy2 ;может быть принято сколько угодно сообщений - берём последнее
call sendjoy1joy2 ;в каждом цикле логики
call menucheckkeys
endif
else
call menucheckkeys
endif
call menuchangetimer ;при окончании таймера вызывает autounpress start
call menudraw
jr KERNS
menudraw
LD A,(STR6) ;time in startmenu
;CP 218
;CALL Z,STR77 ;autounpress start
;CP 219
;CALL Z,menu_printcopyrights;STR7 ;print text TEXT3 (copyrights), TEXT4 (hiscores)
CP 220
JP nc,noscroll;STR4
ld hl,(callpush_curscroll)
bit 7,h
jr nz,noscroll;STR4 ;end of scroll
call menuscroll
;call setpgc3
;call #C000 ;init muzmain
ld a,(SOUNDW)
or a
call z,afxinit ;stop sound
ret;jp KERNS
noscroll;STR4
call menuscreen_tank
call doscreen
ret;JP KERNS ;STR44
stopscroll_draw
ld de,512-200-8
ld (callpush_curscroll),de
call bgpush_draw ;359975t
CALL menu_printcopyrights;STR7 ;print text TEXT3 (copyrights), TEXT4 (hiscores)
call menuscreen_tank
call doscreen ;содержит changescrpg и waitchangescr
;call changescrpg ;с этого момента (точнее, с прерывания) можем видеть, что нарисовали
;halt
call bgpush_draw ;359975t
CALL menu_printcopyrights;STR7 ;print text TEXT3 (copyrights), TEXT4 (hiscores)
call setpgsmain40008000
ld h,-1
ld (callpush_curscroll),hl
call menuscreen_tank
jp doscreen
;ret
if 1==1
STR3
LD A,(STR)
DEC A
LD (STR),A ;--scroll page?
LD HL,65535-228
LD (STR2),HL ;scroll position?
JP STR5
endif
STR77
PUSH AF
LD A,1 ;start unpressed
LD (STAKEY),A
POP AF
RET
menuchangetimer
ld a,(timer)
KERNSoldtimer=$+1
ld b,0
ld (KERNSoldtimer),a
sub b
ld c,a
ld b,0
ret z ;jr z,STR44
ld a,(STR6)
cp 220
ret nc
add a,c
ld (STR6),a ;time in start menu
cp 220
ret nc
CALL STR77 ;autounpress start
ret
menuscroll
if 1==1
ld a,(timer)
scrolloldtimer=$+1
ld bc,0
ld (scrolloldtimer),a
sub c
ld c,a
ld hl,(callpush_curscroll)
;bit 7,h
;jr nz,STR4 ;end of scroll
ld de,512-200-8
or a
sbc hl,de
jr nc,stopscroll
call bgpush_inccurscroll ;bc=scroll increment (signed)
scroll_wait0
ld a,(timer)
lastscrtimer=$+1
cp 0
jr z,scroll_wait0 ;wait screen change
call bgpush_draw ;359975t
call setpgsmain40008000
ld a,(timer)
ld (lastscrtimer),a
call changescrpg ;с этого момента (точнее, с прерывания) можем видеть, что нарисовали
ret;jp STR44
stopscroll
call stopscroll_draw
STR5
else
INC A
LD (STR6),A ;++time in startmenu
LD A,(STR) ;scroll page?
CP 15
JP Z,STR4 ;end of scroll?
LD HL,(STR2) ;scroll position?
LD A,H
CP #C0
JP Z,STR3 ;go to previous scroll page
LD DE,256
SBC HL,DE
STR5 LD (STR2),HL ;scroll position?
if 1==0
PUSH HL
POP DE
LD HL,#C000
LD B,51 ;wid/8-1?
LD C,154 ;hgt-1?
LD A,#C2
LD (PAGEFR),A
LD A,(STR)
LD (PAGETO),A
LD A,%00010001
CALL DMASTART
endif
endif
;STR44
ret
menuscreen_tank
LD HL,(KORM);---X
LD BC,(KORM2);----Y
if TILES87
else
ld a,c
sub 16 ;костыль
ld c,a
endif
LD A,(TANK) ;sprite phase
ADD A,4;44 ;sprite pattern number
LD D,2 ;size
CALL PRINT
LD A,(TANKP) ;anim timer
INC A
CP 4
CALL Z,TANKP2 ;next sprite phase
CP 8
CALL Z,TANKP3 ;prev sprite phase
LD (TANKP),A ;anim timer
;LD BC,TSCONFIG; SPRITE PRINT
;LD A,%10000000
;OUT (C),A
ret
menucheckkeys
CALL EXIT ;if break, set (MAP)=31
if VIRTUALKEYS
ld a,(joy1state)
and JOYMASK_START
else
LD HL,(Keys1PlStart)
LD B,H
LD C,#FE
IN A,(C)
AND L
endif
oldkeystart1=$+1
ld c,0xff
ld (oldkeystart1),a
CALL Z,STR8 ;press start
if VIRTUALKEYS
ld a,(joy1state)
and JOYMASK_FIRE
else
LD HL,(Keys1PlFr)
LD B,H
LD C,#FE
IN A,(C)
AND L
endif
oldkeyfire1=$+1
ld c,0xff
ld (oldkeyfire1),a
CALL Z,STR8 ;press start
;ret
;menucheckkeys_up_down
if VIRTUALKEYS
ld a,(joy1state)
and JOYMASK_DOWN
else
LD HL,(Keys1PlDn) ;LD HL,Keys1PlDn+2
LD B,H ;LD BC,(Keys1PlDn)
LD C,#FE ;CALL CHBIT
IN A,(C)
AND L
endif
oldkeydd2=$+1
ld c,0xff
ld (oldkeydd2),a
CALL Z,KEYDD2
if VIRTUALKEYS
ld a,(joy1state)
and JOYMASK_UP
else
LD HL,(Keys1PlUp) ;LD HL,Keys1PlUp+2
LD B,H ;LD BC,(Keys1PlUp)
LD C,#FE ;CALL CHBIT
IN A,(C)
AND L
endif
oldkeyuu2=$+1
ld c,0xff
ld (oldkeyuu2),a
CALL Z,KEYUU2
ret
STR8
;press start
if 1
cp c
ret z
call stopscroll_draw
jp CHEKSTA ;use menu option depending on Y (KORM2)
else
LD A,(STAKEY) ;start unpressed?
CP 1
jp Z,CHEKSTA ;use menu option depending on Y (KORM2)
LD A,(STR6) ;time in startmenu
CP 220
JR Z,STR10 ;wait start key unpress
LD A,219
LD (STR6),A ;??? time in startmenu
if 1==1
call stopscroll_draw
;RET
else
LD HL,#C000+26+8192+1024
LD (STR2),HL ;scroll position in page?
LD A,#10
LD (STR),A ;scroll page?
CALL CLSSTART ;???
RET
endif
STR10
if 1==0
if VIRTUALKEYS
ld a,(joy1state)
and JOYMASK_START
else
LD HL,(Keys1PlStart)
LD B,H
LD C,#FE
IN A,(C)
AND L
endif
JR Z,STR10
if VIRTUALKEYS
ld a,(joy1state)
and JOYMASK_FIRE
else
LD HL,(Keys1PlFr)
LD B,H
LD C,#FE
IN A,(C)
AND L
endif
JR Z,STR10
endif
LD A,1
LD (STAKEY),A ;start unpressed
RET
endif
CHEKSTA
LD HL,(KORM2) ;Y
LD A,L
CP 126
JP Z,FIGHT
CP 136
JP Z,FIGHT
CP 146
JP Z,EDITOR;START ;editor
CP 156
JP Z,REDIFIN
RET
CLSSTART
if 1==1 ;???
call clstiles
else
LD HL,25998
LD A,%00010001
LD (HL),A
INC HL
LD (HL),A
DEC HL
LD DE,#C000
LD B,95 ;wid/8-1?
LD C,240 ;hgt-1?
LD A,#05
LD (PAGEFR),A
LD A,#10
LD (PAGETO),A
LD A,%00110100
CALL DMASTART
HALT
HALT
endif
RET
STAKEY DEFB 0 ;1=start unpressed
STR DEFB #13 ;scroll page?
STR2 DEFW 65535-228 ;scroll position in page?
STR6 DEFB 0 ;time in startmenu
EXIT
LD BC,#7FFE
IN A,(C)
AND %0000001
RET NZ
LD BC,#FEFE
IN A,(C)
AND %0000001
RET NZ
halt
call setpgc3
CALL #C000 ;init muzmain
call swapimer
QUIT
;LD A,31
;LD (MAP),A
;RET
reter
ret
KERNF
ifdef CLIENT
if CLIENT
call sendjoyTMP
else
call readfrominet_tojoy2 ;может быть принято сколько угодно сообщений - берём последнее
endif
endif
call doscreen_and_logic
;TODO эти события тоже обслуживать в logic:
CALL ENDGAME
LD A,(NEWLEVEL)
CP 1
CALL Z,END5
JR KERNF
doscreen
call showsprites
;закончили рисовать
ld a,(timer)
push af
call changescrpg ;с этого момента (точнее, с прерывания) можем видеть, что нарисовали
pop bc ;b=timer на момент changescrpg
jp waitchangescr0
doscreen_and_logic
;logic=56000..103000
call showsprites
;закончили рисовать
ld a,(timer)
push af
call changescrpg ;с этого момента (точнее, с прерывания) можем видеть, что нарисовали
;логика
;... её вызывать столько раз, сколько прошло прерываний!
mainloop_uvwaittimer0
ld a,(timer)
uvoldtimer=$+1
ld b,0
ld (uvoldtimer),a
sub b
ld b,a
jr z,mainloop_uvwaittimer0 ;если ни одного прерывания не прошло, крутимся тут
cp 4
jr c,$+4
ld b,4
;b=сколько прошло прерываний
ifdef CLIENT
if CLIENT
;call sendjoyTMP
ld hl,logic
call readfrominet_tojoy1joy2 ;читать одно сообщение, выполнить логику - и так пока есть сообщения
else
mainloop_uvlogic0
push bc
;call readfrominet_tojoy2 ;может быть принято сколько угодно сообщений - берём последнее
call sendjoy1joy2 ;в каждом цикле логики
call logic
pop bc
djnz mainloop_uvlogic0
endif
else
mainloop_uvlogic0
push bc
call logic
pop bc
djnz mainloop_uvlogic0
endif
;ждём физического переключения экрана!
;можем начать новую отрисовку, только если с момента changescrpg прошло хотя бы одно прерывание (возможно, внутри logic)
pop bc ;b=timer на момент changescrpg
waitchangescr0
ld a,(timer)
cp b
jr z,waitchangescr0
ret
;pal
include "pal.ast"
clearsprlist
ld hl,sprlist
ld de,sprlist+1
ld bc,sprlistsz-1
ld (hl),0
ldir
ret
clstiles
ld hl,tilemap
ld de,tilemap+1
ld bc,BYTESPERTILELINE*30-1
ld (hl),0
ldir
ld bc,TILEFLAG1*0x0101
if TILES87
ld hl,tilemap+0x800+BYTESPERTILELINE
else
ld hl,tilemap+0x800+(BYTESPERTILELINE*TOPYVISIBLE/8)
endif
call resettileflags
if TILES87
ld hl,tilemap+0x1000+BYTESPERTILELINE
else
ld hl,tilemap+0x1000+(BYTESPERTILELINE*TOPYVISIBLE/8)
endif
;call resettileflags
jp resettileflags
clstiles_field
call clstiles
ld hl,tilemap+34
ld de,BYTESPERTILELINE-6
ld bc,0x600+30 ;b=wid, c=hgt (chrs)
clstileblock0
push bc
ld (hl),0xe0
inc hl
djnz $-3
pop bc
add hl,de
dec c
jr nz,clstileblock0
ret
clstiles_white
call clstiles
ld hl,tilemap
ld de,BYTESPERTILELINE-40
ld bc,40*256+30 ;b=wid, c=hgt (chrs)
jr clstileblock0
prchar_tilemap_hl
;a=char (kept)
;hl=tilemap
;ex de,hl
;call prchar_tilemap
;ex de,hl
PRCHAR_TILEMAP_HL
ret
prchar_tilemap
;a=char (kept)
;de=tilemap
ld (de),a
if BYTESPERTILE == 2
inc de
ex de,hl
ld (hl),0xc0 ;при печати тайла ставим биты изменения обоих экранов (а при печати спрайта надо только на текущем экране)
ex de,hl
dec de
else
ex de,hl
set 3,h
ld (hl),TILEFLAG1 ;при печати тайла ставим биты изменения обоих экранов (а при печати спрайта надо только на текущем экране)
res 3,h
set 4,h
ld (hl),TILEFLAG1 ;при печати тайла ставим биты изменения обоих экранов (а при печати спрайта надо только на текущем экране)
res 4,h
ex de,hl
endif
ret
loadfile
;de=filename
;hl=addr
push hl ;addr
OS_OPENHANDLE
pop de ;addr
push bc ;b=handle
ld hl,0x4000 ;max size
OS_READHANDLE
pop bc ;b=handle
OS_CLOSEHANDLE
ret
savefile
;de=filename
;hl=addr
;bc=size
push hl ;addr
push bc ;size
OS_CREATEHANDLE
pop hl ;size
pop de ;addr
push bc ;b=handle
OS_WRITEHANDLE
pop bc ;b=handle
OS_CLOSEHANDLE
ret
bgfilename ;needs 40008000?
db "menu.bmp",0
macro PRTILE
dup TILEHGT-1
ld a,(de)
inc d
ld (hl),a
set 6,h
ld a,(de)
inc d
ld (hl),a
set 5,h
ld a,(de)
inc d
ld (hl),a
res 6,h
ld a,(de)
inc d
ld (hl),a
add hl,bc
edup
ld a,(de)
inc d
ld (hl),a
set 6,h
ld a,(de)
inc d
ld (hl),a
set 5,h
ld a,(de)
inc d
ld (hl),a
res 6,h
ld a,(de)
ld (hl),a
endm
drawlefttile
;jp drawleftandrighttiles
ld hl,-2-0x800
add hl,sp
;de=screen line start
push de
res 3,h
ld a,l
and 0x3f
add a,e
ld e,a
jr nc,$+3
inc d
ld l,(hl)
ex de,hl
ld d,0x60
PRTILE
pop de
ret
drawrighttile
;jp drawleftandrighttiles
ld hl,-2+1-0x800
add hl,sp
;de=screen line start
push de
res 3,h
ld a,l
and 0x3f
add a,e
ld e,a
jr nc,$+3
inc d
ld l,(hl)
ex de,hl
ld d,0x60
PRTILE
pop de
ret
drawleftandrighttiles
ld hl,-2+1-0x800
add hl,sp
;de=screen line start
push de
res 3,h
ld a,(hl) ;right tile
ex af,af' ;'
dec l
ld a,l
and 0x3f
add a,e
ld e,a
jr nc,$+3
inc d
ld l,(hl) ;left tile
ex de,hl
push hl ;screen (even x)
ld d,0x60
PRTILE
pop hl ;screen (even x)
inc l ;screen (odd x)
ex af,af' ;'
ld e,a ;right tile
ld d,0x60
PRTILE
pop de
ret
nexttileliner
ld hl,TILEHGT*40;-40
add hl,de ;screen
ex de,hl
ld hl,BYTESPERTILELINE-40-2
add hl,sp
ld sp,hl
ret
showtiles
ld (showtilessp),sp
showtilesaddrpatch=$+1
if TILES87
ld sp,tilemap+0x800+BYTESPERTILELINE
else
ld sp,tilemap+0x800+(BYTESPERTILELINE*TOPYVISIBLE/8)
endif
ld de,0x8000
ld bc,40-0x2000
ret
;если флаг отрисовки хранится отдельно (через set N,d), то:
;ret -> пропуск или рисование левого или правого или обоих тайлов
;но тогда надо флаги для 0 и 1 экранов хранить в отдельных таблицах, т.к. они запарываются стеком. и после отрисовки залить текущую таблицу push'ами
endtileliner
showtilessp=$+1
ld sp,0
;сейчас при куче спрайтов
;53000 + 8419(resettileflags)
;TODO делать reset только там, где отрисовка, и по прерыванию (причём прерывание должно восстанавливать адрес nexttileliner)
ret
resettileflags
;hl=start of visible tiles
;ld bc,TILEFLAG0*0x0101
;bc=TILEFLAG0*0x0101 or TILEFLAG1*0x0101
ld (filltileflagsp),sp
if TILES87
ld de,28*64+40+2
ld hx,29
else
ld de,24*64+40+2
ld hx,25
endif
add hl,de
ld de,endtileliner
filltileflagline0
ld sp,hl
push de
dup 40/2
push bc
edup
ld de,-BYTESPERTILELINE
add hl,de
ld de,nexttileliner
dec hx
jp nz,filltileflagline0
filltileflagsp=$+1
ld sp,0
ret
showsprites
ld hl,tileaddrpatch+1
ld a,(hl)
xor 0x18
ld (hl),a
ld hl,showtilesaddrpatch+1
ld a,(hl)
xor 0x18
ld (hl),a
call setpgsscr8000c000
call setpgc2_4000;setpggfxc000
call showtiles
ld hl,(showtilesaddrpatch)
ld bc,TILEFLAG0*0x0101
;ld bc,TILEFLAG1*0x0101
call resettileflags
call setpgsscr40008000
;jp showsprites0q
ld ix,sprlist
ld b,85
showsprites0
;+0: y
;+1: 2(ysize:SPSIZ16) +0x20(SPACT) +0x40(deact) +0x80(mirrorvert) +1(SPSIZBS)
;+2: x
;+3: 2(xsize:SPSIZ16) +1(SPSIZBS) +0x80(mirrorhor)
;+4,5: pattern number
ld a,(ix+1)
or a
jp z,showsprites0skip
bit 6,a
jp nz,showsprites0skip
;jp nz,showsprites0q ;не видно бонус
bit 5,a
jp z,showsprites0skip
;ix+1 bit7 = mirror vert
;ix+3 bit7 = mirror hor
rla
ld a,(ix+3)
rla
rla
and 3 ;%000000vh
or 0xc0
ld (prspr_type+1),a
push bc
ld a,(ix+4) ;sprite pattern ;00(up/down),04(left/right)
ld (prspr_type),a
bit 5,a
jr nz,prspr_setpgright
bit 0,(ix+5) ;+256
call z,setpgc0 ;left sprites (tanks)
call nz,setpgspr2
bit 1,(ix+5) ;+512
call nz,setpgspr3
jp prspr_setpgq
prspr_setpgright
call setpgc1 ;right sprites (bullets)
prspr_setpgq
if TILES87
ld c,(ix+0) ;y
ld a,c
add a,4+(2*8)
rra
rra
rra
and 0x1f ;*1/8
cpl
;inc a
add a,c ;*7/8 (округление такое: 0,1,2,3,3,4,5,6, 7,8,9,10,10,11,12,13...
add a,sprmaxhgt-1 +2 -6;7
cp 199+sprmaxhgt-1 ;защита от второго взрыва сверху с отрицательным y
jp nc,showsprites0popbcskip
sub sprmaxhgt-1;6;7
;sub 6;7
else
ld a,(ix+0) ;y
add a,sprmaxhgt-1 -TOPYVISIBLE
cp 199+sprmaxhgt-1 ;защита от второго взрыва сверху с отрицательным y
jp nc,showsprites0popbcskip
sub sprmaxhgt-1;6;7
endif
ld c,a ;y
ld a,(ix+3) ;xsize, xhsb
rra
ld a,(ix+2) ;x
rra
add a,sprmaxwid-1
ld e,a
prspr_type=$+2
ld iy,(0xc000)
;e=x = -(sprmaxwid-1)..159 (кодируется как x/2+(sprmaxwid-1))
;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
push ix
push de
ld a,(iy-3) ;sprhgt
cp 16
jr nz,prspr_bighgt
call prspr
pop de
pop ix
;ставим флаги обновления на тайлах под спрайтом
ld c,(ix+0) ;y
ld a,e ;x/2
sub sprmaxwid-1
jr nc,$+3
xor a
and 0xfc
ld e,a ;x/2
ld a,c ;y
and 0xf8
cp 8*29;30
jr c,$+3
xor a
ld l,a
ld h,0
ld d,h;0
add hl,hl
add hl,hl
add hl,hl ;Y*64
if BYTESPERTILE == 2
add hl,hl ;*128
endif
srl e
if BYTESPERTILE == 1
srl e
endif
add hl,de
tileaddrpatch=$+1
ld de,tilemap+0x800
add hl,de
ld a,(ix+2) ;x
and 7
ld a,TILEFLAG1
ld (hl),a
jr z,prsprwid2
dup BYTESPERTILE
inc l
edup
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
ld de,BYTESPERTILELINE-(2*BYTESPERTILE)
add hl,de
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
add hl,de
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
if TILES87
;из-за тайлов высотой 7 при y=6 приходится обновить четыре ряда:
ld a,c ;y
cpl
and 7
jr nz,prsprhgt3q
ld a,TILEFLAG1
add hl,de
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
endif
jp prsprhgt3q
prsprwid2
dup BYTESPERTILE
inc l
edup
ld (hl),a
ld de,BYTESPERTILELINE-(1*BYTESPERTILE)
add hl,de
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
add hl,de
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
if TILES87
;из-за тайлов высотой 7 при y=6 приходится обновить четыре ряда:
ld a,c ;y
cpl
and 7
jr nz,prsprhgt3q
ld a,TILEFLAG1
add hl,de
ld (hl),a
dup BYTESPERTILE
inc l
edup
ld (hl),a
endif
jp prsprhgt3q
prspr_bighgt
call prspr
pop de
pop ix
if 1==1
;ставим флаги обновления на тайлах под спрайтом
ld c,(ix+0) ;y
ld a,e ;x/2
sub sprmaxwid-1
jr nc,$+3
xor a
and 0xfc
ld e,a ;x/2
ld a,c ;y
and 0xf8
ld l,a
ld h,0
ld d,h;0
add hl,hl
add hl,hl
add hl,hl ;Y*64
if BYTESPERTILE == 2
add hl,hl ;*128
endif
srl e
if BYTESPERTILE == 1
srl e
endif
add hl,de
ld de,(tileaddrpatch)
add hl,de
ld de,BYTESPERTILELINE-(4*BYTESPERTILE)
if TILES87
ld b,6
else
ld b,5
endif
prspr_bighgt1
ld a,TILEFLAG1
ld (hl),a
dup 4
dup BYTESPERTILE
inc hl ;нельзя l, не компенсируется add
edup
ld (hl),a
edup
ld a,h
add hl,de
xor h
and 0xf8 ;остаёмся в рамках одной карты флагов!
xor h
ld h,a
djnz prspr_bighgt1
endif
jp prsprhgt3q
prsprhgt3q
;если спрайт - танк (не бонус)
;draw tree (one or many) above sprite if needed
if TILES87 || !DRAWFOREST
else
bit 5,(ix+4)
jp nz,prspr_tree_q ;не танк
call setpgc1 ;right sprites (bullets)
ld a,(ix+0) ;y
and 0xf0
ld l,a ;y for tilemap
sub TOPYVISIBLE
;add a,sprmaxhgt-1 -TOPYVISIBLE
;cp 199+sprmaxhgt-1 ;защита от второго взрыва сверху с отрицательным y
;jp nc,showsprites0popbcskip
;sub sprmaxhgt-1;6;7
ld c,a ;y for prspr
ld a,(ix+3) ;xsize, xhsb
rra
ld a,(ix+2) ;x
rra
and 0xf8
ld e,a ;x/2 for tilemap
add a,sprmaxwid-1
ld b,a ;x/2 for prspr
;ld l,c ;y = Y*8
ld h,0
ld d,h;0
add hl,hl
add hl,hl
add hl,hl ;Y*64
srl e
srl e ;x/8
add hl,de
ld de,tilemap;+(TOPYVISIBLE/8*BYTESPERTILELINE)
add hl,de
push bc
push hl
ld e,b ;x/2
ld a,(hl)
cp 24 ;tree
ld iy,(0xc000+62)
;e=x = -(sprmaxwid-1)..159 (кодируется как x/2+(sprmaxwid-1))
;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
push ix
call z,prspr ;округление x влево, y вверх
pop ix
pop hl
pop bc
ld a,(ix+2) ;x
and 0x0e
jr z,prspr_tree_xrightq ;округлять x вправо не требуется
push bc
push hl
inc l
inc l
ld a,b ;x/2
add a,8
ld e,a
ld a,(hl)
cp 24 ;tree
ld iy,(0xc000+62)
;e=x = -(sprmaxwid-1)..159 (кодируется как x/2+(sprmaxwid-1))
;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
push ix
call z,prspr ;округление x влево, y вверх
pop ix
pop hl
pop bc
prspr_tree_xrightq
ld a,(ix+0) ;y
and 0x0f
jr z,prspr_tree_q ;округлять y вниз не требуется
ld de,BYTESPERTILELINE*2
add hl,de
ld a,c
add a,16
ld c,a ;y
push bc
push hl
ld e,b ;x/2
ld a,(hl)
cp 24 ;tree
ld iy,(0xc000+62)
;e=x = -(sprmaxwid-1)..159 (кодируется как x/2+(sprmaxwid-1))
;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
push ix
call z,prspr ;округление x влево, y вверх
pop ix
pop hl
pop bc
ld a,(ix+2) ;x
and 0x0e
jr z,prspr_tree_q ;округлять x вправо не требуется
inc l
inc l
ld a,b ;x/2
add a,8
ld e,a
ld a,(hl)
cp 24 ;tree
ld iy,(0xc000+62)
;e=x = -(sprmaxwid-1)..159 (кодируется как x/2+(sprmaxwid-1))
;c=y = -(sprmaxhgt-1)..199 (кодируется как есть)
push ix
call z,prspr ;округление x влево, y вверх
pop ix
prspr_tree_q
endif
showsprites0popbcskip
pop bc
showsprites0skip
ld de,6
add ix,de
dec b
jp nz,showsprites0
showsprites0q
;сейчас примерно 82000 при куче спрайтов
call setpgsmain40008000
;call setpg8
;ret
setpg8 ;area?
pgarea=$+1
ld a,0
SETPGC000
ret
border1
xor a
ld (curborder),a
;ld e,0;1
;OS_SETBORDER
ret
border8
ld a,12
ld (curborder),a
;ld e,12
;OS_SETBORDER
ret
setpgc ;ending music
pgmuzend=$+1
ld a,0
SETPGC000
ret
setpg16 ;levels 01-16
pglvl0=$+1
ld a,0
SETPGC000
ret
setpg17 ;levels 17-32
pglvl1=$+1
ld a,0
SETPGC000
ret
setpg18 ;level 00 user
pglvl2=$+1
ld a,0
SETPGC000
ret
setpgc0 ;spr0 ;left sprites (tanks)
pgspr0=$+1
ld a,0
SETPGC000
ret
setpgc1 ;spr1 ;right sprites (bullets)
pgspr1=$+1
ld a,0
SETPGC000
ret
setpgc2_4000
ld a,(pgtiles)
SETPG4000
ret
setpgc2 ;tiles
pgtiles=$+1
ld a,0
SETPGC000
ret
setpgc3 ;main music, boss music
pgmuzmain=$+1
ld a,0
SETPGC000
ret
setpgspr2
pgspr2=$+1
ld a,0
SETPGC000
ret
setpgspr3
pgspr3=$+1
ld a,0
SETPGC000
ret
setpg
;a=(SM1),(SM2) ;#10..#13???
ret
;ld ($+4),a
;ld a,(tpgs)
ld c,a
ld b,tpgs/256
ld a,(bc)
SETPGC000
ret
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
INCLUDE "bgpush.asm"
INCLUDE "../../_sdk/bmp.asm"
include "../../_sdk/file.asm"
bgpush_bmpbuf=0x4000 ;ds 1024;320 ;заголовок bmp или одна строка
bgpush_loadbmplinestack=bgpush_bmpbuf+1024 ;ds pushhgt*2+32
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
align 256
tpushpgs ;номера 0..15
tpgs ;номера 16..
ds 256
;align 256
ds TILEFLAG0*256+TILEFLAG0-$
ret
ds TILEFLAG0*256+TILEFLAG1-$
jp drawlefttile
ds TILEFLAG1*256+TILEFLAG0-$
jp drawrighttile
ds TILEFLAG1*256+TILEFLAG1-$
jp drawleftandrighttiles
INCLUDE "int.asm"
ds 0x2000-$
tilemap
if BYTESPERTILE == 1
ds 64*32*BYTESPERTILE
ds 64*32*BYTESPERTILE ;scr0 update flags
endif
ds 64*35*BYTESPERTILE ;scr1 update flags ;40*25 ;35 - запас на любой y при обновлении 4 рядов
INCLUDE "mem.asm"
INCLUDE "prspr.asm"
;display $,"<0x3ee0"
ds 0x3ee0-$
ds 0x4000-$
INCLUDE "units.asm"
INCLUDE "XASASM1.a80"
INCLUDE "BC1.a80"
INCLUDE "BC2.a80"
INCLUDE "BC3.a80"
INCLUDE "BC4.a80"
path
db "zxbattle",0
fn_log
db "zxbattle.log",0
fn_hiscore
db "hi_score.dat",0
fn_soundfx
db "sound_fx.bin",0
fn_muzmain
db "muz_main.dat",0
fn_muzboss
db "muz_boss.dat",0
fn_muzend
db "muz_end.dat",0
if TILES87
fn_lvl0116
db "lvl_0116.dat",0
fn_lvl1732
db "lvl_1732.dat",0
else
fn_lvl0116
db "lvln0116.dat",0
fn_lvl1732
db "lvln1732.dat",0
endif
fn_lvl00us
db "lvl_00us.dat",0
fn_spr0
db "spr0.dat",0
fn_spr1
db "spr1.dat",0
fn_spr2
db "spr2.dat",0
fn_spr3
db "spr3.dat",0
fn_tiles
db "font.bin",0
ifdef CLIENT
inetbuf_sz=256
inetbuf
ds inetbuf_sz
endif
end
display "End=",end
;display "Free after end=",/d,#c000-end
;display "Size ",/d,end-begin," bytes"
display "UP1=",UP1
display "MAP=",MAP
ifdef CLIENT
if CLIENT
savebin "zxbatcli.com",begin,end-begin
else
savebin "zxbatsrv.com",begin,end-begin
endif
else
savebin "zxbattle.com",begin,end-begin
endif
LABELSLIST "../../../us/user.l"