How to get the current tileset

Topics related to the API, programming discussions & questions, coding tips, bugs, etc. should go here.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

How to get the current tileset

Post by nicksen782 »

Looking in videoMode3core.s I see the label for "SetTileTable". It appears to save the values in r24 and r25 into tile_table_lo and tile_table_hi.

I want this value accessible in C because I need to know what the current tileset is. I tried this:

Code: Select all

extern unsigned char * tile_table_lo;
extern unsigned char * tile_table_hi;
But, this did not work. These are the errors that I got:

Code: Select all

undefined reference to `tile_table_lo'
undefined reference to `tile_table_hi'
I based my attempt on videoMode3.c which had this: extern unsigned char *tile_table_lo; It did not have one for tile_table_hi though.

I would like to read the bytes for a tile so that I can compare each pixel byte against another tile which is a ram tile.

I could hard-code my tileset address in there but that doesn't sound like the best idea. I would rather not have to store whatever the tileset addresses are since I assume they could be accessed otherwise.

Any help?
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 »

You only need to declare lo the pointer in C. Since a pointer is 16 bit, the upper half is lo+1, which happens to be where hi is. I think you should be able to directly compare the value of that C pointer to the tileset then..a few drinks take that with a grain of salt.
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 »

To explain a bit better and if I understand your use case, does something like this work for what you are trying to do:

Code: Select all

extern u8 *tile_table_lo;
void main(){
	InitMusicPlayer(patches);
	SetTileTable(gameTiles1);
	SetSpritesTileBank(0,gameSprites);

	if(tile_table_lo == gameTiles1)
	//...
	else if(tile_table_lo == gameTiles2)
//....
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 »

Thanks, Lee. However, I got the same error.

The value for the tileset address is stored somewhere. Could I access it via ASM? I know that GetTile is ASM and returns an id.
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 »

Likely it is not made global in the assembly files. If you want to access the variable directly, add a ".global tile_table_lo" to the assembly file.

It seems like you wanted to create a customized sprite engine, or some other sprite-like solution, guess the workflow would be copying off into an allocated user RAM tile (using a customized allocator), and drawing over it. What would be this exactly? In Mode74 like modes I use a sprite engine capable to blit sprite tiles and pixels, but likely the allocator itself could be exposed, so an interface could be provided which gives you a RAM tile at a given location on which you can draw. Mode 3 is different, I am just asking whether such an interface would be about what you needed here.

(I won't likely add it to Mode 3, however to Mode 74, 748 and 52 I will likely do it then, so if anyone had a similar need, it could be used)
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 »

Likely it is not made global in the assembly files. If you want to access the variable directly, add a ".global tile_table_lo" to the assembly file.
Yes, I started learning assembly and I actually thought that to be the case. But, I didn't want to make a kernel modification without being more certain. Is there any reason why the value is not already global? Could an ASM function be created that would return the current tileset?

So, yes, it is a sort of pseudo sprite engine. I have the ability to alternate frames and do xflipping. All this is done in C at the moment. The source tile data is contained in a ram tile. In my case I wanted to do blitting of that ram tile against background tiles similar to how it works with sprites. At this point, I'm just doing that as the "sprites" do not change position. My method only costs ram tiles for the source, not the blit since I modify the source in ram after I load the data into it. Therefore, you can do the blit on a ram tile only once per load and not every frame.

I hard-coded in the tileset name but I was hoping to just be able to determine what the current tileset was instead.

I have two UCC projects in the queue. One is a FLASH only game, and the other is a more complex SPIRAM/SDCARD.
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 had tried it on Mode 15 but I must have added that as I don't see it in Mode 3. I think the best option is to add:

Code: Select all

.global tile_table_lo
in "videoMode3core.s", since I see no disadvantage to doing so.

You could write an asm function if you wanted, or even you could probably do it in inline asm(I really never played much with the semantics of that though). The function would be something like this:

Code: Select all

.section .text.GetTileTable
GetTileTable:
	lds r24, tile_table_lo
	lds r25, tile_table_hi
	ret
Not tested but it should be right, let me know if if neither of those works for you. Any opinions? Personally I say lets make tile_table_lo visible, since there are valid situations where this would make the code more graceful instead of storing a second copy.
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 11, 2018 3:23 pmMy method only costs ram tiles for the source, not the blit since I modify the source in ram after I load the data into it. Therefore, you can do the blit on a ram tile only once per load and not every frame.
For now I think just go with the global, or a modification like Lee proposed below. It is a bit more complex use case, yet something which has similarities with the sprite engine's RAM tile allocator, so a proper solution would be defining new interface boundaries so the appropriate parts of that could be reused, such as the ROM => RAM tile copy.

Mode 3 is relatively simple in this regard as you can only use a single tileset on one screen. In my video mode designs however you can have more, and in Mode 748 and Mode 52, it is already made completely transparent to the sprite engine (so no matter whether the source is an user RAM tile or some ROM tileset, it works, the correct source is copied, sprites can blit right on anything). Mode 3 also gets a bit more complex if you throw user RAM tiles in the mix: such an use case (to have a new RAM tile prepared with the content of the original tile underneath) just isn't something trivial to serve.
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 »

This question is related a bit.

;***********************************
; SET FONT TILE
; C-callable
; r24=X pos (8 bit)
; r22=Y pos (8 bit)
; r20=Font tile No (8 bit)
;************************************
.section .text.SetFont
SetFont:
lds r21,font_tile_index
add r20,21
rjmp SetTile

That is the ASM for SetFont found in videoMode3core.s on line 1532.

Are 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"?

Also, I am considering two tile sets for the game and a separate font set for the for the fonts. Could you provide an example of how I could use the fonts independent of which tile set I have active at the moment?
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 »

Don't have the code in front of me, but I would say a typo that works as intended. Since it works, and to work it would have to use the value in register 21, I guess you can specify 21 and the assembler assumes you meant r21 as you cannot add an immediate value with add(that I know you can only do adiw to add an immediate to a word). Jubatian or Cunning would know for sure on that, but the arbitrary integer 21 is definitely not what is intended there.
Post Reply