This is an archived, read-only copy of the United-TI subforum , including posts and topic from May 2003 to April 2012. If you would like to discuss any of the topics in this forum, you can visit Cemetech's z80 & ez80 Assembly subforum. Some of these topics may also be directly-linked to active Cemetech topics. If you are a Cemetech member with a linked United-TI account, you can link United-TI topics here with your current Cemetech topics.

This forum is locked: you cannot post, reply to, or edit topics. Z80 & 68k Assembly => z80 & ez80 Assembly
Author Message
omni


Member


Joined: 14 Jun 2003
Posts: 115

Posted: 20 Jan 2004 09:05:58 pm    Post subject:

I would you create a smooth scrolling tilemap? Currently I can have a smooth scrolling sprite with no background, aligned tilemap rountine.

But I am stuck on how to create smooth scrolling tilemap. Would you create a bigger buffer than your data and display your buffer after shifting the bits?
Back to top
tr1p1ea


Elite


Joined: 03 Aug 2003
Posts: 870

Posted: 21 Jan 2004 09:42:41 am    Post subject:

You could do that but it would be memory intensive ... but then again it would be fast Smile. Other ways to do it are to write a special tile drawing routine (sort of like a clipped sprite routine) to draw your tiles. You have a start x,y position for you tilemap .. and another start x,y position that would act as an offsett for your tiles. It is a bit more complicated but saves a lot of memory.
Back to top
omni


Member


Joined: 14 Jun 2003
Posts: 115

Posted: 21 Jan 2004 04:12:59 pm    Post subject:

could you go into a little more depth for your method? And whats clip?
Back to top
tr1p1ea


Elite


Joined: 03 Aug 2003
Posts: 870

Posted: 21 Jan 2004 05:58:32 pm    Post subject:

A clipped sprite routine is a sprite routine that enables you to draw a sprite which is partially on/off the screen.

What you would do is have an offsett that points to the start of your tilemap in your Mapdata. Then you have another offsett which points to the starting position of the first 'tile'. You increase this offsett & redraw your tilemap and it will enable you to scroll. When the offsett reaches say 8, you reset it and increase the map-pointer respectively.

Sorry its a bit vague again (i dont have much time atm). There is a tilemap topic pinned with a routine in it ... you should check it out Smile.
Back to top
Dwedit


Member


Joined: 04 Jan 2004
Posts: 138

Posted: 21 Jan 2004 11:19:00 pm    Post subject:

Crashman made a nice smooth scrolling tilemap routine, but it's very difficult to use. It's the fastest possible routine of that type.
Back to top
tr1p1ea


Elite


Joined: 03 Aug 2003
Posts: 870

Posted: 22 Jan 2004 04:17:39 am    Post subject:

Actually he also made a simple smooth scrolling routine that you should check out. Search ticalc.org for CrASH_Man.
Back to top
omni


Member


Joined: 14 Jun 2003
Posts: 115

Posted: 22 Jan 2004 10:54:47 am    Post subject:

Does anyone know why crashmans routine is so fast?
Back to top
tr1p1ea


Elite


Joined: 03 Aug 2003
Posts: 870

Posted: 22 Jan 2004 02:57:56 pm    Post subject:

1) Because he is a genius.
2) Because his methods arent what you would usually do. He has everytihng vertically aligned etc etc. A lot of thought has gone into it ... but there are some restrictions.
Back to top
JeePee


Member


Joined: 18 Jan 2004
Posts: 181

Posted: 22 Jan 2004 03:34:14 pm    Post subject:

tr1p1ea: why do you call everybody who has done something "useful" for TI a genius. (Probably just a habit, if so, would you mind to call me a genius too? Cool )
Back to top
omni


Member


Joined: 14 Jun 2003
Posts: 115

Posted: 22 Jan 2004 07:58:26 pm    Post subject:

tr1ip1ea,does your method run at a decent speed? Or is it really slow, slow enough that it lags.
Back to top
tr1p1ea


Elite


Joined: 03 Aug 2003
Posts: 870

Posted: 22 Jan 2004 09:34:18 pm    Post subject:

Well CrASH_Man is a genius ... he has done many awesome things.

The method i spoke of isnt the fastest around ... but it certainly wont lag.
Back to top
Dwedit


Member


Joined: 04 Jan 2004
Posts: 138

Posted: 23 Jan 2004 01:53:54 am    Post subject:

I also made a fastcopy + tilemap routine, but it's slower then crashman's. If I tried to optimize it more, it would end up as a clone of his routine :)

Fast (but not fastest) vertical+horizontal scrolling, supports any number of tiles, has a normal plotsscreen. Those features make it slower than crashman's, which has a 32 tile limit, vertically oriented plotsscreen, and is about twice as fast.
Back to top
omni


Member


Joined: 14 Jun 2003
Posts: 115

Posted: 26 Jan 2004 01:12:09 pm    Post subject:

What if I shifted the screen after I had drawn the tilemap to screen aligned?

1.Draw the tilemap to screen aligned, dont acutally display it yet.
2.Then shift all the bits x times.
Where x is the 'shift counter'
Back to top
tr1p1ea


Elite


Joined: 03 Aug 2003
Posts: 870

Posted: 26 Jan 2004 03:52:10 pm    Post subject:

yes you could do that, and of course you would have to fill in a missing row/column with an unaligned routine. But yes that would work nicely ... and reasonable fast too Smile.
Back to top
omni


Member


Joined: 14 Jun 2003
Posts: 115

Posted: 26 Jan 2004 06:12:06 pm    Post subject:

I could fill the missing column with a HUD, but is there an instruction that
will but old carry into bit7 and shift all bits right and then bit0 goes to carry? I checked the instruction set, but no instruction does that.
Back to top
DigiTan
Unregistered HyperCam 2


Super Elite (Last Title)


Joined: 10 Nov 2003
Posts: 4468

Posted: 26 Jan 2004 11:10:12 pm    Post subject:

This code will scroll an entire row by 1 pixel (intended for 96 pixel-wide screens. Naturally, you can modify it for bigger screens, or optimize the repetative code using a "DJNZ" loop:...


Code:
 ld hl,GRAPH_MEM
RIGHT_ROTATE:  ; Special thanks to CrASH_Man
 push hl
  SLA (HL)                    ; 96-bit shift left
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
  RL  (HL)
  DEC HL
 pop hl
 ret nc
 ld a,(hl)
 or %00000001
 ld (hl),a
 ret


...So using the "x=shift counter" method, you should be able to do some basic smooth scrolling. The only limitation is that if you don't use cliped sprites, you'll end up with the "blank column" issue tr1p1ea mentioned--which will be up to 7 pixels wide.


Last edited by Guest on 26 Jan 2004 11:11:12 pm; edited 1 time in total
Back to top
Job the GameQuitter


Member


Joined: 04 Jun 2003
Posts: 102

Posted: 27 Jan 2004 09:45:55 am    Post subject:

If you want the whole screen to scroll 4 pixels to the right/left at a time and don't have a tilemap buffer with the X/Y axis switched, you can also use the RRD and RLD instructions, which do the following:

RRD, before:
A = %XXXXaaaa
HL = %bbbbcccc
after:
A = %XXXXcccc
HL = %aaaabbbb

RLD, before:
A = %XXXXaaaa
HL = %bbbbcccc
after:
A = %XXXXbbbb
HL = %ccccaaaa

cycles: 18.

So you can shift 4 bits trough HL at a time at a faster rate that way, by simply doing

LD A,%0000abcd
LD hl,gbuf
RRD \ INC HL
RRD \ INC HL
etc.

where abcd = the four bits you want to shift in the left side of the screen. Scrolling the other way is done just like that, except you start at the other end of the buffer and use RLD \ DEC HL. It's not smooth, but it's an option.

Now, scrolling up/down with a regular gbuf is just a matter of LDIR-ing the screen. I'm working on an alternative (faster) method of scolling up/down using the Z-adress, which my fellow coders over at Maxcoderz lovingly nicked "Jobean scrolling" Rolling Eyes. Because of that I made three programs which demonstrate different approached to vertical scrolling, which you can find here here. They're not useful routines in practice, but maybe it'll help explain some concepts of scrolling vertically (although I suggest you don't try to use method 2 or 3, because one is memory-hogging, and the other complex as hell).
Back to top
Dwedit


Member


Joined: 04 Jan 2004
Posts: 138

Posted: 27 Jan 2004 10:47:10 am    Post subject:

Shifting after drawing the the map is slow. Don't bother with stuff like that, just get the map drawn in one pass.
This old one I made takes almost constant time to draw the map, regardless of x scroll position.


Code:
;Fastcopy + Horizontal + Vertical Scrolling Tilemap by Dwedit
;
;Input:
;  de = plotsscreen
;  (MapBase) = word,Base address of map
;  (cameray) = word,vertical location of camera
;  (camerax) = word,horizontal location of camera
;  (tilesbase) = word,pointer to tileset
;  tilesbuf = label,destructable tileset buffer equal in size to the tileset
;  tilesbuf2 = label,another destructable tileset buffer, also equal in size to the tileset
;  NUM_TILES = byte constant,number of tiles in the tileset (size of tileset/8)
;  (mapwidth) = word,width of tilemap
;Output:
;  screen copied from buffer to screen
;  tilemap drawn on buffer, with origin (camerax,cameray)
;
;Needs modification, change where it multiplies hl by map width (currently fixed at 12)

FastCopyTilemap:
  di
  ld a,$80
  out ($10),a ;set row 0
  push de
   ;Get new mapbase and x-tile scroll from camerax
    ld hl,(camerax)
    call DivBy8Common
    ld bc,(MapBase)
    add hl,bc
    push hl
      call MessUpTiles
     ;Now get yscroll and adjust basemap for cameray
      ld hl,(cameray)
      call DivBy8Common
      ld (TM_ModYpos+1),a

     ;Multiply HL by map width here (needs modify)
      add hl,hl
      add hl,hl
      ld b,h
      ld c,l
      add hl,hl
      add hl,bc

    pop bc
    add hl,bc
    push hl
     ;RenderTileModder:
      add a,a
      add a,a
      ld c,a
      add a,a
      add a,c
      ld b,0
      ld c,a
      ld hl,RenderTile
      push hl
        add hl,bc
        ld (TM_Mod1+1),hl
      pop hl
      ld a,c
      cpl
      add a,97
      ld c,a
      add hl,bc
      ld (TM_Mod2+1),hl
    pop hl
  pop de
  xor a
TileMapLoop1:
  push af
   push hl \ push de;save base coordinates
    add a,$20    ;$20 + C = set column
    out ($10),a ;set column
    
   ;Draw top tile (clipped)
    push hl
      ld bc,TilesBuf2
      ld a,(hl)
      inc hl
      ld l,(hl)
      ld h,0
      add hl,hl
      add hl,hl
      add hl,hl
      add hl,bc
      push hl
      pop ix
      ld l,a
      ld h,0
      add hl,hl
      add hl,hl
      add hl,hl
      ld bc,TilesBuf
      add hl,bc
TM_ModYpos:
      ld bc,0000
      add hl,bc
      add ix,bc
      
      ex de,hl
      ld bc,12
TM_Mod1:
      call 0
    pop hl
    ld bc,(mapwidth)
    add hl,bc ;advance tile pointer by map's width
    
   ;Draw next 7 tiles
    ld b,7      ;8 tiles per column
TileMapLoop2:
    push bc
      push hl    ;save position on map
        ld bc,tilesBuf2
        ld a,(hl)
        inc hl
        ld l,(hl)
        ld h,0
        add hl,hl
        add hl,hl
        add hl,hl
        add hl,bc
        push hl
        pop ix
        ld l,a
        ld h,0
        add hl,hl
        add hl,hl
        add hl,hl
        ld bc,tilesBuf
        add hl,bc

        ex de,hl
        ld bc,12
        call RenderTile
      pop hl
      ld bc,(mapwidth)
      add hl,bc ;advance tile pointer by map's width
    pop bc
    djnz TileMapLoop2
    
   ;Draw bottom tile (clipped)
    ld bc,tilesBuf2
    ld a,(hl)
    inc hl
    ld l,(hl)
    ld h,0
    add hl,hl
    add hl,hl
    add hl,hl
    add hl,bc
    push hl
    pop ix
    ld l,a
    ld h,0
    add hl,hl
    add hl,hl
    add hl,hl
    ld bc,tilesBuf
    add hl,bc
    
    ex de,hl
    ld bc,12
TM_Mod2:
    call 0
DontRenderLastTile:
   pop de \ pop hl ;back to the top
   inc hl \ inc de ;next column for map and screen
  pop af
  inc a ;next column
;  ld a,c
  cp 12 ;stop after 12 columns  (maybe replace this if you need a smaller map)
  jp c,TileMapLoop1
  ret ;Done

RenderTile:
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ld a,(hl)    ;Write old byte to LCD
  out ($11),a
  ld a,(de)    ;read graphics data
  or (ix+0)
  ld (hl),a
  inc de
  inc ix
  add hl,bc
  ex de,hl
  ret

DivBy8Common:
  ld a,l
  sra h
  rra
  sra h
  rra
  sra h
  rra
  ld c,l
  ld l,a
  ld a,c
  and 7
  ret  

MessUpTiles: ;input: a=x pixel position
  cpl
  add a,8
MessUpTiles2:
  ld (MessUpTilesModify+1),a
  ld hl,InvertedMaskTable
  ld b,0
  ld c,a
  add hl,bc
  ld a,(hl)
  ld (MessUpTilesMask1+1),a
  cpl
  ld (MessUpTilesMask2+1),a
  ld hl,(Tilesbase)
  ld de,TilesBuf
  ld ix,TilesBuf2
  ld bc,8*NUM_TILES
MessUpTilesLoop:
  ld a,(hl)
MessUpTilesModify:
  jr $+2
  rlca
  rlca
  rlca
  rlca
  rlca
  rlca
  rlca
  ld (de),a
MessUpTilesMask2:
  and 0
  ld (ix+0),a
  ld a,(de)
MessUpTilesMask1:
  and 0
  ld (de),a
  inc de
  inc ix
  cpi
  jp pe,MessUpTilesLoop
  ret

InvertedMaskTable: ;stick this wherever you like
  .db %10000000
  .db %11000000
  .db %11100000
  .db %11110000
  .db %11111000
  .db %11111100
  .db %11111110
  .db %11111111


Here's the old fastcopy + tilemap with V/H scrolling routine I made...
Not as fast as crashman's, but doesn't need as many of the tricks.

Tilemaps are horizontally oriented, not vertically, so .db 1,2,3,4,5 is horizontal, not vertical. Needs empty space equal to 2x the size of the tileset. supports up to 255 tiles. Uses the normal plotsscreen, not the rotated one. Need to modify where it multiplies Y by width. To do NES-style global tile animation, you can change the source address of tiles.


Last edited by Guest on 27 Jan 2004 10:48:15 am; edited 1 time in total
Back to top
Job the GameQuitter


Member


Joined: 04 Jun 2003
Posts: 102

Posted: 29 Jan 2004 11:28:04 am    Post subject:

Shifting after drawing the map can be fast, if you only draw the part that is being scrolled in each frame thereafter. You'd have to put the sprite and mask in a seperate buffer though, because you can't mask them on top of the tiles. If you did you'd have to redraw the whole map again. The masking of these buffers and the scrolling can be done minimal speed decrease, using the wasted clocks between outputting bytes to the screen.

Last edited by Guest on 29 Jan 2004 11:29:14 am; edited 1 time in total
Back to top
omni


Member


Joined: 14 Jun 2003
Posts: 115

Posted: 03 Feb 2004 05:10:29 pm    Post subject:

what do you mean by using wasted clock cycles?
Back to top
Display posts from previous:   
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
    » Goto page 1, 2  Next
» View previous topic :: View next topic  
Page 1 of 2 » All times are UTC - 5 Hours

 

Advertisement