Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 38 additions & 7 deletions src/views/game_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,38 @@ void GameView::rasterize()
}
}

void flip_callback(void *gameview){
GameView *gv = (GameView*)gameview;
gv->flip();
}

void GameView::flip()
{
// Start with black
manager->clear(0, 0, 0);

// Create pixels to display from machine memory
rasterize();
_output.update();

// Write it to the SDL Surface
SDL_Rect dest;
if (_scaler == Scaler::UNSCALED)
dest = { (SCREEN_WIDTH - 128) / 2, (SCREEN_HEIGHT - 128) / 2, 128, 128 };
else if (_scaler == Scaler::SCALED_ASPECT_2x)
dest = { (SCREEN_WIDTH - 256) / 2, (SCREEN_HEIGHT - 256) / 2, 256, 256 };
else
dest = { 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT };
manager->blitToScreen(_output, dest);

// We aren't returning control to ::loop, so force this to display now
manager->flip();

// Wait out the right time between frames
// (assumes zero draw time, so this can be improved)
int32_t fps = machine.code().require60fps() ? 60 : 30;
SDL_Delay(1000.0/fps);
}
Copy link
Contributor

@phcoder phcoder Jul 23, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Libretro cores should use no delay. Instead they are synced in frontend on produced frames and audio samples

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, in general the flip() function is a poor design choice because the running loop should be controlled by the caller instead that letting the code itself doing quirky things.

I guess the solution would be a quick return and a synchronization through a variable on backend which are not synched and just wait for the next frame on others?


bool init = false;
void GameView::render()
Expand All @@ -181,9 +212,16 @@ void GameView::render()

_frameCounter = 0;

machine.setflip(flip_callback, (void*)this);
machine.code().loadAPI();
_input.setMachine(&machine);

int32_t fps = machine.code().require60fps() ? 60 : 30;
manager->setFrameRate(fps);

machine.sound().init();
sdlAudio.init(&machine.sound());
sdlAudio.resume();

if (_path.empty())
_path = "cartridges/pico-racer.png";
Expand All @@ -207,9 +245,6 @@ void GameView::render()

machine.memory().backupCartridge();

int32_t fps = machine.code().require60fps() ? 60 : 30;
manager->setFrameRate(fps);

if (machine.code().hasInit())
{
/* init is launched on a different thread because some developers are using busy loops and manual flips */
Expand All @@ -220,10 +255,6 @@ void GameView::render()
});
}

machine.sound().init();
sdlAudio.init(&machine.sound());
sdlAudio.resume();

init = true;
}

Expand Down
2 changes: 2 additions & 0 deletions src/views/main_view.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ namespace ui

void toggleFPS(bool active) { _showFPS = active; }
bool isFPSShown() { return _showFPS; }

void flip();
};

class MenuView : public View
Expand Down
3 changes: 2 additions & 1 deletion src/views/sdl_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ class SDL
void capFPS();

void loop();
void flip();
void handleEvents();

void exit() { willQuit = true; }
Expand Down Expand Up @@ -198,4 +199,4 @@ void SDL<EventHandler, Renderer>::handleEvents()
#include "sdl_impl12.h"
#else
#include "sdl_impl.h"
#endif
#endif
6 changes: 6 additions & 0 deletions src/views/sdl_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ bool SDL<EventHandler, Renderer>::init()
return true;
}

template<typename EventHandler, typename Renderer>
void SDL<EventHandler, Renderer>::flip()
{
SDL_RenderPresent(_renderer);
}

template<typename EventHandler, typename Renderer>
void SDL<EventHandler, Renderer>::loop()
{
Expand Down
6 changes: 6 additions & 0 deletions src/views/sdl_impl12.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ bool SDL<EventHandler, Renderer>::init()
return true;
}

template<typename EventHandler, typename Renderer>
void SDL<EventHandler, Renderer>::flip()
{
SDL_Flip(_screen);
}

template<typename EventHandler, typename Renderer>
void SDL<EventHandler, Renderer>::loop()
{
Expand Down
35 changes: 25 additions & 10 deletions src/vm/lua_bridge.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,10 +975,7 @@ namespace platform

int flip(lua_State* L)
{
//TODO: this call should syncronize to 30fps, at the moment it just
// returns producing a lot of flips in non synchronized code (eg. _init() busy loop)
//TODO: flip is handled by backend so we should find a way to set the callback that should be called

machine.flip();
return 0;
}

Expand Down Expand Up @@ -1161,13 +1158,29 @@ void Code::initFromSource(const std::string& code)
if (error)
printError("lua_pcall on init");

lua_getglobal(L, "_init");

if (lua_isfunction(L, -1))
{
_init = lua_topointer(L, -1);
lua_pop(L, 1);
}

fetchGlobals();
}

void Code::fetchGlobals()
{
lua_getglobal(L, "_update");
if (lua_isfunction(L, -1))
{
_update = lua_topointer(L, -1);
lua_pop(L, 1);
}
else
{
_update = NULL;
}

lua_getglobal(L, "_update60");

Expand All @@ -1176,6 +1189,10 @@ void Code::initFromSource(const std::string& code)
_update60 = lua_topointer(L, -1);
lua_pop(L, 1);
}
else
{
_update60 = NULL;
}

lua_getglobal(L, "_draw");

Expand All @@ -1184,13 +1201,9 @@ void Code::initFromSource(const std::string& code)
_draw = lua_topointer(L, -1);
lua_pop(L, 1);
}

lua_getglobal(L, "_init");

if (lua_isfunction(L, -1))
else
{
_init = lua_topointer(L, -1);
lua_pop(L, 1);
_draw = NULL;
}
}

Expand All @@ -1205,6 +1218,7 @@ void Code::callFunction(const char* name, int ret)

void Code::update()
{
fetchGlobals();
if (_update60)
callFunction("_update60");
else if (_update)
Expand All @@ -1213,6 +1227,7 @@ void Code::update()

void Code::draw()
{
fetchGlobals();
if (_draw)
callFunction("_draw");
}
Expand Down
4 changes: 3 additions & 1 deletion src/vm/lua_bridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ namespace lua
const void* _update60;
const void* _draw;

void fetchGlobals();

public:
Code() : L(nullptr) { }
~Code();
Expand All @@ -49,4 +51,4 @@ namespace lua
lua_State* state() const { return L; }
#endif
};
}
}
12 changes: 12 additions & 0 deletions src/vm/machine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -359,3 +359,15 @@ void Machine::map(coord_t cx, coord_t cy, coord_t x, coord_t y, amount_t cw, amo
}
}
}

void Machine::setflip(void(*newflip)(void*), void *flipdata)
{
_flipdata = flipdata;
_flip = newflip;
}

void Machine::flip()
{
if (_flip)
_flip(_flipdata);
}
5 changes: 5 additions & 0 deletions src/vm/machine.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ namespace retro8
sfx::APU _sound;
gfx::Font _font;
lua::Code _code;
void *_flipdata;
void (*_flip)(void*) = NULL;

private:
void circHelper(coord_t xc, coord_t yc, coord_t x, coord_t y, color_t col);
Expand Down Expand Up @@ -65,6 +67,9 @@ namespace retro8

void print(const std::string& string, coord_t x, coord_t y, color_t color);

void setflip(void (*newflip)(void *), void *flipdata);
void flip();

State& state() { return _state; }
Memory& memory() { return _memory; }
gfx::Font& font() { return _font; }
Expand Down