Consoles: Make Quit Game more stable

This commit is contained in:
UnknownShadow200 2024-06-20 22:14:42 +10:00
parent 5d31caf57b
commit f3326f4f17
4 changed files with 49 additions and 43 deletions

View File

@ -400,7 +400,7 @@ static void LoadPlugins(void) {
static void LoadPlugins(void) { }
#endif
static void Game_Free(void* obj);
static void Game_PendingClose(void* obj) { gameRunning = false; }
static void Game_Load(void) {
struct IGameComponent* comp;
Game_UpdateDimensions();
@ -415,7 +415,7 @@ static void Game_Load(void) {
Event_Register_(&WorldEvents.NewMap, NULL, HandleOnNewMap);
Event_Register_(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
Event_Register_(&WindowEvents.Resized, NULL, Game_OnResize);
Event_Register_(&WindowEvents.Closing, NULL, Game_Free);
Event_Register_(&WindowEvents.Closing, NULL, Game_PendingClose);
Event_Register_(&WindowEvents.InactiveChanged, NULL, HandleInactiveChanged);
Game_AddComponent(&World_Component);
@ -647,10 +647,18 @@ static void DrawSplitscreen(float delta, float t, int i, int x, int y, int w, in
}
#endif
static CC_INLINE void Game_RenderFrame(double delta) {
static CC_INLINE void Game_RenderFrame(void) {
struct ScheduledTask entTask;
float t;
cc_uint64 render = Stopwatch_Measure();
double delta = Stopwatch_ElapsedMicroseconds(Game_FrameStart, render) / (1000.0 * 1000.0);
Window_ProcessEvents(delta);
if (delta > 5.0) delta = 5.0; /* avoid large delta with suspended process */
if (delta <= 0.0) return;
Game_FrameStart = render;
/* TODO: Should other tasks get called back too? */
/* Might not be such a good idea for the http_clearcache, */
/* don't really want all skins getting lost */
@ -722,7 +730,7 @@ static CC_INLINE void Game_RenderFrame(double delta) {
Gfx_EndFrame();
}
static void Game_Free(void* obj) {
static void Game_Free(void) {
struct IGameComponent* comp;
/* Most components will call OnContextLost in their Free functions */
/* Set to false so components will always free managed textures too */
@ -730,7 +738,8 @@ static void Game_Free(void* obj) {
Event_UnregisterAll();
tasksCount = 0;
for (comp = comps_head; comp; comp = comp->next) {
for (comp = comps_head; comp; comp = comp->next)
{
if (comp->Free) comp->Free();
}
@ -741,25 +750,17 @@ static void Game_Free(void* obj) {
Window_DisableRawMouse();
}
#define Game_DoFrameBody() \
render = Stopwatch_Measure();\
delta = Stopwatch_ElapsedMicroseconds(Game_FrameStart, render) / (1000.0 * 1000.0);\
\
Window_ProcessEvents(delta);\
if (!gameRunning) return;\
\
if (delta > 5.0) delta = 5.0; /* avoid large delta with suspended process */ \
if (delta > 0.0) { Game_FrameStart = render; Game_RenderFrame(delta); }
#ifdef CC_BUILD_WEB
void Game_DoFrame(void) {
cc_uint64 render;
double delta;
Game_DoFrameBody()
if (gameRunning) {
Game_RenderFrame();
} else if (tasksCount) {
Game_Free();
Window_Free();
}
}
static void Game_RunLoop(void) {
Game_FrameStart = Stopwatch_Measure();
/* Window_Web.c sets Game_DoFrame as the main loop callback function */
/* (i.e. web browser is in charge of calling Game_DoFrame, not us) */
}
@ -777,11 +778,11 @@ cc_bool Game_ShouldClose(void) {
}
#else
static void Game_RunLoop(void) {
cc_uint64 render;
double delta;
Game_FrameStart = Stopwatch_Measure();
for (;;) { Game_DoFrameBody() }
while (gameRunning)
{
Game_RenderFrame();
}
Game_Free();
}
#endif
@ -793,5 +794,7 @@ void Game_Run(int width, int height, const cc_string* title) {
Game_Load();
Event_RaiseVoid(&WindowEvents.Resized);
Game_FrameStart = Stopwatch_Measure();
Game_RunLoop();
}

View File

@ -14,6 +14,7 @@ extern void* Window_XFB;
static void* xfbs[2];
static int curFB;
static GfxResourceID white_square;
static GXTexRegionCallback regionCB;
// https://wiibrew.org/wiki/Developer_tips
// https://devkitpro.org/wiki/libogc/GX
@ -44,6 +45,9 @@ static void InitGX(void) {
xfbs[0] = Window_XFB;
xfbs[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode));
regionCB = GX_SetTexRegionCallback(NULL);
GX_SetTexRegionCallback(regionCB);
}
void Gfx_Create(void) {
@ -173,7 +177,8 @@ void Gfx_BindTexture(GfxResourceID texId) {
CCTexture* tex = (CCTexture*)texId;
if (!tex) tex = white_square;
GX_LoadTexObj(&tex->obj, GX_TEXMAP0);
GXTexRegion* reg = regionCB(&tex->obj, GX_TEXMAP0);
GX_LoadTexObjPreloaded(&tex->obj, reg, GX_TEXMAP0);
}

View File

@ -413,7 +413,15 @@ void Window_Init(void) {
interop_ForceTouchPageLayout();
}
void Window_Free(void) { }
void Window_Free(void) {
/* If the game is closed while in fullscreen, the last rendered frame stays */
/* shown in fullscreen, but the game can't be interacted with anymore */
Window_ExitFullscreen();
Window_SetSize(0, 0);
UnhookEvents();
emscripten_cancel_main_loop();
}
extern void interop_InitContainer(void);
static void DoCreateWindow(void) {
@ -525,15 +533,6 @@ void Window_SetSize(int width, int height) {
void Window_RequestClose(void) {
Window_Main.Exists = false;
Event_RaiseVoid(&WindowEvents.Closing);
/* If the game is closed while in fullscreen, the last rendered frame stays */
/* shown in fullscreen, but the game can't be interacted with anymore */
Window_ExitFullscreen();
Window_SetSize(0, 0);
UnhookEvents();
/* Game_DoFrame doesn't do anything when WindowExists.False is false, */
/* but it's still better to cancel main loop to minimise resource usage */
emscripten_cancel_main_loop();
}
extern void interop_RequestCanvasResize(void);

View File

@ -19,6 +19,13 @@ typedef struct {
#define ALIGNED_VECTOR_CHUNK_SIZE 256u
#define av_assert(x) \
do {\
if(!(x)) {\
fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\
exit(1);\
}\
} while(0); \
#define ROUND_TO_CHUNK_SIZE(v) \
((((v) + ALIGNED_VECTOR_CHUNK_SIZE - 1) / ALIGNED_VECTOR_CHUNK_SIZE) * ALIGNED_VECTOR_CHUNK_SIZE)
@ -52,14 +59,6 @@ AV_FORCE_INLINE void* aligned_vector_reserve(AlignedVector* vector, uint32_t ele
return vector->data + original_byte_size;
}
#define av_assert(x) \
do {\
if(!(x)) {\
fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\
exit(1);\
}\
} while(0); \
/* Resizes the array and returns a pointer to the first new element (if upsizing) or NULL (if downsizing) */
AV_FORCE_INLINE void* aligned_vector_resize(AlignedVector* vector, const uint32_t element_count) {
void* ret = NULL;