It is currently Sun Dec 17, 2017 12:48 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2
Author Message
PostPosted: Thu Dec 07, 2017 1:37 am 
Offline
User avatar

Joined: Sun Jan 22, 2012 12:03 pm
Posts: 5899
Location: Canada
It has a few names, but the term I'm used to for this type of data structure is "ring buffer".


Top
 Profile  
 
PostPosted: Thu Dec 07, 2017 1:59 am 
Offline
User avatar

Joined: Sat Sep 07, 2013 2:59 pm
Posts: 1517
dougeff wrote:
Your game (DRW) has auto-scrolling. So, load if scroll multiple of 8 makes sense here. Any game where scroll can shift 2 pixels in 1 frame might miss a load.

In this case, you of course have to do a slightly different check.
For example
if ((NewScollingPosition & 7) < (OldScrollingPosition & 7))
or something like that.

na_th_an wrote:
As a hint for future games, you can avoid having to shift the entire array if you use a circular array with a moving, "virtual" first index.

Yeah, I thought about that. But having to calculate the index offset for every time the x position of any character is checked (which is quite a bit for various collision checks and the x position is an integer instead of just a byte) would have been more problematic and would have wasted more ROM space (and therefore more CPU time) than simply shifiting a 34 byte array every eight frames. (I even did this shift in Assembly for maximum speed.)

_________________
Available now: My game "City Trouble".
Website: https://megacatstudios.com/products/city-trouble
Trailer: https://youtu.be/IYXpP59qSxA
Gameplay: https://youtu.be/Eee0yurkIW4
German Retro Gamer article: http://i67.tinypic.com/345o108.jpg


Top
 Profile  
 
PostPosted: Thu Dec 07, 2017 9:48 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 363
rainwarrior wrote:
It has a few names, but the term I'm used to for this type of data structure is "ring buffer".


Thanks for the info. I just translated literrally from Spanish :)

DRW wrote:
Yeah, I thought about that. But having to calculate the index offset for every time the x position of any character is checked (which is quite a bit for various collision checks and the x position is an integer instead of just a byte) would have been more problematic and would have wasted more ROM space (and therefore more CPU time) than simply shifiting a 34 byte array every eight frames. (I even did this shift in Assembly for maximum speed.)


Yeah, I understand. It really depends on the size of your buffer.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Thu Dec 07, 2017 1:39 pm 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
The circular buffer concept is really quite easy to work with, especially in projects that only scroll horizontally or vertically. For me, the trick was to dedicate 2 pages of RAM to house a 2-screen rolling window of collision data (I store it in $600-$7FF). The data is formatted so that every 16 bytes represents a column of 16x16 pixel metatiles in the window. No matter what direction the camera is scrolling, determining where to "dump" newly revealed columns of tiles is extremely easy. You just take the in-level X coordinate of the camera boundary (the left boundary for scrolling left, right for scrolling right), AND it with $01F0, and add $0600. So if the camera scrolls so that the right boundary is at pixel $1BC1, which reveals a new column of metatiles, that column of metatiles would be dumped at (($1BC1 AND $01F0) + $0600) = $07C0.

Collision detection is just a step beyond this logic. After calculating the address of the column of tiles with the X coordinate, you divide the Y coordinate by 16 and use this as and use this as an index to that starting address.

Code:
;XHigh/XLow/YLow represent a set of in-game X/Y coordinates. X is 16-bit, Y is 8-bit due to no vertical scrolling.

lda XHigh
and #$01
clc
adc #$06
sta TempAddH

lda XLow
and #$F0
sta TempAddL

lda YLow
lsr a
lsr a
lsr a
lsr a
tay

lda (TempAddL),y   ;Your tile type


Top
 Profile  
 
PostPosted: Fri Dec 08, 2017 9:12 am 
Offline

Joined: Mon May 27, 2013 9:40 am
Posts: 363
Exactly what I do. For 1 way scrollers, I usually have a 16x16 buffer (specially vertical games), and a two-screener for 2-way scrollers (left-right, mostly). Calculating where to write to the buffer is trival and collision detection is really easy this way.

_________________
http://www.mojontwins.com


Top
 Profile  
 
PostPosted: Fri Dec 08, 2017 11:47 am 
Offline
User avatar

Joined: Sun Jun 05, 2005 2:04 pm
Posts: 2143
Location: Minneapolis, Minnesota, United States
The main thing I like about it is that it just works by itself without a lot of "special case" intervention. The only issue I ran into was if I sized my rolling window to be exactly 2 screens, I saw bad things happen when changing directions. Since both the left and right boundary of the window are exactly 2 screens apart, the address of where to dump new columns in the circular buffer is exactly the same for both directions. If the left bound is at pixel $1BC2, the right bound is at pixel $1DC2, which both evaluate to start at $7C0 in the circular buffer. Long story short, I would run into issues where it would skip updating values in the buffer that needed to change, if the scrolling direction changed. You could easily end up with corrupt collision data.

The easiest solution for me was to shrink my rolling window so that it's a little smaller than the width of the buffer. I just shrunk it down to like 480 pixels instead of 512.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page Previous  1, 2

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 11 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group