summaryrefslogtreecommitdiff
path: root/gltfview/src/game.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2024-01-19 07:21:45 -0800
committer3gg <3gg@shellblade.net>2024-01-19 07:21:45 -0800
commit4212e57d06afac8a19b09fdebc24bad10b78f1ac (patch)
tree322b2e5cc2764ebd1855565bb8d871d9df33d704 /gltfview/src/game.c
parentfc883e0b0449509ba2e1c5d14d187feee098ab34 (diff)
Plugin refactor, moving scene from game to plugin.
Diffstat (limited to 'gltfview/src/game.c')
-rw-r--r--gltfview/src/game.c138
1 files changed, 83 insertions, 55 deletions
diff --git a/gltfview/src/game.c b/gltfview/src/game.c
index c331190..64be4f3 100644
--- a/gltfview/src/game.c
+++ b/gltfview/src/game.c
@@ -39,6 +39,78 @@ static const int WIDTH = 1350;
39static const int HEIGHT = 900; 39static const int HEIGHT = 900;
40static const int MAX_FPS = 60; 40static const int MAX_FPS = 60;
41 41
42/// Initialize the game's plugin.
43static bool init_plugin(Game* game) {
44 assert(game);
45 assert(game->plugin);
46 // Plugin state is allowed to be null, either when the plugin does not
47 // expose an init() or when init() does not initialize a state.
48 if (plugin_resolve(game->plugin, plugin_init, "init")) {
49 State* plugin_state = 0;
50 if (!plugin_call(game->plugin, plugin_init, "init", game, &plugin_state)) {
51 return false;
52 }
53 set_plugin_state(game->plugin, plugin_state);
54 }
55 return true; // Plugin does not need to expose an init().
56}
57
58/// Shutdown the game's plugin.
59/// The game's plugin is allowed to be null in the call to this function.
60static void shutdown_plugin(Game* game) {
61 assert(game);
62 if (game->plugin &&
63 (plugin_resolve(game->plugin, plugin_shutdown, "shutdown"))) {
64 void* plugin_state = get_plugin_state(game->plugin);
65 plugin_call(game->plugin, plugin_shutdown, "shutdown", game, plugin_state);
66 set_plugin_state(game->plugin, 0);
67 }
68}
69
70/// Boot the game's plugin.
71static bool boot_plugin(Game* game) {
72 assert(game);
73 assert(game->plugin);
74 if (plugin_resolve(game->plugin, plugin_boot, "boot")) {
75 void* plugin_state = get_plugin_state(game->plugin);
76 return plugin_call(game->plugin, plugin_boot, "boot", game, plugin_state);
77 }
78 return true; // Plugin does not need to expose a boot().
79}
80
81/// Update the plugin's state.
82static void update_plugin(Game* game, double t, double dt) {
83 assert(game);
84 assert(game->plugin);
85 if (plugin_resolve(game->plugin, plugin_update, "update")) {
86 void* plugin_state = get_plugin_state(game->plugin);
87 plugin_call(
88 game->plugin, plugin_update, "update", game, plugin_state, t, dt);
89 }
90}
91
92/// Plugin render.
93static void render_plugin(const Game* game) {
94 assert(game);
95 assert(game->plugin);
96 if (plugin_resolve(game->plugin, plugin_render, "render")) {
97 void* plugin_state = get_plugin_state(game->plugin);
98 plugin_call(game->plugin, plugin_render, "render", game, plugin_state);
99 }
100}
101
102/// Plugin resize.
103static void resize_plugin(Game* game, int width, int height) {
104 assert(game);
105 assert(game->plugin);
106 if (plugin_resolve(game->plugin, plugin_resize, "resize")) {
107 void* plugin_state = get_plugin_state(game->plugin);
108 plugin_call(
109 game->plugin, plugin_resize, "resize", game, plugin_state, width,
110 height);
111 }
112}
113
42void app_end(Game* game); 114void app_end(Game* game);
43 115
44bool app_init(const GfxAppDesc* desc, void** app_state) { 116bool app_init(const GfxAppDesc* desc, void** app_state) {
@@ -88,30 +160,14 @@ bool app_init(const GfxAppDesc* desc, void** app_state) {
88 if (!(game->gfx = gfx_init())) { 160 if (!(game->gfx = gfx_init())) {
89 goto cleanup; 161 goto cleanup;
90 } 162 }
91 if (!(game->scene = gfx_make_scene())) { 163
164 if (!init_plugin(game)) {
92 goto cleanup; 165 goto cleanup;
93 } 166 }
94 if (!(game->camera = gfx_make_camera())) { 167 if (!boot_plugin(game)) {
95 goto cleanup; 168 goto cleanup;
96 } 169 }
97 170
98 if (plugin_resolve(game->plugin, plugin_init, "init")) {
99 void* plugin_state = plugin_call(game->plugin, plugin_init, "init", game);
100 if (!plugin_state) {
101 goto cleanup;
102 }
103 set_plugin_state(game->plugin, plugin_state);
104 }
105
106 if (plugin_resolve(game->plugin, plugin_boot, "boot")) {
107 void* plugin_state = get_plugin_state(game->plugin);
108 bool boot_success =
109 plugin_call(game->plugin, plugin_boot, "boot", plugin_state, game);
110 if (!boot_success) {
111 goto cleanup;
112 }
113 }
114
115 *app_state = game; 171 *app_state = game;
116 return true; 172 return true;
117 173
@@ -123,6 +179,7 @@ cleanup:
123 179
124void app_end(Game* game) { 180void app_end(Game* game) {
125 assert(game); 181 assert(game);
182 shutdown_plugin(game);
126 if (game->gfx) { 183 if (game->gfx) {
127 gfx_destroy(&game->gfx); 184 gfx_destroy(&game->gfx);
128 } 185 }
@@ -136,53 +193,24 @@ void app_end(Game* game) {
136 193
137void app_update(Game* game, double t, double dt) { 194void app_update(Game* game, double t, double dt) {
138 plugin_engine_update(game->plugin_engine); 195 plugin_engine_update(game->plugin_engine);
139 if (plugin_reloaded(game->plugin) && 196 if (plugin_reloaded(game->plugin)) {
140 plugin_resolve(game->plugin, plugin_init, "init")) { 197 shutdown_plugin(game);
141 void* plugin_state = plugin_call(game->plugin, plugin_init, "init", game); 198 const bool result = init_plugin(game);
142 assert(plugin_state); // TODO: handle error better. 199 assert(result); // TODO: handle error better.
143 set_plugin_state(game->plugin, plugin_state);
144 } 200 }
145 201
146 if (plugin_resolve(game->plugin, plugin_update, "update")) { 202 update_plugin(game, t, dt);
147 // Plugin state may be null if plugin does not expose init().
148 void* plugin_state = get_plugin_state(game->plugin);
149 plugin_call(
150 game->plugin, plugin_update, "update", plugin_state, game, t, dt);
151 }
152} 203}
153 204
154void app_render(const Game* game) { 205void app_render(const Game* game) {
155 RenderBackend* render_backend = gfx_get_render_backend(game->gfx); 206 RenderBackend* render_backend = gfx_get_render_backend(game->gfx);
156 Renderer* renderer = gfx_get_renderer(game->gfx);
157
158 gfx_start_frame(render_backend); 207 gfx_start_frame(render_backend);
159 208 render_plugin(game);
160 gfx_render_scene(
161 renderer,
162 &(RenderSceneParams){
163 .mode = RenderDefault, .scene = game->scene, .camera = game->camera});
164
165 if (plugin_resolve(game->plugin, plugin_render, "render")) {
166 // Plugin state may be null if plugin does not expose init().
167 void* plugin_state = get_plugin_state(game->plugin);
168 plugin_call(game->plugin, plugin_render, "render", plugin_state, game);
169 }
170
171 gfx_end_frame(render_backend); 209 gfx_end_frame(render_backend);
172} 210}
173 211
174void app_resize(Game* game, int width, int height) { 212void app_resize(Game* game, int width, int height) {
175 RenderBackend* render_backend = gfx_get_render_backend(game->gfx); 213 resize_plugin(game, width, height);
176 gfx_set_viewport(render_backend, width, height);
177
178 const R fovy = 90 * TO_RAD;
179 const R aspect = (R)width / (R)height;
180 const R near = 0.1;
181 const R far = 1000;
182 const mat4 projection = mat4_perspective(fovy, aspect, near, far);
183
184 Camera* camera = gfx_get_camera_camera(game->camera);
185 camera->projection = projection;
186} 214}
187 215
188GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS); 216GFX_APP_MAIN(WIDTH, HEIGHT, MAX_FPS);