atm=0
;ZX data:
;music=0;1
debug=0
demorec=0
demoplay=0;1
;control:
doublespeed=0;1
doublerotate=1
autostrafe=1
kempston=0;1
mouse=1
mindist=111 ;max=111
colour=7
ceilingcolour=0
floorcolour=colour*9
showfps=1
showscans=0
crosshair=0
sprites=1
scale64=3;1
;render:
scrhgt=16;24 ;chr$ (10,12,...,24)
scrwid=24;32 ;chr$
scrhgtpix=scrhgt*8
scrtopx=(32-scrwid)/2
scrtop=(24-scrhgt)*16+#4000+scrtopx
attrtop=(scrtop/8)&0x300+(0xff&scrtop)+0x5800
lowscrtop=#4800+scrtopx
lowattrtop=(lowscrtop/8)&0x300+(0xff&lowscrtop)+0x5800
lowscrhgt=8 ;chr$
lowscrhgtpix=lowscrhgt*8
IF scale64
maxscale=63
IF scale64-3 == 0
lowmaxscale=28 ;fit in low screen
ELSE
lowmaxscale=19 ;fit in low screen
ENDIF
ELSE
maxscale=127
lowmaxscale=25 ;fit in low screen
ENDIF
mapdifbit=5;7
lores=0
IF atm == 0
optres=1&(1-lores) ;+22t на мелких, выигрыш на крупных
ELSE
lores=1
optres=0
ENDIF
optfast=0
loresspr=0
optresspr=1&(1-loresspr) ;выигрыш на крупных
loresspr_hires=loresspr&(1-lores)
pixperchr=8>>lores
corr_coord=1
interpolate=16
doublescr=0;1
;tcos=#5B00
imer=#7F7F
imstack=imer
distbuf=#7C00 ;#300 ;ID,texx,dist
;imvec=#9F00
scrbuf=#A040
lowscrbuf=(scrhgtpix-lowscrhgtpix)/2+scrbuf
scrbufflag=scrbuf&#FF00+32
dropline=scrhgt*8+.scrbuf ;Y=192
map=#A001 ;+0 занят dropline, +32 занят флагом высоких
mapend=map+#2000
invmap=1
if atm == 0
tscale=#C000 ;128x64, множители 0 и 63 выдают константы 0 и 3
;64x64 при scale64=1
endif
pgtmp=#01
ORG #C000,pgtmp
INCBIN "walls_bw"
INCBIN "goods_bw"
ORG #6000,0
begin
tlogd2sca
IFN scale64
IF0 scale64-3
INCBIN "logd2sc3"
ELSE
INCBIN "logd2sc2"
ENDIF
ELSE
INCBIN "logd2sc_"
ENDIF
tsqr2
INCBIN "sqr2int"
tlogd
INCBIN "logd"
tcorrlogd
INCBIN "corlogd_"
ORG $-256
DUP 256
DB {$+(scrtopx*8)}&0xff
EDUP
IF lores
ORG $-256
_=$
DUP 128
DB {_}&0xff
_=_+2
EDUP
DS 128
ENDIF
tcos
DS 256
tlogcos
INCBIN "pluslcos"
tda
INCBIN "da"
ORG $-256
DUP 256
DB 0xff&({$}+128)
EDUP
ORG $-256
DUP 256
DB 0xff&({$+(scrtopx*8)})
EDUP
IF lores
ORG $-256
_=$
DUP 128
DB {_}&0xff
_=_+2
EDUP
DS 128
ENDIF
tctg
INCBIN "plusctg"
tsin
INCBIN "sin"
cursprites
DS 256
;DISPLAY "tables end=",$
IFN doublescr
SETPG
LD (curpg),A
curscr=$+1
OR 0
LD BC,#7FFD
OUT (C),A
RET
ENDIF
IFN atmpg
INCLUDE "wctrl*",#08
ELSE
INCLUDE "wctrl*",#C2
ENDIF
;переменные рендера (обновляются в начале рендера)
curXx
curx DB #80
curX DB #0
curYy
cury DB #80
curY DB #0
curxy DW 0
curyx DW 0
curYX DW 0
curangle
DW tsin
demobegin
IFN demoplay
INCBIN "demorec*"
ELSE
DB %00111111 ;all keys released
ENDIF
DS #8000-$
ORG imer
IMER
;store DE in stack
EXD
EX (SP),HL
LD (IMJP),HL
LD (IMSP),SP
LD SP,imstack
PUSH AF,BC,DE
;PUSH HL
PUSH IX
IFN doublescr
LD A,#10 ;pgmus
LD BC,#7FFD
OUT (C),A
IFN music
CALL #8006 ;play mus
ENDIF
LD A,(newscr)
LD (curscr),A
curpg=$+1
LD A,#10
CALL SETPG
ENDIF
timer=$+1
LD HL,2560-25
DEC HL
LD (timer),HL
IFN showfps
IMframe=$+1
LD A,1
DEC A
JNZ IMNSEC
LD DE,#4100
;LD DE,#4100<1
;RR D
IMfps=$+1
LD A,0
LD C,10
CALL PRDIG
LD C,1
CALL PRDIG
XOR A
LD (IMfps),A
LD A,50
IMNSEC
LD (IMframe),A
ENDIF
CALL CONTROL
POP IX
;POP HL
POP DE,BC,AF
IMSP=$+1
LD SP,0
POP HL
EXD
EI
;RET
IMJP=$+1
JP 0
IF showfps
PRDIG
LD L,15
INC L
SUB C
jr NC,$-2
ADD A,C
PUSH AF
LD A,L
ADD A,A
ADD A,A
ADD A,A
INC A
LD L,A
LD H,#3D
PUSH DE
LD B,6
LD A,(HL)
ld (DE),A
INC L,D
DJNZ $-4
POP DE
POP AF
INC E
RET
ENDIF
DS (IMER/256+1)<<8-$
ORG #8000
imvec
DS 257,IMER
IF music
INCBIN "DOOM-MUS"
ENDIF
ZXLOOP
if atm
call changescrpg
; ld a,1
;curscreen=$+1
; xor 1
; ld (curscreen),a
; add a,a
; add a,a
; add a,a
; ld (imer_curscreen_value),a
ld hl,(timer)
ld (endoflastredrawtimer),hl
endif
IF atm == 0
IF doublescr
LD A,#10
CALL SETPG
ENDIF
ENDIF
;HALT
CALL SCAN
IF doublescr
;ждать флаг ожидания готовности экрана (включается по прерыванию)
;иначе будет так:
;фрейм 1:
;видим экран0, рисуем экран1
;фрейм 2:
;видим экран0, закончили рисовать экран1, [вот тут нужно ожидание], начали рисовать экран0 (хотя его видим)
;фрейм 3:
;видим экран1
;готовность - это когда текущий таймер != таймер конца прошлой отрисовки
;проверяем оба таймера, а то могло случиться системное прерывание
EmulatePPU_waitforscreenready0
ld hl,(timer)
endoflastredrawtimer=$+1
ld de,0
or a
sbc hl,de
jr z,EmulatePPU_waitforscreenready0
ENDIF
IF atm
pgscalersnum=$+1
LD A,0
setpgafast
; LD A,2
;setpgs_scr_xor=$+1
; XOR 2
; LD ($-1),A
;setpgs_scr_low=$+1
; XOR 0xff-1;#7F-pgattr1
; ld (curscrpg_low),a
; PUSH AF
; SETPG16K
call getuser_scr_low
SETPG16K
CALL DWCLSALL
xor a;LD A,0
CALL DRAWWALLS
call getuser_scr_high
SETPG16K
; POP AF
;setpgs_scr_high_xor_low=$+1
; XOR 4;pgattr1^pgpix1
; SETPG16K
CALL DWCLSALL
LD A,1
CALL DRAWWALLS
ELSE ;~atm
CALL CLSCRBUF
CALL DRAWWALLS
CALL CHECKHEIGHTS
IF sprites
CALL SCANMONS
CALL DRAWSPRITES
ENDIF
IF crosshair
CALL CROSSHAIR
ENDIF
IF doublescr
LD A,(curscr)
newscr=$+1
CP 0
jr Z,nohalt
HALT ;if CPU is too fast
nohalt
LD A,#17
CALL SETPG
ENDIF
CALL EORFILL
IF doublescr
LD A,(newscr)
XOR 8
LD (newscr),A
ENDIF
ENDIF
;-----------------------
IF showfps
LD HL,IMfps
INC (HL)
ENDIF
curkey=$+1
ld a,0
cp key_esc
jr z,ZXLOOPQUIT
cp key_redraw
call z,redraw
;LD A,0xfe
;IN A,(0xFE)
;rra ;caps shift
;JP c,ZXLOOP
;LD A,0x7F
;IN A,(0xFE)
;RRA ;space
;JP NC,ZXLOOPQUIT
jr ZXLOOP
ZXLOOPQUIT
ret
redraw
xor a
ld (curkey),a ;чтобы redraw не повторялся
call redraw_cls
ld a,1
redraw_cls
ld (curscrnum),a ;for interrupt
ld e,a
OS_SETSCREEN
ld e,0
OS_CLS
ret
INCLUDE "WSCAN10.asm"
INCLUDE "WREND.asm"
MONSTAB
;ZOMBIEMAN
DW #FC00
DW #FC0B
DW #FC16
DW #FC20
DW #FC2A
DW #FC35
DW 0,0
;AMMO
DW #FE89 ;G
DW #FE90 ;R
DW #FE97 ;MEGAHEALTH
DW #FE00 ;RL
DW #FE9D ;AMMO
DW 0,0,0
;STOLB
DW #CB29
DS ((-$)&7)&0xff
MONSTRS
;Xx,Yy,TYPEphase,TIMEenergy
DW #0F80,#AF80,#000,-1;ENEMY
DW #2680,#A080,#000,64
DW #0380,#BA80,#000,64
DW #0780,#B780,#000,64
DW #0F80,#B080,#002,64
DW #1380,#A080,#000,64
DW #1380,#AA80,#000,64
DW #1380,#B280,#000,64
DW #1380,#B380,#000,64
DW #1280,#B580,#002,64
DW #1480,#AB80,#000,64
DW #1480,#AE80,#002,64
DW #1480,#B080,#002,64
DW #1480,#B380,#000,64
DW #1580,#A180,#002,80
DW #1680,#AD80,#002,90
DW #1680,#B180,#002,100
DW #2180,#AD80,#002,10
DW #2380,#A080,#000,50
DW #2380,#A580,#002,50
DW #2680,#A480,#003,50
DW #2680,#B280,#004,50
DW #2780,#A880,#005,50
DW #2780,#B180,#003,64
DW #2780,#A380,#100,150
DW #2080,#A580,#101,100
DW #2280,#A580,#102,100
DW #2580,#A080,#103,20
DW #2080,#A080,#104,40
DW #1380,#A2C0,#200,0
DW #1380,#A440,#200,0
DW #1280,#A2C0,#200,0
DW #1280,#A440,#200,0
DW #1180,#A2C0,#200,0
DW #1180,#A440,#200,0
DW #1080,#A2C0,#200,0
DW #1080,#A440,#200,0
DW #0F80,#A2C0,#200,0
DW #0F80,#A440,#200,0
DW #0E80,#A2C0,#200,0
DW #0E80,#A440,#200,0
DW #0D80,#A2C0,#200,0
DW #0D80,#A440,#200,0
DW -1
eNDMONS
;DISPLAY "PROG END=",$
ORG distbuf
RECMAP
LD HL,WASMAP
LD DE,#4000
PUSH DE
LD BC,szMAP
LDIR
POP HL
LD DE,level
LD BC,endlev-level
LDIR
if atm
LD A,(YX+1) ;Y
SUB #A0
SUB map/256+31
CPL
LD (IMcurYy+1),A
LD A,(YX) ;X
INC A
LD (IMcurXx+1),A
endif
INImons LD A,(HL)
LDI
AND (HL)
LDI
INC A
JR Z,INImonsQ
LD BC,6
LDIR
JR INImons
INImonsQ ;
EXD
if atm
LD H,map/256+31
else
LD H,map/256
endif
IF invmap
LD L,map&0xff
LD C,1
JR GETMAPL
ENDIF
GETMAP0
IF invmap
LD L,0xff&(map+32)
ELSE
LD L,map&0xff
ENDIF
LD C,2
GETMAPL LD B,32;33
GETMAP1 LD A,(DE)
INC DE
LD (HL),0
CP 13
JR Z,GETMCR
IF atm
jr NC,GMNRLE
LD A,(DE)
INC DE
DEC A
GMRLE
INC L
LD (HL),0
DEC B
DEC A
jr NZ,GMRLE
LD A,32
GMNRLE
ENDIF
CP 32
JR Z,GETMAPE
IF atm
CP 64 ;
jr NC,$+4 ;
ADD A,64 ;todo kill
ADD A,128-64
ELSE
SUB "1";+128
CPL
ADD A,A
CP -20
jr NC,$+4
LD A,-20
ENDIF
LD (HL),A
GETMAPE INC L
DJNZ GETMAP1
JR GETMOK
GETMCR LD (HL),0
INC L
DJNZ GETMCR
GETMOK
IF invmap
LD L,map&0xff
ENDIF
DEC C
jr NZ,GETMAPL
if atm
LD A,H
DEC H
CP map/256
JR NZ,GETMAP0
else
INC H
BIT 6,H
JR Z,GETMAP0
endif
IF atm == 0
LD HL,#4000
CALL INICLS
IF doublescr
LD A,#17
CALL SETPG
LD HL,#C000
CALL INICLS
ENDIF
ENDIF
XOR A
LD H,scrbuf/256
LD C,scrwid
PRECLS LD L,scrbuf&0xff
LD B,scrhgtpix
LD (HL),A
INC L
DJNZ $-2
INC H
DEC C
jr NZ,PRECLS
LD BC,#FBDF
IN A,(C)
LD (mouseoldx),A
JP LOOP
INICLS
LD D,H
ld E,1
LD BC,#1800
LD (HL),L
LDIR
LD BC,767
LD (HL),colour
LDIR
RET
DS distbuf+#300-$
ORG #C000
IFN scale64
IF0 scale64-3
INCBIN "tscale3"
ELSE
INCBIN "tscale2"
ENDIF
ELSE
INCBIN "tscale"
ENDIF
end
ORG scrbuf
GO
DI
LD HL,WAStcos
LD DE,tcos
PUSH DE
LD BC,256
LDIR
POP HL
REtcos0
DUP 2;4
SRA (HL)
EDUP
INC L
JNZ REtcos0
IFN music
CALL #8000 ;init mus
ENDIF
LD HL,imvec
LD DE,imvec+1
LD (HL),IMER
LD B,E,C,L
LD A,H
LDIR
LD I,A
IM 2
EI
HALT
LD HL,-2
ADD HL,SP
LD (clscrbufsp),HL
LD (eorfillsp),HL
JP RECMAP ;->LOOP
WASMAP
IF atm
INCBIN "mapatm.E"
ELSE
INCBIN "map48.E"
ENDIF
szMAP=$-WASMAP
level
DB "W"
gfxnr DB "0"
muznr DB "A"
pol DB #E7
potolok DB #F3
color DB 7
levname DS 23
DB 0
monstrs DB 0
prizes DW 0 ;$$$/10
EXITx DB 23
EXITy DB 15+#A0
yx DW #8080
YX DW #BA08
angle DW 64
endlev
WAStcos
INCBIN "cos"
ObjTab
DB "wolfblokC"
DW begin
DW end-begin
DB #10
DW begin
IFN atmpg
INCLUDE "SAVEOBJ*",#20
ELSE
INCLUDE "SAVEOBJ*",#C0
ENDIF
ORG $,0
IFN atmpg ;{#5BE9}-#0F4F ;atm hack
LD BC,_prep
PUSH BC
LD A,#FF
LD BC,#3FF0
PUSH BC
LD BC,#FFF7
JP #3D2F
_prep
ENDIF
;prepare 48K block
DI ;IY
LD H,#C1
INIRETAB0 ;
LD L,0
LD B,maxscale+1
INIRETAB1 ;
LD A,(HL)
CP 128-(scrhgtpix/2)
JNC $+4
LD A,128-(scrhgtpix/2)
CP 128+(scrhgtpix/2);-1
JC $+4
;LD A,128+(scrhgtpix/2)-1 ;видно линию внизу от переполнй
LD A,dropline-(scrbuf+(scrhgtpix/2)-128)
ADD A,scrbuf+(scrhgtpix/2)-128
LD (HL),A
INC L
DJNZ INIRETAB1
INC H
LD A,H
INC A ;#C0XX,#FFXX не трогаем
JNZ INIRETAB0
LD HL,#FF00
LD DE,#FF01
LD BC,maxscale
LD (HL),1
LDIR
LD HL,#5800
LD DE,#5801
LD BC,767
LD (HL),L
LDIR
LD BC,#7FFD
LD A,pgtmp|#10
OUT (C),A
LD HL,#C000
LD DE,#4000
LD BC,#1800
LDIR
LD BC,#7FFD
LD A,#10
OUT (C),A
LD DE,#C000+maxscale+1
LD HY,#FE
;4 upper textures = #09A6
;4 lower textures = #0AAC
LD HL,#4000
CALL GETTEX
CALL GETTEX
CALL GETTEX
CALL GETTEX
LD HL,#4800
CALL GETTEX
CALL GETTEX
CALL GETTEX
CALL GETTEX
LD HL,#5000
CALL GETTEX
CALL GETTEX
PUSH DE
LD BC,#7FFD
LD A,#11
OUT (C),A
LD HL,#DB00
LD DE,#4000
LD BC,#1800
LDIR
LD BC,#7FFD
LD A,#10
OUT (C),A
POP DE
LD HL,#4008
CALL GETSPR;TEX
LD IY,23610
EI
CALL 8026
JP C,GO
JP nenado
GETTEX
IFN scale64
LD LY,#40
ELSE
LD LY,#80
ENDIF
LD BC,#0880 ;B=width/8, C=#80(mask)
GETTEX00 ;
PUSH BC
GETTEX0 CALL GETTEXLINE
INC LY
IF0 scale64
INC LY
ENDIF
RRC C
JNC GETTEX0
INC L
POP BC
DJNZ GETTEX00
DEC HY,HY
RET
GETSPR
IFN scale64
LD LY,#40
ELSE
LD LY,#80
ENDIF
LD BC,#0880 ;B=width/8, C=#80(mask)
GETSPR00 ;
PUSH BC
GETSPR0 CALL GETSPRLINE
INC LY
IF0 scale64
INC LY
ENDIF
RRC C
JNC GETSPR0
INC L
POP BC
DJNZ GETSPR00
DEC HY,HY
RET
GETTEXLINE
PUSH HL
GETTEXRETRY ;
LD (gettexDE),DE ;linelength addr
POP HL
PUSH HL
LD (IY),E
IF0 scale64
LD (IY+1),E
ENDIF
INC HY
LD (IY),D
IF0 scale64
LD (IY+1),D
ENDIF
DEC HY
INC E
JNZ GETTEXniD
GETTEXiD INC D
LD E,maxscale+1
JR GETTEXRETRY
GETTEXniD ;
LD LX,0;C ;bit
LD HX,17 ;dots
LD B,62 ;62..1 -> 1..62
GETTEX1 ;
CALL DHL
LD A,(HL)
AND C
CP LX
LD LX,A
JZ GETTEXN
LD A,HX
OR A
JZ GETTEXN
LD A,'tscale+63
SUB B
LD (DE),A
DEC HX ;17-pixels
INC E ;todo check before write
JZ GETTEXiD
GETTEXN ;
DJNZ GETTEX1
LD A,HX ;17-pixels
ADD A,A
ADD A,A
ADD A,A
SUB HX ;*7
ADD A,DWJP
gettexDE=$+1
LD (0),A
POP HL
RET
GETSPRLINE
PUSH HL
GETSPRRETRY ;
POP HL
PUSH HL
LD (IY),E
IF0 scale64
LD (IY+1),E
ENDIF
INC HY
LD (IY),D
IF0 scale64
LD (IY+1),D
ENDIF
DEC HY
LD A,H
OR 6
LD H,A
LD A,L
ADD A,#E0
LD L,A ;line 62
LD HX,1
GETSPR1 ;
CALL FIND10
JNC GETSPRQ ;end of column
LD A,HX
CPL
LD (DE),A ;Y
INC E
JZ GETSPRiD
CALL FIND1HEIGHT
LD A,HX
CPL
LD (DE),A ;Y2
INC E
JZ GETSPRiD
CALL FIND0HEIGHT
LD A,HX
CPL
LD (DE),A ;Y3
INC E
JZ GETSPRiD
JR GETSPR1
GETSPRQ
LD A,#C0
LD (DE),A
INC E
JNZ GETSPRniD
GETSPRiD INC D
LD E,maxscale+1
JR GETSPRRETRY
GETSPRniD ;
LD A,#FF
LD (DE),A
INC E
JNZ $+5
INC D
LD E,maxscale+1
POP HL
RET
maxVhgt=10;16?
;HX=V
;HL=mask
FIND10
LD A,HX
CP 63
RET Z ;CY=0: end of column
CALL GETPIXEL
RET C ;CY=1: pixel
CALL UHL
INC HX ;V
JR FIND10
FIND1HEIGHT
;LD LX,HX ;oldV
LD B,0
F1H0 CALL GETPIXEL
RET NC ;transparent
RET Z ;0
CALL UHL
INC HX ;V
INC B
LD A,B
CP maxVhgt
JC F1H0
RET
FIND0HEIGHT
;LD LX,HX ;oldV
LD B,0
F0H0 CALL GETPIXEL
RET NC ;transparent
RET NZ ;1
CALL UHL
INC HX ;V
INC B
LD A,B
CP maxVhgt
JC F0H0
RET
GETPIXEL
LD A,HX
CP 63
RET Z ;CY=0: transparent
LD A,(HL)
AND C
RET NZ ;CY=0: transparent
RES 3,L
LD A,(HL)
AND C
SET 3,L
SCF ;CY=1: pixel (Z)
RET
UHL
LD A,H
DEC H
AND 7
RET NZ
LD A,L
SUB #20
LD L,A
RET C
LD A,H
ADD A,8
LD H,A
RET
DS #C000-$