18 call prepareShiftedTiles
77 ld hl,IntrHandlerSmall
89 call WinStick.readMoves
93 ; C,A: state (LRUDF; F is #01)
188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
198 ld de,#4000+4096+6*32+30
236 ld de,#4000+4096+6*32+30
287 ld hl,#4000+4096+6*32+30
339 @scrollTextPtr: equ $+1
348 ld (scrollTextPtr),hl
353 ld (.putLetterAddr),hl
361 .putLetterAddr: equ $+1
376 defm "Welcome to ", 1, "eniJne", 2, " demo -- 8-dir blitting engine! "
377 defm "You can use cursor keys or OPQA to move around. "
378 defm "Some enJine techinfo: "
379 defm "level blitting with 2px horizontal step and 1px vertical step; "
380 defm "level map size limited only by free memory (i used 64x64 FireFly map in this demo); "
381 defm "rebuilding blitter data and blitting the map takes one frame (+/- some ticks %-); "
382 defm "map is stored in plain left-to-right up-to-down format, so checks against map tiles are easy; "
383 defm "map redrawn each 2 frames, so one can easily do tile animations by switching tile sets; "
384 defm "more that one tile set per level allowed (but you will need memory to store pre-shifted tiles); "
385 defm "and much more (and probably much less than you expecting, 'cause Speccy is not your multicore PC %-). "
386 defm "Code: Ketmar // Vampire Avalon "
387 defm "Code: ", 1, "fffimS affoJ", 2, " "
388 defm "Coming soon this summer: fast-paced game made with enJine (or at least i hope it is coming...). "
389 defm "enJine sources will be released too! "
390 defm "Dedicated to ", 1, "fffimS affoJ", 2, "."
395 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
396 ;; build shifted tiles
400 ; tiles are not packed
401 ld de,shiftedTilesBuf
410 ld hl,shiftedTilesBuf
411 ld de,shiftedTilesBuf+6*16*4
414 ld a,3 ; 3 shifts left
417 ; HL: addr of previous tileset
418 ; DE: addr of current tileset
423 ; previous tiles copied, now shift
424 pop hl ; start of the current block
427 ld e,b ; B is always 0 here
442 ex de,hl ; now DE is the new dest address
443 pop hl ; current set address
449 exo_mapbasebits: equ #4000 ; 156 bytes
453 incbin "bdata/tiles_blobs.exo"
455 incbin "bdata/map00.exo"
461 pusherStart: equ $ ; #8800
462 ; max pusher end will be: #8eff
465 scrRowsTable: ds 128*2
468 shiftedTilesBuf: ds 16*4*6*4
472 dw shiftedTilesBuf+0*6*16
473 dw shiftedTilesBuf+1*6*16
474 dw shiftedTilesBuf+2*6*16
475 dw shiftedTilesBuf+3*6*16
480 db 0E5h,0E5h ; 0 : push hl, push hl : 33
481 db 0D5h,0C5h ; 1 : push de, push bc : 01
482 db 0D5h,0D5h ; 2 : push de, push de : 11
483 db 0F5h,0D5h ; 3 : push af, push de : 12
484 db 0C5h,0E5h ; 4 : push bc, push hl : 30
485 db 0E5h,0F5h ; 5 : push hl, push af : 23
486 db 0F5h,0C5h ; 6 : push af, push bc : 02
487 db 0E5h,0C5h ; 7 : push hl, push bc : 03
488 db 0F5h,0E5h ; 8 : push af, push hl : 32
489 db 0F5h,0F5h ; 9 : push af, push af : 22
490 db 0C5h,0C5h ;10 : push bc, push bc : 00
491 db 0D5h,0F5h ;11 : push de, push af : 21
492 db 0C5h,0D5h ;12 : push bc, push de : 10
493 db 0E5h,0D5h ;13 : push hl, push de : 13
494 db 0D5h,0E5h ;14 : push de, push hl : 31
495 db 0C5h,0F5h ;15 : push bc, push af : 20
497 ; jump table for screen pushers
498 ; addr, tilesofs, 2ndtilesofs
502 shiftedTilesOfsTable:
509 plrXOffset: db 0 ; player X offset in the tile (0-7): in 2 pixels
510 plrYOffset: db 0 ; player Y offset in the tile (0-28; step: 4); (0-7): in 2 pixels
521 include "helispr.zas"
576 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
577 ;; blit map onto the screen using prebuild 'pushers'
582 ; A is the index in screen line table
583 ; also it is used as 'stop flag', due
584 ; to the fact that we have to render
585 ; only 2/3 of the screen, which is
589 ;ld hl,%0001000100010001
590 ; HL is always 0 for 'pushers'
591 ; we can load it with some 'background' graphix
593 ex af,af' ; switch to 'working' A
594 exx ; switched to 'loop' register set
596 ; calculate number of visible lines in top tile
601 ld (blitMapRowCountVar),a
608 ld (blitMapShiftCmd),a
609 ; calc tilegfx addr (we have set of shifted tiles)
610 ld a,c ; stored plrXOffset
613 add a,shiftedTilesOfsTable%256
615 IF (shiftedTilesOfsTable+5)/256 != shiftedTilesOfsTable/256
616 ld a,shiftedTilesOfsTable/256
622 ld h,shiftedTilesOfsTable/256
628 ld (blitMapGfxOfs),hl
632 ld hl,pusherJumpTable
637 ld (pusherAddress),bc
638 ; load tile gfx offset to IY
645 ; load 2nd tile gfx offset to IX
652 ; shift tile gfx addresses according to player Y offset
669 ; HL: tile gfx base address
671 blitMapRowCountVar: equ $+1
673 ; start drawing current row
677 ; load screen line address
679 ld h,scrRowsTable/256
680 ; move to next table item
696 ld sp,hl ; put screen address to SP
698 pusherAddress: equ $+1
699 jp 0 ; self-patching code; jump to 'pusher'
700 blitMapPusherDone: ; 'pushers' will return here
701 ld de,6 ; tiles gfx are 6x16
706 ; move to next map row
707 ; DE: table with 'pusher' addresses and tile offsets
708 ; get next 'pusher' address
713 ld (pusherAddress+1),a
715 blitMapGfxOfs: equ $+1
716 ld bc,0 ; tile grafix offset
717 ; get tile gfx addresses
732 ld b,16 ; 16 lines of next tile row
740 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
741 ;; part of code to get new graphics
742 ;; intended for copying
744 ld (relGfxSavedSP),sp ; 4 bytes
749 ld sp,(relGfxSavedSP) ; 4 bytes
751 codeReloadTileGfxLen: equ $-codeReloadTileGfx
754 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
755 ;; calculate address in the map
779 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
785 ; up one row due to 'next map row' below
788 ld (bldCurMapAddr),hl
791 ld (.bldPusherStartAddrVar),hl
793 ld hl,pusherJumpTable
797 ; store current 'pusher' address
798 .bldPusherStartAddrVar: equ $+1
807 @bldCurMapAddr: equ $+1
818 ld (bldCurMapAddr),hl
819 ; pop 'pusher' address
822 ld (bldCurTileBlockX2Var),a
823 ld b,8 ; 8 bytes/16 tiles
832 jr nz,.bldNonEmptyTile
833 ld a,#E5 ; PUSH HL (2 empty tiles)
836 .bldStorePushAndBackOneMapByte:
839 ; back one map byte, with wrapping
850 ; ---------------------------------------------------------------------------
852 ; put only one tile instead of two
855 jr nz,.bldNonEmptyTileEX
856 ld a,#E5 ; PUSH HL (empty tile)
857 jp .bldStorePushAndBackOneMapByte
863 ld (bldCurTileBlockX2Var),a
864 call bldStoreTileBlockOffset
873 ; ---------------------------------------------------------------------------
879 ld (bldCurTileBlockX2Var),a
880 call bldStoreTileBlockOffset
883 jr .bldWeAreNotEmptyAnyway
895 bldCurTileBlockX2Var: equ $+1
898 jp z,.bldSameTileBlock
900 ld (bldCurTileBlockX2Var),a
901 call bldStoreTileBlockOffset
902 ; copy 'gfx switch' code
905 ld hl,codeReloadTileGfx
906 DUP codeReloadTileGfxLen
913 .bldWeAreNotEmptyAnyway:
931 ; previous map byte, with wrapping
942 dec de ; remove one push (border)
945 jr z,$+3 ; skip next command
946 dec de ; remove another push (map is shifted by one tile)
947 ex de,hl ; HL: 'pusher' end
951 ld (hl),blitMapPusherDone%256
953 ld (hl),blitMapPusherDone/256
955 ld (.bldPusherStartAddrVar),hl ; save this address
956 pop hl ; 'pusher' table
963 jp nz,.bldPusherNextRow
966 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
968 bldStoreTileBlockOffset:
971 ; DE: 'pusher' address
974 ; get tile block offset
975 ld l,tileBlockOffsets%256
979 ld a,tileBlockOffsets/256
988 ; store tile block offset
997 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1029 ;call BuildScrLineTable