Sporadic Posted August 10, 2015 Author Share Posted August 10, 2015 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. Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted August 11, 2015 Share Posted August 11, 2015 (edited) 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 August 11, 2015 by sh3-rg Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 Be interesting to see what the cause is once you pin it down. 100% my crap coding . More than likely Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted August 11, 2015 Share Posted August 11, 2015 100% my crap coding . More than likely I see we have much in common in this regard :0) 1 Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 (edited) 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 August 11, 2015 by Sporadic Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 (edited) 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 August 11, 2015 by Sporadic Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 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! Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 F*cks sake. it's back..... It's almost like if I add a variable or code, then it randomly reappears again. The search continues.... Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 (edited) 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 August 11, 2015 by Sporadic Quote Link to comment Share on other sites More sharing options...
ggn Posted August 11, 2015 Share Posted August 11, 2015 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... Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted August 11, 2015 Share Posted August 11, 2015 (edited) 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 Edited August 11, 2015 by sh3-rg Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 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 Yes, I was thinking the same kind of thing. I will report back as soon as i've tried it. 1 Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 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 Quote Link to comment Share on other sites More sharing options...
CrazyChris Posted August 11, 2015 Share Posted August 11, 2015 nonexistent100% my crap coding . More than likely Better than my nonexistent crap coding. Quote Link to comment Share on other sites More sharing options...
ggn Posted August 11, 2015 Share Posted August 11, 2015 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! 2 Quote Link to comment Share on other sites More sharing options...
GroovyBee Posted August 11, 2015 Share Posted August 11, 2015 What we're looking at is the BSS section which in plain terms tells the assembler to reserve RAM for unitialised data.But... but... its initialised to 0 . Is the equivalent of crt0.s doing the right thing with the BSS and DATA sections? Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 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. 2 Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 11, 2015 Author Share Posted August 11, 2015 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? Quote Link to comment Share on other sites More sharing options...
ggn Posted August 12, 2015 Share Posted August 12, 2015 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). Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted August 12, 2015 Share Posted August 12, 2015 (edited) 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 August 12, 2015 by sh3-rg Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 12, 2015 Author Share Posted August 12, 2015 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 Quote Link to comment Share on other sites More sharing options...
+CyranoJ Posted August 12, 2015 Share Posted August 12, 2015 There's no hard sprite/object limit Yes there is... 512. Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted August 12, 2015 Share Posted August 12, 2015 There's effectively no hard sprite/object limit I think I'll STFU now and leave CJ to answer these things... Quote Link to comment Share on other sites More sharing options...
sh3-rg Posted August 12, 2015 Share Posted August 12, 2015 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. Quote Link to comment Share on other sites More sharing options...
Sporadic Posted August 12, 2015 Author Share Posted August 12, 2015 Yes there is... 512. I can safely say i'm not anywhere near that (unless particles count perhaps lmao) 1 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.