It is currently Wed Jun 26, 2019 10:00 pm

All times are UTC - 7 hours





Post new topic Reply to topic  [ 7 posts ] 
Author Message
PostPosted: Sun Aug 21, 2016 3:31 pm 
Offline

Joined: Fri Mar 01, 2013 4:46 am
Posts: 317
Working on a new project from the ground up, coming along nicely, but i'm at a point where I have to alter the attribute table when certain sections of the bg need to be changed to a specific palette.

I already know how to set a 16x16 grid to whichever palette Id like, the problem I'm having, is how do I set the bit within the attribute table?

What I have going on, is depending on the specific position, i'll load up a table that contains values meant as bits. For instance, i'll load up a byte as the value (30). What I need to do from here, is use that value 30 as (..21 ....) and alter the specific address within the attribute table.

I know I cant simply take that 30 and store it to the attribute address, that's no good.

I tried doing as much on my own from memory as I could, but bits have reared its ugly self again, heh. Thanks for reading, hope I can get this situated fast. :-D


Top
 Profile  
 
PostPosted: Sun Aug 21, 2016 3:46 pm 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11371
Location: Rio de Janeiro - Brazil
The smallest data unit that the CPU can manipulate is a byte, meaning there's no way to directly load or store less than 8 bits at once. For this reason, you need to use some bitwise operation tricks to manipulate only the necessary bits inside a byte.

Typically, when you need to change only a few bits in a byte, you first clear the bits with an AND operation and then you set the new values using an OR operation. Say I have loaded the following attribute byte from an attribute table: %10110011; This byte contains 4 palette indices, controlling the colors of a 32x32-pixel area. If I want to change only the upper left 16x16-pixel corner, I have to clear the bits for that area by ANDing the byte with %11111100, which will result in %10110000. Now I can simply ORA the new palette index, say, %00000010, and get %10110010, which I can write back to the attribute tables.

The problem with attribute tables is that reading from VRAM, modifying the data and writing it back is very inefficient. If you have to do a lot of attribute manipulation on on-screen areas, you might want to consider keeping a copy of the attribute tables in RAM, to avoid the trouble of doing it all during vblank.


Top
 Profile  
 
PostPosted: Mon Aug 22, 2016 2:54 am 
Offline

Joined: Fri Mar 01, 2013 4:46 am
Posts: 317
Wow thank for you being so in depth. Your example is perfect for my situation. Free space in ram is no issue for me with this small project I'm doing, so I can do as you suggested and have the ones I need modified stored in ram, modified when needed, then written to the attribute table.

I'll get to it tonight, many thanks yet again! I look forward to sharing what i've done when it's completed. :-)


Top
 Profile  
 
PostPosted: Mon Aug 22, 2016 9:31 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11371
Location: Rio de Janeiro - Brazil
Glad I could help. There are a couple of things I didn't address in my previous post, but I assume you have an idea of how to handle them. For example, how you need to pick 1 out of 4 clear masks (℅11111100, ℅11110011, ℅11001111 or ℅00111111) depending on the corner you need to change. And you also need the new bits to be in the correct position for ORing, so you might need to shift the new palette index into position, or use a lookup table. Personally, I prefer to store the palette index repeated 4 times across a byte in each metatile definition, so I can just clear the unwanted copies before ORing.


Top
 Profile  
 
PostPosted: Tue Aug 23, 2016 5:26 am 
Offline

Joined: Fri Mar 01, 2013 4:46 am
Posts: 317
Using the OR function did the trick. :-) Before ppu rendering comes on, I load up the last 40 bytes of my attribute values to ram.then i turn ppu rendering on. I have a dedicated table which includes specific bits to be set to whichever attribute needs to be altered. So I have the byte loaded, the I OR it to the ram table, then I write that value to the actual attribute. It's 100% how I wanted it to work. :-) Thanks again!


Top
 Profile  
 
PostPosted: Sat Sep 03, 2016 6:13 am 
Offline
User avatar

Joined: Wed Aug 03, 2005 3:15 pm
Posts: 399
tokumaru wrote:
Personally, I prefer to store the palette index repeated 4 times across a byte in each metatile definition, so I can just clear the unwanted copies before ORing.

That's pretty nifty! Does this mean you define your palettes in the 16x16 metatiles as opposed to 32x32 metatiles?


Top
 Profile  
 
PostPosted: Sat Sep 03, 2016 8:51 am 
Offline
User avatar

Joined: Sat Feb 12, 2005 9:43 pm
Posts: 11371
Location: Rio de Janeiro - Brazil
Roth wrote:
That's pretty nifty! Does this mean you define your palettes in the 16x16 metatiles as opposed to 32x32 metatiles?

Yup. Every now and then I feel tempted to do it in the 32x32s because in theory I could just transfer raw attribute bytes to the attribute tables, but then I remember the drawbacks:

1- Since I usually do horizontal + vertical scrolling, 32x32 blocks are only aligned to the attribute tables every other vertical screen, since each name table is 30 tiles tall, or 7.5 32x32 blocks, so I'd still have to manipulate individual bits. I could solve this easily by ignoring the bottom half of the last row of blocks instead of letting them spill into the next NT/AT, but that would make designing levels a little awkward, as I'd have to worry about blocks looking different depending on where they're used. Also, I'd have to account for the skipped parts when doing background collisions and such, which sounds like an unnecessary complications.

2- My designs often allow the destruction/collection of 16x16 blocks by replacing them with actual content rather than just blank tiles every time, meaning I might have to replace the palette index of a 16x16 area anyway. Sonic games on the Master System, which use 32x32 blocks all the way, solve this by having blocks with all combinations of 2x2 rings, for example (destruction only happen at the 32x32 level, though), but that's wasteful and not versatile at all.


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

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 5 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