mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-12 17:17:09 -04:00
Consoles: Make Quit Game more stable
This commit is contained in:
parent
5d31caf57b
commit
f3326f4f17
51
src/Game.c
51
src/Game.c
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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);
|
||||
|
15
third_party/gldc/src/aligned_vector.h
vendored
15
third_party/gldc/src/aligned_vector.h
vendored
@ -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;
|
||||
|
Loading…
x
Reference in New Issue
Block a user