?login_element?

Subversion Repositories NedoOS

Rev

Rev 583 | Blame | Compare with Previous | Last modification | View Log | Download

  1.         DEVICE ZXSPECTRUM128
  2.         include "../../_sdk/sys_h.asm"
  3.  
  4. scrbuf=0xe000 ;делится на 0x800
  5. tilemap=0xdd00 ;0x300
  6. collisionmap=0xda00 ;0x300 (перед ней ~20 байт затирается)
  7. validmap=0xfc00 ;0x300 (перед ней ~20 байт затирается)
  8. VALID0=0xfb ;валидная, не надо обновлять
  9. VALID1=0x80 ;невалидная, надо обновлять, там можно более длинные процедуры
  10. VALID00=VALID0+256*VALID0
  11. VALID01=VALID0+256*VALID1
  12. VALID10=VALID1+256*VALID0
  13. VALID11=VALID1+256*VALID1
  14. validmaplinesize=32
  15. validmapwid=validmaplinesize-2 ;в конце строки лежит validmapnext
  16.  
  17. emptyattr=7
  18.  
  19. fieldwid=10
  20. fieldhgt=8
  21. fieldx=0
  22. fieldy=0
  23.  
  24. coordsfactor=4
  25.  
  26. leftwallx=0
  27. topwally=0
  28. rightwallx=fieldwid*24*coordsfactor
  29. bottomwally=fieldhgt*24*coordsfactor
  30.  
  31. dir_r=0x09
  32. dir_l=0x08
  33. dir_u=0x0b
  34. dir_d=0x0a
  35.  
  36. collisionmaplinesize=32
  37. collisionmapwid=fieldwid*3
  38. collisionmaphgt=fieldhgt*3
  39. collisionmapsize=collisionmaplinesize*collisionmaphgt
  40. tilemaplinesize=collisionmaplinesize
  41. tilemapwid=collisionmapwid
  42. tilemaphgt=collisionmaphgt
  43. tilemapsize=collisionmapsize
  44.  
  45. maxemptytile=9
  46.  
  47. maxobjects=20
  48. maxbullets=100
  49. TERMINATOR=0x80
  50.  
  51. tanksize=16
  52. tankdamagesize=11 ;грязный хак
  53. tankaimsize=8
  54. tankspeed=4 ;2^n!
  55. bulletspeed=6
  56. bulletenergy=20
  57.  
  58. startlives=5
  59. maxlives=10
  60.  
  61. ;timer=23672
  62.        
  63.         include "macro.asm"
  64.        
  65.         org PROGSTART
  66. begin
  67.         OS_HIDEFROMPARENT
  68.         ld e,3 ;6912
  69.         OS_SETGFX ;e=0:EGA, e=2:MC, e=3:6912, e=6:text ;+SET FOCUS ;e=-1: disable gfx (out: e=old gfxmode)
  70.  
  71.         ;OS_GETSCREENPAGES
  72. ;de=страницы 0-го экрана (d=старшая), hl=страницы 1-го экрана (h=старшая)
  73.         ld a,(user_scr0_high) ;ok
  74.         SETPG16K
  75.        
  76.         ld hl,valid00
  77.         ld de,VALID00
  78.         ld bc,valid00_size
  79.         ldir
  80.         ld hl,valid01
  81.         ld de,VALID01
  82.         ld c,valid01_size
  83.         ldir
  84.         ld hl,valid10
  85.         ld de,VALID10
  86.         ld c,valid10_size
  87.         ldir
  88.         ld hl,valid11
  89.         ld de,VALID11
  90.         ld c,valid11_size
  91.         ldir
  92.  
  93.         ld a,1
  94.         ld (nlevel),a
  95.  
  96. newlevel
  97.         call cls
  98.         call clscrbuf
  99.        
  100.         ld a,startlives
  101.         ld (lives),a
  102.         call prlives
  103.  
  104.         call initlevel
  105.  
  106.         call clearvalid
  107.         call restoreobjects_clear
  108.         call restorebullets_clear
  109.  
  110.         call prmap
  111.         call fillcollisionmap
  112.        
  113.         OS_GETTIMER ;dehl=timer
  114.         ;ld hl,(timer)
  115.         ld (oldtimer),hl
  116.        
  117. loop
  118.         call restoreobjects
  119.         call restorebullets
  120.         ;ld a,2
  121.         ;out (0xfe),a
  122.         call probjlist
  123.         ;ld a,4
  124.         ;out (0xfe),a
  125.         call prbulletlist
  126.         ;ld a,0
  127.         ;out (0xfe),a
  128.        
  129. loopdelay
  130.         OS_GETTIMER ;dehl=timer
  131.         ;ld hl,(timer)
  132. oldtimer=$+1
  133.         ld bc,0
  134.         ld (oldtimer),hl
  135.         ld a,l
  136.         sub c
  137.         jr z,loopdelay
  138.         ld b,a
  139.         ;ld a,5
  140.         ;out (0xfe),a
  141. logicloop0
  142.         push bc
  143.         call control
  144.         call animate
  145.         call logic
  146.         call bulletlogic
  147.         ;ld a,1
  148.         ;out (0xfe),a
  149.         call fillcollisionmap
  150.         ;ld a,5
  151.         ;out (0xfe),a
  152.         call bulletcollision
  153.         pop bc
  154.         djnz logicloop0
  155.         ;ld a,6
  156.         ;out (0xfe),a
  157.         call prvalid
  158.         ;call displaycollisionmap
  159. ;TODO сделать что-нибудь, когда врагов не осталось
  160.         ld a,(nenemies)
  161.         or a
  162.         jp nz,loop
  163.         ld hl,nlevel
  164.         inc (hl)
  165.         jp newlevel
  166.  
  167. initlevel
  168.         call genmap
  169.  
  170.         ld ix,objlist
  171.         call genobj_terminate
  172.         ld ix,bulletlist
  173.         call genbullet_terminate
  174.        
  175.         ld de,0x0010 ;x
  176.         ld hl,0x02b0 ;y
  177.         ld bc,params_tank
  178.         ld a,1 ;a=dir
  179.         call genobj
  180.        
  181.         ld a,(nlevel)
  182.         inc a
  183.         ld b,a
  184. initlevel_addenemies0
  185.         push bc
  186.         ;ld de,0x0010 ;x = 0x0010..0x0370
  187.         call rndxcoord ;out: hl=x
  188.         ex de,hl
  189.         ld hl,0x0010 ;y
  190.         ld bc,params_tanke
  191.         ld a,2 ;a=dir
  192.         call genobj
  193.         ld hl,nenemies
  194.         inc (hl)
  195.  
  196.         if 1==0
  197.         ld de,0x0370 ;x
  198.         ld hl,0x0010 ;y
  199.         ld bc,params_tanke
  200.         ld a,2 ;a=dir
  201.         call genobj
  202.         ld hl,nenemies
  203.         inc (hl)
  204.         endif
  205.         pop bc
  206.         djnz initlevel_addenemies0
  207. reter        
  208.         ret
  209.  
  210. attrbox  
  211. ;bc=yx
  212. ;a=фон
  213. ;d=y координата левого верхнего угла
  214. ;е=х координата левого верхнего угла
  215. ;0x5800+xcoordredbox+(32*ycoordredbox)
  216.         ld l,d  ;y
  217.         ld h,0        
  218.         add hl,hl    
  219.         add hl,hl    
  220.         add hl,hl    
  221.         add hl,hl    
  222.         add hl,hl
  223.         ld d,0x58
  224.         add hl,de ;x
  225. attrbox_lines
  226.         ld e,l
  227.         ld d,h  
  228.         push bc
  229. attrbox_pixels
  230.         ld (de),a
  231.         inc e
  232.         dec c        
  233.         jr nz,attrbox_pixels
  234.         pop bc
  235.         ld de,32
  236.         add hl,de    
  237.         djnz attrbox_lines
  238.         ret
  239.  
  240. genmap
  241.         ld hl,tilemap
  242.         ld de,tilemap+1
  243.         ld bc,tilemapsize-1
  244.         ld (hl),0
  245.         ldir
  246.        
  247.         ld hl,tilemap+(3*tilemaplinesize)
  248.         ld b,fieldhgt-2
  249. genmaplines
  250.         push bc
  251.         push hl
  252.         ld b,fieldwid
  253. genmapline
  254.         push bc
  255.         push hl
  256.         push hl
  257.         ld a,b ;1..fieldwid
  258.         sub 2 ;n
  259.         cp fieldwid-2 ;nc=левый или правый край
  260.         adc a,nblocks+1 ;n + cy + (nblocks+1)
  261.         sub b ;n + cy + nblocks - (n+2)
  262.         ld c,a ;nblocks или nblocks-1
  263.         call rnd
  264.         ld c,a
  265.         ld b,0
  266.         ld de,9
  267.         call mulbcde
  268.         ld bc,blocks
  269.         add hl,bc
  270.         ex de,hl
  271.         pop hl
  272.         ld bc,tilemaplinesize-2
  273.         dup 3
  274.         ld a,(de)
  275.         ld (hl),a
  276.         inc de
  277.         inc hl
  278.         ld a,(de)
  279.         ld (hl),a
  280.         inc de
  281.         inc hl
  282.         ld a,(de)
  283.         ld (hl),a
  284.         inc de
  285.         add hl,bc
  286.         edup
  287.         pop hl
  288.         inc hl
  289.         inc hl
  290.         inc hl
  291.         pop bc
  292.         djnz genmapline
  293.         pop hl
  294.         ld bc,tilemaplinesize*3
  295.         add hl,bc
  296.         pop bc
  297.         djnz genmaplines
  298.         ret
  299.  
  300. control
  301.         GET_KEY
  302.         cp key_esc
  303.         jp z,quit
  304.         call getkey ;c=%???lrduf (0=нажато)
  305.         ld a,c
  306.         rra ;f
  307.         jr nc,control_noreleasefire
  308.         ld a,1
  309.         ld (control_firehasbeenreleased),a
  310. control_noreleasefire
  311.  
  312. ;кнопки должны срабатывать, когда мы стоим посредине клетки ((x&(8*coordsfactor-1)) == 4*coordsfactor, (y&(8*coordsfactor-1)) == 4*coordsfactor)
  313.         ld ix,objlist ;первый объект - наш
  314.         call checkevencoords ;nz=не посредине клетки
  315.         ret nz
  316.  
  317.         ld a,c
  318.         rra ;f
  319.         jr c,control_nofire
  320.         ;проверим, что до этого был момент, когда огонь не нажимали
  321. control_firehasbeenreleased=$+1
  322.         ld a,0
  323.         or a
  324.         jr z,control_nofire ;не было момента, когда огонь не нажимали
  325.         xor a
  326.         ld (control_firehasbeenreleased),a
  327.         ;ld ix,objlist ;первый объект - наш
  328.         push bc
  329.         call shoot
  330.         pop bc
  331. control_nofire
  332.  
  333.         ld ix,objlist ;первый объект - наш
  334.         ;если не нажата кнопка движения и мы едем, то остановиться
  335.         rr c
  336.         ld a,c
  337.         cpl
  338.         and 0x0f
  339.         jr nz,control_nokeysreleased
  340.         ld a,(ix+obj_anim)
  341.         cp ANIM_GO
  342.         jr nz,control_nokeysreleased
  343.         SETANIM ANIM_STOP
  344. control_nokeysreleased
  345.  
  346.         ld a,c
  347.         rra ;u
  348.         jr c,control_nou
  349.         call goifpossible
  350.         ld (ix+obj_dir),0
  351. control_nou
  352.         rra ;d
  353.         jr c,control_nod
  354.         call goifpossible
  355.         ld (ix+obj_dir),2
  356. control_nod
  357.         rra ;r
  358.         jr c,control_nor
  359.         call goifpossible
  360.         ld (ix+obj_dir),1
  361. control_nor
  362.         rra ;l
  363.         jr c,control_nol
  364.         call goifpossible
  365.         ld (ix+obj_dir),3
  366. control_nol
  367.        
  368.         ret
  369.        
  370. goifpossible
  371.         ld c,a
  372.         ld a,(ix+obj_anim)
  373.         cp ANIM_APPEAR
  374.         jr nz,$+4
  375.         ld a,ANIM_STOP
  376.         cp ANIM_STOP
  377.         ld a,c
  378.         ret nz ;не стоим, так что не можем поехать
  379.         SETANIM ANIM_GO
  380.         ret
  381.        
  382. checkevencoords
  383. ;out: nz=не посредине клетки
  384.         ld a,(ix+obj_x)
  385.         and 8*coordsfactor-1
  386.         cp 4*coordsfactor
  387.         ret nz
  388.         ld a,(ix+obj_y)
  389.         and 8*coordsfactor-1
  390.         cp 4*coordsfactor
  391.         ret
  392.  
  393. shoot
  394.         SETANIM ANIM_SHOOT
  395.         ld c,(ix+obj_dir)
  396.         ld b,0
  397.         ld hl,tankbulletcoords
  398.         add hl,bc
  399.         add hl,bc
  400.         ld a,(hl) ;dx
  401.         ld c,a ;%sxxxxxxx
  402.         rla    ;%xxxxxxx?, CY=s
  403.         sbc a,a;%ssssssss
  404.         ld b,a ;dx
  405.         inc hl
  406.         ld a,(hl) ;dy
  407.         GETXDE_YHL
  408.         ex de,hl ;hl=x
  409.         add hl,bc ;x+dx
  410.         push hl ;x+dx
  411.         push de ;y
  412.         ld e,a
  413.         rla
  414.         sbc a,a
  415.         ld d,a ;dy
  416.         pop hl ;y
  417.         add hl,de ;hl = y+dy
  418.         pop de ;de = x+dx
  419.         ld a,(ix+obj_dir) ;a=dir
  420.         ld bc,params_bullet
  421. curbulletlistend=$+2
  422.         ld ix,bulletlist
  423.         call genobjorbullet
  424. genbullet_terminate
  425.         ld bc,objterminator
  426.         ld (ix+obj_objaddr),c
  427.         ld (ix+(obj_objaddr+1)),b
  428.         ld (ix+(obj_x+1)),TERMINATOR
  429.         ld (curbulletlistend),ix
  430.         ret
  431.  
  432. genobjorbullet
  433. ;de=x
  434. ;hl=y
  435. ;bc=params (obj(16),energy(8),speed(8))
  436. ;a=dir
  437.         ld (ix+obj_dir),a
  438.         PUTXDE_YHL
  439.         SETANIM ANIM_APPEAR
  440.         ld (ix+obj_delaycounter),1
  441.         ld (ix+obj_gundelaycounter),0
  442.         ld a,(bc)
  443.         ld (ix+obj_objaddr),a
  444.         inc bc
  445.         ld a,(bc)
  446.         ld (ix+(obj_objaddr+1)),a
  447.         inc bc
  448.         ld a,(bc)
  449.         ld (ix+obj_energy),a
  450.         inc bc
  451.         ld a,(bc)
  452.         ld (ix+obj_speed),a
  453.         ld bc,objsize
  454.         add ix,bc
  455.         ret
  456.  
  457. genobj
  458. ;de=x
  459. ;hl=y
  460. ;bc=params (obj(16),energy(8),speed(8))
  461. ;a=dir
  462. curobjlistend=$+2
  463.         ld ix,objlist
  464.         call genobjorbullet
  465. genobj_terminate
  466.         ld bc,objterminator
  467.         ld (ix+obj_objaddr),c
  468.         ld (ix+(obj_objaddr+1)),b
  469.         ld (ix+(obj_x+1)),TERMINATOR
  470.         ld (curobjlistend),ix
  471.         ret
  472.  
  473. animate
  474.         ld ix,objlist-objsize
  475. animate0_prepareregs
  476.         ld a,TERMINATOR
  477.         ld bc,objsize
  478. animate0
  479.         add ix,bc
  480. animate0_afterdel
  481.         cp (ix+(obj_x+1))
  482.         ret z
  483.         dec (ix+obj_animcounter)
  484.         jp nz,animate0
  485.         ;текущая фаза анимации кончилась, ищем следующую
  486.         ld l,(ix+obj_objaddr)
  487.         ld h,(ix+(obj_objaddr+1)) ;hl=адрес описателя объекта (в начале лежит указатель на список анимаций)
  488.         ld a,(hl)
  489.         inc hl
  490.         ld h,(hl)
  491.         ld l,a ;hl=указатель на список анимаций
  492.         ld e,(ix+obj_anim) ;номер анимации
  493.         ld d,0
  494.         add hl,de
  495.         add hl,de
  496.         ld a,(hl)
  497.         inc hl
  498.         ld h,(hl)
  499.         ld l,a ;hl=указатель на анимацию
  500.         ld e,(ix+obj_animphase) ;номер фазы анимации
  501.         inc e ;следующая фаза анимации
  502.         ld (animate_pointer),hl
  503.         add hl,de
  504.         add hl,de
  505.         add hl,de
  506.         ld a,(hl) ;время фазы
  507.         or a ;если 0, то это конец анимации
  508.         jr nz,animate_noend
  509.         inc hl
  510.         ld a,(hl) ;режим зацикливания (0=переход на нулевую анимацию, 1=зацикливаемся тут, 2=удалить)
  511.         cp 2 ;признак ANIMENDDIE
  512.         jr z,animate_delete
  513.         or a
  514.         jr nz,animate_no0
  515.         ld (ix+obj_anim),a ;0-я анимация
  516. animate_no0
  517.         ld e,0
  518. animate_pointer=$+1
  519.         ld hl,0
  520.         add hl,de
  521.         add hl,de
  522.         add hl,de
  523.         ld a,(hl) ;время фазы
  524. animate_noend
  525.         ld (ix+obj_animcounter),a
  526.         ld (ix+obj_animphase),e ;следующая фаза анимации
  527.         jp animate0_prepareregs
  528.        
  529. animate_delete
  530.         push ix
  531.         pop hl
  532.         ld de,objlist
  533.         or a
  534.         sbc hl,de
  535.         jr z,animate_delete_player
  536.         ld hl,curobjlistend
  537.         call delobj ;копируем из ix+objsize в ix
  538.  
  539.         ld hl,nenemies
  540.         dec (hl)
  541.        
  542.         ld a,TERMINATOR
  543.         ld bc,objsize
  544.         jp animate0_afterdel
  545. animate_delete_player
  546.         call decreaselives
  547.         call rndbottomcoords ;bc=x, de=y
  548.         SETANIM ANIM_APPEAR
  549.         ld (ix+obj_dir),1 ;a=dir
  550.         jp animate0_prepareregs
  551.        
  552. bulletlogic
  553.         ld ix,bulletlist-objsize
  554.         jr logic0
  555. logic
  556.         ld ix,objlist-objsize
  557. logic0
  558.         ld bc,objsize
  559.         add ix,bc
  560. logic0_afterdel
  561.         ld l,(ix+obj_objaddr)
  562.         ld h,(ix+(obj_objaddr+1)) ;hl=адрес описателя объекта (в начале лежит указатель на список анимаций)
  563.         inc hl
  564.         inc hl
  565.         jp (hl) ;hl=адрес обработчика объекта
  566.        
  567. rndbottomcoords
  568. ;out: bc=x, de=y
  569. rndbottomcoords_retry
  570.         call rndxcoord
  571.         ex de,hl
  572.         ld hl,0x02b0 ;y
  573.         PUTXDE_YHL
  574.         call checkobstacles_tank ;nc=препятствие
  575.         jr nc,rndbottomcoords_retry
  576.         ret
  577.  
  578. rndxcoord
  579. ;out: hl=x
  580.         ld c,fieldwid
  581.         call rnd
  582.         ld c,a
  583.         ld b,0
  584.         ld de,8*coordsfactor*3
  585.         call mulbcde
  586.         ld bc,4*coordsfactor
  587.         add hl,bc ;x
  588.         ret
  589.  
  590. delobj
  591. ;hl=адрес указателя на конец списка (на терминатор)
  592. ;копируем из ix+objsize в ix
  593.         ld (delobj_curlistend1),hl
  594.         ld (delobj_curlistend2),hl
  595.         ld c,(hl)
  596.         inc hl
  597.         ld b,(hl) ;указатель на конец списка (на терминатор)
  598.         ld hl,objsize
  599.         add hl,bc
  600.         ld b,h
  601.         ld c,l ;указатель на конец списка (после объекта-терминатора)
  602.         ld d,hx
  603.         ld e,lx ;de=ix
  604.         ld a,e
  605.         add a,objsize
  606.         ld l,a
  607.         adc a,d
  608.         sub l
  609.         ld h,a ;hl=ix+objsize
  610.         ld a,c
  611.         sub l
  612.         ld c,a
  613.         ld a,b
  614.         sbc a,h
  615.         ld b,a ;bc=objlistend-hl
  616.         ld a,b
  617.         or c
  618.         ret z ;почему удаляем терминатор после встречи двух пуль??? TODO
  619.         ldir ;копируем все следующие объекты, включая терминатор
  620. delobj_curlistend1=$+1
  621.         ld hl,(curobjlistend)
  622.         ld bc,-objsize
  623.         add hl,bc
  624. delobj_curlistend2=$+1
  625.         ld (curobjlistend),hl
  626.         push ix
  627.         call fillcollisionmap
  628.         pop ix
  629.         ret
  630.        
  631. movetank
  632.         ld a,(ix+obj_anim)
  633.         cp ANIM_GO
  634.         ret nz
  635. moveobj
  636.         GETXDE_YHL
  637.         ld b,(ix+obj_speed)
  638.         ld c,(ix+obj_dir)
  639.         inc c
  640.         dec c
  641.         call z,moveobj_u
  642.         dec c
  643.         call z,moveobj_r
  644.         dec c
  645.         call z,moveobj_d
  646.         dec c
  647.         call z,moveobj_l
  648.         PUTXDE_YHL
  649.         ret
  650. moveobj_u
  651.         dec hl
  652.         djnz $-1
  653.         ret
  654. moveobj_r
  655.         inc de
  656.         djnz $-1
  657.         ret
  658. moveobj_d
  659.         inc hl
  660.         djnz $-1
  661.         ret
  662. moveobj_l
  663.         dec de
  664.         djnz $-1
  665.         ret
  666.  
  667. objtank
  668.         dw anims_tank
  669. objtank_move
  670.         GETXDE_YHL
  671.         push de
  672.         push hl
  673.         call movetank
  674.         call checkobstacles_tank ;nc=коллизия
  675.         jr nc,objtank_collided
  676.         ld c,tanksize ;размер
  677.         call checkwalls ;nc=стена
  678.         ;TODO как-то воткнуть checkwalls в moveobj, но не в ущерб пулям
  679. objtank_collided
  680.         pop hl
  681.         pop de
  682.         jp c,logic0 ;не стена
  683.         PUTXDE_YHL ;стена - восстановим старые координаты
  684.         jp logic0
  685.  
  686. objtanke
  687.         dw anims_tanke
  688.         dec (ix+obj_gundelaycounter)
  689.         jr nz,objtanke_nogundelaystop
  690.         inc (ix+obj_gundelaycounter)
  691.         ld a,(ix+obj_anim)
  692.         cp ANIM_PREPARESHOOT
  693.         jr nz,objtanke_noshoot
  694.         push ix
  695.         call shoot
  696.         pop ix
  697.         ld (ix+obj_gundelaycounter),50
  698.         jr objtanke_stop
  699. objtanke_noshoot
  700. objtanke_nogundelaystop
  701.         ld a,(ix+obj_anim)
  702.         cp ANIM_DIE
  703.         jp z,objtanke_nologic
  704. ;логика должна срабатывать, когда мы стоим посредине клетки ((x&(8*coordsfactor-1)) == 4*coordsfactor, (y&(8*coordsfactor-1)) == 4*coordsfactor)
  705.         call checkevencoords ;nz=не посредине клетки
  706.         jp nz,objtanke_nologic
  707. ;едем энное растояние, потом случайно меняем направление или встаём
  708.         dec (ix+obj_delaycounter)
  709.         jr nz,objtanke_nonewmove
  710.         ld (ix+obj_delaycounter),20
  711.         ld c,5
  712.         call rnd
  713.         cp 4
  714.         jr z,objtanke_stop
  715.         ld (ix+obj_dir),a
  716.         SETANIM ANIM_GO
  717.         jr objtanke_nonewmove
  718. objtanke_stop
  719.         SETANIM ANIM_STOP
  720. objtanke_nonewmove
  721. ;если одна из координат близка к нашей (x-(tanksize/2*coordsfactor) > xe >= x+(tanksize/2*coordsfactor)), то встать, задержать и стрелять
  722.         GETXDE_YHL
  723.         push hl ;y
  724.         ld hl,(objlist+obj_x) ;наша координата
  725.         ld bc,-(tankaimsize/2*coordsfactor)
  726.         add hl,bc
  727.         or a
  728.         sbc hl,de ;надо -tanksize*coordsfactor..-1
  729.         ld bc,tankaimsize*coordsfactor
  730.         add hl,bc ;cy=координата близка к нашей
  731.         pop hl ;y
  732.         ex de,hl ;de=y, hl=x
  733.         jr z,$+4
  734.         jr nc,objtanke_noprepareshootx
  735.         ld hl,(objlist+obj_y) ;наша координата
  736.         or a
  737.         sbc hl,de ;y >= ye? тогда d, иначе u
  738.         ld a,2 ;d
  739.         jr nc,$+4 ;y >= xe
  740.         ld a,0 ;u
  741.         ld (ix+obj_dir),a
  742.         jr objtanke_prepareshoot
  743. objtanke_noprepareshootx
  744.         push hl ;x
  745.         ld hl,(objlist+obj_y) ;наша координата
  746.         ld bc,-(tankaimsize/2*coordsfactor)
  747.         add hl,bc
  748.         or a
  749.         sbc hl,de ;надо -tanksize*coordsfactor..-1
  750.         ld bc,tankaimsize*coordsfactor
  751.         add hl,bc ;cy=координата близка к нашей
  752.         pop de ;x
  753.         jr z,$+4
  754.         jr nc,objtanke_noprepareshoot
  755.         ld hl,(objlist+obj_x) ;наша координата
  756.         or a
  757.         sbc hl,de ;x >= xe? тогда r, иначе l
  758.         ld a,1 ;r
  759.         jr nc,$+4 ;x >= xe
  760.         ld a,3 ;l
  761.         ld (ix+obj_dir),a
  762. objtanke_prepareshoot
  763.         SETANIM ANIM_PREPARESHOOT
  764.         ;ld (ix+obj_delaycounter),1
  765. objtanke_noprepareshoot
  766. objtanke_nologic
  767.         jp objtank_move
  768.  
  769. objbullet
  770.         dw 0
  771.         call moveobj
  772.         ld c,0 ;размер
  773.         call checkwalls ;nc=стена
  774.         jp c,logic0 ;не стена
  775.         ld hl,curbulletlistend
  776.         call delobj ;копируем из ix+objsize в ix
  777.         ld bc,-objsize
  778.         add ix,bc
  779.         jp logic0
  780.        
  781. bulletcollision
  782.         ld ix,bulletlist-objsize
  783.         ld ly,-(128-1)
  784. bulletcollision0
  785.         dec ly
  786.         ld bc,objsize
  787.         add ix,bc
  788. bulletcollision0_afterdel
  789.         ld a,(ix+(obj_x+1))
  790.         cp TERMINATOR
  791.         ret z
  792.         GETXDE_YHL
  793.         call calctilemapaddr_de_hl
  794.         ld a,(hl)
  795.         cp maxemptytile+1
  796.         jr nc,bulletcollision_collided
  797.         call calccollisionmapaddr
  798.         ld a,(hl)
  799.         add a,ly ;номер текущей пули ;CY=1 при совпадении
  800.         call nz,checkbulletcollision
  801.         jp c,bulletcollision0 ;не коллизия
  802. bulletcollision_delete
  803.         ld hl,curbulletlistend
  804.         call delobj ;копируем из ix+objsize в ix
  805.         jp bulletcollision0_afterdel
  806. bulletcollision_collided
  807.         ;ld c,l
  808.         GETXDE_YHL
  809.         push hl
  810.         ex de,hl
  811.         ld a,(ix+obj_dir)
  812.         rra ;nc=vertical direction
  813.         ccf
  814.         call divmul3 ;hl=x клетки карты
  815.         ex (sp),hl ;сохранили x клетки карты ;hl=y
  816.         ld a,(ix+obj_dir)
  817.         rra ;nc=vertical direction
  818.         call divmul3 ;hl=y клетки карты
  819.         pop bc ;x клетки карты
  820.         ld b,l ;y клетки карты
  821.         ld a,c
  822.         call calctilemapaddr_a_l
  823.         ld a,(ix+obj_dir)
  824.         dec a
  825.         jr z,objbullet_collided_ver ;r
  826.         dec a
  827.         jr z,objbullet_collided_hor ;d
  828.         dec a
  829.         jr z,objbullet_collided_ver ;l
  830.                                     ;u
  831. objbullet_collided_hor
  832.         call degradetile
  833.         inc c
  834.         inc hl
  835.         call degradetile
  836.         inc c
  837.         inc hl
  838.         call degradetile
  839.         jp bulletcollision_delete
  840. objbullet_collided_ver
  841.         ld de,tilemaplinesize
  842.         call degradetile
  843.         inc b
  844.         add hl,de
  845.         call degradetile
  846.         inc b
  847.         add hl,de
  848.         call degradetile
  849.         jp bulletcollision_delete
  850.        
  851. divmul3
  852. ;если CY=1, то делим до знакомест и округляем до 3
  853. ;иначе просто делим до знакомест
  854.         ld de,8*coordsfactor
  855.         jp nc,divhlde ;hl=x(y) клетки карты (без округления)
  856.         ld de,8*coordsfactor*3
  857.         call divhlde ;hl=x(y) клетки поля
  858.         ld c,l
  859.         ld b,h
  860.         add hl,hl
  861.         add hl,bc
  862.         ret ;hl=x(y) клетки карты
  863.  
  864. degradetile
  865. ;bc=yx клетки карты
  866. ;hl=tilemap+
  867.         ;push bc
  868.         push de
  869.         ;push hl
  870.         call degradetile_changetile
  871.         call calcscrbufaddr ;de=scrbuf+
  872.         call restoretile
  873.         ;pop hl
  874.         pop de
  875.         ;pop bc
  876.         ret
  877. degradetile_changetile
  878.         ld a,(hl)
  879.         cp tilem
  880.         ret z
  881.         cp tileb
  882.         ld (hl),tile0
  883.         ret z
  884.         cp tilec
  885.         ld (hl),tileb
  886.         ret z
  887.         ld (hl),tile0
  888.         ret
  889.        
  890. objterminator
  891.         dw 0
  892.         ret
  893.  
  894. decreaselives
  895. lives=$+1
  896.         ld a,0
  897.         dec a
  898.         ld (lives),a
  899.         push af
  900.         call prlives
  901.         pop af
  902.         ret nz
  903.        
  904. gameover    
  905. fieldEx=32
  906. fieldEy=24
  907. centr=(fieldEx/2)-(10/2)+(256*fieldEy/2)
  908. ;bc=yx
  909. ;a=фон
  910. ;d=y координата левого верхнего угла
  911. ;е=х координата левого верхнего угла
  912. ;0x5800+xcoordredbox+(32*ycoordredbox)
  913.         ld c,12
  914.         ld b,3
  915.         ld de,centr-0x0101
  916.         ld a,0x57        
  917.         ld (curattr),a
  918.         call attrbox
  919.         ld hl,endtext
  920.         ld bc,centr
  921.         call prtext
  922. gameoverloop
  923.         YIELD
  924.         GET_KEY
  925.         cp key_esc
  926.         jr nz,gameoverloop
  927. quit
  928.         QUIT
  929.  
  930. endtext
  931.         db "Game over!",0
  932.  
  933. font
  934.         incbin "zx.fnt"
  935.        
  936.         include "collisio.asm"
  937.         include "tankgfx.asm"
  938.         include "tankdata.asm"
  939.         include "math.asm"
  940.         include "input.asm"
  941.  
  942. nlevel
  943.         db 0 ;1..
  944. nenemies
  945.         db 0
  946. end
  947.  
  948. reobjlist
  949.         ds 2*(maxobjects+1)
  950. rebulletlist
  951.         ds 2*(maxbullets+1)
  952.  
  953. objlist
  954.         ds objsize*(maxobjects+1)
  955. objlistend
  956.        
  957. bulletlist
  958.         ds objsize*(maxbullets+1)
  959. bulletlistend
  960.  
  961.  
  962.         ;display "End=",end
  963.         ;display "Free after end=",/d,0xc000-end
  964.         ;display "Size ",/d,end-begin," bytes"
  965.        
  966.         savebin "tank.com",begin,end-begin
  967.        
  968.         ;LABELSLIST "..\us\user.l"
  969.