Author Topic: Tilemap scrolling  (Read 8633 times)

0 Members and 1 Guest are viewing this topic.

Offline MRide

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 711
  • Rating: +14/-0
  • You can't see this.
    • View Profile
Tilemap scrolling
« on: July 28, 2010, 12:17:03 pm »
Thanks to SirCmpwn and nemo, I was able to write a tilemap display routine.  I then added scrolling by one tile at a time (as opposed to one pixel.)
Here is the code:

Code: [Select]
:.ATILMAP
:[11111111111111111111→GDB1
:[10001000000000000001
:[10000100000000000001
:[10000001000000000001
:[10000000001000000001
:[10001000000000000001
:[10000010000000000001
:[10000000000000000001
:[10010000000000000001
:[10100000000000000001
:[10000000000000000101
:[11111111111111111111
:[55AA55AA55AA55AA→Pic1
:[FFFFFFFFFFFFFFFF
:0→S→D→U
:ClrDraw
:sub(DS)
:Repeat getKey(15)
:If D<40 and getKey(1)
:20+D→U
:End
:If D≠0 and getKey(4)
:D-20→U
:End
:S+(S<4 and getKey(3))-(S≠0 and getKey(2))→T
:If D≠U or (S≠T)
:U→D
:T→S
:ClrDraw
:End
:sub(DS)
:End
:Return
:Lbl DS
:For(Y,0,7)
:For(X,0,11)
:{Y*10+X+GDB1+D+S}→A
:Pt-On(X*16,Y*8,A/16*8+Pic1
:Pt-On(X*16+8,Y*8,A^16*8+Pic1
:End
:End
:DispGraph

For some reason, it skips two tiles at a time.  So far, I have been unable to figure out why this is.

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: Tilemap scrolling
« Reply #1 on: July 28, 2010, 03:44:10 pm »
by changing
Code: [Select]
:If D<40 and getKey(1)
:20+D→U
:End
:If D≠0 and getKey(4)
:D-20→U
:End

to
Code: [Select]
:If D<40 and getKey(1)
:10+D→U
:End
:If D≠0 and getKey(4)
:D-10→U
:End

the code now scrolls vertically by 1. since the tilemap is half-byte compressed and there are 20 tiles per row of the map, that means there are 10 bytes in each row. so you only need to add 10 to scroll to the next row.

as for horizontal scrolling, that's a bit more challenging and may require changing the way you draw the tilemap. here's some modified code:
Code: [Select]
:.ATILMAP
:[11111111111111111111→GDB1      .Data Map size is 20 tiles (half-bytes aka nibbles) wide by 12 tiles high.
:[10001000000000000001           .The height of the displayed map is 8 tiles. this means the maximum
:[10000100000000000001           . vertical offset is 4 tiles. since each row is 20 tiles, the maximum vertical offset is 80.
:[10000001000000000001           . the width of the displayed map is 12 tiles. this means the maximum horizontal offset is
:[10000000001000000001           . 8 tiles.
:[10001000000000000001
:[10000010000000000001
:[10000000000000000001
:[10010000000000000001
:[10100000000000000001
:[10000000000000000101
:[11111111111111111111
:[55AA55AA55AA55AA→Pic1
:[FFFFFFFFFFFFFFFF
:0→S→D                       .OFFSETS - S = horizontal scroll, D= vertical scroll
:ClrDraw
:Repeat getKey(15)
:If D<80 and getKey(1)       .80 is the maximum vertical offset
:20+D→D:End
:If D≠0 and getKey(4)         .0 is the minimum vertical offset, naturally.
:D-20→D
:End
:S<8 and getKey(3)-(S≠0 and getKey(2))+S→S     .8 is the maximum horizontal offset
:For(Y,0,7
:For(X,0,11
:Pt-Off(X*8,Y*8,sub(GN,Y*20+X+D+S)*8+Pic1     .Y*20+X+D+S is a nibble in the tilemap
:End:End
:DispGraph
:End
:Lbl GN
:{r1/2+GDB1}→T                 .Divide the nibble by two to find the correct byte in the tilemap
If r1^2                        .If the byte in the tilemap isn't divisible by two
T^16:Else                      .Return the low nibble of the byte. Else
T/16:End                       .Return the high nibble of the byte.




Offline MRide

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 711
  • Rating: +14/-0
  • You can't see this.
    • View Profile
Re: Tilemap scrolling
« Reply #2 on: July 28, 2010, 11:37:01 pm »
Thanks.
Also, how would you implement 3 lvl grayscale tiles?  Say, instead of just black tiles, I wanted all gray tiles.

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: Tilemap scrolling
« Reply #3 on: July 28, 2010, 11:40:12 pm »
not sure, but i think you'd just change DispGraph to DispGraphr and have Pt-Off() be Pt-Off()r


Offline MRide

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 711
  • Rating: +14/-0
  • You can't see this.
    • View Profile
Re: Tilemap scrolling
« Reply #4 on: July 28, 2010, 11:43:56 pm »
That just creates a flashy screen.  Wouldn't would need a separate drawing command if you want only the solid black tiles turned gray?

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: Tilemap scrolling
« Reply #5 on: July 28, 2010, 11:47:32 pm »
hmm.. i'm not very good with grayscale, but yes you're correct. you need two drawing commands. one that draws to the buffer, and one to the back-buffer. however, if you only want the black squares to be gray then you need to store the result of the sub(GN) call into a variable, and use an If conditional


Offline MRide

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 711
  • Rating: +14/-0
  • You can't see this.
    • View Profile
Re: Tilemap scrolling
« Reply #6 on: July 28, 2010, 11:55:38 pm »
So you would need to draw the patterned tile to both buffers, and the solid tile to just the back buffer?

EDIT: Well, it starts out looking good (if a bit flickery), but when I try to move, it messes up.

EDIT 2: Would this be a sort of upside down ninja'd?
« Last Edit: July 29, 2010, 12:03:11 am by MRide »

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: Tilemap scrolling
« Reply #7 on: July 29, 2010, 12:01:26 am »
yes. i seem to have it working except when you try to scroll, it starts flickering :/

edit: i found it out, though i'd like to see you get it on your own so i'm not going to post code (but i will later if you want me to)
« Last Edit: July 29, 2010, 12:09:44 am by nemo »


Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Tilemap scrolling
« Reply #8 on: July 29, 2010, 03:33:44 am »
By the way I worked on a tilemapper for a while, but sadly, I couldn't figure out how to change a tile in it. It was for a map editor, by the way. There might be other help available in the topic there (although it's old): http://ourl.ca/5988

I don't recommend my code because it was buggy, but hopefully the advices Quigibo posted might be helpful. At first my tilemap scrolled every 2 tile horizontally but he helped me make it scroll every tile

Offline MRide

  • LV8 Addict (Next: 1000)
  • ********
  • Posts: 711
  • Rating: +14/-0
  • You can't see this.
    • View Profile
Re: Tilemap scrolling
« Reply #9 on: July 29, 2010, 01:26:38 pm »
Well, I fixed one problem.  Now the gray stays the whole time, but instead of being solid gray, it appears to have the checkerboard pattern behind it.

EDIT: Hmm...Well, If store the result of the call to GN in W, then W is either 0 or 1.  If its zero, then I want to write to the buffer, and I always write to the back-buffer.  However, it seems that the patterned tile is being written to the buffer over the whole tilemap.

EDIT 2: I have come to these possibilities:
            1) The GN call does not return 0 or 1 as I had supposed, therefore, the If conditional is always true, and always draws the patterned tile to the buffer
            2) The above statement is false, because the drawing command inside the if conditional wouldn't just draw the patterned tile,  and after looking at the code, GN does return 0 or 1.
            3) If #2 is true, then there shouldn't be anything wrong with that section of the code, and I messed up somewhere else.
« Last Edit: July 29, 2010, 02:21:10 pm by MRide »

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: Tilemap scrolling
« Reply #10 on: July 29, 2010, 04:32:42 pm »
the subroutine GN definitely returns a 0 or a 1, based on the tile in the tilemap. could you post some code? and yes, the way grayscale is made is turning pixels on and off very quickly. so when you do DispGraphr, you actually turn on a checkerboard pattern on the backbuffer, and then the next time you call it the checkerboard pattern is shifted, making the appearance of gray. you probably see the checkerboard because the screen is not updating quickly enough. you could put an If getKey(0) around the part where you draw the tilemap to remedy this.


Offline Quigibo

  • The Executioner
  • CoT Emeritus
  • LV11 Super Veteran (Next: 3000)
  • *
  • Posts: 2031
  • Rating: +1075/-24
  • I wish real life had a "Save" and "Load" button...
    • View Profile
Re: Tilemap scrolling
« Reply #11 on: July 29, 2010, 11:14:14 pm »
GN does not explicitly return 1 or 0, it returns the half byte tile 0-F (0-15 in decimal).  Although personally, I don't like that routine since there is no X and Y its usage is confusing.

If you want a solid gameboy gray, you have to turn interrupts off for the entire code and you also need to make sure to adjust the pause time in between each DispGraph to the perfect amount.  It will take some tuning since every display is different unfortunately.  For me, I have a TI-84 Plus K-0108H and my perfect gray setting is this:

Code: [Select]
:FnOff
:Repeat getkey(15)
:
:Pause 7           ;Long pause
:For(A,0,15):End   ;Fine tuning
:
:DispGraphr
:End

By perfect, I mean like a gameboy, not even one of those slowly scanning lines that moves diagonally from one side to the other, I mean literal gray.  The pause times will of course have to be different depending on how much other code you have in your loop.
« Last Edit: July 29, 2010, 11:17:56 pm by Quigibo »
___Axe_Parser___
Today the calculator, tomorrow the world!

Offline Runer112

  • Project Author
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2289
  • Rating: +639/-31
    • View Profile
Re: Tilemap scrolling
« Reply #12 on: July 29, 2010, 11:40:22 pm »
GN does not explicitly return 1 or 0, it returns the half byte tile 0-F (0-15 in decimal).  Although personally, I don't like that routine since there is no X and Y its usage is confusing.

If you want a solid gameboy gray, you have to turn interrupts off for the entire code and you also need to make sure to adjust the pause time in between each DispGraph to the perfect amount.  It will take some tuning since every display is different unfortunately.  For me, I have a TI-84 Plus K-0108H and my perfect gray setting is this:

Code: [Select]
:FnOff
:Repeat getkey(15)
:
:Pause 7           ;Long pause
:For(A,0,15):End   ;Fine tuning
:
:DispGraphr
:End

By perfect, I mean like a gameboy, not even one of those slowly scanning lines that moves diagonally from one side to the other, I mean literal gray.  The pause times will of course have to be different depending on how much other code you have in your loop.

Why do interrupts have to be off for good-looking grays?

Offline nemo

  • LV9 Veteran (Next: 1337)
  • *********
  • Posts: 1203
  • Rating: +95/-11
    • View Profile
Re: Tilemap scrolling
« Reply #13 on: July 30, 2010, 12:20:19 am »
as a minor clarification, sub GN *does* return a 1 or a 0, since only 1's and 0's are in the tilemap.


Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55943
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Tilemap scrolling
« Reply #14 on: July 30, 2010, 02:54:48 am »
One thing a programmer could do is allow the user to change the Pause delay in an option menu by a certain range. Not too low nor too high, to keep the game speed from changing way too much, depending of the setting. It might allow the game to look good on most models. Desolate did that (although it only let you choose between 4 settings)