Jump to content
IGNORED

[INTYBASIC] How to trim the card info down to smaller numbers.


Kiwi
 Share

Recommended Posts

I trying to wrap my head around trimming the card information down to the GRAM card number. So I can use the card number as software collision detection data. I want to peel off the color information, GRAM bit off the card that been retrieved from the BACKTAB.

 

For right now, I have

 

charx=vmX/8
chary=vmY/8

print at 12 color 7,<3> charx
print at 32 color 7,<3> chary
#Mcard=peek($200+charx+chary*20)

 

I want to get the card # to simplify the comparsion statement. For example, I want card 8-18 to be solid.

 

I want to use

if #Mcard>8 AND #Mcard<18 then.....

 

Instead of having big numbers, slowing the processor down.

 

The character moves in 16 different directions in a top down dungeon crawler type of game. It does make hard collision detection hard to figure out, which I tried.

Link to comment
Share on other sites

I am not sure this is the best way to do it, but this the formula I'm using:

#val=(PEEK(512+cx+cy*20) AND $09F8)/8

The /8 is essentially to mask away the lower three bits in FG/BG mode. If you're using color stack mode, adjust as required.

 

Edit: If you have no GROM cards, you can AND $01F8 and get a number 0-63 instead of 0-319 of which values 64-255 anyway won't occur.

Edited by carlsson
Link to comment
Share on other sites

If you don't divide by 8, won't you have to compare with GROM/GRAM cards 8, 16, 24, 32, 40 etc all the way to card 2560, or is there another way of thinking?

 

Correct! Personally, I would just use constants instead of the magic numbers (after applying a suitable bitwise AND mask) and then leave it at that. That way, when you come back to the game source code after a while, you don't have to remember that GRAM card 13(x8) is a wall etc.

Link to comment
Share on other sites

If you don't divide by 8, won't you have to compare with GROM/GRAM cards 8, 16, 24, 32, 40 etc all the way to card 2560, or is there another way of thinking?

 

Yes, indeed. But if you're just doing a range compare, then the comparison isn't any more costly. It actually saves you the cost of the divide step. For example, if card #s 8 through 18 are solid walls, then you want to compare the masked value against the range 8*8 = 64 through 18*8 = 144.

.

#Mcard = peek($200 + charx + 20*chary) AND $FF8

If #Mcard >= 8*8 AND #Mcard <= 18*8 Then ....

.
And as GroovyBee suggested, replace 8 and 18 with constants, so if your range of 'solid wall' cards ever changes, you can just change the constants.
Link to comment
Share on other sites

I winded up doing,

Mcard=PEEK($200+charx+chary*20)/8

 

Mcard being an 8-bit variable it'll shave off the last 8 bits. And dividing by 8, shifts the bit over by 3 to get card number ranging 0-31.

 

I planned to have the background tiles to take GRAM slot 0-31, and MOBs to take slot 32-63.

Link to comment
Share on other sites

I winded up doing,

 

Mcard=PEEK($200+charx+chary*20)/8

 

Mcard being an 8-bit variable it'll shave off the last 8 bits. And dividing by 8, shifts the bit over by 3 to get card number ranging 0-31.

 

I planned to have the background tiles to take GRAM slot 0-31, and MOBs to take slot 32-63.

 

 

Hmm... Saving that in an 8-bit variable /sorta/ works. You'll end up treating GROM and GRAM tiles identically, though. So, numbers, letters, punctuation, etc... will look similar to GRAM tiles. That is, a space character is GROM #0, and you won't be able to tell that from GRAM #0, for example.

Link to comment
Share on other sites

I suppose there is no space in the dungeon? ;-) Furthermore, does the collission detection signal anything as long as a MOB moves on GROM #0, or does it have to be GROM #1 or a GRAM for it to flag something may have happened?

 

The hardware collision only detects when non-zero pixels touch each other. That is when a non-transparent part of a MOB collides with a non-transparent part of a background card or another MOB.

 

Obviously, if the background card is completely transparent (GROM #0), then no collisions can register.

 

P.S. The visibility of a MOB does not affect collisions. A "hidden" MOB (one with the "Visible" flag in the X register turned off) can still trigger a collision. The only factor is the actual pixels.

Link to comment
Share on other sites

Another factor to consider with hardware collisions, which may or may not affect your game design, is that while collisions occur on the frame when objects move, they are registered during the next frame. Moreover, if you need to react by moving the sprite or changing its card or altering any feature of the STIC, it will not be reflected until the next frame is drawn.

 

In other words, if you move a sprite on Frame #N and this caused a collision with the background, you won't know this until Frame #N+1; and if you moved or changed the colour of the sprite or altered the GRAM card of the background as a reaction to the event, it won't show up until Frame #N+2.

 

For this reason, sometimes it is better to handle collisions in software, so that you can have full control of their timing. With software collisions, you can move objects on Frame #N, detect collisions right away, and react before the end of the frame.

 

However, software collisions are much more expensive in code and processing time than hardware collisions, which come almost for free. It's just another trade-off of game design. ;)

 

-dZ.

Edited by DZ-Jay
  • Like 1
Link to comment
Share on other sites

I winded up doing,

 

Mcard=PEEK($200+charx+chary*20)/8

 

Mcard being an 8-bit variable it'll shave off the last 8 bits. And dividing by 8, shifts the bit over by 3 to get card number ranging 0-31.

 

I planned to have the background tiles to take GRAM slot 0-31, and MOBs to take slot 32-63.

 

If they are all in GRAM, you'll be fine. However, consider what Joe said, if you use GROM for anything, you won't be able to tell them apart. That is because the "GRAM flag" that distinguishes between both is bit #8 (actually, it's bit #11 in the BACKTAB word, which falls on #8 when you divide by eight), which falls outside the range of 0-255, and won't be persisted in 8-bit RAM.

 

-dZ.

Edited by DZ-Jay
Link to comment
Share on other sites

Yeah, hardware collisions actually kinda suck for things like "keeping player in a maze." You want to know before you move a player whether you're moving them into a wall, rather than after. Hardware collision requires the two objects to have actually overlapped already in the past, which for something like maze movement, requires your player to have overlapped the wall already by at least 1px.

 

I mainly save hardware collisions for after-the-fact collision detection for items that are allowed to penetrate each other, and even then I prefer software collision detection. As dZ mentioned upthread, with hardware collision detection, there's effectively a 2 frame delay between when you cause the collision and when you can react to the collision, because you need a displayed frame between the two events.

 

We beat a lot of this to death in a thread a couple years ago: http://atariage.com/forums/topic/231734-the-intv-intybasic-and-collision-detection/

 

 

Here is a different idea that may save you a LOT of headache for your current maze navigation: Bits 14 and 15 in each BACKTAB word are not used by the STIC. You can use these for flags in your game. If you're not using them for something else already, you could use them to mark which squares are passable and ones aren't.

 

For example, dedicate bit 15 to indicate whether a given square is passable by the player or not. Then you don't even have to look at the card # to know if it's a wall. You can either "AND $8000" and see if it's zero or non-zero, or you can compare ">= 0" vs. "< 0" without even masking.

 

That allows you to do other tricks, like having a wall you can walk through (hidden passage? easter egg?), among other things. Bit 14 could be used as a flag for, say, "special squares"—squares that trigger an action when you walk onto them.

  • Like 2
Link to comment
Share on other sites

I do precisely that in Christmas Carol: there are four bits left unused in the BACKTAB word that I use as the "items bitmap." That way, detecting a collision with, say a Snowflake or a piece of Candy is as simple as testing the four bits on the BACKTAB cell over which the sprite is at the moment to see which one is set.

 

Not only that, but on the edge cards around the maze (where no sprite can actually traverse), I set bit #15 of the cards as a "no paint" marker. When the maze is flashed at the end if the level, only those cards with bit #15 clear change colours. This lets the HUD (score, lives indicator, etc.) remain static.

 

dZ.

  • Like 2
Link to comment
Share on other sites

I ended up doing:

CheckWall:procedure

'store your char coor into lx & ly(stands for last position)
lx=vmX
ly=vmY

'subpixel routines for finer movement
while vmsY>=200:vmY=vmY-1:vmsY=vmsY+8:wend
while vmsY>=8:vmY=vmY+1:vmsY=vmsY-8:wend
while vmsX>=200:vmX=vmX-1:vmsX=vmsX+8:wend
while vmsX>=8:vmX=vmX+1:vmsX=vmsX-8:wend

'divide by 8 with offset of -4
charx=(vmX-4)/8
chary=(vmY-4)/8

'debug info on where your char on screen
print at 12 color 7,<3> charx
print at 32 color 7,<3> chary

'get card number from BACKTAB
'storing to a byte to trim the last 8 bits from the card
'dividing by 8 will do a shift operation to trim the first 3 bit off the 
'Mcard.  Mcard is short for Magic Card.
Mcard=PEEK($200+charx+chary*20)/8

'debug info on what card # it got from the screen
print at 233 color 7,<2> Mcard

'if the card ID number higher than 8, then restore last position.
if Mcard>8 then vmY=ly:vmX=lx

'return and end to go back to the main gameloop.  
return
end

I usually can make very detail floors so hardware collision wouldn't work since it wall detect set bits. If I want to make a detail water tile that allow projectile to pass through and keep your player from going through, then software collusion is recommend. And I work in BG/FG mode. Intycolor pick up blank tile as part of the GROM, and blank tile is a 0 so it pass through.

 

For Rockcutter for Colecovision, I did have invisible wall so I loaded the wall graphic to the pass through portion of the charset and the solid portion of the tileset. I may do the same for this game.

  • Like 1
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...