[A83] Re: Tilemap


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

[A83] Re: Tilemap




And how long did you work on this routine?
(Just curious.)
 
> 
> 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: