Jump to content
IGNORED

Scrolling in Bitmap mode


adamantyr

Recommended Posts

Hello fellow 99'ers...

 

I have a bit of a proof-of-concept I'm mulling over... create a large full-screen (maybe just the upper two sections) scrolling map in full bitmap mode on the TI. I'm trying to figure out the best implementation for this.

 

The first method I had in mind was to treat bitmap mode as it is, characters 0-31 along the top row, 32-63 on the next, etc. Moving in a given direction just rotates the screen table assignments and then loads new graphics patterns for the newly visible blocks. The problem I see with this method is you can't buffer anything. It's going to LOOK messy, with characters you just moved out of view re-appearing briefly on the other side until it fills in graphics patterns. Seems way too slow and awkward...

 

The other method would be to have specific character assignments for given tiles (wall, floor, etc). This becomes much easier to implement, but you lose the flexibility of bitmap mode, and you artificially limit yourself to 256 patterns maximum. (My intent is to possibly have much more than that...)

 

So the only thing I can figure on doing is a hybrid approach; treat some part of the character table set as fixed pattern, and then have any objects/tiles I want to be unique actually occupy their own character patterns. That lets me quickly build a new view in CPU memory and output it to VDP quickly. The main headache I can foresee here is that you're going to have to manage those patterns and figure out when a given pattern is available... could end up getting very annoying.

 

Has anyone dealt with this, or has some insight I may be missing?

 

Adam

Link to comment
Share on other sites

There may be another way, if you could get it to pad out the 1st column or more if needed, 2 perhaps, and the last 2 columns, 31 and 32, downwards to row 24 with blanks, every time the screen updates. It may run fast enough to black out the chars coming in and changing? Or would you see the flicker?

Link to comment
Share on other sites

There may be another way, if you could get it to pad out the 1st column or more if needed, 2 perhaps, and the last 2 columns, 31 and 32, downwards to row 24 with blanks, every time the screen updates. It may run fast enough to black out the chars coming in and changing? Or would you see the flicker?

I haven't tested it, but I imagine that you would... the problem is unless you use a certain number of characters as "buffer only", which means it can't be full screen, you have to use characters currently on screen.

 

You'll always need to do three writes to VDP:

 

1 - Write out the screen table change

2 - Write out the pattern changes (ideally in a sequential block)

3 - Write out the color changes (ideally in a sequential block)

 

So for a given section of the screen, you may need 8 patterns (left/right), 32 patterns (up/down) or 39 patterns! (diagonal). So your worst case scenario is writing out 256 bytes of screen table data, and potentially up to 312 bytes of pattern data followed by 312 bytes of color data.

 

Also, this would only be for a single 8x32 section of the screen, you have to repeat this at least once more. You COULD do some symmetrical design around that, if the screen table patterns match up in each section, you'd just repeat it, so that saves a few cycles at least...

 

No matter what, though, I'm pretty sure that's enough VDP action to create a "rip" effect.

  • Like 1
Link to comment
Share on other sites

One way to achieve double buffering requires that no screen on your map shows more than 128 unique tiles at the same time, but the total number of tiles is limited by memory only. You use the hybrid bitmap mode where one pattern table covers the top and middle thirds of the screen. The button third has its own pattern table and can be used as status area.

 

To draw a screen you iterate through the relevant part of your map row-by-row, column-by-column while you build a list (in CPU RAM) mapping tiles to VDP patterns. As each new tile is discovered you allocate a new VDP pattern for it. The trick is that in even frames you allocate patterns in the range 0-127, and in odd frames you allocate patterns in the range 128-255. While doing this you build a name table directly in VDP memory, but in another location than the currently visible name table - this is your double buffer. Next step is to upload patterns and colors to VDP memory based on the list of tile mappings (the master tile patterns are stored in RAM or ROM). You can do this without disturbing the current view because you only update patterns that are not currently visible. Final step is to set VDP register 2 to display your double buffer.

 

The advanced version would remember the tile to pattern mapping list from the last frame (edit: or actually from two frames ago because of the double buffering) and only upload new patterns. It would also mark mappings that are no longer used so they can be recycled in the next frame. This could improve performance significantly.

Link to comment
Share on other sites

One way to achieve double buffering requires that no screen on your map shows more than 128 unique tiles at the same time, but the total number of tiles is limited by memory only. You use the hybrid bitmap mode where one pattern table covers the top and middle thirds of the screen. The button third has its own pattern table and can be used as status area.

 

To draw a screen you iterate through the relevant part of your map row-by-row, column-by-column while you build a list (in CPU RAM) mapping tiles to VDP patterns. As each new tile is discovered you allocate a new VDP pattern for it. The trick is that in even frames you allocate patterns in the range 0-127, and in odd frames you allocate patterns in the range 128-255. While doing this you build a name table directly in VDP memory, but in another location than the currently visible name table - this is your double buffer. Next step is to upload patterns and colors to VDP memory based on the list of tile mappings (the master tile patterns are stored in RAM or ROM). You can do this without disturbing the current view because you only update patterns that are not currently visible. Final step is to set VDP register 2 to display your double buffer.

 

The advanced version would remember the tile to pattern mapping list from the last frame (edit: or actually from two frames ago because of the double buffering) and only upload new patterns. It would also mark mappings that are no longer used so they can be recycled in the next frame. This could improve performance significantly.

 

That's not a bad idea! The only issue is the loss of half your unique tiles... not sure if I can afford that or not, but I do like the even/odd swapping idea.

 

Mind you, it's still expensive in terms of VDP access, and CPU is heavy too... for maximum speed, you'd have to buffer 12k in CPU as well for fast writing. I'd be interested to see how good the frame rate would be though.

Link to comment
Share on other sites

I don't believe you would have to buffer anything in CPU RAM. The max transfer to VDP RAM per frame is 512 bytes for the name table and 4 kb 2 kb for patterns and colors. If you transfer patterns and colors in an unrolled loop with 8 consecutive MOVB it should be reasonably fast. You need RAM for the tile to pattern map, but that's only 256 or 512 bytes depending on whether your tiles numbers are bytes or words.

Link to comment
Share on other sites

Dungeons of Asgard is very simple compared to the method described above: it is "half bitmap" mode with one pattern set for the entire screen. All the patterns are uploaded in advance and only the name table is updated, so this is easy to double buffer. Because I'm using 2x2 metatiles this severely limits the numbers of different metatiles that can be shown, so I have to use the same tiles for many different objects.

Link to comment
Share on other sites

Okay, I think I solved my problem... by using the hybrid mode that has a single pattern table for the upper 2/3 of the screen, plus some other elements, I think I can make it work with a minimum of character pattern/color substitutions. :)

 

The last lower 3rd will be tricky... I don't need the whole space for output, which means there, I'll need to track and upload graphics a bit, but at least it's just one section to maintain.

 

Prototype work continues...

  • Like 2
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...