examples: Wait for VBL in the right place

This change is a bit pedantic, but it makes the ROMs run better in
DeSmuMe.

Some examples (particularly the dual 3D examples) used to flicker during
one or two seconds right after starting. In dual 3D examples the top and
bottom screen would start swapped, and they would eventually swap and
stop flickering. This would never happen in melonDS or real hardware.

I suspect this is because of the interaction between GFX_FLUSH and
swiWaitForVBlank(), where there would be some timing difference to reach
the first swiWaitForVBlank() or GFX_FLUSH, and that caused the desync.

This commit moves swiWaitForVBlank() to the beginning of the game loop.
This means that, even in the first iteration of the game loop, all
emulators and hardware will be synchronized. This doesn't actually
matter in any other situation, it just makes the first iteration
consistent.
This commit is contained in:
Antonio Niño Díaz 2023-01-21 19:32:02 +00:00
parent 7b67161249
commit 1acfca1a24
37 changed files with 107 additions and 66 deletions

View File

@ -150,6 +150,10 @@ int main(void)
while (1)
{
// Update GUI, input and wait for vertical blank. You have to
// call scanKeys() each frame for this to work.
NE_WaitForVBL(NE_UPDATE_GUI);
scanKeys(); // This function is needed for the GUI
printf("\x1b[0;0H");
@ -166,10 +170,6 @@ int main(void)
// Draw things...
NE_Process(Draw3DScene);
// Update GUI, input and wait for vertical blank. You have to
// call scanKeys() each frame for this to work.
NE_WaitForVBL(NE_UPDATE_GUI);
}
return 0;

View File

@ -62,8 +62,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -78,14 +78,16 @@ int main(void)
printf("A: Alpha");
while (1) {
while (1)
{
NE_WaitForVBL(0);
scanKeys();
kheld = keysHeld();
UpdateQuads();
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -65,6 +65,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys();
uint32 keys = keysHeld();
@ -83,7 +85,6 @@ int main(void)
NE_SpriteSetPos(Sprite[2], x, y);
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -72,8 +72,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -85,6 +85,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Refresh keys
scanKeys();
uint32 keys = keysDown();
@ -124,7 +126,6 @@ int main(void)
// Draw scene
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -65,6 +65,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Refresh keys
scanKeys();
uint32 keys = keysHeld();
@ -101,7 +103,6 @@ int main(void)
// Draw 3D scenes
NE_ProcessDual(Draw3DScene, Draw3DScene2);
NE_WaitForVBL(0);
}
return 0;

View File

@ -85,6 +85,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Refresh keys
scanKeys();
uint32 keys = keysHeld();
@ -125,7 +127,6 @@ int main(void)
// Draw scene
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -102,6 +102,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Get keys information
scanKeys();
uint32 keys = keysHeld();
@ -165,7 +167,6 @@ int main(void)
NE_ShininessTableGenerate(shininess);
NE_ProcessDual(Draw3DScene1, Draw3DScene2);
NE_WaitForVBL(0);
}
return 0;

View File

@ -58,6 +58,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
scanKeys();
uint32 keys = keysHeld();
@ -75,7 +77,6 @@ int main(void)
NE_GetCPUPercent(), f32tofloat(NE_ModelAnimGetFrame(Model)));
NE_Process(Draw3DScene);
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
}
return 0;

View File

@ -85,13 +85,14 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Rotate every model
for (int i = 0; i < NUM_MODELS; i++)
NE_ModelRotate(Model[i], -i, i % 5, 5 - i);
// Draw scene
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -56,8 +56,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -97,9 +97,11 @@ int main(void)
NE_ClearColorSet(NE_Black, 31, 63);
printf("\x1b[0;0HPad: Rotate\nSTART: Exit");
while (1)
{
printf("\x1b[0;0HPad: Rotate\nSTART: Exit");
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
scanKeys();
uint32 keys = keysHeld();
@ -118,7 +120,6 @@ int main(void)
// Draw scene...
NE_Process(Draw3DScene);
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
}
return 0;

View File

@ -86,6 +86,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys(); //Get keys information...
uint32 keys = keysDown();
@ -107,7 +109,6 @@ int main(void)
// Draw scene...
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -74,9 +74,10 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Draw 3D scene
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -60,6 +60,9 @@ int main(void)
while (1)
{
// Wait for next frame
NE_WaitForVBL(0);
// Get keys information
scanKeys();
uint32 keys = keysHeld();
@ -78,8 +81,6 @@ int main(void)
// Draw scene
NE_Process(Draw3DScene);
// Wait for next frame
NE_WaitForVBL(0);
}
return 0;

View File

@ -69,13 +69,14 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Rotate every model
for (int i = 0; i < NUM_MODELS; i++)
NE_ModelRotate(Model[i], -i, i % 5, 5 - i);
// Draw scene
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -65,8 +65,9 @@ int main(void)
while (1)
{
NE_ProcessDual(Draw3DScene, Draw3DScene2);
NE_WaitForVBL(0);
NE_ProcessDual(Draw3DScene, Draw3DScene2);
}
return 0;

View File

@ -68,6 +68,9 @@ int main(void)
while (1)
{
// Wait for next frame
NE_WaitForVBL(0);
// Get keys information
scanKeys();
uint32 keys = keysHeld();
@ -86,8 +89,6 @@ int main(void)
// Draw scene
NE_Process(Draw3DScene);
// Wait for next frame
NE_WaitForVBL(0);
}
return 0;

View File

@ -70,6 +70,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
scanKeys();
uint32 keys = keysHeld();
@ -112,7 +114,6 @@ int main(void)
f32tofloat(NE_ModelAnimSecondaryGetFrame(Model)));
NE_Process(Draw3DScene);
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
}
return 0;

View File

@ -76,6 +76,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys();
uint32 keys = keysHeld();
@ -98,7 +100,6 @@ int main(void)
scrollx--;
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -46,8 +46,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -70,6 +70,9 @@ int main(void)
while (1)
{
// Wait for next frame
NE_WaitForVBL(0);
// Get time
time_t unixTime = time(NULL);
struct tm* timeStruct = gmtime((const time_t *)&unixTime);
@ -101,8 +104,7 @@ int main(void)
NE_ModelRotate(Model, 0, -2, 0);
NE_Process(Draw3DScene);
// Wait for next frame
NE_WaitForVBL(0);
// Increase frame count
fpscount++;
}

View File

@ -59,6 +59,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
// Get keys information
scanKeys();
uint32 keys = keysHeld();
@ -87,7 +89,6 @@ int main(void)
NE_CameraMoveFree(Camera, -0.05, 0, 0);
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -49,8 +49,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -51,13 +51,11 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys();
touchRead(&touch);
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
if (keysHeld() & KEY_TOUCH)
{
NE_TextureDrawingStart(Material);
@ -71,6 +69,8 @@ int main(void)
NE_TextureDrawingEnd();
}
NE_Process(Draw3DScene);
}
return 0;

View File

@ -35,12 +35,11 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys();
touchPosition touch;
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
if (keysHeld() & KEY_TOUCH)
{
// Update stylus coordinates when screen is pressed
@ -58,6 +57,8 @@ int main(void)
NE_TextureDrawingEnd();
}
NE_Process(Draw3DScene);
}
return 0;

View File

@ -70,8 +70,9 @@ int main(void)
while (1)
{
scanKeys();
NE_WaitForVBL(0);
scanKeys();
uint16_t keys = keysDown();
if (keys & KEY_A)
@ -82,7 +83,6 @@ int main(void)
NE_MainScreenSetOnBottom();
NE_ProcessDual(Draw3DScene, Draw3DScene2);
NE_WaitForVBL(0);
}
return 0;

View File

@ -52,8 +52,9 @@ int main(void)
while (1)
{
scanKeys();
NE_WaitForVBL(0);
scanKeys();
uint16_t keys = keysDown();
if (keys & KEY_A)
@ -64,7 +65,6 @@ int main(void)
NE_MainScreenSetOnBottom();
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -64,8 +64,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -136,6 +136,8 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys();
keys = keysHeld();
@ -196,7 +198,6 @@ int main(void)
}
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -94,8 +94,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(NE_UPDATE_PHYSICS);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -92,8 +92,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(NE_UPDATE_PHYSICS);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -95,8 +95,9 @@ int main(void)
while (1)
{
NE_Process(Draw3DScene);
NE_WaitForVBL(NE_UPDATE_PHYSICS);
NE_Process(Draw3DScene);
}
return 0;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: CC0-1.0
//
// SPDX-FileContributor: Antonio Niño Díaz, 2008-2011, 2019, 2022
// SPDX-FileContributor: Antonio Niño Díaz, 2008-2011, 2019, 2022-2023
//
// This file is part of Nitro Engine
@ -26,10 +26,13 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys();
// Your code goes here
NE_ProcessDual(Draw3DScene, Draw3DScene2);
NE_WaitForVBL(0);
}
return 0;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: CC0-1.0
//
// SPDX-FileContributor: Antonio Niño Díaz, 2008-2011, 2019, 2022
// SPDX-FileContributor: Antonio Niño Díaz, 2008-2011, 2019, 2022-2023
//
// This file is part of Nitro Engine
@ -21,10 +21,13 @@ int main(void)
while (1)
{
NE_WaitForVBL(0);
scanKeys();
// Your code goes here
NE_Process(Draw3DScene);
NE_WaitForVBL(0);
}
return 0;

View File

@ -1,6 +1,6 @@
// SPDX-License-Identifier: CC0-1.0
//
// SPDX-FileContributor: Antonio Niño Díaz, 2008-2011, 2019, 2022
// SPDX-FileContributor: Antonio Niño Díaz, 2008-2011, 2019, 2022-2023
// SPDX-FileContributor: NightFox, 2009-2011
//
// This file is part of Nitro Engine
@ -200,6 +200,20 @@ int main(void)
while (1)
{
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
// At this point we are in the vertical blank period. This is where 2D
// elements have to be updated to avoid flickering.
// Update the scroll of the backgrounds
for (int n = 0; n < 3; n ++)
NF_ScrollBg(1, n + 1, bg_x[n], 0);
// Copy shadow OAM copy to the OAM of the 2D sub engine
oamUpdate(&oamSub);
// Start processing a new frame after the 2D elements have been updated.
scanKeys();
uint32 keys = keysHeld();
@ -259,19 +273,8 @@ int main(void)
// Refresh shadow OAM copy
NF_SpriteOamSet(1);
// Draw scene...
// Draw 3D scene
NE_Process(Draw3DScene);
NE_WaitForVBL(NE_UPDATE_ANIMATIONS);
// At this point we are in the vertical blank period. This is where 2D
// entities have to be updated to avoid flickering.
// Update the scroll of the backgrounds
for (int n = 0; n < 3; n ++)
NF_ScrollBg(1, n + 1, bg_x[n], 0);
// Copy shadow OAM copy to the OAM of the 2D sub engine
oamUpdate(&oamSub);
}
return 0;