[A83] Re: Tilemap


[Prev][Next][Index][Thread]

[A83] Re: Tilemap




And you would get absolutely _horrible_ performance.  You can't make a
tilemap routine by calling a normal putsprite and expect to get any
performance out of it.  Since it's aligned anyway, you are much better off
using an aligned putsprite routine.

When I started CnC86, I wrote a simple routine to draw part of a large
tilemap (64x64).  It only did aligned, but if you run the demo, you will see
that it is quite fast.  This was written a very long time ago, so the code
isn't that great, but it's not absolutely terrible.  It's commented and you
can see what is going on.  The sprite routine could be improved by not using
IX at all.  Obviously, you want to intregrate everything.  It's stupid to
calculate coordinates and pass them to a sprite routine, when you can just
calculate the address in the map routine and just increment the pointer.  It
makes the code more complicated, but it will be faster.  I'd been doing z80
for maybe six months when I wrote this, so I was just getting into writing
good code.  It takes a while to really get a feel for how to put everything
together.

http://www.ticalc.org/pub/86/asm/source/cnc86.zip

(comments should be aligned when viewed in a fixed width font)

MapX        = _textShadow + 10  ; [1]   upper-left corner of the map display
MapY        = _textShadow + 11  ; [1]   ...

DrawMap:
 ld de,(MapX)               ; load the map coords   (note:  loaded in
reverse order!)
 ld h,d                     ; move the y coord to the high byte (* 256)
 srl h                      ; divide by two (* 128)
 rra                        ; move overflow to low byte
 srl h                      ; again, divide by two (* 64)
 rra                        ; handle final overflow
 and %11000000              ; clear lower 6 bits
 or e                       ; add the x coord (x <= 63)
 ld l,a                     ; move to low byte
 ld de,Map                  ; point to the map
 add hl,de                  ; add the map start to the offset
 ld b,8                     ; we need to draw 8 rows
 ld d,0                     ; start y draw coord at 0
DMYLoop:
 push bc                    ; save the y counter
 ld b,12                    ; each row has 12 tiles in it
 ld e,0                     ; start x draw coord at 0
DMXLoop:
 push bc                    ; save the x counter
 push hl                    ; save the map pointer
 push de                    ; save the tile draw coords
 ld l,(hl)                  ; load the tile number into the low byte
 ld h,0                     ; clear the high byte
 add hl,hl                  ; * 2
 add hl,hl                  ; * 4
 add hl,hl                  ; * 8, each sprite is 8 bytes
 ld de,MapSprites           ; point to the start of the map sprites
 add hl,de                  ; point to the correct sprite
 pop de                     ; restore the tile draw coords
 push de                    ; save the tile draw coords
 call GridPutSprite         ; draw the sprite!
 pop de                     ; restore the tile draw coords
 pop hl                     ; restore the map pointer
 inc hl                     ; move to the next tile
 inc e                      ; move to next x position
 pop bc                     ; restore the x counter
 djnz DMXLoop               ; loop for all tiles in the row
 ld bc,64-12                ; each row is 64 bytes wide (12 on the screen)
 add hl,bc                  ; move to next row
 inc d                      ; move to next y position
 pop bc                     ; restore the y counter
 djnz DMYLoop               ; draw all the rows
 ret                        ; finally, and many t-states later, we're done!

;=====================================================================
; GridPutSprite:
;  Puts an aligned sprite at (E, D), where HL -> Sprite
;=====================================================================
; IN : D  = y (0-7 inclusive)
;      E  = x (0-15 inclusive)
;      HL-> sprite
;
; OUT: AF, BC, DE, HL, IX modified
; Current total : 28b/567t (not counting ret)
;=====================================================================
GridPutSprite:
 push hl
 pop ix             ; ix-> sprite
 srl d              ; de = 128y+x (16 bytes/row, 8 rows)
 rra
 and $80
 or e               ; add x offset (remember x <= 15)
 ld e,a
 ld hl,MapScr       ; hl-> MapScr
 add hl,de          ; hl-> MapScr + offset
 ld b,8             ; initialize loop counter
 ld de,$10          ; initialize line increment
GPS_Loop
 ld a,(ix+0)        ; get byte from sprite
 ld (hl),a          ; put byte on screen
 inc ix             ; move to next byte in sprite
 add hl,de          ; move to next line on screen
 djnz GPS_Loop
 ret

> Looks like another one of them ionPutSprite tilemap routines, like the one
I
> started out with before switching to TCPA's tilemap routine.  It would be
a
> lot better to use a clipped sprite routine, then change the origin by
pixels
> as well as tiles.






Follow-Ups: References: