RetroFiends Posted August 22, 2013 Share Posted August 22, 2013 (edited) 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 August 22, 2013 by RetroFiends Quote Link to comment Share on other sites More sharing options...
bogax Posted August 22, 2013 Share Posted August 22, 2013 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? Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted August 22, 2013 Share Posted August 22, 2013 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). 1 Quote Link to comment Share on other sites More sharing options...
RevEng Posted August 22, 2013 Share Posted August 22, 2013 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. 1 Quote Link to comment Share on other sites More sharing options...
RetroFiends Posted August 22, 2013 Author Share Posted August 22, 2013 (edited) 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 August 22, 2013 by RetroFiends Quote Link to comment Share on other sites More sharing options...
RevEng Posted August 22, 2013 Share Posted August 22, 2013 Check out the warning section of on...goto at RT's website: http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#ongoto Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted August 22, 2013 Share Posted August 22, 2013 (edited) 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 August 22, 2013 by SeaGtGruff Quote Link to comment Share on other sites More sharing options...
RevEng Posted August 22, 2013 Share Posted August 22, 2013 Yup, that's right on all counts. Quote Link to comment Share on other sites More sharing options...
RetroFiends Posted August 22, 2013 Author Share Posted August 22, 2013 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 . Quote Link to comment Share on other sites More sharing options...
SeaGtGruff Posted August 22, 2013 Share Posted August 22, 2013 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. Quote Link to comment Share on other sites More sharing options...
RetroFiends Posted August 22, 2013 Author Share Posted August 22, 2013 (edited) 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. Edited August 22, 2013 by RetroFiends Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted August 22, 2013 Share Posted August 22, 2013 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 Quote Link to comment Share on other sites More sharing options...
Cybearg Posted August 24, 2013 Share Posted August 24, 2013 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. Quote Link to comment Share on other sites More sharing options...
+Random Terrain Posted September 12, 2013 Share Posted September 12, 2013 There are actually . . . When you can find the time, maybe you can see if this needs to be adjusted or updated: randomterrain.com/atari-2600-memories-batari-basic-commands.html#temp_variables Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.