Jump to content
IGNORED

Trying to wrap my head around "on goto"


RetroFiends

Recommended Posts

Okay, I understand that

on x goto LabelA LabelB LabelC

 

is the same thing as

 

if x = 0 then LabelA
if x = 1 then LabelB
if x = 2 then LabelC

 

What I don't understand is how you can possibly split these up with the example given on RT website:

 

y = x - 4 : if y < 4 then on y goto 500 600 700 800
y = x - 8 : if y < 4 then on y goto 900 1000 1100 1200

 

If "on goto" is strictly ordinal, how does it know whether to differentiate between line 1 and line 2?

Sorry if this seems dumb, but I'm just not getting it. Explain it to me like I'm 5, seriously.

 

Now, as for why I think I need this. In my game, I have a large number of screens within a "persistent" world. (Think of Secret Quest to get an idea.) When you reach the edge of the screen, my system checked which screen you were on, where you are and reset your position to the new coodrinates. This all works, of course, but it's an incredibly convoluted system and it takes up a ridiculous amount of space now that I'm approaching about 30 rooms. Additionally, it's messy when you have to have potentially a few lines of code for each room just to check if you can go into another room.

 

So, I finally stopped being lazy and tried to make this system easier by introducing an array of sorts. I've allowed myself a 10x10 grid now to hold the game. So instead of thinking of room data as a strictly linear fashion (Where before I might have been in room 20 that would now be room 2 - 0.) This way I could save myself a lot of hassle by just doing +- 10 to go up or down a screen or +- 1 to go left or right. This would save about 30 needlessly heavy lines.

 

So, that said, since "on goto" is ordinal, I'm confused as to how I would tie that into everything. If I have

on room goto _00 _01 _02 _03 _04 _05 _06 _07 _08 _09

 

And then I add 10 to room to go down to the second row of the 10x10 grid, how does

on room goto _10 _11 _12 _13 _14 _15 _16 _17 _18 _19

even happen? Is there a better way to do this than on goto, am I making things more complicated than it needs to be? (Like, does it remember that "room" has all of these values before _10 to check for since they were previously called?) This wouldn't be an issue at all, I suppose, if I stayed under the (what, 45?) label limit, but I want to future proof myself a little, here.

 

Edit: I suppose what I'm ultimately asking is how splitting "on goto" works in addition to why it works the way it does.

Edited by RetroFiends
Link to comment
Share on other sites

not sure I understand you

 

if you've got a 10 x 10 array and you're doing a row at a time

if x < 10 then on x goto 0, 1, 2, .. 9

that's the firt row

if x is not less than ten then it's a different row

so subtract 10 so that now what was 10 or 11 or 12, .. 19

is now 0 or 1 or 2, .. 9 and do ten more (the second row)

 

if x < 10 then on x goto 10, 11, 12, .. 19

 

etc.

 

 

on .. goto/gosub limited to 12 labels?

Link to comment
Share on other sites

y = x - 4 : if y < 4 then on y goto 500 600 700 800
y = x - 8 : if y < 4 then on y goto 900 1000 1100 1200

 

If "on goto" is strictly ordinal, how does it know whether to differentiate between line 1 and line 2?

Sorry if this seems dumb, but I'm just not getting it. Explain it to me like I'm 5, seriously.

 

If you do something like "on x goto 0 1 2 3" it will go to line 0, 1, 2, or 3 based on whether x is 0, 1, 2, or 3, but if x is anything else the program will fall through to the next line. This can be exploited if you've got too many target lines you want to specify in the "on goto" (being that there's going to be some kind of limit to how many line labels you can specify in the "on goto").

 

Also, the variable you're using in the "on goto" might not have values that fit the nice 0, 1, 2, 3, etc. pattern-- maybe the way the program is written and whatever x is being used for, it just so happens that x will always be some value from 12 to 22, or from 52 to 62, but never anything else. So you could handle that as follows:

 

  y = x - 12 : on y goto x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22 : rem - this will take care of the x=12 through x=22 possibilities
  rem - if x is more than 22, program flow will fall through to the next line
  y = x - 52 : on y goto x52 x53 x54 x55 x56 x57 x58 x59 x60 x61 x62 : rem - this will take care of the x=52 through x=62 possibilities

 

So two possible reasons for splitting a single "on goto" into multiple "on goto" statements are (1) because you can't fit all of the target line labels into one "on goto" statement (as determined by whatever bB's limitations are and any line-length limitations your text editor might have), and (2) so you can handle just the cases that are valid and skip over any values you don't need to worry about.

 

But note that if your "on goto" statements handle only the specific values you know are supposed to be valid, it's good programming practice to handle unexpected cases where a variable somehow got an "illegal" or unplanned value in it. So for example, if you intended that x should only ever be from 12 to 22 but never anything else, it would be best to handle that as follows:

 

  if x < 12 then goto badx
  y = x - 12 : on y goto x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22
badx rem - if x < 12 or x > 22 the program will go here
  gosub sound_the_alarm
  goto mainloop
x12 rem - if x = 12 then do this
  rem - do whatever
  goto mainloop
x13 rem - if x = 13 then do this
  rem - do whatever
  goto mainloop
; etc.

 

If I have

on room goto _00 _01 _02 _03 _04 _05 _06 _07 _08 _09

 

And then I add 10 to room to go down to the second row of the 10x10 grid, how does

on room goto _10 _11 _12 _13 _14 _15 _16 _17 _18 _19

even happen?

 

I think you should be able to figure this out now, but you could do the following:

 

  on room goto _00 _01 _02 _03 _04 _05 _06 _07 _08 _09
  temp = room - 10 : on temp goto _10 _11 _12 _13 _14 _15 _16 _17 _18 _19
  temp = room - 20 : on temp goto _20 _21 _22 _23 _24 _25 _26 _27 _29 _29
; etc.

 

As far as the limit-- I'm not sure what bB's limit is for the length of an "on goto," but speaking for myself, I like to keep lines within the width of the text editor's window so I can see everything on the line without having to scroll the window to the right. And if you plan to ever print out your program then you might want to keep lines within a certain length even if your text window is wider than that. Of course, the font used will affect how much can fit on a printed line, but I think a good rule of thumb is to assume that a fixed-width font is being used and a printed line can have no more than 80 characters before line-wrapping occurs-- so I like to keep my program lines under 80 characters as much as possible. YMMV-- every programmer has his or her own preferences, but if you plan to ever release your code then it might be a good idea to assume that the person looking at your code could be using an OS and a text editor where outputting a "plain text" file to a printer will default to 80 characters per line (i.e., the old "pica" font).

  • Like 1
Link to comment
Share on other sites

but if x is anything else the program will fall through to the next line.

 

A minor correction on an otherwise detailed and informative post. There's no bounds check on the on...goto variable. If the variable is greater than the number of labels, bytes following the jumptable will used as the jump address and bad things will likely happen.

  • Like 1
Link to comment
Share on other sites

Thanks, SeaGtGruff. This helps me understand.

 

So, to be clear, in this example

on room goto _00 _01 _02 _03 _04 _05 _06 _07 _08 _09
temp = room - 10 : on temp goto _10 _11 _12 _13 _14 _15 _16 _17 _18 _19
temp = room - 20 : on temp goto _20 _21 _22 _23 _24 _25 _26 _27 _29 _29

 

You aren't actually subtracting 10 or 20 from the room but rather are denoting the starting point of that line? This is one of the things that was confusing me in the initial example of:

y = x - 4 : if y < 4 then on y goto 500 600 700 800
y = x - 8 : if y < 4 then on y goto 900 1000 1100 1200

I was sitting here trying to figure out how the hell subtracting 8 from x would give you the start of the next line. It's starting to make sense now.

And yeah, I definitely don't want to list a hundred labels even if I could. For one, it isn't very "human" feeling, and it isn't as immediately understandable as having 10 lines with 10 labels to help reinforce the image of a grid. Although, I hope the costs of having 10 lines isn't much (even though it's faaaar better than the 30 or so I have now with more rooms to come.)

 

Edit: Wait, wait, you ARE subtracting from x, hence the use of y so as to not dirty the x variable. Also hence the reason why each row has to subtract the amount needed to come back to the original amount of labels available. And since it skips down the line if y is not less than four the next line acts as if if x was less than 4 and thus uses the new line of labels. I understand now, thanks again!

 

A minor correction on an otherwise detailed and informative post. There's no bounds check on the on...goto variable. If the variable is greater than the number of labels, bytes following the jumptable will used as the jump address and bad things will likely happen.

 

Er, care to elaborate?

Edited by RetroFiends
Link to comment
Share on other sites

A minor correction on an otherwise detailed and informative post. There's no bounds check on the on...goto variable. If the variable is greater than the number of labels, bytes following the jumptable will used as the jump address and bad things will likely happen.

Just to clarify-- it's okay (the program flow will fall through as expected) as long as the variable is *not* larger than expected, right? (I'm remembering this now.) So my example of the "always expect the unexpected" best-practices programming should have been as follows:

 

  if x < 12 then goto badx
  if x > 22 then goto badx
  y = x - 12 : on y goto x12 x13 x14 x15 x16 x17 x18 x19 x20 x21 x22
badx rem - if x < 12 or x > 22 the program will go here
  gosub sound_the_alarm
  goto mainloop
x12 rem - if x = 12 then do this
  rem - do whatever
  goto mainloop
x13 rem - if x = 13 then do this
  rem - do whatever
  goto mainloop
; etc.

 

And the "room" example should have been as follows, correct?

 

  if room > 29 then goto badroom
  if room > 19 then temp = room - 20 : on temp goto _20 _21 _22 _23 _24 _25 _26 _27 _29 _29
  if room > 9 then temp = room - 10 : on temp goto _10 _11 _12 _13 _14 _15 _16 _17 _18 _19
  on room goto _00 _01 _02 _03 _04 _05 _06 _07 _08 _09
badroom rem - room is not 0 to 29
  rem - do whatever
  goto wherever
_00
  rem - etc.

Edited by SeaGtGruff
Link to comment
Share on other sites

It makes more sense to me in this latest example that the hierarchy of "if room >" is now in the opposite order.

Another question, though. In your example, you make use of temp. Is that a valid variable? The guide touches on temp variables but those are all denoted temp1 - temp6 and they need to be reserved or something to that matter. Can I seriously just say "temp = room" and call it a day or is this just for example purposes? Although it's not neccessary, it would be nice to not have to use another variable from a-z.

 

I haven't gotten around to plugging all of this in yet, I've just been sort of working this problem out in my head while I rearrange some code and rename stuff to accommodate this new system, otherwise I'd just plug this all in and see how it works :P.

Link to comment
Share on other sites

Another question, though. In your example, you make use of temp. Is that a valid variable? The guide touches on temp variables but those are all denoted temp1 - temp6 and they need to be reserved or something to that matter.

That's an excellent question! When I wrote my post, I wasn't sure about "temp," but I was too lazy to look it up. I just checked and you're right, "temp" is not a valid (defined) name. (I think it may have been valid many bB versions ago, but I don't feel like checking my old archived versions of bB right now to see.)

 

There are actually *7* "temp" variables, "temp1" through "temp7"-- but "temp7" is used exclusively with bankswitching (I think), so you should avoid it like the plague if you're using bankswitching in your game, although with 2K and 4K games it should actually be the *safest* "temp" variable to use (I think). The other "temp" variables-- "temp1" through "temp6"-- are used by the main kernel and by various bB statements, so they can (generally) be safely used on a *temporary* basis as long as whatever you're using them for doesn't conflict with how bB uses them, and also as long as you realize they might get "blown away" when you call "drawscreen" or use some specific instruction.

 

For example, the "div_mul.asm" and "div_mul16.asm" routines use "temp1" and "temp2," so those two "temp" variables should (generally) be avoided in statements that use any math requiring those routines, because whatever you've set them to will get destroyed whenever the math is done. (But I think something like "temp1 = 23 * a" should be okay, because even though bB will destroy the contents of "temp1" when the math is done, it will then move the results into "temp1" as requested-- so it should be okay as long as you don't do any *more* math that uses the "div_mul.asm" or "div_mul16.asm" routines.)

 

And if you define a user function, calling the user function may use some of the "temp" variables.

 

So I think that "temp1 = room - 10 : on temp1 goto ..." should be safe, because you're using "temp1" on a temporary basis (you don't need it to retain its value after the "on goto" is processed).

 

I haven't memorized all of the bB routines-- and the source code for bB's routines are always subject to future change-- but I *think* bB uses the "temp" variables in the order they're needed. That is, bB will use "temp1" first, and will not use "temp2" unless it's already using "temp1" for something and needs to use another "temp" variable. So that means, generally speaking, that the "temp" variables are safest to use in reverse order-- i.e., "temp6" is safer than "temp5," and "temp5" is safer than "temp4," etc. The exception is "temp7," which-- as I mentioned-- is reserved for bankswitching, so you shouldn't use "temp7" in a bankswitched game or you could screw up the bankswitching big time. The best thing to do is use the "temp" variables sparingly, and only for brief situations where their values will be used right away and it's okay that they'll eventually lose their values when bB uses them for its own purposes.

Link to comment
Share on other sites

Awesome! I'll definitely give the temps a go then when I get to that point, it would save me the hassle of having to use a dedicated variable when they'll only be used for a single frame in the first place. Of course, if that doesn't work out for some reason, there's always the unused playfield variables for storage which I am currently not doing anything with.

 

Update:

 

Although the system is a bit rudimentary atm and I still need to patch bits and pieces here and there for special teleports, doors etc the new system is working thanks to your guys' help. Also, bank 1 now has 2335 bytes of ROM space left, from a very scary 400-something bytes left that I had before, a couple hundred more will be freed up once I tidy some things, remove now unnecessary lines of codes and whatnot. :grin:

Edited by RetroFiends
Link to comment
Share on other sites

A note about using temp variables: sometimes they don't do what you'd expect. Sometimes they have values you didn't expect or they don't update properly. I keep at least one real variable as a "temp" for situations where using temp vars fails.

 

Basically, you should usually have no problem. Just don't trust 'em :)

Link to comment
Share on other sites

Concerning the persistent world thing, I recently was working on a game where the player could move to another room based on a 5 byte array (to create an 8 by 5 map). When the player tries to move to another screen, it checks the array to see if the next bit up/down/left/right is true or false and allow movement based on that.

 

Maybe I misunderstood the problem.

Link to comment
Share on other sites

  • 3 weeks later...

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...
  • Recently Browsing   0 members

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