get tile id - tile collision scripts

I know that tiles have ids which can be used to change one tile to another, but is it possible in a tile script to get the id of the tile?

For example, in the tile collision script if tile is #15 do one thing, but if tile is # 27 do another thing?

I have a script where I want to set a variable when you collide with a tile, but I want the value of the variable to depend on which tile you collided with.
 

jorotroid

Member
Taking a glance at the code, there seems to me that value is stored in temp when you go into the tile code. Give that a try.
 
No luck so far.

Trying to expand the NPC tile code, here is what I have so far:

Code:
;;; NPC TILE
    ; LDA gamepad
    ; AND #%00000010
    ; BEQ +
    ; LDA textBoxFlag
    ; BNE +
    ; LDA #$00
    ; STA stringTemp
    ; LDA #$01
    ; STA textBoxFlag

    ;; Set the flag that we are colliding with an NPC
    CPX player1_object
    BNE +
    LDA npc_collision
    ORA #%00000010
    STA npc_collision
    JMP npcTileCheckOne
    
+:
    JMP skipNpcTile

npcTileCheckOne:
;; Tiles that use first text entry
    LDA temp
    CMP #$60
    BEQ npcTileSetTextOne
    
    JMP npcTileCheckTwo
    
npcTileSetTextOne:
    LDA #$00
    STA textVar
    JMP skipNpcTile

npcTileCheckTwo:
;; Tiles that use second text entry
    LDA temp
    CMP #$62
    BEQ npcTileSetTextTwo
    
    JMP npcTileCheckThree
    
npcTileSetTextTwo:
    LDA #$01
    STA textVar
    JMP skipNpcTile
    
npcTileCheckThree:
npcTileSetTextThree:
npcTileCheckFour:
npcTileSetTextFour:

    JMP npcTileNotSpecial
    
npcTileNotSpecial:
    ;; None of the special tile types were found, default to text entry one.
    LDA #$00
    STA textVar
     
skipNpcTile:
 

jorotroid

Member
Oh, I misunderstood. I thought you wanted to use the same code for two different collision types. What you want might be a pretty tall order. When the collision checks happen, it's only looking up what collision type is at that tile location. The actually graphical metatile information is only retrieved when changing the tile, you would have to switch to Bank 16, but the tile collision stuff happens in bank 14. So if you try switching to Bank 16, the game will most likely lock up. One thing you can do is write some code in the static bank to JSR to from the tile code. Then when you are in the static bank, swap the dynamic bank to 16, get the information you want, swap back to bank 14, then RTS back to the tile code. It's probably not something you would want to do too often in your code, but it can work.

As for accessing the info... uh... this is going to be a sort of Frankensteined guess work on my part, but maybe something like this:
First you need the pointer to the nametable that stores screen graphics info. Use code like this:

Code:
	LDA currentScreen
	ASL
	TAY
	LdA update_screen_details
	CMP #$01
	;;; if it is zero, it is a special screen.
	;;; one is map 1
	;;; two is map 2
	BNE +
	;;;;; UPDATE THIS TO FIND THE RIGHT MAP
	LDA NameTablePointers_Map1,y
	STA updateNT_ntPointer	
	LDA NameTablePointers_Map1+1,y
	STA updateNT_ntPointer+1
	JMP ++
+	
	LDA NameTablePointers_Map2,y
	STA updateNT_ntPointer	
	LDA NameTablePointers_Map2+1,y
	STA updateNT_ntPointer+1
++

Then you need to store the tile positional index in to Y. (What I mean is that each tile on screen is part of a list of tiles, so the tile in the upper left is $00, next to it on the right is $01, and so on)
To do that, you need the y and x position of the tile which are probably still stored in the variables tileY and tileX at this point, then do this:
Code:
	LDA tileY
	AND #%11110000
	STA temp3		;Maybe not temp3, just any temp variable that is not being used
	
	LDA tileX
	LSR
	LSR
	LSR
	LSR
	ORA temp3
	TAY

Ok, so now you will have the nametable pointer and the tile position index. I think at this point all you need to do is this:

Code:
	LDA (updateNT_ntPointer),y

And now you should have the graphical index of the tile stored in the Accumulator. ...I think. Like I said, I'm doing a lot of guesswork here. A lot could go wrong.
 
Wow, that is quite a bit more complicated than I was expecting.

I'm willing to try, but with that much going on I am worried that will possibly introduce slowdown.

What I am trying to accomplish is being able to have 4 different NPC tile signs on screen at once.

I guess if I am willing for the screen to not have any normal monsters on it I could make them monster NPCs
 

jorotroid

Member
If feel like there might be easier ways to get that effect. One that comes to mind is having the NPC text dependent on where the NPC tile is on screen. So if it is in the 1st 1/4, show text 1; 2nd 1/4, show text 2; etc.
 

Mugi

Member
there's a function called getTileAtPosition which you can use by doing JSR getTileAtPosition, and then returning to your code stack, this should leave you with tiletype stored in Y but i havent actually used it myself so i dont really know the specifics of
how it operates.
 

Mugi

Member
jorotroid said:
Awesome! Glad my madman ramblings actually worked out.

I truly believe that "madman ramblings" as you so politely put is the best way to do things.
As such the most neat things of my game were done by completely pulling them out of my ass too after sitting on them thinking that i never get them done for 2 weeks.
Why try too hard when you literally just write random code that will be better at the end :)
 

Atarath

Member
Hey, I got this working based on this discussion here so I just wanted to say thanks. There were a few extra steps I had to do to make it work. All of this code though I found under the RestoreBoxArea label under HandleUpdateNametable.asm. I got it working by putting in some checks to jump around the code that's not needed and get back to the tile script.
 

Atarath

Member
I don't know if this is the most efficient way to go about it but what I did was this:

In my tile collision script I set up a JSR to a subroutine in the static bank. After this line you can set up your checks for the tile ID that will be stored in temp.
Code:
JSR tileIDBankSwitch
LDA temp
   CMP #64 ;bush
   BNE +
   JMP bushBreak
   +


I set up the subroutine tileIDBankSwitch in Main.asm just past the main game loop. I STA currentBank into temp2 instead of prevBank because that will cause the game to crash. I assume the bank stored in prevBank is called after the tile collision script. This switches to bank 16 to get the pointer info, switches to the appropriate screen bank, gets the tile position, put it together to get the tile ID, switches back to original bank, then RTS back to the tile code.
Code:
tileIDBankSwitch:
LDA currentBank
STA temp2
LDY #$16
JSR bankswitchY

JSR getTileID
GetScreenBank newScreen
LDY screenBank
JSR bankswitchY

JSR GetTileAtPosition
LDA (updateNT_ntPointer),y
STA temp
LDY temp2
JSR bankswitchY
RTS


I set up a new script I just called getTileID.asm. In it I put the code to get the pointer info:
Code:
getTileID:	
LDA currentScreen
ASL
TAY
LDA update_screen_details
   CMP #$01
   ;;; if it is zero, it is a special screen.
   ;;; one is map 1
   ;;; two is map 2
   BNE +
   ;;;;; UPDATE THIS TO FIND THE RIGHT MAP
   LDA NameTablePointers_Map1,y
   STA updateNT_ntPointer	
   LDA NameTablePointers_Map1+1,y
   STA updateNT_ntPointer+1
   JMP ++
   +	
   LDA NameTablePointers_Map2,y
   STA updateNT_ntPointer	
   LDA NameTablePointers_Map2+1,y
   STA updateNT_ntPointer+1
   ++
RTS


I included this script in Bank16.asm
Code:
.include Routines\getTileID.asm

That should do it.
 

dale_coop

Moderator
Staff member
Thank you, Elarath <3
I love that kind of post, sharing useful routine or macro... that anyone could need one day.
 
Top Bottom