mirror of
https://github.com/ClassiCube/ClassiCube.git
synced 2025-09-13 17:47:12 -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) { }
|
static void LoadPlugins(void) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void Game_Free(void* obj);
|
static void Game_PendingClose(void* obj) { gameRunning = false; }
|
||||||
static void Game_Load(void) {
|
static void Game_Load(void) {
|
||||||
struct IGameComponent* comp;
|
struct IGameComponent* comp;
|
||||||
Game_UpdateDimensions();
|
Game_UpdateDimensions();
|
||||||
@ -415,7 +415,7 @@ static void Game_Load(void) {
|
|||||||
Event_Register_(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
Event_Register_(&WorldEvents.NewMap, NULL, HandleOnNewMap);
|
||||||
Event_Register_(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
Event_Register_(&WorldEvents.MapLoaded, NULL, HandleOnNewMapLoaded);
|
||||||
Event_Register_(&WindowEvents.Resized, NULL, Game_OnResize);
|
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);
|
Event_Register_(&WindowEvents.InactiveChanged, NULL, HandleInactiveChanged);
|
||||||
|
|
||||||
Game_AddComponent(&World_Component);
|
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
|
#endif
|
||||||
|
|
||||||
static CC_INLINE void Game_RenderFrame(double delta) {
|
static CC_INLINE void Game_RenderFrame(void) {
|
||||||
struct ScheduledTask entTask;
|
struct ScheduledTask entTask;
|
||||||
float t;
|
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? */
|
/* TODO: Should other tasks get called back too? */
|
||||||
/* Might not be such a good idea for the http_clearcache, */
|
/* Might not be such a good idea for the http_clearcache, */
|
||||||
/* don't really want all skins getting lost */
|
/* don't really want all skins getting lost */
|
||||||
@ -722,7 +730,7 @@ static CC_INLINE void Game_RenderFrame(double delta) {
|
|||||||
Gfx_EndFrame();
|
Gfx_EndFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Game_Free(void* obj) {
|
static void Game_Free(void) {
|
||||||
struct IGameComponent* comp;
|
struct IGameComponent* comp;
|
||||||
/* Most components will call OnContextLost in their Free functions */
|
/* Most components will call OnContextLost in their Free functions */
|
||||||
/* Set to false so components will always free managed textures too */
|
/* Set to false so components will always free managed textures too */
|
||||||
@ -730,7 +738,8 @@ static void Game_Free(void* obj) {
|
|||||||
Event_UnregisterAll();
|
Event_UnregisterAll();
|
||||||
tasksCount = 0;
|
tasksCount = 0;
|
||||||
|
|
||||||
for (comp = comps_head; comp; comp = comp->next) {
|
for (comp = comps_head; comp; comp = comp->next)
|
||||||
|
{
|
||||||
if (comp->Free) comp->Free();
|
if (comp->Free) comp->Free();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -741,25 +750,17 @@ static void Game_Free(void* obj) {
|
|||||||
Window_DisableRawMouse();
|
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
|
#ifdef CC_BUILD_WEB
|
||||||
void Game_DoFrame(void) {
|
void Game_DoFrame(void) {
|
||||||
cc_uint64 render;
|
if (gameRunning) {
|
||||||
double delta;
|
Game_RenderFrame();
|
||||||
Game_DoFrameBody()
|
} else if (tasksCount) {
|
||||||
|
Game_Free();
|
||||||
|
Window_Free();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Game_RunLoop(void) {
|
static void Game_RunLoop(void) {
|
||||||
Game_FrameStart = Stopwatch_Measure();
|
|
||||||
/* Window_Web.c sets Game_DoFrame as the main loop callback function */
|
/* 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) */
|
/* (i.e. web browser is in charge of calling Game_DoFrame, not us) */
|
||||||
}
|
}
|
||||||
@ -777,11 +778,11 @@ cc_bool Game_ShouldClose(void) {
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void Game_RunLoop(void) {
|
static void Game_RunLoop(void) {
|
||||||
cc_uint64 render;
|
while (gameRunning)
|
||||||
double delta;
|
{
|
||||||
|
Game_RenderFrame();
|
||||||
Game_FrameStart = Stopwatch_Measure();
|
}
|
||||||
for (;;) { Game_DoFrameBody() }
|
Game_Free();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -793,5 +794,7 @@ void Game_Run(int width, int height, const cc_string* title) {
|
|||||||
|
|
||||||
Game_Load();
|
Game_Load();
|
||||||
Event_RaiseVoid(&WindowEvents.Resized);
|
Event_RaiseVoid(&WindowEvents.Resized);
|
||||||
|
|
||||||
|
Game_FrameStart = Stopwatch_Measure();
|
||||||
Game_RunLoop();
|
Game_RunLoop();
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ extern void* Window_XFB;
|
|||||||
static void* xfbs[2];
|
static void* xfbs[2];
|
||||||
static int curFB;
|
static int curFB;
|
||||||
static GfxResourceID white_square;
|
static GfxResourceID white_square;
|
||||||
|
static GXTexRegionCallback regionCB;
|
||||||
// https://wiibrew.org/wiki/Developer_tips
|
// https://wiibrew.org/wiki/Developer_tips
|
||||||
// https://devkitpro.org/wiki/libogc/GX
|
// https://devkitpro.org/wiki/libogc/GX
|
||||||
|
|
||||||
@ -44,6 +45,9 @@ static void InitGX(void) {
|
|||||||
|
|
||||||
xfbs[0] = Window_XFB;
|
xfbs[0] = Window_XFB;
|
||||||
xfbs[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode));
|
xfbs[1] = MEM_K0_TO_K1(SYS_AllocateFramebuffer(mode));
|
||||||
|
|
||||||
|
regionCB = GX_SetTexRegionCallback(NULL);
|
||||||
|
GX_SetTexRegionCallback(regionCB);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Gfx_Create(void) {
|
void Gfx_Create(void) {
|
||||||
@ -173,7 +177,8 @@ void Gfx_BindTexture(GfxResourceID texId) {
|
|||||||
CCTexture* tex = (CCTexture*)texId;
|
CCTexture* tex = (CCTexture*)texId;
|
||||||
if (!tex) tex = white_square;
|
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();
|
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);
|
extern void interop_InitContainer(void);
|
||||||
static void DoCreateWindow(void) {
|
static void DoCreateWindow(void) {
|
||||||
@ -525,15 +533,6 @@ void Window_SetSize(int width, int height) {
|
|||||||
void Window_RequestClose(void) {
|
void Window_RequestClose(void) {
|
||||||
Window_Main.Exists = false;
|
Window_Main.Exists = false;
|
||||||
Event_RaiseVoid(&WindowEvents.Closing);
|
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);
|
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 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) \
|
#define ROUND_TO_CHUNK_SIZE(v) \
|
||||||
((((v) + ALIGNED_VECTOR_CHUNK_SIZE - 1) / ALIGNED_VECTOR_CHUNK_SIZE) * ALIGNED_VECTOR_CHUNK_SIZE)
|
((((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;
|
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) */
|
/* 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) {
|
AV_FORCE_INLINE void* aligned_vector_resize(AlignedVector* vector, const uint32_t element_count) {
|
||||||
void* ret = NULL;
|
void* ret = NULL;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user