It is currently Thu Oct 19, 2017 7:29 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 8 posts ] 
Author Message
PostPosted: Fri Aug 05, 2016 1:38 pm 
Offline

Joined: Thu Feb 13, 2014 12:37 am
Posts: 5
I'm struggling to understand a concept. I think I'd be able to code it, but I can't get my head around the idea... I want to use 2 bits to represent each tile of a static screen - there are 4 possible tile "types", 0-3. Each byte represents 4 tiles.

Column and row in x and y:

Code:
txa
lsr
lsr
sta byte

txa
and #3
sta bit

tya
asl
adc byte
tax
lda map_data,x
sta byte

ldx bit
lda bit_table,x
and byte

...

bit_table:
.db $C0,$30,$0C,$03



That gets me as far as being able to detect collisions (0 is passable, everything else is not), but how would I go about extracting the bits and ending up with a tile type from 0-3?

eg: $C0 = tiles 3, 0, 0, 0

Do I have to use a table to shift a varying number of places? That sounds like it might be slow...

Sorry if this doesn't make much sense, I'm tired. Any help would be much appreciated :)


Top
 Profile  
 
PostPosted: Fri Aug 05, 2016 1:58 pm 
Offline
User avatar

Joined: Sun May 27, 2012 8:43 pm
Posts: 1305
There are two cheap and quick ways I can think of making this a little easier, if you choose to stick with this tile-property-packing method:

1) Compare against one of four sets of masks, depending on (tile_x % 4).
SOLID_0 might be %00000001, for when the column mod 4 is zero.
SOLID_1 might be %00000100, for when the column mod 4 is one.

So on and so forth. The logic would be choosing which property mask table to check against, but this way you avoid shifts.

2) Using ROR and ROL, you don't have to rotate more than five times in the worst case. You can rotate the lower two bits where you need and mask with %00000011. For the higher ones, you can rotate left instead of shifting four or six times.

If you can, though, you may benefit from organizing your nametable such that certain tile types are above a certain index value. In my Genesis game, tiles in the map nametable lower than $40 are non-solid. This makes collision checks cheaper.


Top
 Profile  
 
PostPosted: Fri Aug 05, 2016 2:56 pm 
Offline
User avatar

Joined: Fri May 08, 2015 7:17 pm
Posts: 1772
Location: DIGDUG
Is there some special reason you are limiting yourself to 4 types of tiles? Trying to cram as much into an NROM space as possible?

Personally... I would just code with the assumption you have 256 possible tiles. Because, if at some point you wanted to expand this code, you would have to rewrite from scratch. Plus, it would be more straightforward, since you won't have to do bit-shifts / bit-masking.

Just my 2 cents.

_________________
nesdoug.com -- blog/tutorial on programming for the NES


Top
 Profile  
 
PostPosted: Fri Aug 05, 2016 7:53 pm 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 284
Brute force approach:

Code:
sta temp

lda #0
asl temp
rol a
asl temp
rol a
sta out1

lda #0
asl temp
rol a
asl temp
rol a
sta out2

lda #0
asl temp
rol a
asl temp
rol a
sta out3

lda #0
asl temp
rol a
asl temp
rol a
sta out4


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 1:18 am 
Offline

Joined: Thu Feb 13, 2014 12:37 am
Posts: 5
Thank you for the suggestions, the brute force approach might be the way forward.

dougeff wrote:
Is there some special reason you are limiting yourself to 4 types of tiles? Trying to cram as much into an NROM space as possible?


Yes, exactly this, I'd like to fit as many screens in as possible. Perhaps some other form of compression would be better?


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 2:37 am 
Offline

Joined: Thu Aug 20, 2015 3:09 am
Posts: 284
chowder wrote:
Yes, exactly this, I'd like to fit as many screens in as possible. Perhaps some other form of compression would be better?

It would help if you said what kind of map you're trying to store. Different forms of compression work best on different kinds of maps. Some common options:

Large metatiles

The method used in the Mega Drive/Genesis Sonic the Hedgehog games. A table of 128x128 pixel blocks is stored, with the map itself being a grid of these tiles, allowing for very large maps at the cost of very coarse layout. On the NES, it may be best to nest the levels - so you have a table of 128x128 metatiles, built out of 64x64 metatiles, built out of 32x32 metatiles, built out of 16x16 metatiles, built out of 8x8 hardware tiles. Unpacking is tedious but straightforward, and can be done on a tile-by-tile basis, meaning you don't need to have a large RAM buffer for collision detection.

Structures

The method used in Super Mario Brothers 3, Metroid and others. Maps are stored as a list of [object type, X, Y] sets. These are essentially treated as drawing instructions, to be rendered to an in-RAM buffer. Super Mario Brothers 3 unpacks whole levels at a time, Metroid unpacks one screen at a time. Works best if your level design has many repeated elements, as both Mario and Metroid demonstrate. Possibly the most ROM-efficient, but quite RAM-hungry - the only game I know of that manages to do it without WRAM is the original Super Mario Brothers, which has very limited layouts and no back-scrolling.

RLE

I can't think of any specific examples right now. Map data is stored as [block type, count] pairs. Very simple in principle, but many different encodings are possible. One good extension is a transition table; instead of runs simply repeating the last block, it is looked up in a table to give the block most likely to come next. Similar to structures, it has high RAM usage, though you may be able to choose the encoding and order of storage so you can unpack it incrementally. Also has the advantage of being able to store any layout, with the downside of high ROM use for complex ones.

....that kind of turned into an essay. Hopefully it's of some use to you.


Top
 Profile  
 
PostPosted: Sat Aug 06, 2016 7:27 am 
Offline

Joined: Thu Feb 13, 2014 12:37 am
Posts: 5
Rahsennor wrote:
....that kind of turned into an essay. Hopefully it's of some use to you.


Very useful, thank you.

I don't think I'll be able to use any of those techniques during the game, as the maps are "randomly" generated, but I'll definitely make use of them for things like the title screen/cutscenes.


Top
 Profile  
 
PostPosted: Sun Aug 07, 2016 8:35 pm 
Offline
User avatar

Joined: Sat Jul 12, 2014 3:04 pm
Posts: 936
mikejmoffitt wrote:
T
2) Using ROR and ROL, you don't have to rotate more than five times in the worst case.

Four.
Code:
000000xx: 0
0000xx00: 2 right
00xx0000: 4 right
xx000000: 3 left
But, f you're accessing all four, then you might as well do the "extract each bitpair" approach mentioned above.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 8 posts ] 

All times are UTC - 7 hours


Who is online

Users browsing this forum: zeroone and 4 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