Use scene idx instead of pointer

scene_man
En Yi 2024-06-29 13:26:48 +08:00
parent 921b59d2ab
commit c5a30bee6d
5 changed files with 37 additions and 90 deletions

View File

@ -91,9 +91,8 @@ void process_inputs(GameEngine_t* engine, Scene_t* scene)
void change_scene(GameEngine_t* engine, unsigned int idx) void change_scene(GameEngine_t* engine, unsigned int idx)
{ {
engine->scenes[engine->curr_scene]->state = SCENE_ENDED; // Backwards compat
engine->curr_scene = idx; change_active_scene(engine, idx);
engine->scenes[engine->curr_scene]->state = SCENE_PLAYING;
} }
bool load_sfx(GameEngine_t* engine, const char* snd_name, uint32_t tag_idx) bool load_sfx(GameEngine_t* engine, const char* snd_name, uint32_t tag_idx)
@ -163,7 +162,7 @@ void init_scene(Scene_t* scene, action_func_t action_func)
scene->bg_colour = WHITE; scene->bg_colour = WHITE;
scene->action_function = action_func; scene->action_function = action_func;
scene->state = SCENE_ENDED; scene->state = SCENE_COMPLETE_ACTIVE;
scene->time_scale = 1.0f; scene->time_scale = 1.0f;
} }
@ -227,70 +226,6 @@ inline ActionResult do_action(Scene_t* scene, ActionType_t action, bool pressed)
return scene->action_function(scene, action, pressed); return scene->action_function(scene, action, pressed);
} }
static void process_scene_key_input(GameEngine_t* engine, int button, bool pressed)
{
if (engine->curr_scene == engine->max_scenes) return;
sc_queue_clear(&engine->scene_stack);
sc_queue_add_first(&engine->scene_stack, engine->scenes[engine->curr_scene]);
while (!sc_queue_empty(&engine->scene_stack))
{
Scene_t* scene = sc_queue_del_first(&engine->scene_stack);
ActionType_t action = sc_map_get_64(&scene->action_map, button);
ActionResult res = ACTION_PROPAGATE;
if (sc_map_found(&scene->action_map))
{
res = do_action(scene, action, pressed);
}
if (scene->child_scene.next != NULL)
{
sc_queue_add_first(&engine->scene_stack, scene->child_scene.next);
}
if (scene->child_scene.scene != NULL && res != ACTION_CONSUMED)
{
sc_queue_add_first(&engine->scene_stack, scene->child_scene.scene);
}
}
}
static void process_scene_mouse_input(GameEngine_t* engine, Vector2 pos, int button)
{
if (engine->curr_scene == engine->max_scenes) return;
sc_queue_clear(&engine->scene_stack);
sc_queue_add_first(&engine->scene_stack, engine->scenes[engine->curr_scene]);
while (!sc_queue_empty(&engine->scene_stack))
{
Scene_t* scene = sc_queue_del_first(&engine->scene_stack);
scene->mouse_pos = pos;
ActionResult res = ACTION_PROPAGATE;
ActionType_t action = sc_map_get_64(&scene->action_map, button);
if (sc_map_found(&scene->action_map))
{
if (IsMouseButtonDown(button))
{
res = do_action(scene, action, true);
}
else if (IsMouseButtonReleased(button))
{
res = do_action(scene, action, false);
}
}
if (scene->child_scene.next != NULL)
{
sc_queue_add_first(&engine->scene_stack, scene->child_scene.next);
}
if (scene->child_scene.scene != NULL && res != ACTION_CONSUMED)
{
sc_queue_add_first(&engine->scene_stack, scene->child_scene.scene);
}
}
}
void process_active_scene_inputs(GameEngine_t* engine) void process_active_scene_inputs(GameEngine_t* engine)
{ {
if (engine->focused_scene == NULL) return; if (engine->focused_scene == NULL) return;
@ -314,6 +249,8 @@ void update_curr_scene(GameEngine_t* engine)
{ {
Scene_t* scene = sc_queue_del_first(&engine->scene_stack); Scene_t* scene = sc_queue_del_first(&engine->scene_stack);
if ((scene->state & SCENE_ACTIVE_BIT) == 0) continue;
update_scene(scene, delta_time); update_scene(scene, delta_time);
if (scene->child_scene.next != NULL) if (scene->child_scene.next != NULL)
@ -336,6 +273,8 @@ void render_curr_scene(GameEngine_t* engine)
while ((elem = sc_heap_pop(&engine->scenes_render_order)) != NULL) while ((elem = sc_heap_pop(&engine->scenes_render_order)) != NULL)
{ {
Scene_t* scene = elem->data; Scene_t* scene = elem->data;
if ((scene->state & SCENE_RENDER_BIT) == 0) continue;
for (uint8_t i = 0; i < scene->layers.n_layers; ++i) for (uint8_t i = 0; i < scene->layers.n_layers; ++i)
{ {
RenderLayer_t* layer = scene->layers.render_layers + i; RenderLayer_t* layer = scene->layers.render_layers + i;
@ -355,8 +294,16 @@ void render_curr_scene(GameEngine_t* engine)
EndDrawing(); EndDrawing();
} }
void add_child_scene(Scene_t* child, Scene_t* parent) void add_child_scene(GameEngine_t* engine, unsigned int child_idx, unsigned int parent_idx)
{ {
if (
child_idx >= engine->max_scenes
|| parent_idx >= engine->max_scenes
) return;
Scene_t* child = engine->scenes[child_idx];
Scene_t* parent = engine->scenes[parent_idx];
if (parent == NULL) return; if (parent == NULL) return;
if (parent->child_scene.scene == NULL) if (parent->child_scene.scene == NULL)
@ -377,8 +324,11 @@ void add_child_scene(Scene_t* child, Scene_t* parent)
child->parent_scene = parent; child->parent_scene = parent;
} }
void remove_child_scene(Scene_t* child) void remove_child_scene(GameEngine_t* engine, unsigned int idx)
{ {
if (idx >= engine->max_scenes) return;
Scene_t* child = engine->scenes[idx];
if (child == NULL) return; if (child == NULL) return;
if (child->parent_scene == NULL) return; if (child->parent_scene == NULL) return;
@ -413,9 +363,9 @@ void remove_child_scene(Scene_t* child)
void change_active_scene(GameEngine_t* engine, unsigned int idx) void change_active_scene(GameEngine_t* engine, unsigned int idx)
{ {
engine->scenes[engine->curr_scene]->state = SCENE_ENDED; engine->scenes[engine->curr_scene]->state = 0;
engine->curr_scene = idx; engine->curr_scene = idx;
engine->scenes[engine->curr_scene]->state = SCENE_PLAYING; engine->scenes[engine->curr_scene]->state = SCENE_COMPLETE_ACTIVE;
} }
void change_focused_scene(GameEngine_t* engine, unsigned int idx) void change_focused_scene(GameEngine_t* engine, unsigned int idx)

View File

@ -39,14 +39,9 @@ typedef struct GameEngine {
Vector2 intended_window_size; Vector2 intended_window_size;
} GameEngine_t; } GameEngine_t;
typedef enum SceneState {
SCENE_PLAYING = 0, // All Systems Active
SCENE_SUSPENDED, //
SCENE_ENDED,
}SceneState_t;
#define SCENE_ACTIVE_BIT (1 << 0) // Systems Active #define SCENE_ACTIVE_BIT (1 << 0) // Systems Active
#define SCENE_RENDER_BIT (1 << 1) // Whether to render #define SCENE_RENDER_BIT (1 << 1) // Whether to render
#define SCENE_COMPLETE_ACTIVE (SCENE_ACTIVE_BIT | SCENE_RENDER_BIT)
typedef enum ActionResult { typedef enum ActionResult {
ACTION_PROPAGATE = 0, ACTION_PROPAGATE = 0,
@ -80,7 +75,7 @@ struct Scene {
float delta_time; float delta_time;
float time_scale; float time_scale;
Vector2 mouse_pos; Vector2 mouse_pos;
SceneState_t state; uint8_t state;
ParticleSystem_t part_sys; ParticleSystem_t part_sys;
GameEngine_t *engine; GameEngine_t *engine;
int8_t depth_index; int8_t depth_index;
@ -112,7 +107,7 @@ extern ActionResult do_action(Scene_t* scene, ActionType_t action, bool pressed)
void init_scene(Scene_t* scene, action_func_t action_func); void init_scene(Scene_t* scene, action_func_t action_func);
bool add_scene_layer(Scene_t* scene, int width, int height, Rectangle render_area); bool add_scene_layer(Scene_t* scene, int width, int height, Rectangle render_area);
void free_scene(Scene_t* scene); void free_scene(Scene_t* scene);
void add_child_scene(Scene_t* child, Scene_t* parent); void add_child_scene(GameEngine_t* engine, unsigned int child_idx, unsigned int parent_idx);
void remove_child_scene(Scene_t* child); void remove_child_scene(GameEngine_t* engine, unsigned int idx);
#endif // __ENGINE_H #endif // __ENGINE_H

4
main.c
View File

@ -86,7 +86,7 @@ int main(void)
// appear in the polling of raylib // appear in the polling of raylib
Scene_t* curr_scene = engine.scenes[engine.curr_scene]; Scene_t* curr_scene = engine.scenes[engine.curr_scene];
if (curr_scene->state == SCENE_ENDED && engine.curr_scene == 0) if (curr_scene->state == 0 && engine.curr_scene == 0)
{ {
break; break;
} }
@ -103,7 +103,7 @@ int main(void)
render_scene(curr_scene); render_scene(curr_scene);
update_sfx_list(&engine); update_sfx_list(&engine);
if (curr_scene->state != SCENE_PLAYING) if (curr_scene->state != 0)
{ {
sc_queue_clear(&key_buffer); sc_queue_clear(&key_buffer);
} }

View File

@ -97,6 +97,8 @@ int main(void)
init_engine(&engine, (Vector2){1280,640}); init_engine(&engine, (Vector2){1280,640});
SetTargetFPS(60); SetTargetFPS(60);
// TODO: Add render function
// Add a way to switch focused scene
static struct DummyScene dummy_scenes[6]; static struct DummyScene dummy_scenes[6];
for (uint8_t i = 0; i < 6; ++i) for (uint8_t i = 0; i < 6; ++i)
{ {
@ -119,9 +121,9 @@ int main(void)
} }
change_active_scene(&engine, 0); change_active_scene(&engine, 0);
add_child_scene(scenes[1], scenes[0]); add_child_scene(&engine, 1, 0);
add_child_scene(scenes[2], scenes[0]); add_child_scene(&engine, 2, 0);
add_child_scene(scenes[3], scenes[0]); add_child_scene(&engine, 3, 0);
float timer = 0; float timer = 0;
while(timer < 1.2f) while(timer < 1.2f)
@ -134,7 +136,7 @@ int main(void)
if (WindowShouldClose()) break; if (WindowShouldClose()) break;
} }
remove_child_scene(scenes[2]); remove_child_scene(&engine, 2);
timer = 0; timer = 0;
while(timer < 1.2f) while(timer < 1.2f)
{ {
@ -146,7 +148,7 @@ int main(void)
if (WindowShouldClose()) break; if (WindowShouldClose()) break;
} }
add_child_scene(scenes[4], scenes[0]); add_child_scene(&engine, 4, 0);
timer = 0; timer = 0;
while(timer < 1.2f) while(timer < 1.2f)
{ {
@ -158,7 +160,7 @@ int main(void)
if (WindowShouldClose()) break; if (WindowShouldClose()) break;
} }
add_child_scene(scenes[2], scenes[1]); add_child_scene(&engine, 2, 1);
timer = 0; timer = 0;
while(timer < 1.2f) while(timer < 1.2f)
{ {

View File

@ -27,7 +27,7 @@ static void exec_component_function(Scene_t* scene, int sel)
change_scene(scene->engine, 2); change_scene(scene->engine, 2);
break; break;
case 3: case 3:
scene->state = SCENE_ENDED; scene->state = 0;
break; break;
default: default:
break; break;