Collision and Vram

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:

Re: Collision and Vram

Post by nicksen782 »

Weird, non-linear VRAM organization. I'd say that picture I attached definitely says that much. I realized that the formula for figuring out the tiles is wrong for my case. Considering the formula that you just gave, I'm glad you provided it. Geeze! LOL.

I think I saw that formula somewhere actually. Can you step me through it?

I have added to the linker flag as you suggested. My output is not garbled. It seems to scroll normally too.

Understood about ramtiles, they come first in the array and that each value in the vram array points to either a flash or ram tile by tile number.
Out of curiosity, what's the reason you need a "GetTile()" function in your game? If it has potential for reuse I could just add one in mode 3.
Collision detection. I would like to compare the x and y coordinates for a character sprite against adjoining tiles in vram. If that tile number is, say, the road or a bridge then I want to let the character walk over it. Otherwise I want to block the movement. Think of it as creating a sort of whitelist for tiles that can be traversed by a sprite. This has been my goal this weekend. I've learned a whole lot but haven't made much progress, until now I think. Once I figure out that formula you gave us.

I can handle sprite to sprite detection by using bounding boxes or just plain distance, once I get to that point and understand what that means.

CunningFellow, thank you for your offer. If I can use that formula then I should be good for the time being. Perhaps I can take a raincheck for the future?
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Collision and Vram

Post by uze6666 »

Weird, non-linear VRAM organization. I'd say that picture I attached definitely says that much.
Yeah tell me about it, I almost killed my brain working on that one! :lol:
Collision detection. I would like to compare the x and y coordinates for a character sprite against adjoining tiles in vram. If that tile number is, say, the road or a bridge then I want to let the character walk over it.
Aaahh yes, I used this approach many times. I added a GetTile() function for mode 3 based on the existing SetTile function (just refresh from the trunk). It works equally well with and without scrolling. The prototype is:

Code: Select all

extern u8 GetTile(u8 x,u8 y);
Note that the function takes tile positions in input, not pixel values. So divide your sprite coordinate by 8. Hopefully this will help you.
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Collision and Vram

Post by nicksen782 »

This will write a tile to each tile on the screen going 32 tiles to the right then starting on the next row down with the next 32 tiles.

Code: Select all

unsigned char TestTile = 18+RAM_TILES_COUNT;
while(ReadJoypad(0) != BTN_A){}
	
	unsigned char x = 0;
	unsigned char y = 0;
	unsigned char thecount =0;
	for( y=0; y<32; y++){
		for( x=0; x<32; x++){
			vram[((y>>3)*256)+(8*(x))+(y&7)] = TestTile; // Write a tile.
			WaitVsync(1);
		}
	WaitVsync(2);
	}
	while(ReadJoypad(0) != BTN_B){}
Now, to read a tile from a specific area:

Code: Select all

unsigned char GetMapTile(unsigned char x, unsigned char y, char direction){
	y=y>>3; // Divide by 8
	x=x>>3; // Divide by 8
	unsigned char thetile = vram[((y>>3)*256)+(8*(x))+(y&7)]-RAM_TILES_COUNT ;
	 SetTile(21,3,thetile); // For test purposes
	 Print(22, 3, PSTR("# ")); PrintByte (26, 3, thetile, true); // For test purposes
	 Print(20, 4, PSTR("ti")); PrintByte (26, 4, thetile, true); // For test purposes
	return thetile;
}
The code accepts pixel-level x and y coordinates and queries the vram using that crazy formula that I had to modify slightly. Here is a mini-breakdown of what I did.

Code: Select all

t(x,y)=vram[((y>>3)*256)+8x+(y&7)] // The original formula
unsigned char thetile = vram[((y>>3)*256)+8*x+(y&7)]. // I changed 8x to 8*x.
unsigned char thetile = vram[((y>>3)*256)+(8*(x))+(y&7)]-RAM_TILES_COUNT ; // Final formula. Considers ram tiles.
It is used by another function to check the tile number to see if it is a 'solid' tile.

Code: Select all

bool IsSolid(unsigned char t){
	if(t == 6 || t == 18 || t==36 || t==37) {return true;}
	else{return false;}
}
Example:

Code: Select all

if (IsSolid(GetMapTile(g_HeroPositionX, g_HeroPositionY, direction))== true) {Do something.}
Of course, you'll want to send over an incremented or decremented X or Y position to test against in order to check if the character should be allowed to move forward.

Uze! I think I have a GetMapTile function here for scrolling mode 3! Is there anything that should be changed?
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Collision and Vram

Post by nicksen782 »

I found the GetTile function in videoMode3core.s.

So, I put the prototype with my other prototypes but I can't seem to call it.

My GetMapTile doesn't work correctly if I scroll the screen. You say that your GetTile works with and without scrolling. How do I implement it?

Error:

Code: Select all

demoprogram.c:398: undefined reference to `GetTile'
make: *** [demoprogram.elf] Error 1
And thanks for the help so far!

** EDIT: I didn't actually bring in the new kernel changes from the trunk.

What is actually returned from GetTile?
User avatar
nicksen782
Posts: 714
Joined: Wed Feb 01, 2012 8:23 pm
Location: Detroit, United States
Contact:

Re: Collision and Vram

Post by nicksen782 »

So, I implemented GetTile and it works nearly exactly like my GetMapTile. I then tried to scroll the screen a bit but the collisions weren't lining up.

Will I need to also take into account the current level of scrolling (how many pixels scrolled?) If so, then this is no different than what I already had other than the fact that GetTile is written in assembly so it's probably faster.

Is that what I need to do or am I doing something wrong?
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Collision and Vram

Post by CunningFellow »

Uze,

It only saves one clock. but one clock is one clock :)

BTW it also is self protecting from people passing in Y values >32.

Code: Select all

;                         r22               r24               XH               XL                T
                        ; y7y6y5y4y3y2y1y0  x7x6x5x4x3x2x1x0  - - - - - - - -  - - - - - - - - 

lsl   r24               ; y7y6y5y4y3y2y1y0  x6x5x4x3x2x1x0 0
lsl   r24               ; y7y6y5y4y3y2y1y0  x5x4x3x2x1x0 0 0
lsl   r24               ; y7y6y5y4y3y2y1y0  x4x3x2x1x0 0 0 0

clr   XH                ;                                     0 0 0 0 0 0 0 0  - - - - - - - -
bst   r22, 3            ;                                                                        y3
bld   XH, 0             ;                                     0 0 0 0 0 0 0y3                    y3
bst   r22, 4            ;                                                                        y4
bld   XH, 1             ;                                     0 0 0 0 0 0y4y3  - - - - - - - -   y4
andi  r22, 7            ; 0 0 0 0 0 y2y1y0
or    r24, r22          ;                   x4x3x2x1x0y2y1y0
mov   XL, r24           ;                                     0 0 0 0 0 0y4y3  x4x3x2x1x0y2y1y0
subi  XL,lo8(-(vram))
sbci  XH,hi8(-(vram))
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Collision and Vram

Post by uze6666 »

nicksen782 wrote:So, I implemented GetTile and it works nearly exactly like my GetMapTile. I then tried to scroll a bit but the collisions weren't lining up.

Will I need to also take into account the current level of scrolling (how many pixels scrolled?) If so, then this is no different than what I already had other than the fact that GetTile is written in assembly so it's probably faster.

Is that what I need to do or am I doing something wrong?
No you are right, your program will have to account for the current scrolling values before calling GetTile. This is the generic behavior off these functions.
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Collision and Vram

Post by CunningFellow »

Don't know why I didn't see the obvious lsl/swap earlier - we now have a >10% improvement.

Must be getting old and slow.

Here is a 12 clock version of the core logic in SetTile:

Saves 2 clocks over the one in videoMode3core.s

Actually saves 3 clocks if you add in the fact that R0 gets left as ZERO

Code: Select all

;                         r22               r24               XH               XL                T
                        ; y7y6y5y4y3y2y1y0  x7x6x5x4x3x2x1x0  - - - - - - - -  - - - - - - - - 

lsl   r24               ; y7y6y5y4y3y2y1y0  x6x5x4x3x2x1x0 0
lsl   r24               ; y7y6y5y4y3y2y1y0  x5x4x3x2x1x0 0 0
lsl   r24               ; y7y6y5y4y3y2y1y0  x4x3x2x1x0 0 0 0

mov   XH,r22            ;                                     y7y6y5y4y3y2y1y0 
lsl   XH                ;                                     y6y5y4y3y2y1y0 0
swap  XH                ;                                     y2y1y0 0y6y5y4y3
andi  XH,3              ;                                     0 0 0 0 0 0 y4y3

andi  r22, 7            ; 0 0 0 0 0 y2y1y0
or    r24, r22          ;                   x4x3x2x1x0y2y1y0
mov   XL, r24           ;                                     0 0 0 0 0 0 y4y3 x4x3x2x1x0y2y1y0
subi  XL,lo8(-(vram))
sbci  XH,hi8(-(vram))
CunningFellow
Posts: 1445
Joined: Mon Feb 11, 2013 8:08 am
Location: Brisbane, Australia

Re: Collision and Vram

Post by CunningFellow »

OH - and as I have said before - could save one more clock and make the scrolling logic easier if people are willing to fix VRAM at a boundary.

That might break some peoples games though as you loose 100 to 150 bytes of RAM

Well you don't really loose them. You loose continuity and have to juggle sections to fit variables into that little annexed bit of RAM between VRAM top and stack.
User avatar
uze6666
Site Admin
Posts: 4801
Joined: Tue Aug 12, 2008 9:13 pm
Location: Montreal, Canada
Contact:

Re: Collision and Vram

Post by uze6666 »

CunningFellow wrote:Don't know why I didn't see the obvious lsl/swap earlier - we now have a >10% improvement.

Must be getting old and slow.

Here is a 12 clock version of the core logic in SetTile:

Saves 2 clocks over the one in videoMode3core.s

Actually saves 3 clocks if you add in the fact that R0 gets left as ZERO

Code: Select all

;                         r22               r24               XH               XL                T
                        ; y7y6y5y4y3y2y1y0  x7x6x5x4x3x2x1x0  - - - - - - - -  - - - - - - - - 

lsl   r24               ; y7y6y5y4y3y2y1y0  x6x5x4x3x2x1x0 0
lsl   r24               ; y7y6y5y4y3y2y1y0  x5x4x3x2x1x0 0 0
lsl   r24               ; y7y6y5y4y3y2y1y0  x4x3x2x1x0 0 0 0

mov   XH,r22            ;                                     y7y6y5y4y3y2y1y0 
lsl   XH                ;                                     y6y5y4y3y2y1y0 0
swap  XH                ;                                     y2y1y0 0y6y5y4y3
andi  XH,3              ;                                     0 0 0 0 0 0 y4y3

andi  r22, 7            ; 0 0 0 0 0 y2y1y0
or    r24, r22          ;                   x4x3x2x1x0y2y1y0
mov   XL, r24           ;                                     0 0 0 0 0 0 y4y3 x4x3x2x1x0y2y1y0
subi  XL,lo8(-(vram))
sbci  XH,hi8(-(vram))
So what's the whole function code? I fail to see the cycles savings... :?:
Post Reply