User Ram Tiles

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
User avatar
D3thAdd3r
Posts: 3289
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

User Ram Tiles

Post by D3thAdd3r »

Alec I noticed your demo in another thread and it is pretty impressive. It must be a pretty fast solution as well since you are running a full 28 tiles tall screen and potentially have up to 21 ram tiles covered by foreground without issue. I am curious as to what kernel level solution you may have on your hands there :)
mario_foreground.jpg
mario_foreground.jpg (26.27 KiB) Viewed 5828 times
User avatar
uze6666
Site Admin
Posts: 4812
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: User Ram Tiles

Post by uze6666 »

It's quite simple in fact. The blit rule becomes: just write sprite pixels if the underneath pixel=background color. In the blitter just replace this:

Code: Select all

x_loop:
	lpm r18,Z		;px=pgm_read_byte(src);
	cpse r18,r19	;if(px!=TRANSLUCENT_COLOR)
	st X,r18		;*dest=px;
	...
	brne x_loop
by this:

Code: Select all

x_loop:
	ld r18,X		;dest pixel
	cpi r18,0x98	;is it background color
	brne noblit
	lpm r18,Z		;px=pgm_read_byte(src);
	cpse r18,r19	;if(px!=TRANSLUCENT_COLOR)
	st X,r18		;*dest=px;
noblit:
	...
	brne x_loop
My example here is obviously global and takes a couple more cycles. The real thing would use a flag in the sprite structure to say which of the mode and blit logic to use. The background color would also be dynamically changeable. A side effect of this logic is that sprite layering is inverted if priority is background. Just something to consider. In other words, if on a screen you have sprites with both priorities, you must have those with foreground priority put in lower sprite indexes.

That's similar to the way the NES hardware did it, except the flasg is in the sprite instead of the background tile (IIRC). For about 112 bytes it could be possible to have a priority attribute bit table for the background. Combined with the sprites priority bit, all kind of neat tricks could be possible without much effort.
User avatar
D3thAdd3r
Posts: 3289
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: User Ram Tiles

Post by D3thAdd3r »

Very efficient and elegant I think you should make it official. I wonder if there is some generic logic that could weed out entire tiles past some index as totally foreground. It seems it still requires ram tile use and blitting for things that are totally opaque and always in front of sprites for instance. Maybe something similar to specifying some tiles that are foreground tiles, and could be left unused if needed. That is if you think such functionality should be standard kernel stuff, though I don't think it would be that uncommon if it was official.
User avatar
uze6666
Site Admin
Posts: 4812
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: User Ram Tiles

Post by uze6666 »

D3thAdd3r wrote:Very efficient and elegant I think you should make it official. I wonder if there is some generic logic that could weed out entire tiles past some index as totally foreground. It seems it still requires ram tile use and blitting for things that are totally opaque and always in front of sprites for instance. Maybe something similar to specifying some tiles that are foreground tiles, and could be left unused if needed. That is if you think such functionality should be standard kernel stuff, though I don't think it would be that uncommon if it was official.
Ah yes, ranges of tiles indexes, neat idea. Though I'm wondering about the use of totally opaque tiles since the goal of sprites is to see them no? But I'm not against it since they could be weeded out pretty quickly in the ProcessSprite function. Tile ranges could (and probably should) be used to indicate background tiles to be treated as transparent. Say indexes 0-10 in your tileset are to be treated transparent. Using the priority bit on the sprite could then allow 2 sprites to both behind and in front of the same background tile at the same time. Think the fences in SMW:
smw.jpg
smw.jpg (32.35 KiB) Viewed 5764 times
Btw, I was thinking that partial occlusion visual effect could make AlterEgo (or its successor) even more awesome. :)
User avatar
D3thAdd3r
Posts: 3289
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: User Ram Tiles

Post by D3thAdd3r »

uze6666 wrote:Though I'm wondering about the use of totally opaque tiles since the goal of sprites is to see them no?
Mostly that's the case, but so much of the time foreground shapes bigger than 1 tile will have fully opaque parts to it as well. It would be possible to not even setup a sprite that wasn't actually going to be displayed. I was never able to find any efficient method to determine when this is the case in normal game logic. Essentially you have to break down screen coordinates to tiles, then check against vram indices, which is sneakingly suspicious to something that already has to be done. I think it's a detail that most wouldn't want to deal with and worth at least a #if option?
uze6666 wrote: Think the fences in SMW
I remember the first time I ever saw that and I was blown away punching a turtle in the face through a fence! I don't think it's any mistake the first castle of the flagship pack in game heavily showed graphics layer and mode 7 tilting platform boss. I'd say besides colors, foreground/layers and parallax were what made the SNES beyond NES. I think we can rival the SNES in the right situations if things are time efficient enough for people to actually use.
Attachments
full_occlude.jpg
full_occlude.jpg (156.22 KiB) Viewed 5732 times
User avatar
uze6666
Site Admin
Posts: 4812
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: User Ram Tiles

Post by uze6666 »

You've got enough examples and good point to convince me! :) So I think I'll add that too. So the proposed way with indices>x sounds good?
User avatar
D3thAdd3r
Posts: 3289
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: User Ram Tiles

Post by D3thAdd3r »

uze6666 wrote: So the proposed way with indices>x sounds good?
I think that's the best essential direction you can get though sprite flags could have good use . AE used a 1 bit per tile index map, but indices>x handled in ProcessSprites() is better. The 1 bpp for all tiles on screen combined with sprite flags could be really powerful but I'd have to think on it to even have something to say about it. AE had simple backgrounds of course and such things would work great for any game like that with the code you already have there. I used an entire 1 byte per tile(flash) in Jump n' Bump(rabbits demo somewhere in my rants thread) but I don't recommend that at all, though it was near "unlimited" backgrounds and you got to keep all tile indices for normal tiles. Scales terribly with more than 1 game level and forget scrolling.

Mega Bomber igloos you can walk under with non-solid color ground I tried a bunch of stuff, essentially nothing I tried was better than making a tile that looks like a composite of foreground+floor and layering over higher indice sprites than players with only the pixels that should be foreground to complete the illusion. It wouldn't be that bad a solution for mode 13 where you can have a good number of tile aligned sprites and nothing would need to be added to the kernel beyond what's posted. I had to use game logic code to put sprites there only when necessary(until I just accepted a hacked kernel), but perhaps there is a better clever way now with user ram tiles and basic FG functionality already in the code you posted. All the posted screenshots however require a more complex rule than global background....or do they.

If you want the fences with any sort of background behind it, I think you would need an entire table of 1bpp masks for the graphics(only tile that are foreground though), where indices>x would only blit sprite pixels where the bit is not set in the mask. Problem might be that X,Y, and Z already look used in the current BlitSprite version, so I thought a fast version of masking becomes impossible then? It would be simple to add .rept 64 overdraw right in ProcessSprites after the standard blit though and the whole thing just works. It would cost additional 2 byte of ram for a pointer to the 1bpp foreground mask table and a little code space for the unrolled overdraw and might average ~6*(64/2)=~192 cycles per ram tile that was half density overdrawn by FG. 8 bytes flash per foreground tile mask. ProcessSprites() is still not too scary of a function even with extra conditionals added for that IMO.

What do you think on rule based masking, is it worth it going past global BG color, and then is there any possible way faster than overdraw? If you liked the idea, I think it's not bad to implement and not too much resources either at least. Beats the hell out of doing it by looping through ram tiles in C code after the fact :lol:
User avatar
uze6666
Site Admin
Posts: 4812
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: User Ram Tiles

Post by uze6666 »

What do you think on rule based masking, is it worth it going past global BG color, and then is there any possible way faster than overdraw? If you liked the idea, I think it's not bad to implement and not too much resources either at least. Beats the hell out of doing it by looping through ram tiles in C code after the fact :lol:
There's Y that is still free in the current loop. But it will slowdown for sure specially if working with bit masks. The idea is very good, though considering the added complexity, I'd keep that one for last. The overdraw would not work if sprites can/must also be blitted over the tile.

Another option I though was to use an extra flash byte per tile to store it's background color. That byte would probably be in a separate attribute table. A globally index, say 0xfe, would mean the tile is completely opaque and would indicate to skip the blitter. Downside is that it wastes a couple flash bytes since most tile won't have transparency. But it would allow on the same screen to have various bg color: blue for sky/water, green for soil/grass,etc.

A complementary option is to have multiple blitter inner loops tuned for transparency or not. More performance but more complex to code and maintain.
User avatar
D3thAdd3r
Posts: 3289
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: User Ram Tiles

Post by D3thAdd3r »

uze6666 wrote:A complementary option is to have multiple blitter inner loops tuned for transparency or not.
It sounds very difficult but it could be the best option.

A lot depends if we are trying to find a way to mimic that SMW image. Best I can figure, the global colors fails the "fence test" because you cannot have a background to even rival SMB1 behind it. Outside of that, the global color concept is a clear winner in any of the various possible configurations no doubt.
uze6666 wrote: The overdraw would not work if sprites can/must also be blitted over the tile.
I might misunderstand your meaning. If it immediately overdrew after every BlitSprite() I think it should still work, since the sprite is blit on a tile, then FG over that...and if another sprite overlaps that ram tile later, it is drawn over the FG...but the parts of the FG that should be over still end up drawn over that sprite too in the end..Now if you have lots of sprites overlapping a ram tile then the repeated overdraw becomes expensive. Either way, I think still all sprite pixels that should be visible are, and in the end the foreground still comes out on top.

vram tiles
step1.jpg
step1.jpg (3.05 KiB) Viewed 5643 times
BlitSprite();
step2.jpg
step2.jpg (3.39 KiB) Viewed 5653 times
BlitFG();
step3.jpg
step3.jpg (3.4 KiB) Viewed 5646 times
BlitSprite();
step4.jpg
step4.jpg (3.66 KiB) Viewed 5648 times
BlitFG();
step5.jpg
step5.jpg (3.61 KiB) Viewed 5651 times
BlitSprite();//do not BlitFG() since the sprite flags specify not to
step6.jpg
step6.jpg (3.81 KiB) Viewed 5645 times
You would still need to take care to sort the sprites so that sprites over the FG always come after all the sprites under the FG or it would get wrecked.
User avatar
uze6666
Site Admin
Posts: 4812
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: User Ram Tiles

Post by uze6666 »

You would still need to take care to sort the sprites so that sprites over the FG always come after all the sprites under the FG or it would get wrecked.
Yes, thatès what I meant. This requires more overhead to sort sprites and multiples pass render. It's a cool concept but perhaps overkill when we are trying to maximize the number of simultaneous ramtiles blitting.
Post Reply