LoginLogin
Nintendo shutting down 3DS + Wii U online services, see our post

Flicker-less graphics without VSYNC/WAIT

Root / Submissions / [.]

12Me21Created:
Graphics drawing loops commonly look like this:
WHILE 1
 GCLS
 'graphics stuff
 VSYNC
WEND
The VSYNC stops the image from flickering, but if the graphics code takes longer than 1 frame, the VSYNC will do nothing and it will flicker. Here is a solution:
VAR PAGE%

WHILE 1
 GCLS
 'graphics stuff
 GPAGE PAGE%,!PAGE%
 PAGE%=!PAGE%
 BSYNC
WEND
This makes the program display one page, and edit another. After it finishes drawing the graphics for one loop, it switches the pages.

Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
FRAME=MAINCNT
WHILE 1
 GPUTCHR 100,100,(MAINCNT-FRAME)/60
 GPAGE PAGE,!PAGE
 PAGE=!PAGE
WEND
Your timer should not be affected by how fast the loop runs.

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
Yes :) you got me, I overstated the case. It's not the LAST thing. But taking them out and replacing them with something that doesn't use MAINCNT (as the original content of the page) is a step in the wrong direction.

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
Your method, 12Me, would be best for games. The technique you showed is what Calc84 used in his Raycaster engine for SBv2. Pretty much all modern games for some console use techniques like this. However, for making a timer, this method is bad, because the crazy speed at which it could will make it lose accuracy.

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
MAINCNT doesn't lose accuracy, as far as I know. And the new timer commands definitely won't.
But taking them out and replacing them with something that doesn't use MAINCNT (as the original content of the page) is a step in the wrong direction.
I'm not sure what you mean

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
I mean to say that changing from the type of code in the first block (with VSYNC) to the type of code in the second block (without VSYNC, and without MAINCNT) will make for a less accurate timer, not a more accurate one.

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
The example code is for graphics display, not a timer.

Removing VSYNC and WAIT, simply because one of their effects (helping reduce flicker) can be obtained in a different way, is not a good idea without also addressing their other effects (helping manage time). Imagine that you have written a game where sometimes, there is more processing to do than at other times (e.g. at the end of a level, you face a boss, who spawns more enemies than are usually on the screen). Compare
VAR I

ACLS
WHILE TRUE
 GCLS
 GCIRCLE 200,120,50,0,I
 I=(I+1) MOD 360
 DO_GAME
 VSYNC
WEND

DEF DO_GAME
 VAR DELAY
 IF (I>250) THEN ' boss time
  DELAY=3000+10000*HARDWARE
  FOR DELAY=DELAY TO 0 STEP -1
  NEXT
 ENDIF
END
with:
VAR I,PAGE

ACLS
WHILE TRUE
 GCLS
 GCIRCLE 200,120,50,0,I
 I=(I+1) MOD 360
 DO_GAME
 GPAGE PAGE,!PAGE
 PAGE=!PAGE
WEND

DEF DO_GAME
 VAR DELAY
 IF (I>250) THEN ' boss time
  DELAY=3000+10000*HARDWARE
  FOR DELAY=DELAY TO 0 STEP -1
  NEXT
 ENDIF
END

Replying to:SquareFingers
Removing VSYNC and WAIT, simply because one of their effects (helping reduce flicker) can be obtained in a different way, is not a good idea without also addressing their other effects (helping manage time). Imagine that you have written a game where sometimes, there is more processing to do than at other times (e.g. at the end of a level, you face a boss, who spawns more enemies than are usually on the screen). Compare
VAR I

ACLS
WHILE TRUE
 GCLS
 GCIRCLE 200,120,50,0,I
 I=(I+1) MOD 360
 DO_GAME
 VSYNC
WEND

DEF DO_GAME
 VAR DELAY
 IF (I>250) THEN ' boss time
  DELAY=3000+10000*HARDWARE
  FOR DELAY=DELAY TO 0 STEP -1
  NEXT
 ENDIF
END
with:
VAR I,PAGE

ACLS
WHILE TRUE
 GCLS
 GCIRCLE 200,120,50,0,I
 I=(I+1) MOD 360
 DO_GAME
 GPAGE PAGE,!PAGE
 PAGE=!PAGE
WEND

DEF DO_GAME
 VAR DELAY
 IF (I>250) THEN ' boss time
  DELAY=3000+10000*HARDWARE
  FOR DELAY=DELAY TO 0 STEP -1
  NEXT
 ENDIF
END
For timed events you can use MAINCNT for an event to happen ever 700 frames, you could do IF !(MAINCNT MOD 700) THEN ...

This helped me to reduce flicker in LISA

hmm this page sucks. I tried to remove most of the bad information...

you could just recreate the
WAIT
function by using the following:
DEF WAITMILLISEC NUM
M=MILLISEC
WHILE MILLISEC-M<NUM
WEND
END
IF THISWORKS==TRUE THEN
PRINT "GOOD IDEA!"

Replying to:DFrost
you could just recreate the
WAIT
function by using the following:
DEF WAITMILLISEC NUM
M=MILLISEC
WHILE MILLISEC-M<NUM
WEND
END
IF THISWORKS==TRUE THEN
PRINT "GOOD IDEA!"
Although the page is terrible and the intent not clear, the WAIT/VSYNC commands are not what is being discussed. The issue here is redrawing before previous drawing procedures finished, resulting in partially complete frames being shown, and, as a result, "flicker". The solution given is to use extra pages to implement a double-buffer and page swap when finished drawing. This approach has the trade-off of ALWAYS finishing drawing before the display is updated, and for long draw cycles can fail to keep a steady frame rate.

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
a frame isn't always the same amount of time so MAINCNT can be inaccurate. For example: MAINCNT/MILLISEC is non - proportional, therefore MAINCNT is not always the same amount of time

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
What do you mean by 'non-proportional'?

Replying to:SquareFingers
Removing VSYNC and WAIT is the LAST thing you want to do if you want "a very accurate timer". They help ensure accurate and consistent timing, certainly not reduce it (when used right).
It's math stuff.

What is BSync?

Replying to:KHypno
What is BSync?
a typo.

Replying to:KHypno
What is BSync?
now let's discover Async

Replying to:KHypno
What is BSync?
DIM _ASYNC_TIMER = 0
DEF ASYNC T, FN$
  IF MAINCNT>=_ASYNC_TIMER THEN
    CALL FN$
    _ASYNC_TIMER = MAINCNT + T
  ENDIF
END
instead of this
WHILE !BUTTON(2)
  'ono blocking plshelp
  WAIT 1
  KILL_BIRD
WEND
say this
WHILE !BUTTON(2)
  'nonblocking owo very bird-frenly
  ASYNC 1, "KILL_HUMAN"
WEND