View previous topic :: View next topic |
Author |
Message |
nodtveidt Elder

Joined: 27 Dec 2004 Posts: 414 Location: Isla del Encanto
|
Posted: Sun May 14, 2006 8:47 am Post subject: Is this a HuC fault? |
|
|
I'm having a bit of trouble with a collision detection routine I've written here. I've used this technique twice now, and the first time it worked fine but this time it seems to be failing at a certain value. This is primitive sprite-to-background coldet using map_get_tile and it's not optimized in any way...just functional for now to iron out movement details. Here's the code:
Code: | char_collision(direction)
int direction;
{
int checkx1,checkx2,checky1,checky2;
if (direction & DIR_LEFT)
{
checkx1 = (charx + vmapx + 2)>>4;
checky1 = (chary + vmapy + 16)>>4;
checky2 = (chary + vmapy + 26)>>4;
if ((map_get_tile(checkx1, checky1) < HIT_THRESHHOLD) && (map_get_tile(checkx1, checky2) < HIT_THRESHHOLD))
{ return 0; } else { return 1; }
}
if (direction & DIR_RIGHT)
{
checkx1 = (charx + vmapx + 14)>>4;
checky1 = (chary + vmapy + 16)>>4;
checky2 = (chary + vmapy + 26)>>4;
if ((map_get_tile(checkx1, checky1) < HIT_THRESHHOLD) && (map_get_tile(checkx1, checky2) < HIT_THRESHHOLD))
{ return 0; } else { return 1; }
}
if (direction & DIR_UP)
{
checkx1 = (charx + vmapx + 2)>>4;
checkx2 = (charx + vmapx + 14)>>4;
checky1 = (chary + vmapy + 14)>>4;
if ((map_get_tile(checkx1, checky1) < HIT_THRESHHOLD) && (map_get_tile(checkx2, checky1) < HIT_THRESHHOLD))
{ return 0; } else { return 1; }
}
if (direction & DIR_DOWN)
{
checkx1 = (charx + vmapx + 2)>>4;
checkx2 = (charx + vmapx + 14)>>4;
checky1 = (chary + vmapy + 28)>>4;
if ((map_get_tile(checkx1, checky1) < HIT_THRESHHOLD) && (map_get_tile(checkx2, checky1) < HIT_THRESHHOLD))
{ return 0; } else { return 1; }
}
} |
charx and chary are the screen coordinates of the sprite that is checked against the background. vmapx and vmapy should be easy to figure out. HIT_THRESHHOLD is the "cutoff" tile; all tiles above this value are non-walkable.
Now, when I disable all but the left check (by placing a return 0 between the left and right if blocks), I observe that the function works correctly up until Code: | (chary + mapy)>>4 = 225 | ...then it starts to go haywire...tiles previously "blocked" are now walkable, and the sprite gets stuck on ordinarily walkable tiles.
This code that I'm using is a more simplified version of the code that is in another game engine of mine, but this one required a much smaller hit area (the other had a large hit area and required multiple hit zones) but the other code seems to work just fine, where this one fails. Any thoughts?
EDIT: I've changed all &&'s to ||'s and coldet works in each direction above 225 as before, but it's still wanked otherwise...changing the check to or's instead of and's "broke" the collision enough to allow the sprite to move out of the area (it starts past the 225 area) but ultimately, it still doesn't solve the real problem...
EDIT2: I realized that the first game engine that used this technique had no maps that had that many rows of tiles. So for the time being, I'll limit the maps to 224 rows, which should be more than enough anyways. _________________ Frozen Utopia
Retro gaming was never this cool. |
|
Back to top |
|
 |
Charles MacDonald Member

Joined: 07 Dec 2005 Posts: 35
|
Posted: Tue May 16, 2006 4:21 am Post subject: Re: Is this a HuC fault? |
|
|
Quote: | Now, when I disable all but the left check (by placing a return 0 between the left and right if blocks), I observe that the function works correctly up until Code: | (chary + mapy)>>4 = 225 | ...then it starts to go haywire...tiles previously "blocked" are now walkable, and the sprite gets stuck on ordinarily walkable tiles.
|
Have you disassembled the code relating to that particular line to see what HuC generated? If you change the shift to "/ 16" instead does it work? What about making the variables wider than int? (say unsigned int, or unsigned long int of HuC supports it?) |
|
Back to top |
|
 |
nodtveidt Elder

Joined: 27 Dec 2004 Posts: 414 Location: Isla del Encanto
|
Posted: Tue May 16, 2006 4:33 am Post subject: |
|
|
I could make a new map to test it with, I suppose...if only for testing purposes to see what the problem is. I'd never use /16 in actual code though, unless I knew that the compiler was going to optimize it with a shift, in which case I'd just use the shift manually anyways (division is expensive, a little too expensive for how it would be being used here). I don't think HuC supports unsigned integers, and I'm positive it doesn't support long integers (wouldn't that be nice if it did though). But it doesn't seem to be a problem with the variable size...chary+mapy don't ever come anywhere near the max value allowed by a signed integer, which is what leads me to believe it's a problem with HuC's clib, specifically regarding map_get_tile. But I don't have enough knowledge of how that function works (or even where it is in the clib sourcecode) to make any attempt at a correction.  _________________ Frozen Utopia
Retro gaming was never this cool. |
|
Back to top |
|
 |
Tomaitheous Elder

Joined: 27 Sep 2005 Posts: 306 Location: Tucson
|
Posted: Tue May 16, 2006 5:16 am Post subject: |
|
|
Here's the routine in the lst file.
Code: |
1236 ; map_get_tile(char x [dl], char y)
1237 ; map_put_tile(char x [dl], char y [dh], char tile)
1238 ; ----
1239
1240 00:F4DF _map_get_tile.2:
1241 00:F4DF 86 FF stx <_dh
1242 00:F4E1 20 F1 F4 jsr _map_calc_tile_addr
1243 ; --
1244 00:F4E4 B2 FC lda [_cx]
1245 00:F4E6 AA tax
1246 00:F4E7 62 cla
1247 00:F4E8 60 rts
1248
1249 00:F4E9 _map_put_tile.3:
1250 00:F4E9 DA phx
1251 00:F4EA 20 F1 F4 jsr _map_calc_tile_addr
1252 00:F4ED 68 pla
1253 00:F4EE 92 FC sta [_cx]
1254 00:F4F0 60 rts
1255
1256 ; map_calc_tile_addr(char x [dl], char y [dh])
1257 ; ----
1258 00:F4F1 _map_calc_tile_addr:
1259 00:F4F1 A6 FF ldx <_dh
1260 00:F4F3 AD B5 26 lda mapwidth+1
1261 00:F4F6 F0 08 beq .l1
1262 00:F4F8 86 FD stx <_ch
1263 00:F4FA A5 FE lda <_dl
1264 00:F4FC 85 FC sta <_cl
1265 00:F4FE 80 13 bra .l2
1266 ; --
1267 00:F500 86 F8 .l1: stx <_al
1268 00:F502 AD B4 26 lda mapwidth
1269 00:F505 85 FA sta <_bl
1270 00:F507 20 DB E6 jsr mulu8
1271 ; --
1272 00:F50A A5 FC lda <_cl
1273 add <_dl
0000 .if (1 = 2) ; register A (handle carry
.else
00:F50C 18 clc
00:F50D 65 FE adc <_dl
.endif
1274 00:F50F 90 02 bcc .l2
1275 00:F511 E6 FD inc <_ch
1276 ; --
1277 .l2: add mapaddr
0000 .if (1 = 2) ; register A (handle carry
.else
00:F513 18 clc
00:F514 6D B2 26 adc mapaddr
.endif
1278 00:F517 85 FC sta <_cl
1279 00:F519 AD B3 26 lda mapaddr+1
1280 00:F51C 29 1F and #$1F
1281 00:F51E 65 FD adc <_ch
1282 00:F520 AA tax
1283 ; --
1284 ; rol A
1285 ; rol A
1286 ; rol A
1287 ; rol A
1288 00:F521 4A lsr A
1289 00:F522 4A lsr A
1290 00:F523 4A lsr A
1291 00:F524 4A lsr A
1292 00:F525 4A lsr A
1293 00:F526 29 0F and #$0F
1294 add mapbank
0000 .if (1 = 2) ; register A (handle carry
.else
00:F528 18 clc
00:F529 6D B1 26 adc mapbank
.endif
1295 00:F52C 53 08 tam #3
1296 ; --
1297 00:F52E 8A txa
1298 00:F52F 29 1F and #$1F
1299 00:F531 09 60 ora #$60
1300 00:F533 85 FD sta <_ch
1301 00:F535 A6 FC ldx <_cl
1302 00:F537 60 rts
|
Note sure if this helps, but I think magickit uses pseudo regs(macros), so dx= dl + dh is like an x86 cpu style reg. So dl and dh arguements should be an 8bit(char) value. If you submit an integer it won't read the high byte (_address+1), so a var containing 0x100 would be read as 0x00 in the function.
Ofcourse this lst file is not from your project, so it's possible there's an alt map_get_tile function.
Quote: | I don't think HuC supports unsigned integers |
I didn't see support for it either, but magickit appears to have support for it - you can see it in the lst HuC creates - were it clears the A reg for unsigned variables. _________________ www.pcedev.net |
|
Back to top |
|
 |
dmichel Admin

Joined: 04 Apr 2002 Posts: 1166 Location: France
|
Posted: Tue May 16, 2006 7:53 am Post subject: |
|
|
You could try to access the map data directly too, like this :
Code: |
#incbin(game_map, "map.fmp")
...
tile = game_map[(y * MAP_WIDTH) + x];
|
This will be slower but this may help to find if the problem is in your code or in the library. _________________ David Michel |
|
Back to top |
|
 |
Charles MacDonald Member

Joined: 07 Dec 2005 Posts: 35
|
Posted: Wed May 17, 2006 5:59 pm Post subject: |
|
|
nodtveidt wrote: | I could make a new map to test it with, I suppose...if only for testing purposes to see what the problem is. I'd never use /16 in actual code though, unless I knew that the compiler was going to optimize it with a shift, in which case I'd just use the shift manually anyways (division is expensive, a little too expensive for how it would be being used here). |
My concern was more that HuC might be generating incorrect code for that statement, so by changing the logic around to something else (replacing the shift with a divide) you may find a working combination and therefore positively identify HuC's handling of the old code as a bug.
The compiler output didn't look too wrong though admittedly tracing through that is difficult. Wonder what the problem is, though it sounds like you've got a workaround. |
|
Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|