How to get the current tileset

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

Re: How to get the current tileset

Post by D3thAdd3r »

On the fonts, are you trying to use separate tilesets but only store 1 font set? If so what worked for me was including the first tiles, then including the font, then the next tiles. The tricky part is that the font is at the end of the 1st tileset and at the beginning of the second. So you would meed to call SetFontTileIndex() with every set change, and also draw the level with those offsets in mind. Alter Ego or else Frog Feast does that IIRC. Of course you are still limited to 256-RAM_TILES_COUNT range at all times, so for the second tileset you would SetTileTable to the font.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: How to get the current tileset

Post by nicksen782 »

I'm still having trouble with this.

Code: Select all

while(1){
	SetTileTable(tileset1);
	ClearVram();
	u16 ind = 0;
	u8  newVal=0;
	for(ind=0; ind<(VRAM_TILES_H * VRAM_TILES_V); ind++){
		vram[ind] = RAM_TILES_COUNT+newVal++;
		WaitVsync(1);

	}
}
So, you set your tileset to tileset1 and you define your tileset1 and then immediately define your fontset. I just combined the areas (no change.) This doesn't work. You would think that the next value after sizeof(tileset1) would be the fontset but no, it is gibberish instead.

Could you provide a working code example?
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: How to get the current tileset

Post by Jubatian »

nicksen782 wrote: Fri Jun 15, 2018 10:14 pmAre you doing r20 = r20 + 21? The integer "21"? Seems that you get data into r21 with lds and then you don't use that register value? It is not used in SetTile either which is run directly at the end of SetFont.

Is this a bug? Should it be "add r20,r21" instead of "add r20,21"?
That's a typo, no bug there (it still refers to r21). I didn't touch those parts, I have no much knowledge on how they operate as of now. Mode 3 however (the video frame) doesn't have a split tileset capability (like Mode 74), the ROM tiles are in one contiguous block. I guess these routines would allow you to specify the location of a font (which index the font is starting at) within a tileset.

So to be sure, you need one tileset which includes your tiles and character images, and of course it must not exceed the index range reserved for ROM tiles.
nicksen782 wrote: Mon Jun 18, 2018 1:27 amSo, you set your tileset to tileset1 and you define your tileset1 and then immediately define your fontset. I just combined the areas (no change.) This doesn't work. You would think that the next value after sizeof(tileset1) would be the fontset but no, it is gibberish instead.
I guess what you are doing here is having the definitions after each other (still seperate definitions), expecting that the font would end up in the game binary after the tileset. This won't happen with some optimizations enabled, as since this definition is never explicitly accessed, the linker likely discards it. It isn't a good practice anyway (it is not mandatory for the linker to place these after each other), so better combine them. Hopefully then it would work.
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: How to get the current tileset

Post by D3thAdd3r »

I checked Frog Feast and just the numbers were "sandwiched" between the title tiles and gameplay tiles(as they were needed for both), and there are more than 256-RAM_TILES_COUNT tiles in the game. I included a .inc file, and in that file included the title, then numbers, then level tiles. Did not check further, but I may have stripped off the array elements from the numbers and made all 3 into 1 array...ultimately I used to manually build all graphics, but the suggestion to put them in 1 graphics file seems better. Then you know it is all sequential, and it is just a matter of fiddlig with offsets.
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: How to get the current tileset

Post by D3thAdd3r »

A little out there, but if you only need font in certain situations, you may not need them as tiles at all. In the past I have stored a 1bpp version of the font set, then loaded them as needed into ram tiles setting whatever desired BG and FG colors, or even copying the tile underneath first. It is not applicable most places, Columns, FF, and old MegaBomber code are examples. It is a bit annoyingly complex, but saves a few K sometimes.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: How to get the current tileset

Post by nicksen782 »

SetFontTilesIndex did not seem like the best idea anyway but it made enough sense I guess. For one of my tests I had actually combined the graphics and font into the same array though which is why I am still surprised that the font tiles did not appear.

How is SetFontTilesIndex supposed to work? Lets say I had 0 ram tiles. I should be able to address 255 tiles then, right? What about the font tiles? Let us say that 64 tiles are used in the font set. This is 255 + 64 tiles? There is no tile index 256 in vram since 255 is the highest number usable there.

If r20 and r21 are combined with an ADD (no carry) wouldn't the value just roll over? How could you get those higher tile values? I would understand if this were some sort of pointer but it is just the addition of an 8-bit value to another 8-bit value which combined can not go over 255.

Or, in my example case would it be 191 tiles max in the tileset plus the 64 in the font set (total 255, no ram tiles?) If that is the case, what is the point since the font tiles still go against the available 255?

D3thAdd3r: I considered putting font data into ram tiles but in my actual use case I will only have 8 ram tiles left and it is likely that any text will have more than 8 unique characters in it. I'm not sure that I know how to implement your suggestion but it is interesting if I could somehow "split" a ram tile. If I had 16 then I wouldn't have as much of a problem.
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: How to get the current tileset

Post by D3thAdd3r »

It is just an offset to the first character, so that the print functions know where to offset from. The print functions basically utilize SetTile and the offset. There is no extension past 256 entries so it could roll over depending on the character you try to print and the offset.

Code: Select all

SetFontTileIndex(67);
PrintChar(10, 10, 'Z');
would accomplish the same as:

Code: Select all

SetFontTileIndex(0);
SetTile(10, 10, 67+'Z');
All that asm does is allow to send the ASCII value of 'Z', and it will be converted to 'Z'+font_tile_index in this example, and passed to SetTile like anything else. There are no tricks past the 8 bit boundary anywhere in Mode 3.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: How to get the current tileset

Post by nicksen782 »

Okay.

Would it be 255-ramtiles-fonttiles to get the umber of tiles allowed for each tileset?

How could I do it with two tilesets and 1 fontset?
User avatar
Jubatian
Posts: 1564
Joined: Thu Oct 01, 2015 9:44 pm
Location: Hungary
Contact:

Re: How to get the current tileset

Post by Jubatian »

nicksen782 wrote: Mon Jun 18, 2018 8:08 pmOkay.

Would it be 255-ramtiles-fonttiles to get the umber of tiles allowed for each tileset?

How could I do it with two tilesets and 1 fontset?
If you arrange them (combined into one big chunk of data) sandwiching the font between the two tilesets, you should be able to do this. If the order of the data is tileset1-fontset-tileset2, then to access tileset1, you need to set up your tile data (SetTileTable I think) to tileset1, and tileset1's tiles will be below the font tiles. For tileset2, you have to set the tile data to the address where fontset begins (for example by adding 64 * count_of_tiles_in_tileset1 to tileset1 for SetTileTable), and the font tiles will be below tileset2's tiles. So the font tiles end up using different VRAM indices in the two setups, but that's the only way how this can be done.
User avatar
D3thAdd3r
Posts: 3222
Joined: Wed Apr 29, 2009 10:00 am
Location: Minneapolis, United States

Re: How to get the current tileset

Post by D3thAdd3r »

Jubatian wrote: Mon Jun 18, 2018 8:54 pm If the order of the data is tileset1-fontset-tileset2, then to access tileset1, you need to set up your tile data (SetTileTable I think) to tileset1, and tileset1's tiles will be below the font tiles. For tileset2, you have to set the tile data to the address where fontset begins (for example by adding 64 * count_of_tiles_in_tileset1 to tileset1 for SetTileTable), and the font tiles will be below tileset2's tiles.
Exactly right.

Code: Select all

//untested
SetTileTable(TileTable1);
SetFontTileIndex(NUM_TILES_IN_SET1);
Print(10, 10, PSTR("UZEBOX"));//print with the first tile table

SetTileTable(TileTable1 + ((NUM_TILES_IN_SET1+NUM_FONT_TILES) * 64));
SetFontTileIndex(0);
Print(10, 10, PSTR("UZEBOX"));//print with the second tile table
Ultimately you just have to remember that SetTileTable is just a pointer to somewhere in rom, and tiles are just offsets that are 64 bytes multiplied by the tile index. Fonts are tiles just like everything else, just that for the built in printing functions to work with any tileset the user might make, it has to know which tiles is the first ASCII tile, which is ' ' / space I believe. I have messed with it in the past, and at least a couple times ended up making custom printing functions. Frequently I do not want to store an entire ASCII map when I will only use maybe half the characters..for an RPG or something that is likely different.
Post Reply