Jump to content

Photo

Scanline problem. I'm stuck


25 replies to this topic

#1 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • 364 posts
  • Location:Stockholm

Posted Wed Oct 3, 2018 3:21 PM

Ok so I've been fighting the scanlines in my game the last few days but to no avail. I've narrowed it down to it being the AI as its stable when in 2p mode and flickering when in 1p mode. (leftwitch to A) The flicker always seems to happen when playfieldpos = 7 or 8 (It depends on if the frame showing too many scanlines is the one on which its happening or if thats the frame after the overload.) However, turning off the AI at certain playfieldpos does not seem to work. Adding in an additional drawscreen solves the problem, but it also slows down the game beyond the point of it being playable. 

 

So I was wondering if anyone has an idea on how to solve this.

  • Is there a way to keep the scrollspeed high while adding a new drawscreen?  
  • Is there a way to know were in the script the code is when its overloading? Most sections are not timing critical within 1 frame, so heavy things could be turned off at a certain playfieldpos.
  • Are there any other brilliant solutions that I am missing? 

The starting speed in this version is high because the blinking only happens at high speeds. That's ~100 in this build. 

 

Any help would be massively appreciated, as the grim alternative is killing the AI. 

Attached Files



#2 Lewis2907 OFFLINE  

Lewis2907

    Moonsweeper

  • 276 posts
  • Location:Senatobia, MS

Posted Wed Oct 3, 2018 5:05 PM

What I did in the past was moved the drawscreen to another location in bank and that solved it. Example was that the collision need to be after the drawscreen to work properly. That may help you until someone else chimes in.

#3 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 532 posts

Posted Wed Oct 3, 2018 6:11 PM

I don't know when I'll have a chance to look at your code, but a couple of thoughts:

 

The latest RevEng build of bB has a change that names the build files with names that will be recognized by the Stella debugger.  Using the debugger and being able to see your variable/label names makes troubleshooting this stuff much easier.

 

Lewis has a good point about whether the code is before or after the drawscreen, because playfieldpos is incremented at this point.

 

At any rate, the problem happens when the AI is active, so it may just be a matter of trial and error to figure out where it is encountering problems.  Maybe go extreme for the sake of experimentation, and only run the AI when playfieldpos < 5.  If that works, move it up to 6 or 7.

 

Since you had issues with the AI being too good, having a couple of frames where it does nothing might cause it to make a few mistakes without being overly obvious.



#4 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Thu Oct 4, 2018 3:21 AM

What I did in the past was moved the drawscreen to another location in bank and that solved it. Example was that the collision need to be after the drawscreen to work properly. That may help you until someone else chimes in.

I tried that and it does need to be above the collisions yes, but other then that it doesn't seem to change much. Also moving the AI section to above or below it doesn't seem to help much. (Apart from the AI getting dumber when it's above :P)

 

I don't know when I'll have a chance to look at your code, but a couple of thoughts:

 

The latest RevEng build of bB has a change that names the build files with names that will be recognized by the Stella debugger.  Using the debugger and being able to see your variable/label names makes troubleshooting this stuff much easier.

 

Lewis has a good point about whether the code is before or after the drawscreen, because playfieldpos is incremented at this point.

 

At any rate, the problem happens when the AI is active, so it may just be a matter of trial and error to figure out where it is encountering problems.  Maybe go extreme for the sake of experimentation, and only run the AI when playfieldpos < 5.  If that works, move it up to 6 or 7.

 

Since you had issues with the AI being too good, having a couple of frames where it does nothing might cause it to make a few mistakes without being overly obvious.

I've tried just running it on certain pfpostions but it doesn't seem to solve the issue. And that surprised me because it still only happens when the pfpos is ~0. But turning it off all together does solve it. So that's strange. Perhaps I'm doing something very dumb, I'll keep looking. But if you manage to find some time that would be great too! I'll also look into the debugger, as I still cant get that to work properly.



#5 Lewis2907 OFFLINE  

Lewis2907

    Moonsweeper

  • 276 posts
  • Location:Senatobia, MS

Posted Thu Oct 4, 2018 7:24 AM

I forgot to mention as I have not seen your code yet, but I use return thisbank and otherbank as it seemed to help when I had an issue with scalines.

#6 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 532 posts

Posted Thu Oct 4, 2018 7:56 AM

His project isn't bankswitched, so that's not the issue.



#7 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Thu Oct 4, 2018 3:14 PM

Moving the drawscreen does not seem to work either 



#8 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,779 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Thu Oct 4, 2018 3:32 PM

I don't know if I can do anything, but I'm looking now.



#9 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,779 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Thu Oct 4, 2018 3:43 PM

Found two problems so far:
 

   if bally > 200 && !(rand&7) then bally = 0 : _Ch0_Sound = 5 : _Ch0_Duration = 25 : _F0 = 31 : _bleep =0 ;: missile0y = 160 : missile1y = 160

 

   if _speed > 254 && !_left_right{1} then _left_right{1} = 1 : _speed = 0

 

According to the chart, NOT cannot be used with < > =. You also have "_bleep =0 ;: missile0y = 160 : missile1y = 160" is that semicolon supposed to be there?



#10 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,779 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Thu Oct 4, 2018 7:52 PM

Just glancing at the code below, could that last if-then cause too much time to go by before a drawscreen happens?

 

__scrolldown

   ; animate sprite 
   _animate = _animate + 1
   if _animate > 5 then _animate = 0


   ; check if a new tree block needs to be made and then see if a branch should be made
   if playfieldpos = 1 then _left_right{0} = 1  : pfpixel 8 0 8 on : pfpixel 24 0 24 on   else _left_right{0} = 0 
   if _left_right{0} && (rand&1) then gosub __branch 


   ; Move magic stones & ball & scroll screen

   missile0y = missile0y + 1
   missile1y = missile1y + 1
   bally = bally + 2
   pfscroll down

__skipscroll

   if _left_right{1} && _left_right{2} then _left_right{2} =0 : goto __scrolldown

 



#11 ZackAttack ONLINE  

ZackAttack

    Dragonstomper

  • 747 posts
  • Location:Orlando, FL US

Posted Thu Oct 4, 2018 8:57 PM

I'm not very familiar with bB, but I think replacing this

if _left_right{1} && _left_right{2} then

 with

if (_left_right & 6) = 6 then

may be faster.

 

Also I think you could replace

if _left_right{0} && (rand&1) then gosub __branch 

with

if _left_right & rand & 1 then gosub __branch 

Of course you would probably want to verify the cycle counts with stella to confirm which way is faster.

 

*Edit: Fixed syntax for equal comparison


Edited by ZackAttack, Thu Oct 4, 2018 9:43 PM.


#12 Random Terrain OFFLINE  

Random Terrain

    Visual batari Basic User

  • 28,779 posts
  • Controlled Randomness
    Replay Value
    Nonlinear
  • Location:North Carolina (USA)

Posted Thu Oct 4, 2018 9:38 PM

I don't think we can use ==.

 

Boolean Operators

 

I can't find it, but I saw a thread where the parentheses made a difference.



#13 ZackAttack ONLINE  

ZackAttack

    Dragonstomper

  • 747 posts
  • Location:Orlando, FL US

Posted Thu Oct 4, 2018 9:44 PM

I don't think we can use ==.

 

Edited syntax above. Better?



#14 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Fri Oct 5, 2018 2:04 AM

Just glancing at the code below, could that last if-then cause too much time to go by before a drawscreen happens?

 

__scrolldown

   ; animate sprite 
   _animate = _animate + 1
   if _animate > 5 then _animate = 0


   ; check if a new tree block needs to be made and then see if a branch should be made
   if playfieldpos = 1 then _left_right{0} = 1  : pfpixel 8 0 8 on : pfpixel 24 0 24 on   else _left_right{0} = 0 
   if _left_right{0} && (rand&1) then gosub __branch 


   ; Move magic stones & ball & scroll screen

   missile0y = missile0y + 1
   missile1y = missile1y + 1
   bally = bally + 2
   pfscroll down

__skipscroll

   if _left_right{1} && _left_right{2} then _left_right{2} =0 : goto __scrolldown

 

 

It only happens at high speeds (so when _left_right{1} = 1) so I think that that running that twice + the AI is too much yes. But without it the game moves to slowly so I never really did much with that line. I tried to turn it off on certain PFpositions once but then the tree got very glitchy with holes in it and double branches, etc. The blink also usually happens when a block is made, but not always! So this probably also is a culprit. 

if playfieldpos = 1 then _left_right{0} = 1  : pfpixel 8 0 8 on : pfpixel 24 0 24 on   else _left_right{0} = 0 

And this one should stay on PFpos=1 because otherwise the scrolling of the tree is ugly. 

 

I'm not very familiar with bB, but I think replacing this

if _left_right{1} && _left_right{2} then

 with

if (_left_right & 6) = 6 then

may be faster.

 

Also I think you could replace

if _left_right{0} && (rand&1) then gosub __branch 

with

if _left_right & rand & 1 then gosub __branch 

Of course you would probably want to verify the cycle counts with stella to confirm which way is faster.

 

*Edit: Fixed syntax for equal comparison

 

What does the first one actually do? The (_left_right & 6) ? _left_right{3} is also sometimes used, so you can't just compare it to a value based on the rest being 0. (If thats what it does!) And if it is I might be able to make the rest 0 and move the used bits to other variables. 

 

Same question with the other line. What does the single & do? (Not really easy to google for :P). (Don't have my laptop on me now, so can't try it until later this evening.)

 

Thanks for looking everyone!


Edited by Coolcrab, Fri Oct 5, 2018 2:05 AM.


#15 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 532 posts

Posted Fri Oct 5, 2018 6:36 AM

I've looked at this a bit, and I don't think there's a simple "magic bullet" solution - it will take trial and error and rearranging code to see what works.  I noticed that it overcycles sometimes when playfieldpos = 1 even without the AI.  pfpixel operations are expensive in terms of cycles, so this may be a factor.

 

What may help is using cycles from vblank.  If you add a vblank section and move your AI code there, and perhaps your pfpixel operations as well then this may help solve your issue with overcycling.



#16 ZackAttack ONLINE  

ZackAttack

    Dragonstomper

  • 747 posts
  • Location:Orlando, FL US

Posted Fri Oct 5, 2018 8:59 AM

What does the first one actually do? The (_left_right & 6) ? _left_right{3} is also sometimes used, so you can't just compare it to a value based on the rest being 0. (If thats what it does!) And if it is I might be able to make the rest 0 and move the used bits to other variables. 

 

Same question with the other line. What does the single & do? (Not really easy to google for :P). (Don't have my laptop on me now, so can't try it until later this evening.)

 

Thanks for looking everyone!

 

See http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#bitwise_simplified 

 

The & is the bitwise AND operator 6 is %00000110 in binary which is the mask you would need for bits 1 and 2. So _left_right & 6 is basically giving you a value that is only dependent on _left_right{1} and _left_right{2}. Then we compare that value with 6 to verify that both bits 1 and 2 are set.

 

In the second case you only car about bit 0 everywhere so it's possible to just bitwise AND them all together and then the result will only be 1 if all 3 values had bit 0 set.

 

I assume both examples will be smaller and faster because they should reduce the amount of compare/branch pairs needed to implement the same logic.



#17 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Fri Oct 5, 2018 2:44 PM

I've looked at this a bit, and I don't think there's a simple "magic bullet" solution - it will take trial and error and rearranging code to see what works.  I noticed that it overcycles sometimes when playfieldpos = 1 even without the AI.  pfpixel operations are expensive in terms of cycles, so this may be a factor.

 

What may help is using cycles from vblank.  If you add a vblank section and move your AI code there, and perhaps your pfpixel operations as well then this may help solve your issue with overcycling.

I tried this plus some rearranging and I think that it worked!!! I'm now trying it out to see if it still glitches, but so far so good. Thanks a million!

 

 

See http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#bitwise_simplified 

 

The & is the bitwise AND operator 6 is %00000110 in binary which is the mask you would need for bits 1 and 2. So _left_right & 6 is basically giving you a value that is only dependent on _left_right{1} and _left_right{2}. Then we compare that value with 6 to verify that both bits 1 and 2 are set.

 

In the second case you only car about bit 0 everywhere so it's possible to just bitwise AND them all together and then the result will only be 1 if all 3 values had bit 0 set.

 

I assume both examples will be smaller and faster because they should reduce the amount of compare/branch pairs needed to implement the same logic.

The first one works the 2nd one does something different. (Hardly any branches show up) So I'm guessing that there is some kind of translation error. 

I know that bB does not like more than 2 &&'s so maybe it's the same for &'s? 

Attached Files


Edited by Coolcrab, Fri Oct 5, 2018 2:44 PM.


#18 bogax OFFLINE  

bogax

    Dragonstomper

  • 776 posts

Posted Fri Oct 5, 2018 11:15 PM

Here I've meddled with your code some.

 

Aside from thowing in a few goto's in empty goto spots (necessary to even get it to compile) and other minor rearrangements

 

mainly I

 

poked the screen variables directly in some places, clearing the branches in particular

 

moved the new row/branch generation to after the scroll down and added a drawscreen

so that's all you do in the rest of that frame having bumped the playfield up in the scroll routine (which takes time)

 

moved the drawscreen into the sprite_color routine since they go together

 

 

Unfortunately I've added a bug which I haven't figured out yet (you'll probably notice it ;) ) edit: fixed (so you wont notice it :) )

 

I haven't seen it go over on the line count (neither this, or your original code)

 

 

What makes you think bB doesn't like more than two &&'s ?

Attached Files


Edited by bogax, Sat Oct 6, 2018 12:40 AM.


#19 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Sun Oct 7, 2018 12:52 AM

Here I've meddled with your code some.
 
Aside from thowing in a few goto's in empty goto spots (necessary to even get it to compile) and other minor rearrangements
 
mainly I
 
poked the screen variables directly in some places, clearing the branches in particular
 
moved the new row/branch generation to after the scroll down and added a drawscreen
so that's all you do in the rest of that frame having bumped the playfield up in the scroll routine (which takes time)
 
moved the drawscreen into the sprite_color routine since they go together
 
 
Unfortunately I've added a bug which I haven't figured out yet (you'll probably notice it ;) ) edit: fixed (so you wont notice it :) )
 
I haven't seen it go over on the line count (neither this, or your original code)
 
 
What makes you think bB doesn't like more than two &&'s ?

Wow that's amazing! Could you explain what you did exactly with the branch destruction? You are not using PFpixel but how does this other thing work?

 

Like how does this

 var0 = 15 : var2 = 15 

equal

pfhline 4 0 7 on : pfhline 20 0 23 on

?


Edited by Coolcrab, Sun Oct 7, 2018 2:18 PM.


#20 bogax OFFLINE  

bogax

    Dragonstomper

  • 776 posts

Posted Sun Oct 7, 2018 3:46 PM

This applies to the plain vanilla standard kernel, things will be different with some of the kernel options

 

the playfield is 32 pfpixels x 12 pfpixels

each pfpixel is 4 pixels x 8 scanlines

 

the pfpixels are represented in memory by 32 x 12 bits

the pf pixels go row x column starting at the top left

the top left corner is pfpixel 0 0 (x y) the bottom right is 11 31 

with 8 bits per byte that's 48 bytes 4 x 12

those are named var0..var47 in bB

 

the bytes are consecutive in memory and every 4 bytes is a playfield row

var0 is pfpixels 0..7 in row 0, var4 is pfpixels 0..7 in row 1 (the second row of pixels)

 

the odd number bytes are reversed

 

we number the the bits in a byte 7 6 5 4 3 2 1 0

 

var0 = %10000000 (128 decimal)  will result in pfpixel 0 0 on and pf pixels 1..7 0 off  (ie x = 1 to 7 with y = 0)

var1 = %00000011 (3 decimal)  will result in pfpixels 8..9 0 on and pfpixels 10..15 0 off

 

the trunk of the player0 tree is at pfpixel 8 0..11

 

so to clear the branches on the right var1 = 1

the second column of 8 pfpixels are reversed so the bits in var1 numbered  as 7 6 5 4 3 2 1 0

appear as playfield pixels 8 9 10 11 12 13 14 15 corresponding to var1 bits 0 1 2 3 4 5 6 7

 

to create a player0 tree right branch on row 0,

var1 = %00011111 (31 decimal)

(and it just occured to me that you've got the right side branch creation

under the __left label and I used the value15 so the right side branches are only

3 pfpixels wide in my code)

 

the branch clearing just sets every fourth playfield variable to the correct value

 

and the way bB works it's faster if you put all the assignments on the same line (because they're all the same value)

if you put the assignments on different lines it'd be something like this (in bB)(acc is a processor register, the accumulator)

  acc = 1
 var1 = acc
 acc = 1
 var5 = acc
 acc = 1
 var9 = acc  etc.
 

since they're all assigning the same value and if they're all consecutively on the same line it's more like this

 acc = 1
 var1 = acc
 var5 = acc
 var9 = acc  etc.
 

(of course it's in machine code not bB)

 

 

if playfieldpos is 1 when pfscroll down returns

you know pfscroll down just spent a lot of time moving

the playfield otherwise it just increments playfieldpos

 

you could move the playfield in bB it might save you 200+ cycles

but it would take 200 bytes or so

you'd basically do your own version of pfscroll down in bB 


Edited by bogax, Sun Oct 7, 2018 8:23 PM.


#21 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Mon Oct 8, 2018 4:50 AM

I'll probably have to do this on paper to really get it, but I understand the principle. Thanks!

 

Also  does this mean that basically you never want to use PFread? Since most of that stuff can be done with bitwise, would that be faster? 

 

It freed up a lot of space at any rate. :) I'm now making a hybrid version between yours and mine to make sure I get all the steps. 

The draw screen in the loop seems to have trouble though as the glitching score number is back. (Which apparently appears if the code has too many compound gosubs to deal with.)



#22 bogax OFFLINE  

bogax

    Dragonstomper

  • 776 posts

Posted Mon Oct 8, 2018 7:46 PM

what do you expect

 

player0score = $a

 

to display? 

 

if you're shooting for 10 it should be $10



#23 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Tue Oct 9, 2018 12:24 AM

what do you expect

player0score = $a

to display? 

 

if you're shooting for 10 it should be $10

I added 6 extra custom font chars for the powerups. They are in the font under $a - $f

Its those symbols. They come from the minikernel thats on the bottom. (That you turned off) 

You can download it in the top post, together with the font. 

Attached Thumbnails

  • qOz3SDj.png


#24 Karl G OFFLINE  

Karl G

    Dragonstomper

  • 532 posts

Posted Wed Oct 10, 2018 8:37 AM

Actually, the custom symbols are defined in the included score_graphics.asm, not in the minikernel itself.



#25 Coolcrab OFFLINE  

Coolcrab

    Moonsweeper

  • Topic Starter
  • 364 posts
  • Location:Stockholm

Posted Wed Oct 10, 2018 2:22 PM

Yes that is true, the other kernel brings in the digit placement. 






0 user(s) are browsing this forum

0 members, 0 guests, 0 anonymous users