Jump to content

Photo

7800basic strange variable behaviour

7800basic

8 replies to this topic

#1 Dalta OFFLINE  

Dalta

    Space Invader

  • 17 posts
  • Location:France

Posted Sun Mar 10, 2019 6:48 PM

Sorry couldn't think of a better title.

 

So, I'm trying to implement moving and placing blocks in order to place them as defenses in front of the player's base. I wrote a simple code, just two lines, so that when the player's x and y are within a range of the block's x and y (15 pixels on the x, 10 on the y), and then the player presses a button, the block will jump to be 4 pixels away from the player's x and y ("carrying" the block). Everything works fine until the block gets to blockx=14 (and blocky=9) when the the block will detach from the player (the variable 'nearbase' is no longer true) and will not allow itself to be picked up again (nearbase is never re-set as 1), even if the player's x and y go away from the edge of the screen. I used plotvalue to display that the variables for player and base x and y are correct, stay what they should be and stay within range. There is no problem on the other end of the screen, only in the lower numbers. When the strange behaviour is happening, I ask (via plotting a debug image) if the playerx is within range, it says it isn't, despite the plotvalue clearly showing that, in fact, it is.

playerx and playery are dimensioned as a and b while blockx and blocky are $2557 and $2561 so it doesn't seem to be an overwriting issue.

 

The block is called 'base' in the code, so blockx=basex.

 if playerx<basex+15 && playerx>basex-15 && playery<basey+10 && playery>basey-10 then nearbase=1 else nearbase=0
 if joy0fire1 && nearbase=1 then basex=playerx+4:basey=playery+4:basepickedup=1 else basepickedup=0

Anyone know what's going on?



#2 RevEng OFFLINE  

RevEng

    Bit Player

  • 5,192 posts
  • Location:bottom of the stack

Posted Sun Mar 10, 2019 8:12 PM

Yeah, it's clear what's going on, but let me give you some background...

On the 6502, numbers are only "negative" in a limited way. If you take 0 and subtract 1, the result is 255. This is called an underflow. There's a similar overflow situation when you add 1 to 255, and the result becomes 0.

The 6502 instructions that check for one value being larger than another aren't hip to whether a particular value is "meant" to be negative or positive. They always assume positive values.

In your code, when basex=14 and you test "playerx>basex-15", the test evaluates to "playerx>255", due to underflow. This test is never true, while your desired "playerx > -1" test would always be true.

One way to work around this is to rewrite your tests to avoid the underflow. e.g. "playerx>basex-15" is the same as "playerx+15>basex". (Just be careful you don't overflow "playerx+15", which won't happen with regular screen coordinates)
  • Trebor , swapd0 and Dalta like this

#3 Dalta OFFLINE  

Dalta

    Space Invader

  • Topic Starter
  • 17 posts
  • Location:France

Posted Wed Mar 20, 2019 2:42 AM

So sorry not to reply sooner, was travelling. Thank you for that explanation, I had read that before but hadn't thought of it as a possible reason for this bug. I implemented your suggested workaround and everything works as intended now. Thanks so much!



#4 RevEng OFFLINE  

RevEng

    Bit Player

  • 5,192 posts
  • Location:bottom of the stack

Posted Wed Mar 20, 2019 6:54 AM

You're welcome!
  • Dalta likes this

#5 Dalta OFFLINE  

Dalta

    Space Invader

  • Topic Starter
  • 17 posts
  • Location:France

Posted Mon Apr 1, 2019 12:44 PM

So I've had another problem with this section of code. I was implementing multiple base blocks, so I made every variable into an array to accommodate each base block. The only change to the code I made was adding [bco] after the variable names. [bco] is the counter I use to loop through each array in order to manipulate each block. This broke the code, but it seems to be the specific configuration 'playerx+15>basex[bco]' that doesn't work (and presumably the playery equivalent), I've tested the other operations and they seem to work fine. Switching the signs to their opposite also works fine, and replacing the operation with playerx>basex[bco]-15 works, but causes the same problems as in my original post.

When I say the code doesn't work, it never evaluates 'playerx+15>basex[bco]' to true.

if playerx<basex[bco]+15 && playerx+15>basex[bco] && playery<basey[bco]+10 && playery+10<basey[bco] then plotsprite face1 0 100 100:nearbase[bco]=1 else nearbase[bco]=0
if joy0fire1 && nearbase[bco]=1 then basex[bco]=playerx+4:basey[bco]=playery+4:basepickedup[bco]=1 else basepickedup[bco]=0

Anyone know what could be wrong?



#6 RevEng OFFLINE  

RevEng

    Bit Player

  • 5,192 posts
  • Location:bottom of the stack

Posted Mon Apr 1, 2019 2:46 PM

Yeah, it looks like both the "if...then complex math" handling code and "if...then array index" handling code are stepping on each other's X register reference.

I'll need to dig deeper. To work around it, move the array index outside of the if then, something like...
 
temp1=basex[bco]
if playerx<temp1+15 && playerx+15>temp1 ...


#7 Dalta OFFLINE  

Dalta

    Space Invader

  • Topic Starter
  • 17 posts
  • Location:France

Posted Sat Apr 6, 2019 7:40 PM

Thanks for that help, don't know why I didn't just create a new variable, I guess I was too focused on figuring out a solution to the problem.

 

Now that you mention it, I ran into two other issues that seem related, perhaps it will be helpful to you.

 

One was when I was trying to implement some simple collision with a bullet and had a line that was something like

if bullx>ex && bullx<ex+8 && bully>ey && bully<ey+16 then goto BulletInactive

with ex being the enemy x position, and ex+8 being the enemy's width with ey the corresponding measures for the y axis. This code wouldn't run and I had to replace ex+8 with a new variable eh (enemy height) which was equal to the same thing. I copied this line or something similar from the http://www.randomter.../7800basic.htmlwebsite, but I've looked through and I can't find anything like it now so I'm not sure what part I got it from.

 

The other time wasn't an if statement but is kind of similar, it was with the plotsprite command. I had

plotsprite enemy 0 ex[eco] ey[eco]

but it wouldn't run, so I had to create a single use 'nex' variable which is equal to ex[eco] and ditto for ey to replace them in that statement. This is the same for all my plotsprite commands.



#8 RevEng OFFLINE  

RevEng

    Bit Player

  • 5,192 posts
  • Location:bottom of the stack

Posted Wed Apr 10, 2019 10:07 PM

Now that you mention it, I ran into two other issues that seem related, perhaps it will be helpful to you.
 
One was when I was trying to implement some simple collision with a bullet and had a line that was something like

Not sure what went on here. This should have worked.

 

The other time wasn't an if statement but is kind of similar, it was with the plotsprite command.

The arrays work great for math, but not at all for statement arguments. It's a weakness inherited from the language's batari Basic origins, and would require more overhaul than I can put in.

I'll update the docs to make this clearer. Coming from a bB background, I forget this stuff isn't as clear as it should be for new coders.
  • Dalta likes this

#9 Dalta OFFLINE  

Dalta

    Space Invader

  • Topic Starter
  • 17 posts
  • Location:France

Posted Sun Apr 14, 2019 11:42 AM

Cool, no problem. I'm eternally grateful just for 7800basic's existence, I never would've made much progress if I was still struggling with assembly.


  • Trebor , RevEng and SmittyB like this





Also tagged with one or more of these keywords: 7800basic

0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users