Jump to content
IGNORED

Astro-Storm - My new RB+ Game


Recommended Posts

Would have posted another version by now but I have a bug that i'm trying to kill.

 

Basically when I display one of my new score sprites, I get about 6 particles appear on the particle layer in a horizontal line next to each other.

 

I've seen this kind of wierdness before when getting something out of range or knackering something in the memory somehow. I've picked through everything and there seems to be a certain couple of lines that cause the problem (in my new score sprite code).

If I take out or change the values in these lines then it seems to stop, but I cannot see why they would be causing the problem.

 

So, I'm going to keep messing around and hopefully come up with a fix soon. Just thought i'd post a status update.

Link to comment
Share on other sites

Be interesting to see what the cause is once you pin it down.

 

Only time I encounter odd behaviour is when accidentally making the last object in the list inactive - raptor doesn't like this. To prevent it I usually add a tiny dummy object at the end of the list and keep it active but out of the visible screen area.

 

That's probably got nothing to do with that's happening with your particles, but that kind of thing can happen when raptor encounters some unexpected stuff.

Edited by sh3-rg
Link to comment
Share on other sites

Ok that is weird. I seem to have got it working. But I have no idea why it now works.

 

The "Does not Work" code produces a small horizontal line of pixels (of varying colours) in the particle layer that eventually gets erased by the star field as it's overdrawn. The line will re-appear whenever I call the SUB again though. The SUB gets called when you shoot a rock.

The line that appears is in the same location on the screen every time (not near the sprite i'm drawing).

 

Here is the code in question;

 

Works
SUB SHOWPOINTS
  FOR scorei = 0 TO 4
    tmpscorespr = scoresprites+scorei

    IF RGETOBJ(tmpscorespr,R_sprite_active) = R_is_inactive THEN
      RSETOBJ(tmpscorespr,R_sprite_gfxbase,score500gfx)

      RSETOBJ(tmpscorespr,R_sprite_x,(tx)<<16)
      RSETOBJ(tmpscorespr,R_sprite_y,(ty)<<16)

      RSETOBJ(tmpscorespr,R_sprite_scale_x,64)
      RSETOBJ(tmpscorespr,R_sprite_scale_y,64)

      RSETOBJ(tmpscorespr,R_sprite_active,R_is_active)

      EXIT FOR
    ENDIF
  NEXT
END SUB
Does Not Work
SUB SHOWPOINTS
  FOR scorei = 0 TO 4
 
    IF RGETOBJ(scoresprites+scorei,R_sprite_active) = R_is_inactive THEN
      RSETOBJ(scoresprites+scorei,R_sprite_gfxbase,score500gfx)
 
      RSETOBJ(scoresprites+scorei,R_sprite_x,(tx)<<16)
      RSETOBJ(scoresprites+scorei,R_sprite_y,(ty)<<16)
 
      RSETOBJ(scoresprites+scorei,R_sprite_scale_x,64)
      RSETOBJ(scoresprites+scorei,R_sprite_scale_y,64)
 
      RSETOBJ(scoresprites+scorei,R_sprite_active,R_is_active)
 
      EXIT FOR
    ENDIF
  NEXT
END SUB
Basically scoresprites is an INT variable pointing to the score sprite in the object list. This sprite in the object list has its number (quantity) set to 5. Hence the FOR loop to iterate over those 5 to find an available one.
As you can see, all i've done is to move the addition to a separate variable and then use that.
There is a separate SUB called in the main loop to shink and eventually hide any active score sprites but i've not included that here as it didn't seem to have any affect.
I have used the "does not work" technique in a couple of other places and it worked fine. The only difference is the "Exit For" which i've not used elsewhere. But if I take that out, the problem persists.
The only other way I got the "Does not work" method to show a sprite without the dots was to remove the FOR loop and hard code scorei=0.
All in all, very strange but it appears to work now so I am more than happy to just accept it and move on.
I've just put this here for reference in case anyone is interested.
Edited by Sporadic
Link to comment
Share on other sites

I jumped the gun there.

 

Just changed to this so I can tell it which sprite to show and the line appears again now;

 

SUB SHOWPOINTS(num%)
  FOR scorei = 0 TO 4
    tmpscorespr = scoresprites+scorei
 
    IF RGETOBJ(tmpscorespr,R_sprite_active) = R_is_inactive THEN
 
      IF num% = 100 THEN
        RSETOBJ(tmpscorespr,R_sprite_gfxbase,score100gfx)
      ELSEIF num% = 200 THEN
        RSETOBJ(tmpscorespr,R_sprite_gfxbase,score200gfx)
      ELSEIF num% = 500 THEN
        RSETOBJ(tmpscorespr,R_sprite_gfxbase,score500gfx)
      ENDIF
 
      RSETOBJ(tmpscorespr,R_sprite_x,(tx)<<16)
      RSETOBJ(tmpscorespr,R_sprite_y,(ty)<<16)
 
      RSETOBJ(tmpscorespr,R_sprite_scale_x,64)
      RSETOBJ(tmpscorespr,R_sprite_scale_y,64)
 
      RSETOBJ(tmpscorespr,R_sprite_active,R_is_active)
 
      EXIT FOR
    ENDIF
  NEXT
END SUB
I'll keep looking......
Edited by Sporadic
Link to comment
Share on other sites

Now it works again....

 

I removed the parameter from the SUB and created 3 subs instead, one for each score size (Yuk!)

 

Still, it helps me with my UberLineNumber Achievement.


SUB SHOWPOINTS100
	FOR scorei = 0 TO 4	
		tmpscorespr = scoresprites+scorei
	
		IF RGETOBJ(tmpscorespr,R_sprite_active) = R_is_inactive THEN		
		
			RSETOBJ(tmpscorespr,R_sprite_gfxbase,score100gfx)			
			
			RSETOBJ(tmpscorespr,R_sprite_x,(tx)<<16)
			RSETOBJ(tmpscorespr,R_sprite_y,(ty)<<16)
			
			RSETOBJ(tmpscorespr,R_sprite_scale_x,64)	
			RSETOBJ(tmpscorespr,R_sprite_scale_y,64)	
			
			RSETOBJ(tmpscorespr,R_sprite_active,R_is_active)
			
			EXIT FOR
		ENDIF
	NEXT
END SUB

SUB SHOWPOINTS200
	FOR scorei = 0 TO 4	
		tmpscorespr = scoresprites+scorei
	
		IF RGETOBJ(tmpscorespr,R_sprite_active) = R_is_inactive THEN		
		
			RSETOBJ(tmpscorespr,R_sprite_gfxbase,score200gfx)			
			
			RSETOBJ(tmpscorespr,R_sprite_x,(tx)<<16)
			RSETOBJ(tmpscorespr,R_sprite_y,(ty)<<16)
			
			RSETOBJ(tmpscorespr,R_sprite_scale_x,64)	
			RSETOBJ(tmpscorespr,R_sprite_scale_y,64)	
			
			RSETOBJ(tmpscorespr,R_sprite_active,R_is_active)
			
			EXIT FOR
		ENDIF
	NEXT
END SUB

SUB SHOWPOINTS500
	FOR scorei = 0 TO 4	
		tmpscorespr = scoresprites+scorei
	
		IF RGETOBJ(tmpscorespr,R_sprite_active) = R_is_inactive THEN		
		
			RSETOBJ(tmpscorespr,R_sprite_gfxbase,score500gfx)			
			
			RSETOBJ(tmpscorespr,R_sprite_x,(tx)<<16)
			RSETOBJ(tmpscorespr,R_sprite_y,(ty)<<16)
			
			RSETOBJ(tmpscorespr,R_sprite_scale_x,64)	
			RSETOBJ(tmpscorespr,R_sprite_scale_y,64)	
			
			RSETOBJ(tmpscorespr,R_sprite_active,R_is_active)
			
			EXIT FOR
		ENDIF
	NEXT
END SUB

So, its working again. Hopefully thats that now!

Link to comment
Share on other sites

Out of time for today now.

 

If I take these lines out of those 3 score SUBs then the particle layer 'line' doesn't appear...

RSETOBJ(tmpscorespr,R_sprite_gfxbase,score100gfx)
RSETOBJ(tmpscorespr,R_sprite_gfxbase,score200gfx)
RSETOBJ(tmpscorespr,R_sprite_gfxbase,score500gfx)

So that to me says it's a funky graphics memory corruption type situation.

 

I'm sure I have my vars set correctly.

'Snippet of DIMs;
DIM scoresprites%	:scoresprites=turreth+1
DIM score200%		:score200=scoresprites+5
DIM score500%		:score500=score200+1

'Grabbing the gfx locations;
dim score100gfx%
score100gfx=RGETOBJ(scoresprites,R_sprite_gfxbase)

dim score200gfx%
score200gfx=RGETOBJ(score200,R_sprite_gfxbase)

dim score500gfx%
score500gfx=RGETOBJ(score500,R_sprite_gfxbase)

I've used a similar technique for the rocks, explosions, fonts etc and they seem ok.

 

I might just try creating 3 of each score sprite in the object list and take out the R_sprite_gfxbase manipulation to see if that helps. That'll have to be another time though as back to work now.

Edited by Sporadic
Link to comment
Share on other sites

Ok, I might be miles off here but try this: open build.bat and seach for the lines it calls m68k-atari-mint-gcc. Now there should be a -O2 switch there. Try changing it to -O0 (that's capital o, zero) or -Os and see if it fixes anything...

Link to comment
Share on other sites

been reading back and forth and cannot see anything obvious at all, but I do know that when there are issues with available resources, particle oddness can be one way they show up. only thing I can think of is maybe you're on the limit of doing stuff in a frame and things are falling down when you rejiggle things that seem to be doing exactly the same code-wise but might end up executing slightly differently when run?

 

oh, GGN thinks maybe optimisations stuff, that has potentially cause a few issues for me trying to do too many palette blends at the same time. ignore my junk above :P

Edited by sh3-rg
Link to comment
Share on other sites

Ok, I might be miles off here but try this: open build.bat and seach for the lines it calls m68k-atari-mint-gcc. Now there should be a -O2 switch there. Try changing it to -O0 (that's capital o, zero) or -Os and see if it fixes anything...

I will give it a go later, thank you for the suggestion.

 

been reading back and forth and cannot see anything obvious at all, but I do know that when there are issues with available resources, particle oddness can be one way they show up. only thing I can think of is maybe you're on the limit of doing stuff in a frame and things are falling down when you rejiggle things that seem to be doing exactly the same code-wise but might end up executing slightly differently when run?

 

oh, GGN thinks maybe optimisations stuff, that has potentially cause a few issues for me trying to do too many palette blends at the same time. ignore my junk above :P

Yes, I was thinking the same kind of thing.

 

I will report back as soon as i've tried it.

  • Like 1
Link to comment
Share on other sites

Ok, I might be miles off here but try this: open build.bat and seach for the lines it calls m68k-atari-mint-gcc. Now there should be a -O2 switch there. Try changing it to -O0 (that's capital o, zero) or -Os and see if it fixes anything...

Unfortunately neither worked.

 

I don't know if it's relevant but the "line" appeared in a different location for -Os

Link to comment
Share on other sites

Ok, back home with some painkillers for my head, which means I can actually read and comprehend what everyone's talking about!

 

First of all, I'd use something similar to the "works" version because there are much less computations that are carried out in the subroutine. You can of course use the first subroutine and there's a chance of the wishful statement of all C programmers "the compiler will optimise it" might happen (i.e. do something like the "works" version behind the scenes) but you really can't count on it. Actually I'd set tmpscorespr to scoresprites outside the loop and then increase it by one at the end. Of course this isn't the real problem here, just wanted to write this here as it's a good thing to do.

 

Now then, for the issue at hand. Let's take a look at the end of rapapp.s of a typical rb+ program. This is a copy/paste from the template file

 

 


;;
;; BSS SECTION
;;

.bss
top_of_bss:

RAPTOR_MTtrash: .ds.b 16384 ; Workspace for MemoryTrack routines

.dphrase
RAPTOR_particle_gfx: .ds.b (raptor_particle_buffer_width/2)*raptor_particle_buffer_height ; particle FX buffer
RAPTOR_particle_gfxe:
.dphrase
RAPTOR_sprite_table: .ds.b sprite_max*sprite_tabwidth ; RAPTOR sprite database
.dphrase
RAPTOR_particle_table: .ds.b raptor_particle_pixels*particle_tabwidth ; RAPTOR particle database
.dphrase


_trashram:

What we're looking at is the BSS section which in plain terms tells the assembler to reserve RAM for unitialised data. As you see, we have space for the MT, the particle/text layer, the sprites table and finally the particle table. Now this is the exact order that these buffers will be allocated. So if your code+data ends at $6000, RAPTOR_MTtrash will be $6000, RAPTOR_particle_gfx will be $6000+16384 etc etc. Now, I'm almost sure that the particle layer is written by something from your code, which means something is pointing to the wrong address. I see the sprite table is close to the particle layer. So if some rsetobj is corrupting the particles layer it would probably be given a negative value. The code that is actually rsetobj takes the sprite index, multiplies it by 188 and then adds the offset you're telling it to.

 

How to debug this? Try lowering the for...next limit. Does it poop out from 0 to 0? 0 to 3? 0 to 2? Try printing the parameters you're passing to rsetobj. Any weird values there?

 

That's all I can think of right now. Good luck!

  • Like 2
Link to comment
Share on other sites

Ok, back home with some painkillers for my head, which means I can actually read and comprehend what everyone's talking about!

 

First of all, I'd use something similar to the "works" version because there are much less computations that are carried out in the subroutine. You can of course use the first subroutine and there's a chance of the wishful statement of all C programmers "the compiler will optimise it" might happen (i.e. do something like the "works" version behind the scenes) but you really can't count on it. Actually I'd set tmpscorespr to scoresprites outside the loop and then increase it by one at the end. Of course this isn't the real problem here, just wanted to write this here as it's a good thing to do.

 

Now then, for the issue at hand. Let's take a look at the end of rapapp.s of a typical rb+ program. This is a copy/paste from the template file

 

What we're looking at is the BSS section which in plain terms tells the assembler to reserve RAM for unitialised data. As you see, we have space for the MT, the particle/text layer, the sprites table and finally the particle table. Now this is the exact order that these buffers will be allocated. So if your code+data ends at $6000, RAPTOR_MTtrash will be $6000, RAPTOR_particle_gfx will be $6000+16384 etc etc. Now, I'm almost sure that the particle layer is written by something from your code, which means something is pointing to the wrong address. I see the sprite table is close to the particle layer. So if some rsetobj is corrupting the particles layer it would probably be given a negative value. The code that is actually rsetobj takes the sprite index, multiplies it by 188 and then adds the offset you're telling it to.

How to debug this? Try lowering the for...next limit. Does it poop out from 0 to 0? 0 to 3? 0 to 2? Try printing the parameters you're passing to rsetobj. Any weird values there?

 

That's all I can think of right now. Good luck!

 

Thank you for the in-depth explanation.

 

I have just had the chance to try again at home (on a different machine) and it's currently working. I forgot to copy my latest version of code so had the non-working version from yesterday - I changed the SUB to the code below and it just worked....

SUB SHOWPOINTS(num%)
	scoretmpcnt = scoresprites
	FOR scorei = 0 TO 4		
		IF RGETOBJ(scoretmpcnt,R_sprite_active) = R_is_inactive THEN	
		
			IF num% = 100 THEN
				RSETOBJ(scoretmpcnt,R_sprite_gfxbase,score100gfx)
			ELSEIF num% = 200 THEN
				RSETOBJ(scoretmpcnt,R_sprite_gfxbase,score200gfx)
			ELSEIF num% = 500 THEN
				RSETOBJ(scoretmpcnt,R_sprite_gfxbase,score500gfx)
			ENDIF
			
			RSETOBJ(scoretmpcnt,R_sprite_active,R_is_active)		
			
			RSETOBJ(scoretmpcnt,R_sprite_x,tx<<16)
			RSETOBJ(scoretmpcnt,R_sprite_y,ty<<16)
			
			RSETOBJ(scoretmpcnt,R_sprite_scale_x,50)	
			RSETOBJ(scoretmpcnt,R_sprite_scale_y,50)	
			
			EXIT FOR
		ENDIF
		scoretmpcnt++
	NEXT
END SUB

As you can see, I have taken your advice regarding the variable and incrementing it at the end.

 

I will try this code again tomorrow and see how it goes (if the problem reappears).

 

If this works on my other machine then I will try swapping out code to try and break it again, then play spot the difference. It would be nice to know the cause, not just for my sanity but also in case it helps others.

 

Thanks all again for the help and suggestions.

  • Like 2
Link to comment
Share on other sites

I need to stop speaking too soon :(

 

I just thought I would apply the tip for the variable in the loops to another area of code. I made that change and the problem has reappeared.

 

I changed this;

LIFECHECK=0
	FOR currentmob = 0 TO mobsloop
		IF mobLife[currentmob] > 0 THEN
			LIFECHECK++	
			
			mobX[currentmob] = RGETOBJ(startmob+currentmob,R_sprite_x)
			mobY[currentmob] = RGETOBJ(startmob+currentmob,R_sprite_y)
		
			IF mobX[currentmob] < (minxx)<<16 THEN
				mobX[currentmob] = maxxx
				RSETOBJ(startmob+currentmob,R_sprite_x,(mobX[currentmob]<<16))
			ELSEIF mobX[currentmob] > (maxxx)<<16 THEN
				mobX[currentmob] = minxx
				RSETOBJ(startmob+currentmob,R_sprite_x,(mobX[currentmob]<<16))
			ENDIF
			
			IF mobY[currentmob] < (minyy)<<16 THEN
				mobY[currentmob] = maxyy
				RSETOBJ(startmob+currentmob,R_sprite_y,(mobY[currentmob]<<16))
			ELSEIF mobY[currentmob] > (maxyy)<<16 THEN
				mobY[currentmob] = minyy
				RSETOBJ(startmob+currentmob,R_sprite_y,(mobY[currentmob]<<16))
			ENDIF
				
		ENDIF
	NEXT

To this;

        LIFECHECK=0
	mobtmpcnt = startmob
	FOR currentmob = 0 TO mobsloop
		IF mobLife[currentmob] > 0 THEN
			LIFECHECK++	
			
			mobX[currentmob] = RGETOBJ(mobtmpcnt,R_sprite_x)
			mobY[currentmob] = RGETOBJ(mobtmpcnt,R_sprite_y)
		
			IF mobX[currentmob] < (minxx)<<16 THEN
				mobX[currentmob] = maxxx
				RSETOBJ(mobtmpcnt,R_sprite_x,(mobX[currentmob]<<16))
			ELSEIF mobX[currentmob] > (maxxx)<<16 THEN
				mobX[currentmob] = minxx
				RSETOBJ(mobtmpcnt,R_sprite_x,(mobX[currentmob]<<16))
			ENDIF
			
			IF mobY[currentmob] < (minyy)<<16 THEN
				mobY[currentmob] = maxyy
				RSETOBJ(mobtmpcnt,R_sprite_y,(mobY[currentmob]<<16))
			ELSEIF mobY[currentmob] > (maxyy)<<16 THEN
				mobY[currentmob] = minyy
				RSETOBJ(mobtmpcnt,R_sprite_y,(mobY[currentmob]<<16))
			ENDIF
				
		ENDIF
		mobtmpcnt++
	NEXT

At the top of the main program I also DIM'ed the new variable mobtmpcnt .

 

Is there any chance I am near some kind of limit for sprite count, sprite memory, code memory?

Link to comment
Share on other sites

Is there any chance I am near some kind of limit for sprite count, sprite memory, code memory?

 

That's not impossible - check the size of the created .abs file. If it's close to 1.9-2mb then probably yes. (come to think of it, I never put any protection against that).

Link to comment
Share on other sites

Is there any chance I am near some kind of limit for sprite count, sprite memory, code memory?

There's no hard sprite/object limit, but there will come a time when things fall apart because you're asking for too many. This could be having a list that is too lengthy to process or having too many objects overlapping on screen. The first one could be helped with the use of branch objects, but rB+ doesn't support those fully yet. The second is down to how you manage your game and is obvious to spot as you'll see objects momentarily flicker or black lines appear through your screen and the remainder stretching out. Neither of these would seem like a cause for what you're seeing, but your game could be low on RAM and falling down because of that.

 

A quick way to help free some up might be to temporarily replace one of the larger sound samples with a tiny one and see if the problem still shows. If it is that, you might be able to claw back a tiny amount of RAM by clipping dead areas form the start and end of those, before doing anything drastic like reducing colour depths on your objects or whatever.

Edited by sh3-rg
Link to comment
Share on other sites

 

That's not impossible - check the size of the created .abs file. If it's close to 1.9-2mb then probably yes. (come to think of it, I never put any protection against that).

The .abs is 1049k. So plenty there.

 

There's no hard sprite/object limit, but there will come a time when things fall apart because you're asking for too many. This could be having a list that is too lengthy to process or having too many objects overlapping on screen. The first one could be helped with the use of branch objects, but rB+ doesn't support those fully yet. The second is down to how you manage your game and is obvious to spot as you'll see objects momentarily flicker or black lines appear through your screen and the remainder stretching out. Neither of these would seem like a cause for what you're seeing, but your game could be low on RAM and falling down because of that.

 

A quick way to help free some up might be to temporarily replace one of the larger sound samples with a tiny one and see if the problem still shows. If it is that, you might be able to claw back a tiny amount of RAM by clipping dead areas form the start and end of those, before doing anything drastic like reducing colour depths on your objects or whatever.

I've not have time today (pub lunch was more appealing) so I will have a mess around as soon as I can and report back.

 

Thanks

Link to comment
Share on other sites

 

But, the highscore table works with and without the memory track inserted.

I managed to save my first highscores :) So thanks again everyone involved in getting that added.

 

 

Going to attempt to pick your brains here... did you have any issues implementing this at all?

 

I gave it a go as I got high score handling working in my game, but everything freezes when I attempt to perform the write.

 

If I check the MT the save is there, so it is created when it first loads... but after that nope.

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...