Jump to content
IGNORED

Stack disruption - Intybasic


cmadruga

Recommended Posts

Quick question... having a GOTO jump to a label outside a procedure creates a stack disruption error on Intybasic.

What is the best way to avoid this situation if the jump is really needed?

 

I tend to use variables that get flagged inside the procedure... so once I'm back to the main loop the variable will trigger the GOTO I need.

 

Are there better ways to deal with this? I'm sure there are. Please enlighten me.

 

 

Link to comment
Share on other sites

Flag variable? Ok I guess I’m already doing that, thanks for confirming.

 

To Artrag’s comments, yes sometimes it is better not to use subroutines... but I have this impulse to leave the main loop as clean as possible... don’t know where that comes from, probably the way I was taught structured/procedural programming decades ago.

Edited by cmadruga
Link to comment
Share on other sites

On 3/14/2020 at 8:58 AM, cmadruga said:

Quick question... having a GOTO jump to a label outside a procedure creates a stack disruption error on Intybasic.

What is the best way to avoid this situation if the jump is really needed?

 

I tend to use variables that get flagged inside the procedure... so once I'm back to the main loop the variable will trigger the GOTO I need.

 

Are there better ways to deal with this? I'm sure there are. Please enlighten me.

 

 

Some Structured Programmers would say GOTOs are forbidden, I rarely use them in IntyBasic but I use a lot of GOSUBs (which made me chuckle way too much while I was writing the SuperPro Gosub game )

 

Your "yes sometimes it is better not to use subroutines" doesn't make sense to me as it isn't the subroutines that are the issue, it is you GOTOing into one instead of GOSUBing. If your subroutine has a lot of labels that you are jumping to, then make the parts of the subroutine small PROCEDUREs and GOSUB to them, a RETURN (or END of the PROCEDURE) will clear the stack properly on exit from the PROCEDURE

 

 

I use variations of this:

WhichCritter=0

MainLoop:
	MovePlayer
	MoveCritters
	WhichCritter=WhichCritter+1:If WhichCritter>2 then WhichCritter=0
Goto MainLoop


MoveCritters: Procedure
On WhichCritter Gosub MoveSnake,MovePig,MoveBird
End

MoveSnake:Procedure
Rem Do something
End

MovePig:Procedure
Rem Do something
End

MoveBird:Procedure
Rem Do something
End

Alternate with GOTO inside the Procedure instead of Gosubs

MoveCritters: Procedure
	On WhichCritter Goto MoveSnake,MovePig,MoveBird

MoveSnake:
	rem do something
Return

MovePig:
	rem do something
Return

MoveBird:
	rem do something
Return

End

 

Link to comment
Share on other sites

I think my comment was misunderstood.

I don't use a lot of GOTOs and I'm not generally replacing GOSUBs by them.

 

The type of situation I'm talking about is this... how would you trigger a new level to be restarted?

Suppose any "dead" condition should decrement LIFE immediately and restart the level.

 

 

 

Start_level:

 

CLS

<initialize variables, etc>

 

main_loop:

      <do a lot of stuff>

      IF (FRAME AND 3)=0 THEN GOSUB check_sprite_and_tile_collision

      <do more stuff>

      IF (FRAME AND 7)=0 THEN GOSUB check_for_other_death_situations

      <do a lot more stuff>

GOTO main_loop

 

 

Check_sprite_and_tile_collision: PROCEDURE

   <if sprite touched a particular tile: dead>

END

 

Check_for_other_death_situations: PROCEDURE

    <if condition: dead>

END

Edited by cmadruga
Link to comment
Share on other sites

For Coleco stuff, I use while(game==1){} Then event to occur below it
if(game==2){...;} or/and while(game==2){} if I need an animation to play like death animation.
additional cases like if(game==3){if you won etc.}  So I use goto to send the pointer up to resetgame or resetlevel labels.

I probably should do the same with my Inty stuff.  I use goto and use flags if I'm using subroutines in Mad Bomer.  I used to do the same with my older Coleco project before I figured out how to use arguments properly.

Mad Bomber exempt:
 

gameloop1:
...
gosub dropbombs
if droptimer=0 then droptimer=bombrate:gosub spawnbombs
if bomberbombs=0 and game=1 then game=0:bomberpause=100
if hitflflag=1 then goto bombhitfloor
...
goto gameloop1
dropbombs:procedure
for i=0 to 4
if bomba(i)=1 then
if dropspeed<>0 then
...

if bomby(i)>100 then hitflflag=1
if bomby(i)<5 then bomby(i)=6
next i

return
end



At late development point, Mad Bomber was going to have stack overflow if I haven't noticed that I was jumping out of the lives procedure into the game over sequence.

 

Link to comment
Share on other sites

6 hours ago, cmadruga said:

I think my comment was misunderstood.

I don't use a lot of GOTOs and I'm not generally replacing GOSUBs by them.

 

The type of situation I'm talking about is this... how would you trigger a new level to be restarted?

Suppose any "dead" condition should decrement LIFE immediately and restart the level.

 

 

 

Start_level:

 

CLS

<initialize variables, etc>

 

main_loop:

      <do a lot of stuff>

      IF (FRAME AND 3)=0 THEN GOSUB check_sprite_and_tile_collision

      <do more stuff>

      IF (FRAME AND 7)=0 THEN GOSUB check_for_other_death_situations

      <do a lot more stuff>

GOTO main_loop

 

 

Check_sprite_and_tile_collision: PROCEDURE

   <if sprite touched a particular tile: dead>

END

 

Check_for_other_death_situations: PROCEDURE

    <if condition: dead>

END

 

I actually do something more like below

You could also use the DO WHILE PlayerDead=0 construct instead of a Main_Loop:

CartLoop:
	Gosub MainMenu
	Gosub MainGame
Goto CartLoop

MainGame:
Start_level:

CLS
<initialize variables, etc>

Restart_Level: 
	Gosub DrawLevelScreen
	PlayerDead=0

main_loop:
      <do a lot of stuff>
      IF (FRAME AND 3)=0 THEN GOSUB check_sprite_and_tile_collision
      <do more stuff>
      IF (FRAME AND 7)=0 THEN GOSUB check_for_other_death_situations
      <do a lot more stuff>
If Lives<=0 then Gosub GameOverScreen:Return Rem Exits MainGame Procedure gracefully back to cartloop
If PlayerDead=1 then GOTO RestartLevel
GOTO main_loop
End Rem End of MainGame Procedures

Check_sprite_and_tile_collision: PROCEDURE
   <if sprite touched a particular tile then PlayerDead=1:Lives=Lives-1>
END 

 

Edited by Tarzilla
Fixed Lives <=0
Link to comment
Share on other sites

5 hours ago, Tarzilla said:

 

I actually do something more like below

You could also use the DO WHILE PlayerDead=0 construct instead of a Main_Loop:


CartLoop:
	Gosub MainMenu
	Gosub MainGame
Goto CartLoop

MainGame:
Start_level:

CLS
<initialize variables, etc>

Restart_Level: 
	Gosub DrawLevelScreen
	PlayerDead=0

main_loop:
      <do a lot of stuff>
      IF (FRAME AND 3)=0 THEN GOSUB check_sprite_and_tile_collision
      <do more stuff>
      IF (FRAME AND 7)=0 THEN GOSUB check_for_other_death_situations
      <do a lot more stuff>
If Lives<=0 then Gosub GameOverScreen:Return Rem Exits MainGame Procedure gracefully back to cartloop
If PlayerDead=1 then GOTO RestartLevel
GOTO main_loop
End Rem End of MainGame Procedures

Check_sprite_and_tile_collision: PROCEDURE
   <if sprite touched a particular tile then PlayerDead=1:Lives=Lives-1>
END 

 

 

Yep, that's what I do too. Like I said on my first post:

 

"I tend to use variables that get flagged inside the procedure... so once I'm back to the main loop the variable will trigger the GOTO I need."

 

And like nanochess said:

 

"The easiest way is to use a flag variable."

 

... Which you did as well with the variable PlayerDead.

 

Thanks for confirming... was just trying to see if there were other ways to deal with it.  ? 

 

 

Link to comment
Share on other sites

5 hours ago, Kiwi said:

For Coleco stuff, I use while(game==1){} Then event to occur below it
if(game==2){...;} or/and while(game==2){} if I need an animation to play like death animation.
additional cases like if(game==3){if you won etc.}  So I use goto to send the pointer up to resetgame or resetlevel labels.

I probably should do the same with my Inty stuff.  I use goto and use flags if I'm using subroutines in Mad Bomer.  I used to do the same with my older Coleco project before I figured out how to use arguments properly.

Mad Bomber exempt:
 


gameloop1:
...
gosub dropbombs
if droptimer=0 then droptimer=bombrate:gosub spawnbombs
if bomberbombs=0 and game=1 then game=0:bomberpause=100
if hitflflag=1 then goto bombhitfloor
...
goto gameloop1
dropbombs:procedure
for i=0 to 4
if bomba(i)=1 then
if dropspeed<>0 then
...

if bomby(i)>100 then hitflflag=1
if bomby(i)<5 then bomby(i)=6
next i

return
end



At late development point, Mad Bomber was going to have stack overflow if I haven't noticed that I was jumping out of the lives procedure into the game over sequence.

 

 

Yep, similar to Tarzilla, you are using a flag variable ("hitflflag") to do the GOTO from the main loop versus inside the procedure ("dropbombs").

 

(I didn't quite get the use of "game=1" and "game=0", but probably because I would need to read a little more of your code.)

 

Thanks guys!

 

 

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

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