MagicEngine
Forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Japanese English 

Is this a HuC fault?

 
Post new topic   Reply to topic    MagicEngine Forum Index -> General
View previous topic :: View next topic  
Author Message
nodtveidt
Elder
Elder


Joined: 27 Dec 2004
Posts: 414
Location: Isla del Encanto

PostPosted: Sun May 14, 2006 8:47 am    Post subject: Is this a HuC fault? Reply with quote

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. Smile 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
View user's profile Send private message Visit poster's website MSN Messenger
Charles MacDonald
Member
Member


Joined: 07 Dec 2005
Posts: 35

PostPosted: Tue May 16, 2006 4:21 am    Post subject: Re: Is this a HuC fault? Reply with quote

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
View user's profile Send private message Visit poster's website
nodtveidt
Elder
Elder


Joined: 27 Dec 2004
Posts: 414
Location: Isla del Encanto

PostPosted: Tue May 16, 2006 4:33 am    Post subject: Reply with quote

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. Sad
_________________
Frozen Utopia
Retro gaming was never this cool.
Back to top
View user's profile Send private message Visit poster's website MSN Messenger
Tomaitheous
Elder
Elder


Joined: 27 Sep 2005
Posts: 306
Location: Tucson

PostPosted: Tue May 16, 2006 5:16 am    Post subject: Reply with quote

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
View user's profile Send private message
dmichel
Admin
Admin


Joined: 04 Apr 2002
Posts: 1166
Location: France

PostPosted: Tue May 16, 2006 7:53 am    Post subject: Reply with quote

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
View user's profile Send private message
Charles MacDonald
Member
Member


Joined: 07 Dec 2005
Posts: 35

PostPosted: Wed May 17, 2006 5:59 pm    Post subject: Reply with quote

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. Wink Wonder what the problem is, though it sounds like you've got a workaround.
Back to top
View user's profile Send private message Visit poster's website
Display posts from previous:   
Post new topic   Reply to topic    MagicEngine Forum Index -> General All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
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